Skip to content

Commit a59d0ef

Browse files
committed
feat: add component toggle
1 parent 1465571 commit a59d0ef

File tree

11 files changed

+227
-1
lines changed

11 files changed

+227
-1
lines changed

packages/ui/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
"main": "./dist/index.js",
1212
"module": "./dist/index.js",
1313
"types": "./dist/index.d.ts",
14-
"files": ["dist"],
14+
"files": [
15+
"dist"
16+
],
1517
"scripts": {
1618
"build": "pnpm run pgk:prod && pnpm run build:components && pnpm run registry",
1719
"build:components": "tsdown",
@@ -42,6 +44,7 @@
4244
"@radix-ui/react-slot": "1.2.3",
4345
"@radix-ui/react-switch": "^1.2.5",
4446
"@radix-ui/react-tabs": "1.1.12",
47+
"@radix-ui/react-toggle": "^1.1.9",
4548
"@radix-ui/react-tooltip": "^1.2.7",
4649
"@soybean-react-ui/tailwind-plugin": "workspace:*",
4750
"clsx": "2.1.1",
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Root } from '@radix-ui/react-toggle';
2+
3+
import { cn } from '@/lib/utils';
4+
5+
import { toggleVariants } from './toggle-variants';
6+
import type { ToggleProps } from './types';
7+
8+
const Toggle = (props: ToggleProps) => {
9+
const { className, size, variant, ...rest } = props;
10+
const { toggle } = toggleVariants({ size, variant });
11+
12+
const mergedCls = cn(toggle(), className);
13+
14+
return (
15+
<Root
16+
className={mergedCls}
17+
data-slot="toggle"
18+
{...rest}
19+
/>
20+
);
21+
};
22+
23+
export default Toggle;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { default as Toggle } from './Toggle';
2+
3+
export * from './types';
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { tv } from 'tailwind-variants';
2+
import type { VariantProps } from 'tailwind-variants';
3+
4+
export const toggleVariants = tv({
5+
defaultVariants: {
6+
size: 'md',
7+
variant: 'ghost'
8+
},
9+
slots: {
10+
groupRoot: `flex justify-center items-center`,
11+
toggle: [
12+
`inline-flex items-center justify-center rounded-md font-medium transition-colors duration-200`,
13+
`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-background focus-visible:ring-primary`,
14+
`hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50`,
15+
`data-[state=on]:bg-accent data-[state=on]:hover:bg-accent data-[state=on]:text-accent-foreground`
16+
]
17+
},
18+
variants: {
19+
size: {
20+
'2xl': {
21+
groupRoot: `gap-3`,
22+
toggle: `h-12 px-10 text-xl`
23+
},
24+
lg: {
25+
groupRoot: `gap-2.5`,
26+
toggle: `h-9 px-6 text-base`
27+
},
28+
md: {
29+
groupRoot: `gap-2`,
30+
toggle: `h-8 px-4 text-sm`
31+
},
32+
sm: {
33+
groupRoot: `gap-1.75`,
34+
toggle: `h-7 px-2 text-xs`
35+
},
36+
xl: {
37+
groupRoot: `gap-3`,
38+
toggle: `h-10 px-8 text-lg`
39+
},
40+
xs: {
41+
groupRoot: `gap-1.5`,
42+
toggle: `h-6 px-1.5 text-2xs`
43+
}
44+
},
45+
variant: {
46+
ghost: {
47+
toggle: `bg-transparent`
48+
},
49+
outline: {
50+
toggle: `border border-input bg-transparent shadow-sm hover:bg-accent hover:text-accent-foreground`
51+
}
52+
}
53+
}
54+
});
55+
56+
type ToggleVariants = VariantProps<typeof toggleVariants>;
57+
58+
export type ToggleVariant = NonNullable<ToggleVariants['variant']>;
59+
60+
export type ToggleSlots = keyof typeof toggleVariants.slots;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import type { ToggleProps as _ToggleProps } from '@radix-ui/react-toggle';
2+
3+
import type { BaseNodeProps } from '@/types/other';
4+
5+
import type { ToggleVariant } from './toggle-variants';
6+
7+
export interface ToggleProps extends BaseNodeProps<_ToggleProps> {
8+
variant?: ToggleVariant;
9+
}

packages/ui/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ export * from './components/switch';
6262

6363
export * from './components/tabs';
6464

65+
export * from './components/toggle';
66+
6567
export * from './components/tooltip';
6668

6769
export * from './lib';
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import type { ToggleProps } from 'soybean-react-ui';
2+
import { Card, Toggle } from 'soybean-react-ui';
3+
4+
const variants: ToggleProps['variant'][] = ['ghost', 'outline'];
5+
6+
const ToggleDemo = () => {
7+
return (
8+
<Card
9+
split
10+
title="Variant"
11+
>
12+
<div className="flex gap-12px">
13+
{variants.map(variant => (
14+
<Toggle
15+
key={variant}
16+
variant={variant}
17+
>
18+
{variant}
19+
</Toggle>
20+
))}
21+
</div>
22+
</Card>
23+
);
24+
};
25+
26+
export default ToggleDemo;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { Card, Toggle } from 'soybean-react-ui';
2+
3+
const ToggleDisabled = () => {
4+
return (
5+
<Card
6+
split
7+
title="Disabled"
8+
>
9+
<div className="flex flex-wrap gap-12px">
10+
<Toggle
11+
disabled
12+
size="md"
13+
variant="ghost"
14+
>
15+
disabled
16+
</Toggle>
17+
<Toggle
18+
disabled
19+
size="md"
20+
variant="outline"
21+
>
22+
disabled
23+
</Toggle>
24+
</div>
25+
</Card>
26+
);
27+
};
28+
29+
export default ToggleDisabled;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { ToggleProps } from 'soybean-react-ui';
2+
import { Card, Toggle } from 'soybean-react-ui';
3+
4+
const sizes: ToggleProps['size'][] = ['sm', 'md', 'lg', 'xl', '2xl'];
5+
6+
const ToggleDemo = () => {
7+
return (
8+
<Card
9+
split
10+
title="Size"
11+
>
12+
<div className="flex gap-12px">
13+
{sizes.map(size => (
14+
<Toggle
15+
key={size}
16+
size={size}
17+
variant="ghost"
18+
>
19+
{size}
20+
</Toggle>
21+
))}
22+
</div>
23+
</Card>
24+
);
25+
};
26+
27+
export default ToggleDemo;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import ToggleDemo from './modules/ToggleDemo';
2+
import ToggleDisabled from './modules/ToggleDisabled';
3+
import ToggleSize from './modules/ToggleSize';
4+
5+
const TogglePage = () => {
6+
return (
7+
<div className="flex-c gap-4">
8+
<ToggleDemo />
9+
10+
<ToggleSize />
11+
12+
<ToggleDisabled />
13+
</div>
14+
);
15+
};
16+
17+
export default TogglePage;

0 commit comments

Comments
 (0)