Skip to content

Commit 4bd21b5

Browse files
authored
Styled accordion 100 score on lighthouse (#1024)
* Revert "fix(select): types for multiple yes/no (#1021)" This reverts commit 7a98c2c. * docs(styled accordion): 100 score on lighthouse
1 parent 7a98c2c commit 4bd21b5

File tree

8 files changed

+45
-39
lines changed

8 files changed

+45
-39
lines changed

.changeset/shy-bottles-agree.md

-5
This file was deleted.

.changeset/tender-pens-run.md

-5
This file was deleted.

apps/website/src/routes/docs/styled/accordion/examples/hero.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default component$(() => {
55
return (
66
<Accordion.Root class="w-full">
77
<Accordion.Item>
8-
<Accordion.Trigger>Is it accessible?</Accordion.Trigger>
8+
<Accordion.Trigger header="h2">Is it accessible?</Accordion.Trigger>
99
<Accordion.Content>
1010
Yes. It adheres to the WAI-ARIA design pattern.
1111
</Accordion.Content>

apps/website/src/routes/docs/styled/accordion/index.mdx

+2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
---
22
title: Qwik UI | Styled Accordion Component
3+
description: A vertically stacked set of interactive headings that each reveal a section of content. Copy/paste into your project from the documentation or by using the CLI. Easily customize the CVA variants according to your brand requirements.
34
---
45

56
import { statusByComponent } from '~/_state/component-statuses';
67

8+
79
<StatusBanner status={statusByComponent.styled.Accordion} />
810

911
# Accordion

packages/kit-headless/src/components/modal/modal-trigger.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const HModalTrigger = component$((props: PropsOf<'button'>) => {
1111
return (
1212
<button
1313
aria-haspopup="dialog"
14+
aria-label="Open Theme Customization Panel"
1415
aria-expanded={context.showSig.value}
1516
data-open={context.showSig.value ? '' : undefined}
1617
data-closed={!context.showSig.value ? '' : undefined}

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type JSXNode, type PublicProps } from '@builder.io/qwik';
1+
import { type JSXNode, Component } from '@builder.io/qwik';
22
import { HSelectImpl, type SelectProps } from './select-root';
33
import { HSelectItem as InternalSelectItem } from './select-item';
44
import { HSelectItemLabel as InternalSelectItemLabel } from './select-item-label';
@@ -14,8 +14,8 @@ type InlineCompProps = {
1414
This is an inline component. An example use case of an inline component to get the proper indexes with CSR. See issue #4757
1515
for more information.
1616
*/
17-
export const HSelectRoot = <M extends true>(
18-
props: PublicProps<SelectProps<M> & InlineCompProps>,
17+
export const HSelectRoot: Component<SelectProps & InlineCompProps> = (
18+
props: SelectProps & InlineCompProps,
1919
) => {
2020
const {
2121
children: myChildren,

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

+36-21
Original file line numberDiff line numberDiff line change
@@ -32,24 +32,44 @@ export type InternalSelectProps = {
3232
_itemsMap: TItemsMap;
3333
};
3434

35-
export type SelectProps<
36-
M extends true,
37-
T = boolean extends M ? string : M extends true ? string[] : string,
38-
> = Omit<PropsOf<'div'>, 'onChange$'> & {
35+
export type TMultiple<M> = M extends true ? string[] : string;
36+
37+
/**
38+
* Value sets an initial value for the select. If multiple is true, value is disabled
39+
*
40+
*/
41+
type TMultiValue =
42+
| { multiple: true; value?: never }
43+
| { multiple?: false; value?: string };
44+
45+
type TStringOrArray =
46+
| {
47+
multiple?: true;
48+
onChange$?: QRL<(value: string[]) => void>;
49+
}
50+
| {
51+
multiple?: false;
52+
onChange$?: QRL<(value: string) => void>;
53+
};
54+
55+
export type SelectProps<M extends boolean = boolean> = Omit<
56+
PropsOf<'div'>,
57+
'onChange$'
58+
> & {
3959
/** A signal that controls the current selected value (controlled). */
40-
'bind:value'?: T extends string ? Signal<T> : never;
60+
'bind:value'?: Signal<TMultiple<M>>;
4161

4262
/** A signal that controls the current open state (controlled). */
4363
'bind:open'?: Signal<boolean>;
4464

4565
// eslint-disable-next-line @typescript-eslint/no-explicit-any
46-
'bind:displayValue'?: T extends string ? Signal<T> : never;
66+
'bind:displayValue'?: Signal<TMultiple<M>>;
4767

4868
/**
4969
* QRL handler that runs when a select value changes.
5070
* @param value The new value as a string.
5171
*/
52-
onChange$?: QRL<(value: T) => void>;
72+
onChange$?: QRL<(value: TMultiple<M>) => void>;
5373
/**
5474
* QRL handler that runs when the listbox opens or closes.
5575
* @param open The new state of the listbox.
@@ -87,18 +107,13 @@ export type SelectProps<
87107
*/
88108
multiple?: M;
89109

90-
/**
91-
* Value sets an initial value for the select. If multiple is true, value is disabled
92-
*
93-
*/
94-
value?: M extends false ? string : never;
95-
96110
invalid?: boolean;
97-
};
111+
} & TMultiValue &
112+
TStringOrArray;
98113

99114
/* root component in select-inline.tsx */
100-
export const HSelectImpl = component$(
101-
<M extends true, T>(props: SelectProps<M, T> & InternalSelectProps) => {
115+
export const HSelectImpl = component$<SelectProps<boolean> & InternalSelectProps>(
116+
(props: SelectProps<boolean> & InternalSelectProps) => {
102117
const {
103118
_itemsMap,
104119
_valuePropIndex: givenValuePropIndex,
@@ -244,7 +259,7 @@ export const HSelectImpl = component$(
244259
}
245260

246261
if (onChange$ && selectedIndexSetSig.value.size > 0) {
247-
await onChange$(context.multiple ? (values as T) : (values[0] as T));
262+
await onChange$(context.multiple ? values : values[0]);
248263
}
249264

250265
// sync the user's given signal when an option is selected
@@ -254,9 +269,9 @@ export const HSelectImpl = component$(
254269

255270
if (currUserSigValues !== newUserSigValues) {
256271
if (context.multiple) {
257-
bindValueSig.value = values as T;
272+
bindValueSig.value = values;
258273
} else {
259-
bindValueSig.value = values[0] as T;
274+
bindValueSig.value = values[0];
260275
}
261276
}
262277
}
@@ -266,8 +281,8 @@ export const HSelectImpl = component$(
266281
// sync the user's given signal for the display value
267282
if (bindDisplayTextSig && context.currDisplayValueSig.value) {
268283
bindDisplayTextSig.value = context.multiple
269-
? (context.currDisplayValueSig.value as T)
270-
: (context.currDisplayValueSig.value[0] as T);
284+
? context.currDisplayValueSig.value
285+
: context.currDisplayValueSig.value[0];
271286
}
272287
});
273288

packages/kit-styled/src/components/select/select.tsx

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
import { type PropsOf, type PublicProps, Slot, component$ } from '@builder.io/qwik';
1+
import { type PropsOf, Slot, component$ } from '@builder.io/qwik';
22
import { Select as HeadlessSelect } from '@qwik-ui/headless';
33
import { cn } from '@qwik-ui/utils';
44
import { LuCheck, LuChevronDown } from '@qwikest/icons/lucide';
55

6-
const Root = <M extends true>(
7-
props: PublicProps<PropsOf<typeof HeadlessSelect.Root<M>>>,
8-
) => (
6+
const Root = (props: PropsOf<typeof HeadlessSelect.Root>) => (
97
<HeadlessSelect.Root
108
{...props}
119
selectItemComponent={Item}

0 commit comments

Comments
 (0)