Skip to content

Commit

Permalink
Merge branch 'main' into chore-16
Browse files Browse the repository at this point in the history
  • Loading branch information
DongjaJ authored Jan 17, 2025
2 parents 135cc77 + 8339a50 commit 71ba3ea
Show file tree
Hide file tree
Showing 6 changed files with 349 additions and 0 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
},
"dependencies": {
"@hookform/resolvers": "^3.9.1",
"@radix-ui/react-switch": "^1.1.2",
"@t3-oss/env-core": "^0.11.1",
"@tanstack/react-query": "^5.62.11",
"@tanstack/react-virtual": "^3.11.2",
Expand Down
181 changes: 181 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/ui/switch/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Switch, type SwitchProps } from './switch.tsx';
47 changes: 47 additions & 0 deletions src/ui/switch/switch.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useState } from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { Switch } from './switch.tsx';

const meta: Meta<typeof Switch> = {
title: 'ui/Switch',
component: Switch,
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 Switch>;

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

export const SwitchFirst: Story = {
args: {
left: '증상 AI 검색',
right: '제품 검색',
},
};
67 changes: 67 additions & 0 deletions src/ui/switch/switch.styles.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { style } from '@vanilla-extract/css';
import { recipe } from '@vanilla-extract/recipes';
import { globalVars } from '../theme.css.ts';
import { typography } from '../typography.css.ts';

export const switchRoot = 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',
gap: '4px',
},
]);

export const switchSlider = recipe({
base: {
position: 'absolute',
width: '50%',
height: '100%',
borderRadius: '20px',
backgroundColor: globalVars.color.mainblue500,
transition: 'transform 200ms ease',
},
variants: {
checked: {
false: {
transform: 'translateX(0)',
},
true: {
transform: 'translateX(calc(100%))',
},
},
},
});

export const switchThumb = recipe({
base: {
all: 'unset',
position: 'relative',
zIndex: 1,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: '20px',
width: '92px',
borderRadius: '20px',
transition: 'color 200ms ease',
userSelect: 'none',
},
variants: {
checked: {
true: {
color: globalVars.color.white,
},
false: {
color: globalVars.color.grey500,
},
},
},
});
52 changes: 52 additions & 0 deletions src/ui/switch/switch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as RadixSwitch from '@radix-ui/react-switch';
import * as styles from './switch.styles.css.ts';

export type SwitchProps = Omit<
RadixSwitch.SwitchProps,
'checked' | 'onCheckedChange'
> & {
left: string;
right: string;
value: string;
onValueChange: (value: string) => void;
};

export const Switch = ({
left,
right,
value,
onValueChange,
...props
}: SwitchProps) => {
const isChecked = value === right;

const handleCheckedChange = (checked: boolean) => {
onValueChange(checked ? right : left);
};

return (
<RadixSwitch.Root
{...props}
checked={isChecked}
onCheckedChange={handleCheckedChange}
className={styles.switchRoot}
>
<div className={styles.switchSlider({ checked: isChecked })} />

<RadixSwitch.Thumb
className={styles.switchThumb({
checked: !isChecked,
})}
>
{left}
</RadixSwitch.Thumb>
<RadixSwitch.Thumb
className={styles.switchThumb({
checked: isChecked,
})}
>
{right}
</RadixSwitch.Thumb>
</RadixSwitch.Root>
);
};

0 comments on commit 71ba3ea

Please sign in to comment.