Skip to content

Commit e224497

Browse files
committed
feat: add component toggle-group
1 parent d5a0e4b commit e224497

File tree

12 files changed

+227
-0
lines changed

12 files changed

+227
-0
lines changed

packages/ui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"@radix-ui/react-switch": "^1.2.5",
4646
"@radix-ui/react-tabs": "1.1.12",
4747
"@radix-ui/react-toggle": "^1.1.9",
48+
"@radix-ui/react-toggle-group": "^1.1.10",
4849
"@radix-ui/react-tooltip": "^1.2.7",
4950
"@soybean-react-ui/tailwind-plugin": "workspace:*",
5051
"clsx": "2.1.1",
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { isFunction } from '@/lib/typed';
2+
3+
import ToggleGroupItem from './ToggleGroupItem';
4+
import ToggleGroupRoot from './ToggleGroupRoot';
5+
import type { ToggleGroupProps } from './types';
6+
7+
const ToggleGroup = (props: ToggleGroupProps) => {
8+
const { className, classNames, itemRender, items, size, variant, ...rest } = props;
9+
10+
return (
11+
<ToggleGroupRoot
12+
{...rest}
13+
className={[classNames?.groupRoot, className]}
14+
size={size}
15+
>
16+
{items.map(item => {
17+
const { label, ...restItem } = item;
18+
19+
return (
20+
<ToggleGroupItem
21+
key={item.value}
22+
size={size}
23+
variant={variant}
24+
{...restItem}
25+
>
26+
{isFunction(itemRender) ? itemRender(item) : label}
27+
</ToggleGroupItem>
28+
);
29+
})}
30+
</ToggleGroupRoot>
31+
);
32+
};
33+
34+
export default ToggleGroup;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Item } from '@radix-ui/react-toggle-group';
2+
3+
import { cn } from '@/lib/utils';
4+
5+
import { toggleVariants } from '../toggle/toggle-variants';
6+
7+
import type { ToggleGroupItemProps } from './types';
8+
9+
const ToggleGroupItem = (props: ToggleGroupItemProps) => {
10+
const { className, size, variant, ...rest } = props;
11+
12+
const { toggle } = toggleVariants({ size, variant });
13+
14+
const mergedCls = cn(toggle(), className);
15+
16+
return (
17+
<Item
18+
className={mergedCls}
19+
data-size={size}
20+
data-slot="toggle-group-item"
21+
data-variant={variant}
22+
{...rest}
23+
/>
24+
);
25+
};
26+
27+
export default ToggleGroupItem;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Root } from '@radix-ui/react-toggle-group';
2+
3+
import { cn } from '@/lib/utils';
4+
5+
import { toggleVariants } from '../toggle/toggle-variants';
6+
7+
import type { ToggleGroupRootProps } from './types';
8+
9+
const ToggleGroupRoot = (props: ToggleGroupRootProps) => {
10+
const { className, size, ...rest } = props;
11+
12+
const { groupRoot } = toggleVariants({ size });
13+
14+
const mergedCls = cn(groupRoot(), className);
15+
16+
return (
17+
<Root
18+
data-size={size}
19+
data-slot="toggle-group"
20+
{...rest}
21+
className={mergedCls}
22+
/>
23+
);
24+
};
25+
26+
export default ToggleGroupRoot;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export { default as ToggleGroup } from './ToggleGroup';
2+
export { default as ToggleGroupItem } from './ToggleGroupItem';
3+
export { default as ToggleGroupRoot } from './ToggleGroupRoot';
4+
5+
export * from './types';
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import type {
2+
// eslint-disable-next-line sort/import-members
3+
ToggleGroupMultipleProps,
4+
ToggleGroupSingleProps,
5+
ToggleGroupItemProps as _ToggleGroupItemProps
6+
} from '@radix-ui/react-toggle-group';
7+
import type { ReactNode } from 'react';
8+
9+
import type { BaseNodeProps, ClassValue } from '@/types/other';
10+
11+
import type { ToggleProps } from '../toggle';
12+
import type { ToggleSlots } from '../toggle/toggle-variants';
13+
14+
export type ToggleGroupRootProps = BaseNodeProps<ToggleGroupMultipleProps> | BaseNodeProps<ToggleGroupSingleProps>;
15+
16+
export type ToggleGroupItemProps = BaseNodeProps<_ToggleGroupItemProps> & {
17+
variant?: ToggleProps['variant'];
18+
};
19+
20+
export type ToggleGroupClassNames = Partial<Record<ToggleSlots, ClassValue>>;
21+
22+
export type ToggleGroupItemData = Omit<ToggleGroupItemProps, 'children'> & {
23+
label: ReactNode;
24+
};
25+
26+
export type ToggleGroupProps<T extends ToggleGroupItemData = ToggleGroupItemData> = ToggleGroupRootProps & {
27+
classNames?: ToggleGroupClassNames;
28+
itemRender?: (item: T) => ReactNode;
29+
items: T[];
30+
variant?: ToggleProps['variant'];
31+
};

packages/ui/src/index.ts

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

6565
export * from './components/toggle';
6666

67+
export * from './components/toggle-group';
68+
6769
export * from './components/tooltip';
6870

6971
export * from './lib';
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Card, Label, ToggleGroup } from 'soybean-react-ui';
2+
3+
import { items } from './shared';
4+
5+
const ToggleGroupMulti = () => {
6+
return (
7+
<Card
8+
split
9+
title="Multi"
10+
>
11+
<ToggleGroup
12+
items={items}
13+
type="multiple"
14+
itemRender={item => {
15+
return <Label>{item.label}</Label>;
16+
}}
17+
/>
18+
</Card>
19+
);
20+
};
21+
22+
export default ToggleGroupMulti;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Card, ToggleGroup } from 'soybean-react-ui';
2+
3+
import { items } from './shared';
4+
5+
const ToggleGroupSingle = () => {
6+
return (
7+
<Card
8+
split
9+
title="Single"
10+
>
11+
<ToggleGroup
12+
items={items}
13+
type="single"
14+
/>
15+
</Card>
16+
);
17+
};
18+
19+
export default ToggleGroupSingle;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { ToggleGroupProps } from 'soybean-react-ui';
2+
3+
export const items: ToggleGroupProps['items'] = [
4+
{ disabled: false, label: 'Top', value: 'top' },
5+
{ disabled: false, label: 'Right', value: 'right' },
6+
{ disabled: false, label: 'Bottom', value: 'bottom' },
7+
{ disabled: false, label: 'Left', value: 'left' }
8+
];
9+
10+
export const items2: ToggleGroupProps['items'] = [
11+
{ disabled: false, label: 'Top', value: 'top' },
12+
{ disabled: true, label: 'Right', value: 'right' },
13+
{ disabled: false, label: 'Bottom', value: 'bottom' },
14+
{ disabled: false, label: 'Left', value: 'left' }
15+
];

0 commit comments

Comments
 (0)