fix(dashboard-v2): migrate Switch to styled-components

This commit is contained in:
Michał Leszczyk 2022-03-13 10:43:39 +01:00
parent a00d4f8db9
commit cb5a162fe4
No known key found for this signature in database
GPG Key ID: FA123CA8BAA2FBF4
3 changed files with 72 additions and 63 deletions

View File

@ -1,40 +0,0 @@
.react-switch-checkbox {
height: 0;
width: 0;
visibility: hidden;
}
.react-switch-label {
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
width: 44px;
height: 22px;
background: white;
border-radius: 11px;
@apply border-palette-200;
border-width: 1px;
position: relative;
transition: background-color 0.2s;
}
.react-switch-label .react-switch-button {
content: "";
position: absolute;
top: 2px;
left: 2px;
width: 16px;
height: 16px;
border-radius: 8px;
transition: 0.2s;
}
.react-switch-checkbox:checked + .react-switch-label .react-switch-button {
left: calc(100% - 2px);
transform: translateX(-100%);
}
.react-switch-label:active .react-switch-button {
width: 20px;
}

View File

@ -1,37 +1,86 @@
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import "./Switch.css"; import { useEffect, useMemo, useState } from "react";
import styled from "styled-components";
import { nanoid } from "nanoid";
const Container = styled.div.attrs({
className: "inline-flex items-center gap-1 cursor-pointer select-none",
})``;
const Checkbox = styled.input.attrs({
type: "checkbox",
className: `h-0 w-0 hidden`,
})``;
const Label = styled.label.attrs({
className: "cursor-pointer inline-flex items-center gap-2",
})`
&:active .toggle-pin {
width: 20px;
}
`;
const Toggle = styled.span.attrs({
className: `flex flex-row items-center justify-between
w-[44px] h-[22px] bg-white rounded-full
border border-palette-200 relative cursor-pointer`,
})`
&:active .toggle-pin {
width: 20px;
}
`;
const TogglePin = styled.span.attrs(({ $checked }) => ({
className: `toggle-pin
absolute top-[2px] w-4 h-4 rounded-full
transition-[width_left] active:w-5
${$checked ? "checked bg-primary" : "bg-palette-200"}`,
}))`
left: 2px;
&.checked {
left: calc(100% - 2px);
transform: translateX(-100%);
}
`;
export const Switch = ({ children, defaultChecked, onChange, ...props }) => {
const id = useMemo(nanoid, [onChange]);
const [checked, setChecked] = useState(defaultChecked);
useEffect(() => {
onChange(checked);
}, [checked, onChange]);
/**
* Primary UI component for user interaction
*/
export const Switch = ({ isOn, handleToggle }) => {
return ( return (
<> <Container {...props}>
<input <Checkbox checked={checked} onChange={(ev) => setChecked(ev.target.checked)} id={id} />
checked={isOn} <Label htmlFor={id}>
onChange={handleToggle} <Toggle>
className="react-switch-checkbox" <TogglePin $checked={checked} />
id={`react-switch-new`} </Toggle>
type="checkbox" {children}
/> </Label>
<label className={"react-switch-label"} htmlFor={`react-switch-new`}> </Container>
<span className={`react-switch-button ${isOn ? "bg-primary" : "bg-palette-200"}`} />
</label>
</>
); );
}; };
Switch.propTypes = { Switch.propTypes = {
/** /**
* Switch's current value * Should the checkbox be checked by default?
*/ */
isOn: PropTypes.bool, defaultChecked: PropTypes.bool,
/**
* Element to be rendered as the switch label
*/
children: PropTypes.element,
/** /**
* Function to execute on change * Function to execute on change
*/ */
handleToggle: PropTypes.func, onChange: PropTypes.func.isRequired,
}; };
Switch.defaultProps = { Switch.defaultProps = {
isOn: false, defaultChecked: false,
}; };

View File

@ -13,10 +13,10 @@ const Template = (args) => <Switch {...args} />;
export const SwitchTrue = Template.bind({}); export const SwitchTrue = Template.bind({});
// More on args: https://storybook.js.org/docs/react/writing-stories/args // More on args: https://storybook.js.org/docs/react/writing-stories/args
SwitchTrue.args = { SwitchTrue.args = {
isOn: true, defaultChecked: true,
}; };
export const SwitchFalse = Template.bind({}); export const SwitchFalse = Template.bind({});
// More on args: https://storybook.js.org/docs/react/writing-stories/args // More on args: https://storybook.js.org/docs/react/writing-stories/args
SwitchFalse.args = { SwitchFalse.args = {
isOn: false, defaultChecked: false,
}; };