Skip to content
Snippets Groups Projects
Commit 11480021 authored by Jure's avatar Jure
Browse files

Merge master

parents deab2ffe 3ad02171
No related branches found
No related tags found
No related merge requests found
Showing
with 728 additions and 0 deletions
.icon {
color: var(--color-primary);
display: inline-flex;
margin-right: 10px;
}
.filename {
font-size: 0.7em;
height: 2em;
max-width: 25ch;
overflow-wrap: break-word;
padding: 0;
}
A file attached to a note.
```js
const value = {
name: faker.system.commonFileName(),
url: faker.internet.url()
};
<Attachment value={value}/>
```
import React from 'react'
import classes from './Avatar.local.scss'
const Avatar = ({ status, width, height, reviewerLetter }) => {
const classValue =
status && classes[status.toLowerCase()] ? status.toLowerCase() : 'default'
return (
<svg
className={classes[classValue]}
height={height || '70'}
viewBox={`0 0 ${width ? width + 5 : '105'} ${height || '70'}`}
width={width || '100'}
xmlns="http://www.w3.org/2000/svg"
>
<path
className={classes.persona}
d=" M 47.666 50.14 C 44.947 49 41.588 47.535 41.588 46.395 L 41.588 39.07 C 45.587 35.977 47.986 31.093 47.986 26.047 L 47.986 16.279 C 47.986 7.326 40.788 0 31.991 0 C 23.193 0 15.995 7.326 15.995 16.279 L 15.995 26.047 C 15.995 31.093 18.395 36.14 22.393 39.07 L 22.393 46.395 C 22.393 47.372 19.034 48.837 16.315 50.14 C 9.757 52.907 0 57.14 0 68.372 L 0 70 L 63.981 70 L 63.981 68.372 C 63.981 57.14 54.224 52.907 47.666 50.14 Z "
/>
<path
className={classes.check}
d=" M 60.106 37.467 C 59.299 36.645 58.895 35.617 58.895 34.486 C 58.895 33.458 59.299 32.43 60.106 31.608 C 60.813 30.888 61.823 30.375 62.934 30.375 C 64.045 30.375 65.055 30.888 65.762 31.608 L 74.246 40.242 L 93.132 21.021 C 93.839 20.301 94.95 19.89 95.96 19.89 C 97.071 19.89 98.081 20.301 98.788 21.021 C 99.596 21.843 100 22.871 100 24.002 C 100 25.03 99.596 26.057 98.788 26.88 L 74.246 51.857 L 60.106 37.467 Z "
/>
<path
className={classes.x}
d="M 70.964 37.518 L 62.025 46.615 C 61.217 47.54 60.712 48.671 60.712 49.904 C 60.712 51.138 61.217 52.268 62.025 53.091 C 62.934 54.016 64.045 54.427 65.257 54.427 C 66.469 54.427 67.58 54.016 68.388 53.091 L 77.326 43.994 L 86.265 53.091 C 87.173 54.016 88.284 54.427 89.496 54.427 C 90.708 54.427 91.819 54.016 92.627 53.091 C 93.536 52.268 93.94 51.138 93.94 49.904 C 93.94 48.671 93.536 47.54 92.627 46.615 L 83.689 37.518 L 92.627 28.422 C 93.536 27.599 93.94 26.469 93.94 25.235 C 93.94 24.002 93.536 22.871 92.627 21.946 C 91.819 21.124 90.708 20.61 89.496 20.61 C 88.284 20.61 87.173 21.124 86.265 21.946 L 77.326 31.043 L 68.388 21.946 C 67.58 21.124 66.469 20.61 65.257 20.61 C 64.045 20.61 62.934 21.124 62.025 21.946 C 61.217 22.871 60.712 24.002 60.712 25.235 C 60.712 26.469 61.217 27.599 62.025 28.422 L 70.964 37.518 Z"
/>
<path
className={classes['question-mark']}
d=" M 79.674 23.203 L 79.674 23.203 Q 83.397 23.203 85.424 25.077 L 85.424 25.077 L 85.424 25.077 Q 87.451 26.95 87.451 29.771 L 87.451 29.771 L 87.451 29.771 Q 87.451 31.75 86.728 33.14 L 86.728 33.14 L 86.728 33.14 Q 86.003 34.529 85.011 35.371 L 85.011 35.371 L 85.011 35.371 Q 84.018 36.214 82.404 37.224 L 82.404 37.224 L 82.404 37.224 Q 80.625 38.361 79.798 39.182 L 79.798 39.182 L 79.798 39.182 Q 78.97 40.003 78.97 41.308 L 78.97 41.308 L 78.97 41.308 Q 78.97 41.94 79.094 42.319 L 79.094 42.319 L 72.971 43.287 L 72.971 43.287 Q 72.64 42.024 72.64 41.098 L 72.64 41.098 L 72.64 41.098 Q 72.64 39.203 73.282 37.898 L 73.282 37.898 L 73.282 37.898 Q 73.923 36.593 74.833 35.814 L 74.833 35.814 L 74.833 35.814 Q 75.743 35.035 77.15 34.108 L 77.15 34.108 L 77.15 34.108 Q 78.681 33.056 79.405 32.298 L 79.405 32.298 L 79.405 32.298 Q 80.129 31.54 80.129 30.403 L 80.129 30.403 L 80.129 30.403 Q 80.129 29.603 79.653 29.203 L 79.653 29.203 L 79.653 29.203 Q 79.177 28.803 78.35 28.803 L 78.35 28.803 L 78.35 28.803 Q 76.405 28.803 74.006 31.245 L 74.006 31.245 L 70.282 27.708 L 70.282 27.708 Q 74.171 23.203 79.674 23.203 L 79.674 23.203 Z M 75.371 53.94 L 75.371 53.94 Q 73.84 53.94 72.93 52.951 L 72.93 52.951 L 72.93 52.951 Q 72.02 51.961 72.02 50.445 L 72.02 50.445 L 72.02 50.445 Q 72.02 48.635 73.24 47.33 L 73.24 47.33 L 73.24 47.33 Q 74.461 46.024 76.24 46.024 L 76.24 46.024 L 76.24 46.024 Q 77.77 46.024 78.681 47.014 L 78.681 47.014 L 78.681 47.014 Q 79.591 48.003 79.591 49.561 L 79.591 49.561 L 79.591 49.561 Q 79.591 51.414 78.37 52.677 L 78.37 52.677 L 78.37 52.677 Q 77.15 53.94 75.371 53.94 L 75.371 53.94 Z "
/>
<g transform="matrix(1.01,0,0,1.028,64.651,6.065)">
<text
className={classes['reviewer-number']}
transform="matrix(1,0,0,1,0,46.75)"
>
{reviewerLetter}
</text>
</g>
</svg>
)
}
export default Avatar
figure {
margin: 0 auto 2px;
text-align: center;
width: auto;
}
svg {
height: auto;
max-height: 100vh;
max-width: 100%;
width: auto;
}
.default {
.persona {
display: block;
fill: var(--color-primary);
}
.check {
display: none;
}
.x {
display: none;
}
.question-mark {
display: none;
}
.reviewer-number {
display: none;
}
}
.accepted {
.persona {
display: block;
fill: var(--color-primary);
}
.check {
display: block;
fill: var(--color-primary);
}
.x {
display: none;
}
.question-mark {
display: none;
}
.reviewer-number {
display: none;
}
}
.declined {
.persona {
display: block;
fill: var(--color-danger);
}
.check {
display: none;
}
.x {
display: block;
fill: var(--color-danger);
}
.question-mark {
display: none;
}
.reviewer-number {
display: none;
}
}
.pending {
.persona {
display: block;
fill: var(--color-pending);
}
.check {
display: none;
}
.x {
display: none;
}
.question-mark {
display: block;
fill: var(--color-pending);
}
.reviewer-number {
display: none;
}
}
.submitted {
.persona {
display: block;
fill: var(--color-primary);
}
.check {
display: none;
}
.x {
display: none;
}
.question-mark {
display: none;
}
.reviewer-number {
fill: var(--color-primary);
font-family: 'Fira Sans Condensed', sans-serif;
font-size: 50px;
font-style: normal;
font-weight: 600;
stroke: none;
text-transform: uppercase;
}
}
.fullname {
color: red;
font-family: var(--font-reviewer);
}
A general purpose Avatar element.
```js
const statusFactory = () => {
const statuses = ['Accepted', 'Pending', 'Declined', 'Submitted']
return statuses[Math.floor(Math.random() * statuses.length)]
};
<Avatar status={statusFactory()}/>
```
import React from 'react'
import classes from './Badge.local.scss'
const Badge = ({ count, label, plural }) => (
<span className={classes.root}>
<span className={classes.count}>{count}</span>
<span className={classes.label}>
{plural && count !== 1 ? plural : label}
</span>
</span>
)
export default Badge
.root {
align-items: center;
// background: lightgrey;
background: linear-gradient(#fff 0, #fff 1.1em, grey 1.1em, grey 1.15em, #fff 1.15em, #fff 2em);
color: inherit;
display: inline-flex;
font-size: 0.8rem;
margin-right: 1em;
padding-bottom: 1em;
}
.count {
border-radius: 50%;
color: grey;
font-size: 1em;
font-weight: 600;
padding-right: 0.5em;
text-align: center;
}
.label {
display: inline-block;
padding: 0;
text-shadow: 0.05em 0.05em 0 #fff, -0.05em -0.05em 0 #fff, -0.05em 0.05em 0 #fff, 0.05em -0.05em 0 #fff;
}
A badge that displays a count and a label.
```js
<Badge count={5} label="created"/>
```
A plural form of the label can be provided.
```js
<div>
<Badge count={1} label="thing" plural="things"/>
<Badge count={99} label="thing" plural="things"/>
<Badge count={0} label="thing" plural="things"/>
<Badge count={299} label="thing" plural="things"/>
</div>
```
import React from 'react'
import classnames from 'classnames'
import classes from './Button.local.scss'
const Button = ({
className,
children,
type = 'button',
disabled,
primary,
onClick,
}) => (
<button
className={classnames(className, classes.root, {
[classes.disabled]: disabled,
[classes.primary]: primary,
})}
disabled={disabled}
onClick={onClick}
type={type}
>
{children}
</button>
)
export default Button
.root {
background: #ddd;
border: none;
cursor: pointer;
font-family: var(--font-interface);
font-size: inherit;
letter-spacing: 0.05em;
padding: 10px 20px;
position: relative;
text-transform: uppercase;
}
.root:hover,
.root:focus {
background: #777;
color: white;
outline: 1px solid transparent;
}
// this will be added to the button that need a feedback to the user.
// &::after {
// content: "Saved!";
// top: 20%;
// left: 115%;
// position: absolute;
// background: var(--color-primary);
// color: white;
// padding: 0.1em 0.3em;
// opacity: 0;
// }
.root :active {
transform: scale(0.8);
}
.root ::after {
animation: 1s warning;
opacity: 1;
}
.primary {
background-color: var(--color-primary);
border: 2px solid transparent;
border-bottom: 4px solid var(--color-primary);
color: white;
}
.primary:hover {
background: white;
border: 2px solid var(--color-primary);
border-bottom: 4px solid var(--color-primary);
color: var(--color-primary);
outline: 1px solid transparent;
}
.primary:focus {
background: white;
border: 2px solid var(--color-primary);
border-bottom: 4px solid var(--color-primary);
box-shadow: 0 2px 0 0 var(--color-primary);
color: var(--color-primary);
outline: 1px solid transparent;
}
.disabled {
background: white;
border: 2px solid transparent;
border-bottom: 2px solid #bbb;
color: #bbb;
}
.disabled:hover {
background: transparent;
border: 2px solid transparent;
border-bottom: 2px solid #bbb;
color: #aaa;
cursor: not-allowed;
}
.disabled:hover::after {
color: var(--color-danger);
content: "sorry, this action is not possible";
display: inline;
font-size: 0.9em;
font-style: italic;
left: 115%;
letter-spacing: 0;
opacity: 1;
position: absolute;
text-align: left;
text-transform: lowercase;
top: 30%;
// width: 30ch;
}
.addFile {
background: none;
border: none;
font-style: normal;
letter-spacing: 0;
padding: 0;
text-transform: none;
}
A button.
```js
<Button>Save</Button>
```
A button can be disabled.
```js
<Button disabled>Save</Button>
```
A button can be marked as the "primary" action.
```js
<Button primary>Save</Button>
```
import React from 'react'
import classnames from 'classnames'
import classes from './Checkbox.local.scss'
const Checkbox = ({
inline,
name,
value,
label,
checked,
required,
onChange,
}) => (
<label
className={classnames(classes.root, {
[classes.inline]: inline,
})}
>
<input
checked={checked || false}
className={classes.input}
name={name}
onChange={onChange}
required={required}
type="checkbox"
value={value}
/>
<span>{label}</span>
</label>
)
export default Checkbox
.root {
align-items: center;
display: flex;
font-family: var(--font-author);
font-size: 1em;
font-style: italic;
letter-spacing: 1px;
transition: all 2s;
}
.root.inline {
display: inline-flex;
}
.root.inline:not(:last-child) {
margin-right: 2.7em;
}
.root:not(.inline):not(:last-child) {
margin-bottom: 0.5rem;
}
.root .input {
display: none;
margin-right: 0.25rem;
}
.root span::before {
background-size: 0;
border: 1px solid black; // border-radius: 20px;
content: ' ';
display: inline-block;
height: 9px;
margin-right: 0.3em;
transition: border 0.5s ease, background-size 0.3s ease;
vertical-align: middle;
width: 9px;
}
.root:hover span::before {
//background-size: 100%;
background: var(--color-primary);
box-shadow: inset 1px 1px 0 0 white, inset -1px -1px 0 0 white;
}
.root input:checked + span {
font-weight: 600;
&::before {
background: black;
border: 1px solid black;
box-shadow: inset 1px 1px 0 0 white, inset -1px -1px 0 0 white;
transition: border 0.5s ease, background-size 0.3s ease;
}
}
A checkbox.
```js
initialState = { checked: null };
<Checkbox
name="checkbox"
checked={state.checked}
onChange={event => setState({ checked: event.target.checked })}/>
```
A checked checkbox.
```js
initialState = { checked: true };
<Checkbox
name="checkbox-checked"
checked={state.checked}
onChange={event => setState({ checked: event.target.checked })}/>
```
A checkbox with a label.
```js
initialState = { checked: false };
<Checkbox
name="checkbox-labelled"
checked={state.checked}
label="Foo"
onChange={event => setState({ checked: event.target.checked })}/>
```
import React from 'react'
import classes from './File.local.scss'
const extension = ({ name }) => name.replace(/^.+\./, '')
const File = ({ value }) => (
<div className={classes.root}>
<div className={classes.icon}>
<div className={classes.extension}>{extension(value)}</div>
</div>
<div className={classes.name}>
<a download={value.name} href={value.url}>
{value.name}
</a>
</div>
</div>
)
export default File
.root {
align-items: center;
display: inline-flex;
flex-direction: column;
margin-bottom: 2em;
margin-right: 3em;
position: relative;
width: 20ch;
&::before,
&::after {
cursor: pointer;
transition: transform 0.3s;
}
&::after {
background: var(--color-danger);
border: 1px solid white;
color: white;
content: 'remove';
cursor: pointer;
font-size: 0.8em;
left: 70%;
letter-spacing: 0.5px;
padding: 0.2em 0.4em;
position: absolute;
text-transform: uppercase;
top: 4em;
transform: scaleX(0);
transform-origin: 0 0;
z-index: 2;
}
&::before {
background: var(--color-primary);
border: 1px solid white;
color: white;
content: 'replace';
cursor: pointer;
font-size: 0.8em;
left: 70%;
letter-spacing: 0.5px;
padding: 0.2em 0.4em;
position: absolute;
text-transform: uppercase;
top: 6em;
transform: scaleX(0);
transform-origin: 0 0;
z-index: 3;
}
.icon {
background: #ddd;
height: 100px;
padding: 5px;
position: relative;
transition: transform 0.3s ease;
width: 70px;
}
.extension {
background: #888;
color: white;
font-size: 12px;
left: 20px;
padding: 2px;
position: absolute;
right: 0;
text-align: center;
text-transform: uppercase;
top: 20px;
}
.name {
color: #aaa;
font-size: 0.9em;
font-style: italic;
margin: 5px;
max-width: 15ch;
text-align: center;
word-break: break-all; /* to divide into lines */
}
&:hover {
.extension {
background: white;
border-right: 2px solid #ddd;
color: var(--color-primary);
}
.icon {
background: var(--color-primary);
transform: skewY(6deg) rotate(-6deg);
}
&::after,
&::before {
transform: scaleX(1);
}
}
}
A file.
```js
const value = {
name: faker.system.commonFileName(),
// type: faker.system.commonFileType(),
// size: faker.random.number(),
};
<File value={value}/>
```
Upload progress is displayed as an overlay.
```js
const value = {
name: faker.system.commonFileName(),
};
<File value={value} progress={0.5}/>
```
An upload error is displayed above the file.
```js
const value = {
name: faker.system.commonFileName(),
};
<File value={value} error="There was an error"/>
```
import React from 'react'
import { pascalize } from 'humps'
import * as icons from 'react-feather'
import classes from './Icon.local.scss'
const Icon = ({ children, color = 'black', size = 24 }) => {
// convert `arrow_left` to `ArrowLeft`
const name = pascalize(children)
// select the icon
const icon = icons[name]
return <span className={classes.root}>{icon({ color, size })}</span>
}
export default Icon
.root {
display: inline-flex;
}
An icon, from the [Feather](https://feathericons.com/) icon set.
```js
<Icon>arrow_right</Icon>
```
The color can be changed.
```js
<Icon color="red">arrow_right</Icon>
```
The size can be changed.
```js
<Icon size={48}>arrow_right</Icon>
```
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment