Skip to content

Commit 099c5cc

Browse files
committed
feat(styled select): add component
1 parent 5d6f4fb commit 099c5cc

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed

.changeset/orange-points-reflect.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik-ui/styled': patch
3+
---
4+
5+
FEAT new styled select component
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import { PropsOf, Slot, component$ } from '@builder.io/qwik';
2+
import { Select as HeadlessSelect } from '@qwik-ui/headless';
3+
import { cn } from '@qwik-ui/utils';
4+
import { LuCheck, LuFilter } from '@qwikest/icons/lucide';
5+
6+
const Root = HeadlessSelect.Root;
7+
8+
const Label = component$<PropsOf<typeof HeadlessSelect.Label>>(({ ...props }) => {
9+
return (
10+
<>
11+
<HeadlessSelect.Label
12+
class={cn('px-2 py-1.5 text-sm font-semibold', props.class)}
13+
{...props}
14+
>
15+
<Slot />
16+
</HeadlessSelect.Label>
17+
</>
18+
);
19+
});
20+
21+
const Trigger = component$<PropsOf<typeof HeadlessSelect.Trigger>>(({ ...props }) => {
22+
return (
23+
<>
24+
<HeadlessSelect.Trigger
25+
class={cn(
26+
'flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
27+
props.class,
28+
{ ...props },
29+
)}
30+
>
31+
<Slot />
32+
<LuFilter class="h-4 w-4 opacity-50" />
33+
</HeadlessSelect.Trigger>
34+
</>
35+
);
36+
});
37+
38+
const DisplayText = HeadlessSelect.DisplayText;
39+
40+
const Popover = component$<PropsOf<typeof HeadlessSelect.Popover>>(({ ...props }) => {
41+
return (
42+
<>
43+
<HeadlessSelect.Popover
44+
class={cn(
45+
'w-full max-w-[15rem]',
46+
// 'overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md',
47+
props.class,
48+
)}
49+
{...props}
50+
>
51+
<Slot />
52+
</HeadlessSelect.Popover>
53+
</>
54+
);
55+
});
56+
57+
type ListboxProps = PropsOf<typeof HeadlessSelect.Listbox>;
58+
const Listbox = component$<ListboxProps>(({ ...props }) => {
59+
return (
60+
<>
61+
<HeadlessSelect.Listbox
62+
class={cn(
63+
'relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
64+
props.class,
65+
)}
66+
{...props}
67+
>
68+
<Slot />
69+
</HeadlessSelect.Listbox>
70+
</>
71+
);
72+
});
73+
74+
const Group = HeadlessSelect.Group;
75+
76+
const GroupLabel = HeadlessSelect.GroupLabel;
77+
78+
const Item = component$<PropsOf<typeof HeadlessSelect.Item>>(({ ...props }) => {
79+
return (
80+
<HeadlessSelect.Item
81+
class={cn(
82+
'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
83+
props.class,
84+
)}
85+
>
86+
<span class="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
87+
<HeadlessSelect.ItemIndicator>
88+
<LuCheck class="h-4 w-4" />
89+
</HeadlessSelect.ItemIndicator>
90+
</span>
91+
<HeadlessSelect.ItemLabel>
92+
<Slot />
93+
</HeadlessSelect.ItemLabel>
94+
</HeadlessSelect.Item>
95+
);
96+
});
97+
98+
export const Select = {
99+
Root,
100+
Label,
101+
Trigger,
102+
DisplayText,
103+
Popover,
104+
Listbox,
105+
Group,
106+
GroupLabel,
107+
Item,
108+
};

packages/kit-styled/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export * from './components/popover/popover';
1414
export * from './components/progress/progress';
1515
export * from './components/radio-group/radio-group';
1616
export * from './components/separator/separator';
17+
export * from './components/select/select';
1718
export * from './components/skeleton/skeleton';
1819
export * from './components/tabs/tabs';
1920
export * from './components/textarea/textarea';

0 commit comments

Comments
 (0)