feat: Button Component
This commit is contained in:
parent
4a24bcbeb5
commit
36d5a46028
@ -1,19 +1,23 @@
|
||||
import React from 'react';
|
||||
import React, { useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
|
||||
const baseClasses =
|
||||
'text-center items-center outline-none transition duration-300 ease-in-out font-bold focus:outline-none';
|
||||
|
||||
const defaults = {
|
||||
variant: 'contained',
|
||||
color: 'default',
|
||||
size: 'medium',
|
||||
radius: 'medium',
|
||||
disabled: false,
|
||||
fullWidth: false,
|
||||
rounded: 'medium',
|
||||
size: 'medium',
|
||||
type: 'button',
|
||||
variant: 'contained',
|
||||
};
|
||||
|
||||
const radiusClasses = {
|
||||
const roundedClasses = {
|
||||
none: '',
|
||||
small: 'rounded-sm',
|
||||
small: 'rounded',
|
||||
medium: 'rounded-md',
|
||||
large: 'rounded-lg',
|
||||
full: 'rounded-full',
|
||||
@ -26,26 +30,46 @@ const disabledClasses = {
|
||||
|
||||
const variantClasses = {
|
||||
text: {
|
||||
default: 'hover:bg-gray-200 text-black',
|
||||
primary: 'hover:bg-blue-100 text-blue-900',
|
||||
secondary: 'hover:bg-blue-100 text-blue-300',
|
||||
default:
|
||||
'text-primary-light hover:bg-primary-light hover:text-white active:opacity-80 focus:bg-primary-light focus:text-white',
|
||||
primary:
|
||||
'text-primary-main hover:bg-primary-main hover:text-white active:opacity-80 focus:bg-primary-main focus:text-white',
|
||||
secondary:
|
||||
'text-darkBlue-100 hover:bg-darkBlue-100 hover:text-white active:opacity-80 focus:bg-darkBlue-100 focus:text-white',
|
||||
white:
|
||||
'text-white hover:bg-white hover:text-black active:opacity-80 focus:bg-white focus:text-black',
|
||||
},
|
||||
outlined: {
|
||||
default: 'border border-black text-black hover:bg-gray-200',
|
||||
primary: 'border border-blue-900 text-blue-900 hover:bg-blue-100',
|
||||
secondary: 'border border-blue-300 text-blue-300 hover:bg-blue-100',
|
||||
default:
|
||||
'border bg-trasparent border-primary-light text-primary-light hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
primary:
|
||||
'border bg-transparent border-primary-main text-primary-main hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
secondary:
|
||||
'border bg-transparent border-darkBlue-100 text-darkBlue-100 hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
white:
|
||||
'border bg-transparent border-white text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
},
|
||||
contained: {
|
||||
default: 'bg-black hover:bg-gray-800 text-white',
|
||||
primary: 'bg-blue-900 hover:bg-blue-800 text-white',
|
||||
secondary: 'bg-blue-300 hover:bg-blue-500 text-black',
|
||||
default:
|
||||
'bg-primary-light text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
primary:
|
||||
'bg-primary-main text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
secondary:
|
||||
'bg-darkBlue-100 text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
white:
|
||||
'bg-white text-black hover:opacity-80 active:opacity-100 focus:opacity-80',
|
||||
},
|
||||
};
|
||||
|
||||
const sizeClasses = {
|
||||
small: 'py-1 px-2 text-sm',
|
||||
medium: 'py-2 px-4 text-base',
|
||||
large: 'py-3 px-6 text-lg',
|
||||
small: 'py-1 px-3 text-base',
|
||||
medium: 'py-1 px-4 text-lg',
|
||||
large: 'py-1 px-6 text-xl',
|
||||
};
|
||||
|
||||
const fullWidthClasses = {
|
||||
true: 'flex w-full',
|
||||
false: 'inline-flex',
|
||||
};
|
||||
|
||||
const Button = ({
|
||||
@ -53,33 +77,52 @@ const Button = ({
|
||||
variant = defaults.variant,
|
||||
color = defaults.color,
|
||||
size = defaults.size,
|
||||
radius = defaults.radius,
|
||||
rounded = defaults.rounded,
|
||||
disabled = defaults.disabled,
|
||||
type = defaults.type,
|
||||
fullWidth = defaults.fullWidth,
|
||||
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>
|
||||
<div className="mr-2">
|
||||
{React.cloneElement(startIconProp, {
|
||||
className: classnames('w-4 h-4 fill-current'),
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
|
||||
const endIcon = endIconProp && <div className="ml-2">{endIconProp}</div>;
|
||||
const endIcon = endIconProp && (
|
||||
<div className="ml-2">
|
||||
{React.cloneElement(endIconProp, {
|
||||
className: classnames('w-4 h-4 fill-current'),
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
const buttonElement = useRef(null);
|
||||
|
||||
const handleOnClick = e => {
|
||||
buttonElement.current.blur();
|
||||
if (rest.onClick) {
|
||||
rest.onClick(e);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
className={classnames(
|
||||
baseClasses,
|
||||
variantClasses[variant][color],
|
||||
radiusClasses[radius],
|
||||
roundedClasses[rounded],
|
||||
sizeClasses[size],
|
||||
fullWidthClasses[fullWidth],
|
||||
disabledClasses[disabled],
|
||||
className
|
||||
)}
|
||||
ref={buttonElement}
|
||||
onClick={handleOnClick}
|
||||
type={type}
|
||||
{...rest}
|
||||
>
|
||||
@ -93,9 +136,10 @@ const Button = ({
|
||||
Button.propTypes = {
|
||||
children: PropTypes.node,
|
||||
size: PropTypes.oneOf(['small', 'medium', 'large']),
|
||||
radius: PropTypes.oneOf(['none', 'small', 'medium', 'large', 'full']),
|
||||
rounded: PropTypes.oneOf(['none', 'small', 'medium', 'large', 'full']),
|
||||
variant: PropTypes.oneOf(['text', 'outlined', 'contained']),
|
||||
color: PropTypes.oneOf(['default', 'primary', 'secondary']),
|
||||
color: PropTypes.oneOf(['default', 'primary', 'secondary', 'white']),
|
||||
fullWidth: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
type: PropTypes.string,
|
||||
startIcon: PropTypes.node,
|
||||
|
||||
@ -15,22 +15,6 @@ Buttons are used to execute actions when users interacts with them.
|
||||
|
||||
<Props of={Button} />
|
||||
|
||||
## Contained Buttons
|
||||
|
||||
<Playground>
|
||||
<>
|
||||
<Button variant="contained" className="m-1">
|
||||
Default
|
||||
</Button>
|
||||
<Button variant="contained" color="primary" className="m-1">
|
||||
Primary
|
||||
</Button>
|
||||
<Button variant="contained" color="secondary" className="m-1">
|
||||
Secondary
|
||||
</Button>
|
||||
</>
|
||||
</Playground>
|
||||
|
||||
## Outlined Buttons
|
||||
|
||||
<Playground>
|
||||
@ -44,9 +28,33 @@ Buttons are used to execute actions when users interacts with them.
|
||||
<Button variant="outlined" color="secondary" className="m-1">
|
||||
Secondary
|
||||
</Button>
|
||||
<Button variant="outlined" color="white" className="m-1">
|
||||
White
|
||||
</Button>
|
||||
</>
|
||||
</Playground>
|
||||
|
||||
## Contained Buttons
|
||||
|
||||
<Playground>
|
||||
<>
|
||||
<Button variant="contained" className="m-1">
|
||||
Default
|
||||
</Button>
|
||||
<Button variant="contained" color="primary" className="m-1">
|
||||
Primary
|
||||
</Button>
|
||||
<Button variant="contained" color="secondary" className="m-1">
|
||||
Secondary
|
||||
</Button>
|
||||
<Button variant="contained" color="white" className="m-1">
|
||||
White
|
||||
</Button>
|
||||
</>
|
||||
</Playground>
|
||||
|
||||
|
||||
|
||||
## Text Buttons
|
||||
|
||||
<Playground>
|
||||
@ -60,6 +68,159 @@ Buttons are used to execute actions when users interacts with them.
|
||||
<Button variant="text" color="secondary" className="m-1">
|
||||
Secondary
|
||||
</Button>
|
||||
<Button variant="text" color="white" className="m-1">
|
||||
White
|
||||
</Button>
|
||||
</>
|
||||
</Playground>
|
||||
|
||||
## Rounded Buttons
|
||||
|
||||
<Playground>
|
||||
<>
|
||||
<div className="mb-2">
|
||||
<Button variant="contained" rounded="none" className="m-1">
|
||||
Non Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="small" className="m-1">
|
||||
Small Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="medium" className="m-1">
|
||||
Medium Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="large" className="m-1">
|
||||
Large Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="full" className="m-1">
|
||||
Full Rounded
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="none"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
>
|
||||
Non Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="small"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
>
|
||||
Small Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="medium"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
>
|
||||
Medium Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="large"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
>
|
||||
Large Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="full"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
>
|
||||
Full Rounded
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="none"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Non Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="small"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Small Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="medium"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Medium Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="large"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Large Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="full"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Full Rounded
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="none"
|
||||
color="white"
|
||||
className="m-1"
|
||||
>
|
||||
Non Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="small"
|
||||
color="white"
|
||||
className="m-1"
|
||||
>
|
||||
Small Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="medium"
|
||||
color="white"
|
||||
className="m-1"
|
||||
>
|
||||
Medium Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="large"
|
||||
color="white"
|
||||
className="m-1"
|
||||
>
|
||||
Large Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="full"
|
||||
color="white"
|
||||
className="m-1"
|
||||
>
|
||||
Full Rounded
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
</Playground>
|
||||
|
||||
@ -68,19 +229,19 @@ Buttons are used to execute actions when users interacts with them.
|
||||
<Playground>
|
||||
<>
|
||||
<div>
|
||||
<Button variant="text" size="small" className="m-1">
|
||||
<Button variant="contained" size="small" className="m-1">
|
||||
Small
|
||||
</Button>
|
||||
<Button variant="contained" size="medium" className="m-1">
|
||||
Medium
|
||||
</Button>
|
||||
<Button variant="outlined" size="large" className="m-1">
|
||||
<Button variant="contained" size="large" className="m-1">
|
||||
Large
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
variant="text"
|
||||
variant="contained"
|
||||
size="small"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
@ -96,39 +257,65 @@ Buttons are used to execute actions when users interacts with them.
|
||||
Medium
|
||||
</Button>
|
||||
<Button
|
||||
variant="outlined"
|
||||
variant="contained"
|
||||
size="large"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
>
|
||||
large
|
||||
Large
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
variant="text"
|
||||
size="small"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Small
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="medium"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Medium
|
||||
</Button>
|
||||
<Button
|
||||
variant="outlined"
|
||||
size="large"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Large
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="small"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Small
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="medium"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Medium
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="large"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Large
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="small"
|
||||
color="white"
|
||||
className="m-1"
|
||||
>
|
||||
Small
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="medium"
|
||||
color="white"
|
||||
className="m-1"
|
||||
>
|
||||
Medium
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="large"
|
||||
color="white"
|
||||
className="m-1"
|
||||
>
|
||||
Large
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
</>
|
||||
@ -147,7 +334,6 @@ Buttons are used to execute actions when users interacts with them.
|
||||
className="m-1"
|
||||
startIcon={
|
||||
<svg
|
||||
class="fill-current w-4 h-4"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
@ -163,12 +349,22 @@ Buttons are used to execute actions when users interacts with them.
|
||||
className="m-1"
|
||||
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>
|
||||
<Button
|
||||
variant="outlined"
|
||||
rounded="full"
|
||||
color="default"
|
||||
className="m-1"
|
||||
endIcon={
|
||||
<svg height="512pt" viewBox="0 0 512 512" width="512pt" xmlns="http://www.w3.org/2000/svg"><path d="m277.332031 128c0 11.78125-9.550781 21.332031-21.332031 21.332031s-21.332031-9.550781-21.332031-21.332031 9.550781-21.332031 21.332031-21.332031 21.332031 9.550781 21.332031 21.332031zm0 0"/><path d="m256 405.332031c-8.832031 0-16-7.167969-16-16v-165.332031h-21.332031c-8.832031 0-16-7.167969-16-16s7.167969-16 16-16h37.332031c8.832031 0 16 7.167969 16 16v181.332031c0 8.832031-7.167969 16-16 16zm0 0"/><path d="m256 512c-141.164062 0-256-114.835938-256-256s114.835938-256 256-256 256 114.835938 256 256-114.835938 256-256 256zm0-480c-123.519531 0-224 100.480469-224 224s100.480469 224 224 224 224-100.480469 224-224-100.480469-224-224-224zm0 0"/><path d="m304 405.332031h-96c-8.832031 0-16-7.167969-16-16s7.167969-16 16-16h96c8.832031 0 16 7.167969 16 16s-7.167969 16-16 16zm0 0"/></svg>
|
||||
}
|
||||
>
|
||||
Download
|
||||
|
||||
@ -153,7 +153,7 @@ module.exports = {
|
||||
spacing: {
|
||||
px: '1px',
|
||||
'0': '0',
|
||||
'1': '0.25rem',
|
||||
'1': '0.15rem',
|
||||
'2': '0.5rem',
|
||||
'3': '0.75rem',
|
||||
'4': '1rem',
|
||||
@ -277,9 +277,9 @@ module.exports = {
|
||||
],
|
||||
},
|
||||
fontSize: {
|
||||
xs: '0.75rem',
|
||||
sm: '0.875rem',
|
||||
base: '1rem',
|
||||
xs: '0.65rem',
|
||||
sm: '0.75rem',
|
||||
base: '0.875rem',
|
||||
lg: '1.125rem',
|
||||
xl: '1.25rem',
|
||||
'2xl': '1.5rem',
|
||||
@ -384,9 +384,25 @@ module.exports = {
|
||||
},
|
||||
opacity: {
|
||||
'0': '0',
|
||||
'25': '0.25',
|
||||
'50': '0.5',
|
||||
'75': '0.75',
|
||||
'5': '.5',
|
||||
'10': '.10',
|
||||
'15': '.15',
|
||||
'20': '.20',
|
||||
'25': '.25',
|
||||
'30': '.30',
|
||||
'35': '.35',
|
||||
'40': '.40',
|
||||
'45': '.45',
|
||||
'50': '.50',
|
||||
'55': '.55',
|
||||
'60': '.60',
|
||||
'65': '.65',
|
||||
'70': '.70',
|
||||
'75': '.75',
|
||||
'80': '.80',
|
||||
'85': '.85',
|
||||
'90': '.90',
|
||||
'95': '.95',
|
||||
'100': '1',
|
||||
},
|
||||
order: {
|
||||
@ -642,15 +658,15 @@ module.exports = {
|
||||
alignSelf: ['responsive'],
|
||||
appearance: ['responsive'],
|
||||
backgroundAttachment: ['responsive'],
|
||||
backgroundColor: ['responsive', 'hover', 'focus'],
|
||||
backgroundColor: ['responsive', 'hover', 'focus', 'active'],
|
||||
backgroundPosition: ['responsive'],
|
||||
backgroundRepeat: ['responsive'],
|
||||
backgroundSize: ['responsive'],
|
||||
borderCollapse: ['responsive'],
|
||||
borderColor: ['responsive', 'hover', 'focus'],
|
||||
borderRadius: ['responsive'],
|
||||
borderStyle: ['responsive'],
|
||||
borderWidth: ['responsive'],
|
||||
borderColor: ['responsive', 'hover', 'focus', 'active'],
|
||||
borderRadius: ['responsive', 'focus'],
|
||||
borderStyle: ['responsive', 'focus'],
|
||||
borderWidth: ['responsive', 'focus'],
|
||||
boxShadow: ['responsive', 'hover', 'focus'],
|
||||
boxSizing: ['responsive'],
|
||||
cursor: ['responsive'],
|
||||
@ -682,7 +698,7 @@ module.exports = {
|
||||
minWidth: ['responsive'],
|
||||
objectFit: ['responsive'],
|
||||
objectPosition: ['responsive'],
|
||||
opacity: ['responsive', 'hover', 'focus'],
|
||||
opacity: ['responsive', 'hover', 'focus', 'active'],
|
||||
order: ['responsive'],
|
||||
outline: ['responsive', 'focus'],
|
||||
overflow: ['responsive'],
|
||||
@ -695,7 +711,7 @@ module.exports = {
|
||||
strokeWidth: ['responsive'],
|
||||
tableLayout: ['responsive'],
|
||||
textAlign: ['responsive'],
|
||||
textColor: ['responsive', 'hover', 'focus'],
|
||||
textColor: ['responsive', 'hover', 'focus', 'active'],
|
||||
textDecoration: ['responsive', 'hover', 'focus'],
|
||||
textTransform: ['responsive'],
|
||||
userSelect: ['responsive'],
|
||||
|
||||
@ -4,4 +4,10 @@
|
||||
|
||||
[data-testid='live-preview'] {
|
||||
padding: 10px;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
[data-testid='main-container'] h2 {
|
||||
margin: 20px 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user