From 3771f93ce74ab7f30247c95b5ff8dd3efce94c26 Mon Sep 17 00:00:00 2001 From: dev-redo Date: Mon, 29 Jul 2024 19:13:20 +0900 Subject: [PATCH 1/4] feat: init --- src/component/Switch/Switch.stories.tsx | 43 ++++++ src/component/Switch/Switch.tsx | 181 ++++++++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 src/component/Switch/Switch.stories.tsx create mode 100644 src/component/Switch/Switch.tsx diff --git a/src/component/Switch/Switch.stories.tsx b/src/component/Switch/Switch.stories.tsx new file mode 100644 index 00000000..a3c4d5e0 --- /dev/null +++ b/src/component/Switch/Switch.stories.tsx @@ -0,0 +1,43 @@ +import { useState } from 'react'; + +import type { Meta, StoryFn } from '@storybook/react'; +import { Switch } from './Switch'; +import { hstack, vstack } from '../../../styled-system/patterns'; + +export default { + component: Switch, + parameters: { + design: { + type: 'figma', + url: 'https://www.figma.com/file/tN7Q8dJZqVsjo2FWflOKfu/CDS(Corca-Design-System)?type=design&node-id=435-15115&mode=design&t=bhY2SksBs7AqptYx-0', + }, + }, +} as Meta; + +const Template: StoryFn = args => ; +export const Basic = Template.bind({}); +Basic.args = { + disabled: false, + checked: true, +}; + +const containerStyle = vstack({ gap: 20, flexDirection: 'column' }); +const wrapperStyle = hstack({ gap: 15 }); + +export function Active() { + const [active, setActive1] = useState(false); + const [disabled1, setdDisabled1] = useState(true); + const [disabled2, setdDisabled2] = useState(false); + + return ( +
+
+ +
+
+ + +
+
+ ); +} diff --git a/src/component/Switch/Switch.tsx b/src/component/Switch/Switch.tsx new file mode 100644 index 00000000..d28fa702 --- /dev/null +++ b/src/component/Switch/Switch.tsx @@ -0,0 +1,181 @@ +import { forwardRef } from 'react'; +import { cx, sva } from '../../../styled-system/css'; + +export interface SwitchProps { + checked: boolean; + onChange: (checked: boolean) => void; + disabled?: boolean; +} + +export const Switch = forwardRef(function Switch( + { checked, onChange, disabled = false, ...props }, + ref, +) { + const classes = switchSlot({ disabled, checked }); + + return ( + + ); +}); + +const switchSlot = sva({ + slots: ['root', 'checkbox', 'slider', 'text', 'textOn', 'textOff'], + base: { + root: { + position: 'relative', + width: '38px', + height: '18px', + userSelect: 'none', + display: 'inline-block', + cursor: 'pointer', + }, + checkbox: { + opacity: 0, + width: 0, + height: 0, + }, + slider: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + borderRadius: '10px', + display: 'flex', + alignItems: 'center', + transition: 'background 0.2s ease', + '&::before': { + content: '""', + zIndex: 10, + width: '12px', + height: '12px', + bg: 'etc.white', + borderRadius: '50%', + transition: 'transform 0.2s ease, background-color 0.2s ease', + transform: 'translateX(3px)', + }, + }, + text: { + position: 'absolute', + fontSize: '9px', + fontWeight: 500, + fontFamily: 'Pretendard Variable, Pretendard', + lineHeight: '1.2', + }, + textOn: { + left: '5px', + }, + textOff: { + right: '3.5px', + }, + }, + variants: { + checked: { + true: { + slider: { + bg: 'main.black', + '&::before': { + transform: 'translateX(23px)', + }, + }, + textOn: { + opacity: 1, + }, + textOff: { + opacity: 0, + }, + }, + false: { + slider: { + bg: 'grey.40', + '&::before': { + transform: 'translateX(3px)', + }, + }, + textOn: { + opacity: 0, + }, + textOff: { + opacity: 1, + }, + }, + }, + disabled: { + true: { + slider: { + bg: 'grey.50', + cursor: 'not-allowed', + '&::before': { + bg: 'grey.60', + }, + }, + text: { + color: 'grey.60', + }, + }, + false: { + slider: { + bg: 'grey.40', + }, + textOn: { + color: 'etc.white', + }, + textOff: { + color: 'grey.50', + }, + }, + }, + }, + compoundVariants: [ + { + disabled: true, + css: { + slider: { + bg: 'grey.50', + '&::before': { + bg: 'grey.60', + }, + }, + text: { + color: 'grey.60', + }, + }, + }, + { + checked: true, + disabled: false, + css: { + slider: { + bg: 'main.black', + '&::before': { + transform: 'translateX(23px)', + }, + }, + }, + }, + { + checked: false, + disabled: false, + css: { + slider: { + bg: 'grey.40', + '&::before': { + transform: 'translateX(3px)', + }, + }, + }, + }, + ], +}); From b6d64866cc49ec18494555e0b48997733853325f Mon Sep 17 00:00:00 2001 From: dev-redo Date: Mon, 29 Jul 2024 19:32:27 +0900 Subject: [PATCH 2/4] refactor: refactor switch component --- src/component/Switch/Switch.tsx | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/src/component/Switch/Switch.tsx b/src/component/Switch/Switch.tsx index d28fa702..47298ea2 100644 --- a/src/component/Switch/Switch.tsx +++ b/src/component/Switch/Switch.tsx @@ -30,6 +30,8 @@ export const Switch = forwardRef(function Switch( ); }); +Switch.displayName = 'Switch'; + const switchSlot = sva({ slots: ['root', 'checkbox', 'slider', 'text', 'textOn', 'textOff'], base: { @@ -153,29 +155,5 @@ const switchSlot = sva({ }, }, }, - { - checked: true, - disabled: false, - css: { - slider: { - bg: 'main.black', - '&::before': { - transform: 'translateX(23px)', - }, - }, - }, - }, - { - checked: false, - disabled: false, - css: { - slider: { - bg: 'grey.40', - '&::before': { - transform: 'translateX(3px)', - }, - }, - }, - }, ], }); From bfa605e9e96687b03e9f7c39c351df5ec2088d66 Mon Sep 17 00:00:00 2001 From: dev-redo Date: Mon, 29 Jul 2024 19:43:59 +0900 Subject: [PATCH 3/4] feat: export switch component --- src/component/index.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/component/index.ts b/src/component/index.ts index 89c768e9..126793c7 100644 --- a/src/component/index.ts +++ b/src/component/index.ts @@ -1,4 +1,8 @@ export { Button } from './Button/button'; export type { IButtonProps } from './Button/button'; + export { Badge } from './Badge/Badge'; export type { BadgeProps } from './Badge/Badge'; + +export { Switch } from './Switch/Switch'; +export type { SwitchProps } from './Switch/Switch'; From ead537c969f5d46061c4b4f44bb3f512912036e2 Mon Sep 17 00:00:00 2001 From: dev-redo Date: Mon, 29 Jul 2024 20:46:43 +0900 Subject: [PATCH 4/4] refactor: refactor switch --- src/component/Switch/Switch.tsx | 47 +++++++++++++-------------------- src/component/index.ts | 3 +++ 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/src/component/Switch/Switch.tsx b/src/component/Switch/Switch.tsx index 47298ea2..d7145790 100644 --- a/src/component/Switch/Switch.tsx +++ b/src/component/Switch/Switch.tsx @@ -32,13 +32,18 @@ export const Switch = forwardRef(function Switch( Switch.displayName = 'Switch'; +const SWITCH_WIDTH = 38; +const SWITCH_HEIGHT = 18; +const SWITCH_CIRCLE_SIZE = 12; +const SWITCH_CIRCLE_GAP = 3; + const switchSlot = sva({ slots: ['root', 'checkbox', 'slider', 'text', 'textOn', 'textOff'], base: { root: { position: 'relative', - width: '38px', - height: '18px', + width: `${SWITCH_WIDTH}px`, + height: `${SWITCH_HEIGHT}px`, userSelect: 'none', display: 'inline-block', cursor: 'pointer', @@ -61,12 +66,12 @@ const switchSlot = sva({ '&::before': { content: '""', zIndex: 10, - width: '12px', - height: '12px', - bg: 'etc.white', + width: `${SWITCH_CIRCLE_SIZE}px`, + height: `${SWITCH_CIRCLE_SIZE}px`, + backgroundColor: 'etc.white', borderRadius: '50%', transition: 'transform 0.2s ease, background-color 0.2s ease', - transform: 'translateX(3px)', + transform: `translateX(${SWITCH_CIRCLE_GAP}px)`, }, }, text: { @@ -87,9 +92,9 @@ const switchSlot = sva({ checked: { true: { slider: { - bg: 'main.black', + backgroundColor: 'main.black', '&::before': { - transform: 'translateX(23px)', + transform: `translateX(${SWITCH_WIDTH - SWITCH_CIRCLE_SIZE - SWITCH_CIRCLE_GAP}px)`, }, }, textOn: { @@ -101,9 +106,9 @@ const switchSlot = sva({ }, false: { slider: { - bg: 'grey.40', + backgroundColor: 'grey.40', '&::before': { - transform: 'translateX(3px)', + transform: `translateX(${SWITCH_CIRCLE_GAP}px)`, }, }, textOn: { @@ -117,10 +122,10 @@ const switchSlot = sva({ disabled: { true: { slider: { - bg: 'grey.50', + backgroundColor: 'grey.50', cursor: 'not-allowed', '&::before': { - bg: 'grey.60', + backgroundColor: 'grey.60', }, }, text: { @@ -129,7 +134,7 @@ const switchSlot = sva({ }, false: { slider: { - bg: 'grey.40', + backgroundColor: 'grey.40', }, textOn: { color: 'etc.white', @@ -140,20 +145,4 @@ const switchSlot = sva({ }, }, }, - compoundVariants: [ - { - disabled: true, - css: { - slider: { - bg: 'grey.50', - '&::before': { - bg: 'grey.60', - }, - }, - text: { - color: 'grey.60', - }, - }, - }, - ], }); diff --git a/src/component/index.ts b/src/component/index.ts index 126793c7..a96bdb53 100644 --- a/src/component/index.ts +++ b/src/component/index.ts @@ -4,5 +4,8 @@ export type { IButtonProps } from './Button/button'; export { Badge } from './Badge/Badge'; export type { BadgeProps } from './Badge/Badge'; +export { Thumbnail } from './Thumbnail/Thumbnail'; +export type { ThumbnailProps } from './Thumbnail/Thumbnail'; + export { Switch } from './Switch/Switch'; export type { SwitchProps } from './Switch/Switch';