new examples buttonModules & buttonEmotion + refac

This commit is contained in:
Rodrigo Antinarelli 2020-02-19 19:45:17 -03:00 committed by James A. Petts
parent d03e3d3928
commit b53d4528fb
16 changed files with 1347 additions and 22089 deletions

View File

@ -1,3 +1,6 @@
{
"extends": "stylelint-config-standard"
"extends": "stylelint-config-standard",
"rules": {
"declaration-empty-line-before": "never"
}
}

View File

@ -0,0 +1,3 @@
module.exports = {
plugins: ['gatsby-plugin-sass'],
};

View File

@ -18,6 +18,7 @@
"README.md"
],
"scripts": {
"start": "yarn run dev",
"dev": "concurrently \"npm run watch:css\" \"docz dev\"",
"build": "concurrently \"npm run build:css\" \"docz build\"",
"serve": "docz serve",
@ -25,8 +26,13 @@
"watch:css": "postcss src/styles/tailwind.css -o src/gatsby-theme-docz/app.css -w"
},
"dependencies": {
"@emotion/core": "^10.0.27",
"@emotion/styled": "^10.0.27",
"classnames": "^2.2.6",
"concurrently": "^5.1.0",
"docz": "latest",
"docz": "^2.2.0",
"gatsby-plugin-sass": "^2.1.28",
"node-sass": "^4.13.1",
"prop-types": "^15.7.2",
"react": "^16.11.0",
"react-dom": "^16.11.0"

View File

@ -1,79 +1,18 @@
import React from 'react';
import PropTypes from 'prop-types';
const Button = ({
children,
variant = defaults.variant,
color = defaults.color,
size = defaults.size,
radius = defaults.radius,
disabled = defaults.disabled,
elevation,
type = defaults.type,
startIcon: startIconProp,
endIcon: endIconProp,
className,
...rest
}) => {
const hasIcon = startIconProp || endIconProp;
const getClasses = () => {
const classes = [];
let buttonElevation;
if (variant === 'text') {
if (elevation) {
buttonElevation = elevation;
} else {
buttonElevation = false;
}
} else {
buttonElevation = defaults.elevation;
}
classes.push(variantClasses[variant][color]);
classes.push(radiusClasses[radius]);
classes.push(sizeClasses[size]);
classes.push(disabledClasses[disabled]);
classes.push(elevationClasses[buttonElevation]);
classes.push(className);
if (hasIcon) {
classes.push(baseIconClasses);
}
return classes.join(' ');
};
const baseIconClasses = 'inline-flex items-center';
const baseClasses =
'outline-none transition duration-300 ease-in-out rounded font-bold focus:outline-none';
const startIcon = startIconProp && (
<div className="mr-2">{startIconProp}</div>
);
const endIcon = endIconProp && <div className="ml-2">{endIconProp}</div>;
return (
<button className={`${baseClasses} ${getClasses()}`} type={type} {...rest}>
{startIcon}
{children}
{endIcon}
</button>
);
};
import classnames from 'classnames';
const defaults = {
variant: 'outlined',
variant: 'contained',
color: 'default',
size: 'medium',
radius: 'medium',
disabled: false,
elevation: true,
type: 'button',
};
const radiusClasses = {
none: '',
small: 'rounded-sm',
medium: 'rounded-md',
large: 'rounded-lg',
@ -85,11 +24,6 @@ const disabledClasses = {
false: '',
};
const elevationClasses = {
true: 'shadow',
false: 'shadow-none',
};
const variantClasses = {
text: {
default: 'hover:bg-gray-200 text-black',
@ -114,14 +48,55 @@ const sizeClasses = {
large: 'py-3 px-6 text-lg',
};
const Button = ({
children,
variant = defaults.variant,
color = defaults.color,
size = defaults.size,
radius = defaults.radius,
disabled = defaults.disabled,
type = defaults.type,
startIcon: startIconProp,
endIcon: endIconProp,
className,
...rest
}) => {
const baseClasses =
'inline-flex items-center outline-none transition duration-300 ease-in-out font-bold focus:outline-none';
const startIcon = startIconProp && (
<div className="mr-2">{startIconProp}</div>
);
const endIcon = endIconProp && <div className="ml-2">{endIconProp}</div>;
return (
<button
className={classnames(
baseClasses,
variantClasses[variant][color],
radiusClasses[radius],
sizeClasses[size],
disabledClasses[disabled],
className
)}
type={type}
{...rest}
>
{startIcon}
{children}
{endIcon}
</button>
);
};
Button.propTypes = {
children: PropTypes.node,
size: PropTypes.oneOf(['small', 'medium', 'large']),
radius: PropTypes.oneOf(['small', 'medium', 'large', 'full']),
radius: PropTypes.oneOf(['none', 'small', 'medium', 'large', 'full']),
variant: PropTypes.oneOf(['text', 'outlined', 'contained']),
color: PropTypes.oneOf(['default', 'primary', 'secondary']),
disabled: PropTypes.bool,
elevation: PropTypes.bool,
type: PropTypes.string,
startIcon: PropTypes.node,
endIcon: PropTypes.node,

View File

@ -0,0 +1,318 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled from '@emotion/styled';
import { fade } from '../../utils/colorManipulator';
import capitalize from '../../utils/capitalize';
import theme from '../../styles/theme';
const styles = {
base: {
'box-sizing': 'border-box',
'min-width': '64px',
padding: '6px 16px',
'border-radius': '20px',
color: theme.palette.primary.main,
transition: 'all 300ms ease',
'&:hover': {
'text-decoration': 'none',
'background-color': fade(
theme.palette.default.main,
theme.palette.action.hoverOpacity
),
},
'&:active': {
outline: 'none',
},
'&:focus': {
outline: 'none',
},
'&:disabled': {
color: theme.palette.action.disabled,
cursor: 'not-allowed',
},
},
/* Styles applied to the root element if `variant="text"`. */
text: {
padding: '6px 8px',
},
/* Styles applied to the root element if `variant="text"` and `color="primary"`. */
textPrimary: {
color: theme.palette.primary.main,
'&:hover': {
'background-color': fade(
theme.palette.primary.light,
theme.palette.action.hoverOpacity
),
},
},
/* Styles applied to the root element if `variant="text"` and `color="secondary"`. */
textSecondary: {
color: theme.palette.secondary.main,
'&:hover': {
'background-color': fade(
theme.palette.secondary.light,
theme.palette.action.hoverOpacity
),
},
},
/* Styles applied to the root element if `variant="outlined"`. */
outlined: {
padding: '5px 15px',
border: `1px solid ${
theme.palette.type === 'light'
? 'rgba(0, 0, 0, 0.23)'
: 'rgba(255, 255, 255, 0.23)'
}`,
'&:disabled': {
border: `1px solid ${theme.palette.default.main}`,
},
},
/* Styles applied to the root element if `variant="outlined"` and `color="primary"`. */
outlinedPrimary: {
color: theme.palette.primary.main,
border: `1px solid ${fade(
theme.palette.primary.light,
theme.palette.action.hoverOpacity
)}`,
'&:hover': {
border: `1px solid ${theme.palette.primary.main}`,
'background-color': fade(
theme.palette.primary.light,
theme.palette.action.hoverOpacity
),
},
},
/* Styles applied to the root element if `variant="outlined"` and `color="secondary"`. */
outlinedSecondary: {
color: theme.palette.secondary.main,
border: `1px solid ${fade(
theme.palette.secondary.main,
theme.palette.action.hoverOpacity
)}`,
'&:hover': {
border: `1px solid ${theme.palette.secondary.main}`,
'background-color': fade(
theme.palette.secondary.light,
theme.palette.action.hoverOpacity
),
},
'&$disabled': {
border: `1px solid ${theme.palette.action.disabled}`,
},
},
/* Styles applied to the root element if `variant="contained"`. */
contained: {
color: '#000',
'background-color': theme.palette.default.light,
// 'box-shadow': theme.shadows[2],
'&:hover': {
'background-color': theme.palette.default.light,
// 'box-shadow': theme.shadows[4],
'&$disabled': {
'background-color': theme.palette.action.disabledBackground,
},
},
'&:active': {
// 'box-shadow': typographyows[8],
},
'&$disabled': {
color: theme.palette.action.disabled,
// 'box-shadow': theme.shadows[0],
'background-color': theme.palette.action.disabledBackground,
},
},
/* Styles applied to the root element if `variant="contained"` and `color="primary"`. */
containedPrimary: {
color: 'white',
'background-color': theme.palette.primary.main,
'&:hover': {
'background-color': fade(
theme.palette.primary.light,
theme.palette.action.hoverOpacity
),
},
},
/* Styles applied to the root element if `variant="contained"` and `color="secondary"`. */
containedSecondary: {
color: 'white',
'background-color': theme.palette.secondary.main,
'&:hover': {
'background-color': fade(
theme.palette.secondary.light,
theme.palette.action.hoverOpacity
),
},
},
/* Styles applied to the root element if `size="small"` and `variant="text"`. */
textSizeSmall: {
padding: '4px 5px',
fontSize: '13px',
},
/* Styles applied to the root element if `size="medium"` and `variant="text"`. */
textSizeMedium: {
padding: '6px 9px',
fontSize: '14px',
},
/* Styles applied to the root element if `size="large"` and `variant="text"`. */
textSizeLarge: {
padding: '8px 11px',
fontSize: '15px',
},
/* Styles applied to the root element if `size="small"` and `variant="outlined"`. */
outlinedSizeSmall: {
padding: '3px 9px',
fontSize: '13px',
},
/* Styles applied to the root element if `size="medium"` and `variant="outlined"`. */
outlinedSizeMedium: {
padding: '5px 15px',
fontSize: '14px',
},
/* Styles applied to the root element if `size="large"` and `variant="outlined"`. */
outlinedSizeLarge: {
padding: '7px 21px',
fontSize: '15px',
},
/* Styles applied to the root element if `size="small"` and `variant="contained"`. */
containedSizeSmall: {
padding: '4px 10px',
fontSize: '13px',
},
/* Styles applied to the root element if `size="medium"` and `variant="contained"`. */
containedSizeMedium: {
padding: '6px 16px',
fontSize: '13px',
},
/* Styles applied to the root element if `size="large"` and `variant="contained"`. */
containedSizeLarge: {
padding: '8px 22px',
fontSize: '15px',
},
/* Styles applied to the startIcon element if supplied. */
startIcon: {
display: 'inherit',
'margin-right': '8px',
'margin-left': '-4px',
},
/* Styles applied to the endIcon element if supplied. */
endIcon: {
display: 'inherit',
'margin-right': '-4px',
'margin-left': '8px',
},
};
const BaseButton = styled.button`
display: inline-flex;
align-items: center;
justify-content: center;
position: relative;
background-color: transparent;
outline: 0;
border: 0;
margin: 0;
border-radius: 0;
padding: 0;
cursor: pointer;
user-select: none;
vertical-align: middle;
-moz-appearance: none;
appearance: none;
text-decoration: none;
color: inherit;
`;
const ButtonIcon = styled.div`
${props => ({
...styles[`${props.icon}`],
})}
`;
const ButtonComponent = styled(BaseButton)`
/* base styles */
${props => ({
...styles.base,
})}
/* variant styles */
${props => ({
...styles[`${props.variant}`],
})}
/* color */
${props => ({
...styles[`${props.variant}${capitalize(props.color)}`],
})}
/* size styles */
${props => ({
...styles[`${props.variant}Size${capitalize(props.size)}`],
})}
`;
const Button = props => {
const {
children,
variant = defaults.variant,
color = defaults.color,
size = defaults.size,
radius = defaults.radius,
disabled = defaults.disabled,
elevation,
type = defaults.type,
startIcon: startIconProp,
endIcon: endIconProp,
className,
...rest
} = props;
const startIcon = startIconProp && (
<ButtonIcon icon="startIcon">{startIconProp}</ButtonIcon>
);
const endIcon = endIconProp && (
<ButtonIcon icon="endIcon">{endIconProp}</ButtonIcon>
);
return (
<ButtonComponent
variant={variant}
color={color}
size={size}
radius={radius}
disabled={disabled}
type={type}
{...rest}
>
{startIcon}
{children}
{endIcon}
</ButtonComponent>
);
};
const defaults = {
variant: 'outlined',
color: 'default',
size: 'large',
radius: 'medium',
disabled: false,
elevation: true,
type: 'button',
};
Button.propTypes = {
children: PropTypes.node,
size: PropTypes.oneOf(['small', 'medium', 'large']),
radius: PropTypes.oneOf(['small', 'medium', 'large', 'full']),
variant: PropTypes.oneOf(['text', 'outlined', 'contained']),
color: PropTypes.oneOf(['default', 'primary', 'secondary']),
disabled: PropTypes.bool,
elevation: PropTypes.bool,
type: PropTypes.string,
startIcon: PropTypes.node,
endIcon: PropTypes.node,
className: PropTypes.node,
};
export default Button;

View File

@ -0,0 +1,180 @@
---
name: ButtonEmotion
menu: Components
route: components/button-emotion
---
import { Playground, Props } from 'docz';
import Button from './';
# ButtonEmotion
Buttons are used to execute actions when users interacts with them.
## Properties
<Props of={Button} />
## Contained Buttons
<Playground>
<>
<Button variant="contained" style={{ margin: 5 }}>
Default
</Button>
<Button variant="contained" color="primary" style={{ margin: 5 }}>
Primary
</Button>
<Button variant="contained" color="secondary" style={{ margin: 5 }}>
Secondary
</Button>
</>
</Playground>
## Outlined Buttons
<Playground>
<>
<Button variant="outlined" style={{ margin: 5 }}>
Default
</Button>
<Button variant="outlined" color="primary" style={{ margin: 5 }}>
Primary
</Button>
<Button variant="outlined" color="secondary" style={{ margin: 5 }}>
Secondary
</Button>
</>
</Playground>
## Text Buttons
<Playground>
<>
<Button variant="text" style={{ margin: 5 }}>
Default
</Button>
<Button variant="text" color="primary" style={{ margin: 5 }}>
Primary
</Button>
<Button variant="text" color="secondary" style={{ margin: 5 }}>
Secondary
</Button>
</>
</Playground>
## Sizes
<Playground>
<>
<div>
<Button variant="text" size="small" style={{ margin: 5 }}>
Small
</Button>
<Button variant="contained" size="medium" style={{ margin: 5 }}>
Medium
</Button>
<Button variant="outlined" size="large" style={{ margin: 5 }}>
Large
</Button>
</div>
<div>
<Button
variant="text"
size="small"
color="primary"
style={{ margin: 5 }}
>
Small
</Button>
<Button
variant="contained"
size="medium"
color="primary"
style={{ margin: 5 }}
>
Medium
</Button>
<Button
variant="outlined"
size="large"
color="primary"
style={{ margin: 5 }}
>
large
</Button>
</div>
<div>
<Button
variant="text"
size="small"
color="secondary"
style={{ margin: 5 }}
>
Small
</Button>
<Button
variant="contained"
size="medium"
color="secondary"
style={{ margin: 5 }}
>
Medium
</Button>
<Button
variant="outlined"
size="large"
color="secondary"
style={{ margin: 5 }}
>
Large
</Button>
</div>
</>
</Playground>
## Buttons with icons
<Playground>
{() => {
return (
<div className="flex">
<Button
variant="contained"
color="primary"
style={{ margin: 5 }}
startIcon={
<svg
class="fill-current w-4 h-4"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
>
<path d="M13 8V2H7v6H2l8 8 8-8h-5zM0 18h20v2H0v-2z" />
</svg>
}
>
Download
</Button>
<Button
variant="contained"
color="primary"
style={{ margin: 5 }}
endIcon={
<svg
class="fill-current w-4 h-4"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
>
<path d="M13 8V2H7v6H2l8 8 8-8h-5zM0 18h20v2H0v-2z" />
</svg>
}
>
Download
</Button>
</div>
)
}}
</Playground>

View File

@ -0,0 +1,2 @@
import ButtonEmotion from './ButtonEmotion';
export default ButtonEmotion;

View File

@ -0,0 +1,68 @@
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import capitalize from '../../utils/capitalize';
import styles from './ButtonModules.module.scss';
const Button = props => {
const {
children,
variant = defaults.variant,
color = defaults.color,
size = defaults.size,
type = defaults.type,
startIcon: startIconProp,
endIcon: endIconProp,
className,
...rest
} = props;
const startIcon = startIconProp && (
<div className={styles.startIcon}>{startIconProp}</div>
);
const endIcon = endIconProp && (
<div className={styles.endIcon}>{endIconProp}</div>
);
return (
<button
className={classnames(
styles.baseButton,
styles[variant],
styles[`${variant}${capitalize(color)}`],
styles[`${variant}Size${capitalize(size)}`],
className
)}
type={type}
{...rest}
>
{startIcon}
{children}
{endIcon}
</button>
);
};
const defaults = {
variant: 'outlined',
color: 'default',
size: 'large',
radius: 'medium',
disabled: false,
type: 'button',
};
Button.propTypes = {
children: PropTypes.node,
size: PropTypes.oneOf(['small', 'medium', 'large']),
radius: PropTypes.oneOf(['small', 'medium', 'large', 'full']),
variant: PropTypes.oneOf(['text', 'outlined', 'contained']),
color: PropTypes.oneOf(['default', 'primary', 'secondary']),
disabled: PropTypes.bool,
type: PropTypes.string,
startIcon: PropTypes.node,
endIcon: PropTypes.node,
className: PropTypes.node,
};
export default Button;

View File

@ -0,0 +1,180 @@
---
name: ButtonModules
menu: Components
route: components/button-modules
---
import { Playground, Props } from 'docz';
import Button from './';
# ButtonModules
Buttons are used to execute actions when users interacts with them.
## Properties
<Props of={Button} />
## Contained Buttons
<Playground>
<>
<Button variant="contained" style={{ margin: 5 }}>
Default
</Button>
<Button variant="contained" color="primary" style={{ margin: 5 }}>
Primary
</Button>
<Button variant="contained" color="secondary" style={{ margin: 5 }}>
Secondary
</Button>
</>
</Playground>
## Outlined Buttons
<Playground>
<>
<Button variant="outlined" style={{ margin: 5 }}>
Default
</Button>
<Button variant="outlined" color="primary" style={{ margin: 5 }}>
Primary
</Button>
<Button variant="outlined" color="secondary" style={{ margin: 5 }}>
Secondary
</Button>
</>
</Playground>
## Text Buttons
<Playground>
<>
<Button variant="text" style={{ margin: 5 }}>
Default
</Button>
<Button variant="text" color="primary" style={{ margin: 5 }}>
Primary
</Button>
<Button variant="text" color="secondary" style={{ margin: 5 }}>
Secondary
</Button>
</>
</Playground>
## Sizes
<Playground>
<>
<div>
<Button variant="text" size="small" style={{ margin: 5 }}>
Small
</Button>
<Button variant="contained" size="medium" style={{ margin: 5 }}>
Medium
</Button>
<Button variant="outlined" size="large" style={{ margin: 5 }}>
Large
</Button>
</div>
<div>
<Button
variant="text"
size="small"
color="primary"
style={{ margin: 5 }}
>
Small
</Button>
<Button
variant="contained"
size="medium"
color="primary"
style={{ margin: 5 }}
>
Medium
</Button>
<Button
variant="outlined"
size="large"
color="primary"
style={{ margin: 5 }}
>
large
</Button>
</div>
<div>
<Button
variant="text"
size="small"
color="secondary"
style={{ margin: 5 }}
>
Small
</Button>
<Button
variant="contained"
size="medium"
color="secondary"
style={{ margin: 5 }}
>
Medium
</Button>
<Button
variant="outlined"
size="large"
color="secondary"
style={{ margin: 5 }}
>
Large
</Button>
</div>
</>
</Playground>
## Buttons with icons
<Playground>
{() => {
return (
<div className="flex">
<Button
variant="contained"
color="primary"
style={{ margin: 5 }}
startIcon={
<svg
className="fill-current w-4 h-4"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
>
<path d="M13 8V2H7v6H2l8 8 8-8h-5zM0 18h20v2H0v-2z" />
</svg>
}
>
Download
</Button>
<Button
variant="contained"
color="primary"
style={{ margin: 5 }}
endIcon={
<svg
className="fill-current w-4 h-4"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
>
<path d="M13 8V2H7v6H2l8 8 8-8h-5zM0 18h20v2H0v-2z" />
</svg>
}
>
Download
</Button>
</div>
)
}}
</Playground>

View File

@ -0,0 +1,213 @@
$default: #aaa;
$primary: #00a;
$secondary: #a00;
$hoverOpacity: 40%;
.baseButton {
display: inline-flex;
align-items: center;
justify-content: center;
position: relative;
background-color: transparent;
outline: 0;
border: 0;
margin: 0;
cursor: pointer;
user-select: none;
vertical-align: middle;
-moz-appearance: none;
appearance: none;
text-decoration: none;
box-sizing: border-box;
min-width: 64px;
padding: 6px 16px;
border-radius: 20px;
color: inherit;
transition: all 300ms ease;
&:hover {
text-decoration: none;
background-color: lighten($default, $hoverOpacity / 2);
}
&:active,
&:focus {
outline: none;
}
&:disabled {
color: $default;
cursor: not-allowed;
}
}
/* Styles applied to the root element if `variant="text"`. */
.text {
padding: 6px 8px;
&:hover {
background-color: lighten($default, $hoverOpacity / 2);
}
}
/* Styles applied to the root element if `variant="text"` and `color="primary"`. */
.textPrimary {
color: $primary;
&:hover {
background-color: lighten($primary, $hoverOpacity);
}
}
/* Styles applied to the root element if `variant="text"` and `color="secondary"`. */
.textSecondary {
color: $secondary;
&:hover {
background-color: lighten($secondary, $hoverOpacity);
}
}
/* Styles applied to the root element if `variant="outlined"`. */
.outlined {
padding: 5px 15px;
border: 1px solid $default;
&:disabled {
border: 1px solid $default;
}
}
/* Styles applied to the root element if `variant="outlined"` and `color="primary"`. */
.outlinedPrimary {
color: $primary;
border: 1px solid lighten($primary, $hoverOpacity);
&:hover {
border: 1px solid $primary;
background-color: lighten($primary, $hoverOpacity);
}
}
/* Styles applied to the root element if `variant="outlined"` and `color="secondary"`. */
.outlinedSecondary {
color: $secondary;
border: 1px solid lighten($secondary, $hoverOpacity);
&:hover {
border: 1px solid $secondary;
background-color: lighten($secondary, $hoverOpacity);
}
&:disabled {
border: 1px solid $default;
}
}
/* Styles applied to the root element if `variant="contained"`. */
.contained {
color: #fff;
background-color: $default;
&:disabled {
color: lighten($default, $hoverOpacity);
background-color: $default;
}
&:hover {
background-color: darken($default, $hoverOpacity / 2);
&:disabled {
color: lighten($default, $hoverOpacity);
background-color: $default;
}
}
}
/* Styles applied to the root element if `variant="contained"` and `color="primary"`. */
.containedPrimary {
color: white;
background-color: $primary;
&:hover {
background-color: darken($primary, $hoverOpacity / 2);
}
}
/* Styles applied to the root element if `variant="contained"` and `color="secondary"`. */
.containedSecondary {
color: white;
background-color: $secondary;
&:hover {
background-color: darken($secondary, $hoverOpacity / 2);
}
}
/* Styles applied to the root element if `size="small"` and `variant="text"`. */
.textSizeSmall {
padding: 4px 5px;
font-size: 13px;
}
/* Styles applied to the root element if `size="medium"` and `variant="text"`. */
.textSizeMedium {
padding: 6px 9px;
font-size: 14px;
}
/* Styles applied to the root element if `size="large"` and `variant="text"`. */
.textSizeLarge {
padding: 8px 11px;
font-size: 15px;
}
/* Styles applied to the root element if `size="small"` and `variant="outlined"`. */
.outlinedSizeSmall {
padding: 3px 9px;
font-size: 13px;
}
/* Styles applied to the root element if `size="medium"` and `variant="outlined"`. */
.outlinedSizeMedium {
padding: 5px 15px;
font-size: 14px;
}
/* Styles applied to the root element if `size="large"` and `variant="outlined"`. */
.outlinedSizeLarge {
padding: 7px 21px;
font-size: 15px;
}
/* Styles applied to the root element if `size="small"` and `variant="contained"`. */
.containedSizeSmall {
padding: 4px 10px;
font-size: 13px;
}
/* Styles applied to the root element if `size="medium"` and `variant="contained"`. */
.containedSizeMedium {
padding: 6px 16px;
font-size: 13px;
}
/* Styles applied to the root element if `size="large"` and `variant="contained"`. */
.containedSizeLarge {
padding: 8px 22px;
font-size: 15px;
}
/* Styles applied to the startIcon element if supplied. */
.startIcon {
display: inherit;
margin-right: 8px;
margin-left: -4px;
}
/* Styles applied to the endIcon element if supplied. */
.endIcon {
display: inherit;
margin-right: -4px;
margin-left: 8px;
}

View File

@ -0,0 +1,2 @@
import ButtonModules from './ButtonModules';
export default ButtonModules;

View File

@ -1,5 +1,5 @@
import React from 'react';
import t from 'prop-types';
import PropTypes from 'prop-types';
const Label = ({ children, spacing, className, text, ...rest }) => {
const baseClasses = 'flex flex-1 flex-col text-gray-700 text-sm font-bold';
@ -12,7 +12,7 @@ const Label = ({ children, spacing, className, text, ...rest }) => {
};
return (
<label className={getClasses()}>
<label className={getClasses()} {...rest}>
{text}
{children}
</label>
@ -27,6 +27,8 @@ const spacing = {
Label.defaultProps = {};
Label.prototypes = {};
Label.propTypes = {
children: PropTypes.node,
};
export default Label;

View File

@ -0,0 +1,46 @@
const theme = {
palette: {
action: {
hoverOpacity: 0.4,
disabledBackground: '',
disabled: '',
},
default: {
light: '#eee',
main: '#ccc',
dark: '#aaa',
},
primary: {
light: '#0000ff',
main: '#0000aa',
dark: '#000099',
},
secondary: {
light: '#ff0000',
main: '#aa0000',
dark: '#990000',
},
error: {
light: '',
main: '',
dark: '',
},
info: {
light: '',
main: '',
dark: '',
},
warning: {
light: '',
main: '',
dark: '',
},
success: {
light: '',
main: '',
dark: '',
},
},
};
export default theme;

View File

@ -0,0 +1,3 @@
export default string => {
return string.charAt(0).toUpperCase() + string.slice(1);
};

View File

@ -0,0 +1,270 @@
/* eslint-disable no-use-before-define */
/**
* Returns a number whose value is limited to the given range.
*
* @param {number} value The value to be clamped
* @param {number} min The lower boundary of the output range
* @param {number} max The upper boundary of the output range
* @returns {number} A number in the range [min, max]
*/
function clamp(value, min = 0, max = 1) {
if (process.env.NODE_ENV !== 'production') {
if (value < min || value > max) {
console.error(
`@ohif/ui: the value provided ${value} is out of range [${min}, ${max}].`
);
}
}
return Math.min(Math.max(min, value), max);
}
/**
* Converts a color from CSS hex format to CSS rgb format.
*
* @param {string} color - Hex color, i.e. #nnn or #nnnnnn
* @returns {string} A CSS rgb color string
*/
export function hexToRgb(color) {
color = color.substr(1);
const re = new RegExp(`.{1,${color.length / 3}}`, 'g');
let colors = color.match(re);
if (colors && colors[0].length === 1) {
colors = colors.map(n => n + n);
}
return colors ? `rgb(${colors.map(n => parseInt(n, 16)).join(', ')})` : '';
}
function intToHex(int) {
const hex = int.toString(16);
return hex.length === 1 ? `0${hex}` : hex;
}
/**
* Converts a color from CSS rgb format to CSS hex format.
*
* @param {string} color - RGB color, i.e. rgb(n, n, n)
* @returns {string} A CSS rgb color string, i.e. #nnnnnn
*/
export function rgbToHex(color) {
// Idempotent
if (color.indexOf('#') === 0) {
return color;
}
const { values } = decomposeColor(color);
return `#${values.map(n => intToHex(n)).join('')}`;
}
/**
* Converts a color from hsl format to rgb format.
*
* @param {string} color - HSL color values
* @returns {string} rgb color values
*/
export function hslToRgb(color) {
color = decomposeColor(color);
const { values } = color;
const h = values[0];
const s = values[1] / 100;
const l = values[2] / 100;
const a = s * Math.min(l, 1 - l);
const f = (n, k = (n + h / 30) % 12) =>
l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
let type = 'rgb';
const rgb = [
Math.round(f(0) * 255),
Math.round(f(8) * 255),
Math.round(f(4) * 255),
];
if (color.type === 'hsla') {
type += 'a';
rgb.push(values[3]);
}
return recomposeColor({ type, values: rgb });
}
/**
* Returns an object with the type and values of a color.
*
* Note: Does not support rgb % values.
*
* @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()
* @returns {object} - A MUI color object: {type: string, values: number[]}
*/
export function decomposeColor(color) {
// Idempotent
if (color.type) {
return color;
}
if (color.charAt(0) === '#') {
return decomposeColor(hexToRgb(color));
}
const marker = color.indexOf('(');
const type = color.substring(0, marker);
if (['rgb', 'rgba', 'hsl', 'hsla'].indexOf(type) === -1) {
throw new Error(
[
`@ohif/ui: unsupported \`${color}\` color.`,
'We support the following formats: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla().',
].join('\n')
);
}
let values = color.substring(marker + 1, color.length - 1).split(',');
values = values.map(value => parseFloat(value));
return { type, values };
}
/**
* Converts a color object with type and values to a string.
*
* @param {object} color - Decomposed color
* @param {string} color.type - One of: 'rgb', 'rgba', 'hsl', 'hsla'
* @param {array} color.values - [n,n,n] or [n,n,n,n]
* @returns {string} A CSS color string
*/
export function recomposeColor(color) {
const { type } = color;
let { values } = color;
if (type.indexOf('rgb') !== -1) {
// Only convert the first 3 values to int (i.e. not alpha)
values = values.map((n, i) => (i < 3 ? parseInt(n, 10) : n));
} else if (type.indexOf('hsl') !== -1) {
values[1] = `${values[1]}%`;
values[2] = `${values[2]}%`;
}
return `${type}(${values.join(', ')})`;
}
/**
* Calculates the contrast ratio between two colors.
*
* Formula: https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
*
* @param {string} foreground - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()
* @param {string} background - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()
* @returns {number} A contrast ratio value in the range 0 - 21.
*/
export function getContrastRatio(foreground, background) {
const lumA = getLuminance(foreground);
const lumB = getLuminance(background);
return (Math.max(lumA, lumB) + 0.05) / (Math.min(lumA, lumB) + 0.05);
}
/**
* The relative brightness of any point in a color space,
* normalized to 0 for darkest black and 1 for lightest white.
*
* Formula: https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
*
* @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()
* @returns {number} The relative brightness of the color in the range 0 - 1
*/
export function getLuminance(color) {
color = decomposeColor(color);
let rgb =
color.type === 'hsl'
? decomposeColor(hslToRgb(color)).values
: color.values;
rgb = rgb.map(val => {
val /= 255; // normalized
return val <= 0.03928 ? val / 12.92 : ((val + 0.055) / 1.055) ** 2.4;
});
// Truncate at 3 digits
return Number(
(0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]).toFixed(3)
);
}
/**
* Darken or lighten a color, depending on its luminance.
* Light colors are darkened, dark colors are lightened.
*
* @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()
* @param {number} coefficient=0.15 - multiplier in the range 0 - 1
* @returns {string} A CSS color string. Hex input values are returned as rgb
*/
export function emphasize(color, coefficient = 0.15) {
return getLuminance(color) > 0.5
? darken(color, coefficient)
: lighten(color, coefficient);
}
/**
* Set the absolute transparency of a color.
* Any existing alpha values are overwritten.
*
* @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()
* @param {number} value - value to set the alpha channel to in the range 0 -1
* @returns {string} A CSS color string. Hex input values are returned as rgb
*/
export function fade(color, value) {
color = decomposeColor(color);
value = clamp(value);
if (color.type === 'rgb' || color.type === 'hsl') {
color.type += 'a';
}
color.values[3] = value;
return recomposeColor(color);
}
/**
* Darkens a color.
*
* @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()
* @param {number} coefficient - multiplier in the range 0 - 1
* @returns {string} A CSS color string. Hex input values are returned as rgb
*/
export function darken(color, coefficient) {
color = decomposeColor(color);
coefficient = clamp(coefficient);
if (color.type.indexOf('hsl') !== -1) {
color.values[2] *= 1 - coefficient;
} else if (color.type.indexOf('rgb') !== -1) {
for (let i = 0; i < 3; i += 1) {
color.values[i] *= 1 - coefficient;
}
}
return recomposeColor(color);
}
/**
* Lightens a color.
*
* @param {string} color - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()
* @param {number} coefficient - multiplier in the range 0 - 1
* @returns {string} A CSS color string. Hex input values are returned as rgb
*/
export function lighten(color, coefficient) {
color = decomposeColor(color);
coefficient = clamp(coefficient);
if (color.type.indexOf('hsl') !== -1) {
color.values[2] += (100 - color.values[2]) * coefficient;
} else if (color.type.indexOf('rgb') !== -1) {
for (let i = 0; i < 3; i += 1) {
color.values[i] += (255 - color.values[i]) * coefficient;
}
}
return recomposeColor(color);
}

22013
yarn.lock

File diff suppressed because it is too large Load Diff