Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .changeset/shy-bottles-agree.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/tender-pens-run.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default component$(() => {
return (
<Accordion.Root class="w-full">
<Accordion.Item>
<Accordion.Trigger>Is it accessible?</Accordion.Trigger>
<Accordion.Trigger header="h2">Is it accessible?</Accordion.Trigger>
<Accordion.Content>
Yes. It adheres to the WAI-ARIA design pattern.
</Accordion.Content>
Expand Down
2 changes: 2 additions & 0 deletions apps/website/src/routes/docs/styled/accordion/index.mdx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
---
title: Qwik UI | Styled Accordion Component
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.
---

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


<StatusBanner status={statusByComponent.styled.Accordion} />

# Accordion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const HModalTrigger = component$((props: PropsOf<'button'>) => {
return (
<button
aria-haspopup="dialog"
aria-label="Open Theme Customization Panel"
aria-expanded={context.showSig.value}
data-open={context.showSig.value ? '' : undefined}
data-closed={!context.showSig.value ? '' : undefined}
Expand Down
6 changes: 3 additions & 3 deletions packages/kit-headless/src/components/select/select-inline.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type JSXNode, type PublicProps } from '@builder.io/qwik';
import { type JSXNode, Component } from '@builder.io/qwik';
import { HSelectImpl, type SelectProps } from './select-root';
import { HSelectItem as InternalSelectItem } from './select-item';
import { HSelectItemLabel as InternalSelectItemLabel } from './select-item-label';
Expand All @@ -14,8 +14,8 @@ type InlineCompProps = {
This is an inline component. An example use case of an inline component to get the proper indexes with CSR. See issue #4757
for more information.
*/
export const HSelectRoot = <M extends true>(
props: PublicProps<SelectProps<M> & InlineCompProps>,
export const HSelectRoot: Component<SelectProps & InlineCompProps> = (
props: SelectProps & InlineCompProps,
) => {
const {
children: myChildren,
Expand Down
57 changes: 36 additions & 21 deletions packages/kit-headless/src/components/select/select-root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,44 @@ export type InternalSelectProps = {
_itemsMap: TItemsMap;
};

export type SelectProps<
M extends true,
T = boolean extends M ? string : M extends true ? string[] : string,
> = Omit<PropsOf<'div'>, 'onChange$'> & {
export type TMultiple<M> = M extends true ? string[] : string;

/**
* Value sets an initial value for the select. If multiple is true, value is disabled
*
*/
type TMultiValue =
| { multiple: true; value?: never }
| { multiple?: false; value?: string };

type TStringOrArray =
| {
multiple?: true;
onChange$?: QRL<(value: string[]) => void>;
}
| {
multiple?: false;
onChange$?: QRL<(value: string) => void>;
};

export type SelectProps<M extends boolean = boolean> = Omit<
PropsOf<'div'>,
'onChange$'
> & {
/** A signal that controls the current selected value (controlled). */
'bind:value'?: T extends string ? Signal<T> : never;
'bind:value'?: Signal<TMultiple<M>>;

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

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

/**
* QRL handler that runs when a select value changes.
* @param value The new value as a string.
*/
onChange$?: QRL<(value: T) => void>;
onChange$?: QRL<(value: TMultiple<M>) => void>;
/**
* QRL handler that runs when the listbox opens or closes.
* @param open The new state of the listbox.
Expand Down Expand Up @@ -87,18 +107,13 @@ export type SelectProps<
*/
multiple?: M;

/**
* Value sets an initial value for the select. If multiple is true, value is disabled
*
*/
value?: M extends false ? string : never;

invalid?: boolean;
};
} & TMultiValue &
TStringOrArray;

/* root component in select-inline.tsx */
export const HSelectImpl = component$(
<M extends true, T>(props: SelectProps<M, T> & InternalSelectProps) => {
export const HSelectImpl = component$<SelectProps<boolean> & InternalSelectProps>(
(props: SelectProps<boolean> & InternalSelectProps) => {
const {
_itemsMap,
_valuePropIndex: givenValuePropIndex,
Expand Down Expand Up @@ -244,7 +259,7 @@ export const HSelectImpl = component$(
}

if (onChange$ && selectedIndexSetSig.value.size > 0) {
await onChange$(context.multiple ? (values as T) : (values[0] as T));
await onChange$(context.multiple ? values : values[0]);
}

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

if (currUserSigValues !== newUserSigValues) {
if (context.multiple) {
bindValueSig.value = values as T;
bindValueSig.value = values;
} else {
bindValueSig.value = values[0] as T;
bindValueSig.value = values[0];
}
}
}
Expand All @@ -266,8 +281,8 @@ export const HSelectImpl = component$(
// sync the user's given signal for the display value
if (bindDisplayTextSig && context.currDisplayValueSig.value) {
bindDisplayTextSig.value = context.multiple
? (context.currDisplayValueSig.value as T)
: (context.currDisplayValueSig.value[0] as T);
? context.currDisplayValueSig.value
: context.currDisplayValueSig.value[0];
}
});

Expand Down
6 changes: 2 additions & 4 deletions packages/kit-styled/src/components/select/select.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { type PropsOf, type PublicProps, Slot, component$ } from '@builder.io/qwik';
import { type PropsOf, Slot, component$ } from '@builder.io/qwik';
import { Select as HeadlessSelect } from '@qwik-ui/headless';
import { cn } from '@qwik-ui/utils';
import { LuCheck, LuChevronDown } from '@qwikest/icons/lucide';

const Root = <M extends true>(
props: PublicProps<PropsOf<typeof HeadlessSelect.Root<M>>>,
) => (
const Root = (props: PropsOf<typeof HeadlessSelect.Root>) => (
<HeadlessSelect.Root
{...props}
selectItemComponent={Item}
Expand Down
Loading