Skip to content

Commit 927dafc

Browse files
committed
feat: combobox has been initially completed.
1 parent 3054b79 commit 927dafc

File tree

5 files changed

+114
-0
lines changed

5 files changed

+114
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* eslint-disable unocss/order */
2+
import { CommandEmpty, CommandInput, CommandList, CommandOption, CommandRoot } from '../command';
3+
import { PopoverAnchor, PopoverContent, PopoverPortal, PopoverRoot, PopoverTrigger } from '../popover';
4+
5+
import type { ComboboxProps } from './types';
6+
7+
const Combobox = (props: ComboboxProps) => {
8+
const {
9+
className,
10+
classNames,
11+
empty = 'No results.',
12+
inputProps,
13+
items,
14+
mode = 'modern',
15+
size,
16+
trigger,
17+
...rest
18+
} = props;
19+
20+
return (
21+
<PopoverRoot>
22+
{mode === 'modern' && <PopoverTrigger asChild>{trigger}</PopoverTrigger>}
23+
<PopoverPortal>
24+
<PopoverContent className="w-(--radix-popover-trigger-width)">
25+
<CommandRoot
26+
{...rest}
27+
className={className || classNames?.root}
28+
>
29+
<CommandList
30+
className={classNames?.list}
31+
size={size}
32+
>
33+
<CommandEmpty
34+
className={classNames?.empty}
35+
size={size}
36+
>
37+
{empty}
38+
</CommandEmpty>
39+
40+
{items.map((item, index) => (
41+
<CommandOption
42+
classNames={classNames}
43+
item={item}
44+
key={String(index)}
45+
size={size}
46+
/>
47+
))}
48+
</CommandList>
49+
</CommandRoot>
50+
</PopoverContent>
51+
</PopoverPortal>
52+
</PopoverRoot>
53+
);
54+
};
55+
56+
export default Combobox;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { default as Combobox } from './Combobox';
2+
3+
export * from './types';
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import type { CommandProps } from '../command';
2+
import type { PopoverProps } from '../popover';
3+
4+
export type ComboboxProps = CommandProps &
5+
PopoverProps & {
6+
mode?: 'modern' | 'traditional';
7+
};

packages/ui/src/components/popover/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
export { Popover as PopoverRoot, PopoverPortal, PopoverTrigger } from '@radix-ui/react-popover';
2+
3+
export { default as PopoverAnchor } from './PopoverAnchor';
4+
15
export { default as PopoverArrow } from './PopoverArrow';
26

37
export { default as PopoverContent } from './PopoverContent';
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'use client';
2+
3+
import { ChevronsUpDown } from 'lucide-react';
4+
import { useState } from 'react';
5+
import { Button, Card, Combobox } from 'soybean-react-ui';
6+
7+
const frameworks = [
8+
{ label: 'Vue', value: '0' },
9+
{ label: 'React', value: '1' },
10+
{ label: 'Next.js', value: '2' },
11+
{ label: 'SvelteKit', value: '3' },
12+
{ label: 'Nuxt', value: '4' },
13+
{ label: 'Remix', value: '5' },
14+
{ label: 'Astro', value: '6' }
15+
];
16+
17+
const ComboboxDemo = () => {
18+
const [open, setOpen] = useState(false);
19+
const [value, setValue] = useState('');
20+
21+
return (
22+
<Card
23+
split
24+
title="Combobox Size"
25+
>
26+
<Combobox
27+
items={frameworks}
28+
trigger={
29+
<Button
30+
aria-expanded={open}
31+
className="w-full justify-between md:max-w-[200px]"
32+
role="combobox"
33+
variant="pure"
34+
>
35+
{value ? frameworks.find(framework => framework.value === value)?.label : 'Select framework...'}
36+
<ChevronsUpDown className="text-muted-foreground" />
37+
</Button>
38+
}
39+
/>
40+
</Card>
41+
);
42+
};
43+
44+
export default ComboboxDemo;

0 commit comments

Comments
 (0)