vcc-ui
Version:
VCC UI is a collection of React UI Components that can be used for developing front-end applications at Volvo Car Corporation.
109 lines (101 loc) • 2.5 kB
JavaScript
import React from 'react';
import { bool, func } from 'prop-types';
import { useFela } from 'react-fela';
import { Inline } from '../inline';
const rootStyle = {
width: 40,
height: 25,
position: 'relative',
display: 'inline-block',
verticalAlign: 'middle',
flexGrow: 0,
flexShrink: 0,
};
const inputStyle = () => ({
appearance: 'none',
border: 'none',
':focus + span span': {
boxShadow: '0 0 2px #000',
},
});
const backgroundStyle = ({ checked, theme, disabled, isValid }) => ({
position: 'absolute',
borderWidth: 1,
borderStyle: 'solid',
borderRadius: 45,
top: 0,
left: 0,
right: 0,
bottom: 0,
outline: 0,
padding: 0,
borderColor: theme.tokens.inputBorder,
extend: [
{
condition: !isValid,
style: {
borderColor: theme.color.foreground.alert,
},
},
{
condition: disabled,
style: {
borderColor: theme.tokens.inputDisabledBorder,
},
},
],
transition: 'background 300ms cubic-bezier(0.230, 1.000, 0.320, 1.000)',
background: checked
? theme.color.ornament.highlight
: theme.color.background.primary,
cursor: disabled ? 'not-allowed' : 'pointer',
'& span': {
position: 'absolute',
bottom: 2,
left: 2,
width: 17,
height: 17,
borderWidth: 1,
boxShadow: '0px 0px 1px inset ' + theme.color.foreground.secondary,
borderStyle: 'solid',
background: theme.color.background.primary,
borderColor: disabled
? theme.tokens.inputDisabledBorder
: theme.tokens.inputBorder,
borderRadius: '50%',
transition: 'transform 300ms cubic-bezier(0.230, 1.000, 0.320, 1.000)',
transform: checked ? 'translateX(15px)' : 'translateX(0px)',
},
});
export const Toggle = React.forwardRef(
({ checked, disabled, onChange, isValid = true, ...props }, ref) => {
const { theme } = useFela();
return (
<Inline as="label" extend={rootStyle}>
<Inline
ref={ref}
as="input"
type="checkbox"
extend={inputStyle()}
checked={checked}
onChange={onChange}
disabled={disabled}
{...props}
/>
<Inline
aria-label="toggle"
extend={backgroundStyle({ checked, theme, disabled, isValid })}
>
<Inline />
</Inline>
</Inline>
);
}
);
Toggle.displayName = 'Toggle';
Toggle.propTypes = {
onChange: func.isRequired,
checked: bool,
disabled: bool,
isValid: bool,
};