Skip to content

Commit 0968eae

Browse files
Merge pull request #825 from thejackshelton/select-improvements
export select description
2 parents 2b60e47 + 427ea3a commit 0968eae

File tree

17 files changed

+130
-6
lines changed

17 files changed

+130
-6
lines changed

.changeset/gorgeous-falcons-care.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@qwik-ui/headless': patch
3+
---
4+
5+
feat: new Select.ErrorMessage component
6+
7+
feat: data-invalid attribute to style when the select is invalid
8+
9+
feat: new Select.Description component
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { component$, useStyles$ } from '@builder.io/qwik';
2+
import { Select } from '@qwik-ui/headless';
3+
4+
export default component$(() => {
5+
useStyles$(styles);
6+
const users = ['Tim', 'Ryan', 'Jim', 'Jessie', 'Abby'];
7+
8+
return (
9+
<Select.Root class="select">
10+
<Select.Label>Logged in users</Select.Label>
11+
<Select.Trigger class="select-trigger">
12+
<Select.DisplayValue placeholder="Select an option" />
13+
</Select.Trigger>
14+
<Select.Description>Select a user to see their profile</Select.Description>
15+
<Select.Popover class="select-popover">
16+
<Select.Listbox class="select-listbox">
17+
{users.map((user) => (
18+
<Select.Item class="select-item" key={user}>
19+
<Select.ItemLabel>{user}</Select.ItemLabel>
20+
<Select.ItemIndicator>
21+
<LuCheck />
22+
</Select.ItemIndicator>
23+
</Select.Item>
24+
))}
25+
</Select.Listbox>
26+
</Select.Popover>
27+
</Select.Root>
28+
);
29+
});
30+
31+
// internal
32+
import styles from '../snippets/select.css?inline';
33+
import { LuCheck } from '@qwikest/icons/lucide';

apps/website/src/routes/docs/headless/select/examples/validation.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ export default component$(() => {
3434
<Select.Trigger class="select-trigger">
3535
<Select.DisplayValue placeholder="Select an option" />
3636
</Select.Trigger>
37-
{field.error && <div style={{ color: '#D2122E' }}>{field.error}</div>}
37+
{field.error && (
38+
<Select.ErrorMessage style={{ color: '#D2122E' }}>
39+
{field.error}
40+
</Select.ErrorMessage>
41+
)}
3842
<Select.Popover class="select-popover">
3943
<Select.Listbox class="select-listbox">
4044
{users.map((user) => (

apps/website/src/routes/docs/headless/select/index.mdx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,15 @@ The native select element is created when a form name has been given to `<Select
175175

176176
<Showcase name="validation" />
177177

178-
Above is an example of submitting a multi-select form.
178+
The `<Select.ErrorMessage />` component is used to display errors when the select is invalid.
179+
180+
To style based on the invalid state, use the `data-invalid` data attribute.
181+
182+
### Descriptions
183+
184+
Provide more information to assistive technologies by adding a description to the select.
185+
186+
<Showcase name="description" />
179187

180188
## Component state
181189

apps/website/src/routes/docs/headless/select/snippets/select.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
outline-offset: 2px;
2929
}
3030

31+
.select-trigger[data-invalid] {
32+
border: 2px dotted #d2122e;
33+
}
34+
3135
.select-popover {
3236
width: 100%;
3337
max-width: var(--select-width);

packages/kit-headless/src/components/accordion/accordion-root.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@ export const HAccordionRootImpl = component$((props: AccordionRootProps) => {
1919
disabled,
2020
collapsible = true,
2121
animated,
22+
itemsMap,
2223
...rest
2324
} = props;
2425

26+
itemsMap;
27+
2528
const selectedIndexSig = useSignal<number>(initialIndex ?? -1);
2629
const triggerRefsArray = useSignal<Array<Signal>>([]);
2730
const isAnimatedSig = useSignal<boolean>(animated === true);

packages/kit-headless/src/components/select/hidden-select.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ export const HHiddenNativeSelect = component$(
4141
// @ts-expect-error modular forms ref function
4242
ref?.(element);
4343
}}
44+
onFocus$={() => {
45+
// override modular forms focus event
46+
return;
47+
}}
4448
multiple={context.multiple}
4549
tabIndex={-1}
4650
autocomplete={autoComplete}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
export { HSelectRoot as Root } from './select-inline';
22
export { HSelectLabel as Label } from './select-label';
33
export { HSelectTrigger as Trigger } from './select-trigger';
4-
export { HSelectDisplayText as DisplayValue } from './select-display-text';
4+
export { HSelectDisplayValue as DisplayValue } from './select-display-value';
55
export { HSelectPopover as Popover } from './select-popover';
66
export { HSelectListbox as Listbox } from './select-listbox';
77
export { HSelectGroup as Group } from './select-group';
88
export { HSelectGroupLabel as GroupLabel } from './select-group-label';
99
export { HSelectItem as Item } from './select-item';
1010
export { HSelectItemLabel as ItemLabel } from './select-item-label';
1111
export { HSelectItemIndicator as ItemIndicator } from './select-item-indicator';
12+
export { HSelectDescription as Description } from './select-description';
1213
export { HHiddenNativeSelect as HiddenNativeSelect } from './hidden-select';
14+
export { HSelectErrorMessage as ErrorMessage } from './select-error-message';

packages/kit-headless/src/components/select/select-context.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ export type SelectContext = {
3939
* Specifies that the user must select a value before submitting the form. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select#required).
4040
*/
4141
required?: boolean;
42+
43+
isInvalidSig?: Signal<boolean>;
4244
};
4345

4446
export const groupContextId = createContextId<GroupContext>('Select-Group');

packages/kit-headless/src/components/select/select-display-text.tsx renamed to packages/kit-headless/src/components/select/select-display-value.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ type SelectValueProps = PropsOf<'span'> & {
1515
placeholder?: string;
1616
};
1717

18-
export const HSelectDisplayText = component$((props: SelectValueProps) => {
18+
export const HSelectDisplayValue = component$((props: SelectValueProps) => {
1919
const { placeholder, ...rest } = props;
2020
const context = useContext(SelectContextId);
2121
const valueId = `${context.localId}-value`;

0 commit comments

Comments
 (0)