Skip to content

Commit

Permalink
feat: toggle-switch 컴포넌트, 스토리 추가
Browse files Browse the repository at this point in the history
DongjaJ committed Jan 16, 2025
1 parent f551f82 commit 87c9594
Showing 4 changed files with 140 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/ui/toggle-switch/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ToggleSwitch, type ToggleSwitchProps } from './toggle-switch.tsx';
53 changes: 53 additions & 0 deletions src/ui/toggle-switch/toggle-switch.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { useState } from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { ToggleSwitch } from './toggle-switch.tsx';

const meta: Meta<typeof ToggleSwitch> = {
title: 'ui/ToggleSwitch',
component: ToggleSwitch,
parameters: {
layout: 'centered',
},
argTypes: {
left: { control: 'text' },
right: { control: 'text' },
},
tags: ['autodocs'],
decorators: [
(Story, context) => {
const [value, setValue] = useState(context.args.left);

return (
<div>
<Story
args={{
...context.args,
value,
onValueChange: setValue,
}}
/>
<div
style={{ marginTop: '1rem', fontSize: '0.875rem', color: '#666' }}
>
Current state: {value}
</div>
</div>
);
},
],
} satisfies Meta<typeof ToggleSwitch>;

export default meta;
type Story = StoryObj<typeof meta>;

export const SwitchFirst: Story = {
args: {
left: '증상 AI 검색',
right: '제품 검색',
},
// render: (args) => {
// const [checked, setChecked] = useState(false);

// return <Switch {...args} checked={checked} onCheckedChange={setChecked} />;
// },
};
58 changes: 58 additions & 0 deletions src/ui/toggle-switch/toggle-switch.styles.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { style } from '@vanilla-extract/css';
import { globalVars } from '../theme.css.ts';
import { typography } from '../typography.css.ts';

export const toggleGroupRoot = style([
typography('body_2_14_sb'),
{
all: 'unset',
position: 'relative',
display: 'inline-flex',
alignItems: 'center',
width: '184px',
height: '40px',
backgroundColor: globalVars.color.grey200,
borderRadius: '20px',
cursor: 'pointer',
},
]);

export const toggleGroupSlider = style({
position: 'absolute',
width: '50%',
height: '100%',
borderRadius: '20px',
backgroundColor: globalVars.color.mainblue500,
transition: 'transform 200ms ease',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
selectors: {
':has(> * + [data-state="on"]) &': {
transform: 'translateX(100%)',
},
},
});

export const toggleGroupItem = style({
all: 'unset',
position: 'relative',
zIndex: 1,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: '20px',
width: '92px',
borderRadius: '20px',
transition: 'color 200ms ease',
userSelect: 'none',
cursor: 'pointer',
selectors: {
'&[data-state="on"]': {
color: globalVars.color.white,
},
'&[data-state="off"]': {
color: globalVars.color.grey500,
},
},
});
28 changes: 28 additions & 0 deletions src/ui/toggle-switch/toggle-switch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as ToggleGroup from '@radix-ui/react-toggle-group';
import * as styles from './toggle-switch.styles.css.ts';

export type ToggleSwitchProps = Pick<
ToggleGroup.ToggleGroupSingleProps,
'value' | 'onValueChange'
> & {
left: string;
right: string;
};

export const ToggleSwitch = ({ left, right, ...props }: ToggleSwitchProps) => {
return (
<ToggleGroup.Root
type="single"
className={styles.toggleGroupRoot}
{...props}
>
<ToggleGroup.Item value={left} className={styles.toggleGroupItem}>
{left}
</ToggleGroup.Item>
<ToggleGroup.Item value={right} className={styles.toggleGroupItem}>
{right}
</ToggleGroup.Item>
<div className={styles.toggleGroupSlider} />
</ToggleGroup.Root>
);
};

0 comments on commit 87c9594

Please sign in to comment.