diff --git a/src/lib/components/description/Description.svelte b/src/lib/components/description/Description.svelte index 0929da24..b371e07b 100644 --- a/src/lib/components/description/Description.svelte +++ b/src/lib/components/description/Description.svelte @@ -26,7 +26,7 @@ diff --git a/src/lib/components/dialog/DialogTitle.svelte b/src/lib/components/dialog/DialogTitle.svelte index dc32263f..e15cf41d 100644 --- a/src/lib/components/dialog/DialogTitle.svelte +++ b/src/lib/components/dialog/DialogTitle.svelte @@ -46,7 +46,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"DialogTitle"} + componentName={"DialogTitle"} > diff --git a/src/lib/components/disclosure/Disclosure.svelte b/src/lib/components/disclosure/Disclosure.svelte index 65c3e163..74d1474c 100644 --- a/src/lib/components/disclosure/Disclosure.svelte +++ b/src/lib/components/disclosure/Disclosure.svelte @@ -146,7 +146,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"Disclosure"} + componentName={"Disclosure"} > diff --git a/src/lib/components/disclosure/DisclosureButton.svelte b/src/lib/components/disclosure/DisclosureButton.svelte index 440cdec1..b45db0f4 100644 --- a/src/lib/components/disclosure/DisclosureButton.svelte +++ b/src/lib/components/disclosure/DisclosureButton.svelte @@ -118,7 +118,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"DisclosureButton"} + componentName={"DisclosureButton"} bind:el={$ourStore} on:click={handleClick} on:keydown={handleKeyDown} @@ -131,7 +131,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"DisclosureButton"} + componentName={"DisclosureButton"} bind:el={$ourStore} on:click={handleClick} on:keydown={handleKeyDown} diff --git a/src/lib/components/disclosure/DisclosurePanel.svelte b/src/lib/components/disclosure/DisclosurePanel.svelte index d8c619c6..38b2c1b4 100644 --- a/src/lib/components/disclosure/DisclosurePanel.svelte +++ b/src/lib/components/disclosure/DisclosurePanel.svelte @@ -62,7 +62,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"DisclosurePanel"} + componentName={"DisclosurePanel"} bind:el={$panelStore} {visible} features={Features.RenderStrategy | Features.Static} diff --git a/src/lib/components/label/Label.svelte b/src/lib/components/label/Label.svelte index 38fdf3ba..8b1ce2e3 100644 --- a/src/lib/components/label/Label.svelte +++ b/src/lib/components/label/Label.svelte @@ -32,7 +32,7 @@ @@ -90,6 +93,7 @@ export let disabled = false; export let horizontal = false; export let value: StateDefinition["value"]; + export let name: string | null = null; /***** Events *****/ const forwardEvents = forwardEventsBuilder(get_current_component(), [ @@ -124,6 +128,7 @@ activeOptionIndex, disabled, orientation, + name, closeListbox() { if (disabled) return; if (listboxState === ListboxStates.Closed) return; @@ -281,7 +286,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"Listbox"} + componentName={"Listbox"} > diff --git a/src/lib/components/listbox/ListboxButton.svelte b/src/lib/components/listbox/ListboxButton.svelte index 4d76259c..b745496f 100644 --- a/src/lib/components/listbox/ListboxButton.svelte +++ b/src/lib/components/listbox/ListboxButton.svelte @@ -97,6 +97,7 @@ : $api.listboxState === ListboxStates.Open, "aria-labelledby": $labelRef ? [$labelRef?.id, id].join(" ") : undefined, disabled: $api.disabled === true ? true : undefined, + name: $api.name, }; $: slotProps = { @@ -111,7 +112,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"ListboxButton"} + componentName={"ListboxButton"} bind:el={$buttonRef} on:click={handleClick} on:keydown={handleKeyDown} diff --git a/src/lib/components/listbox/ListboxLabel.svelte b/src/lib/components/listbox/ListboxLabel.svelte index 0f62785d..d5ba2457 100644 --- a/src/lib/components/listbox/ListboxLabel.svelte +++ b/src/lib/components/listbox/ListboxLabel.svelte @@ -48,7 +48,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"ListboxLabel"} + componentName={"ListboxLabel"} bind:el={$labelRef} on:click={handleClick} > diff --git a/src/lib/components/listbox/ListboxOption.svelte b/src/lib/components/listbox/ListboxOption.svelte index 8b80033b..73bad537 100644 --- a/src/lib/components/listbox/ListboxOption.svelte +++ b/src/lib/components/listbox/ListboxOption.svelte @@ -132,7 +132,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"ListboxOption"} + componentName={"ListboxOption"} on:click={handleClick} on:focus={handleFocus} on:pointermove={handleMove} diff --git a/src/lib/components/listbox/ListboxOptions.svelte b/src/lib/components/listbox/ListboxOptions.svelte index ee733e35..2ab46eca 100644 --- a/src/lib/components/listbox/ListboxOptions.svelte +++ b/src/lib/components/listbox/ListboxOptions.svelte @@ -146,7 +146,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"ListboxOptions"} + componentName={"ListboxOptions"} bind:el={$optionsRef} on:keydown={handleKeyDown} {visible} diff --git a/src/lib/components/listbox/listbox.test.ts b/src/lib/components/listbox/listbox.test.ts index ad4a0018..2c4b7eef 100644 --- a/src/lib/components/listbox/listbox.test.ts +++ b/src/lib/components/listbox/listbox.test.ts @@ -178,6 +178,28 @@ describe('Rendering', () => { assertListbox({ state: ListboxState.InvisibleUnmounted }) }) ) + + describe("`name` attribute", () => { + it('should set the `name` to "listbox-name"', async () => { + render(svelte` + + Trigger + + `); + + expect(getListboxButton()).toHaveAttribute('name', 'listbox-name') + }) + + it('should not set the name if no "name" prop is passed', async () => { + render(svelte` + + Trigger + + `); + + expect(getListboxButton()).not.toHaveAttribute('name') + }) + }) }) describe('ListboxLabel', () => { diff --git a/src/lib/components/menu/Menu.svelte b/src/lib/components/menu/Menu.svelte index 1e8f2d41..dfa7647b 100644 --- a/src/lib/components/menu/Menu.svelte +++ b/src/lib/components/menu/Menu.svelte @@ -219,7 +219,7 @@ use={[...use, forwardEvents]} {as} {slotProps} - name={"Menu"} + componentName={"Menu"} > diff --git a/src/lib/components/menu/MenuButton.svelte b/src/lib/components/menu/MenuButton.svelte index 68420edc..ab3d5dda 100644 --- a/src/lib/components/menu/MenuButton.svelte +++ b/src/lib/components/menu/MenuButton.svelte @@ -112,7 +112,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"MenuButton"} + componentName={"MenuButton"} bind:el={$buttonStore} on:click={handleClick} on:keydown={handleKeyDown} diff --git a/src/lib/components/menu/MenuItem.svelte b/src/lib/components/menu/MenuItem.svelte index 1df4f0d7..5e7c3618 100644 --- a/src/lib/components/menu/MenuItem.svelte +++ b/src/lib/components/menu/MenuItem.svelte @@ -107,7 +107,7 @@ use={[...use, forwardEvents]} {as} {slotProps} - name={"MenuItem"} + componentName={"MenuItem"} bind:el={elementRef} on:click={handleClick} on:focus={handleFocus} diff --git a/src/lib/components/menu/MenuItems.svelte b/src/lib/components/menu/MenuItems.svelte index ad7823f0..3276a9f5 100644 --- a/src/lib/components/menu/MenuItems.svelte +++ b/src/lib/components/menu/MenuItems.svelte @@ -167,7 +167,7 @@ {slotProps} use={[...use, forwardEvents]} bind:el={$itemsStore} - name={"MenuItems"} + componentName={"MenuItems"} on:keydown={handleKeyDown} on:keyup={handleKeyUp} {visible} diff --git a/src/lib/components/popover/Popover.svelte b/src/lib/components/popover/Popover.svelte index 945fff87..5189d7b7 100644 --- a/src/lib/components/popover/Popover.svelte +++ b/src/lib/components/popover/Popover.svelte @@ -191,7 +191,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"Popover"} + componentName={"Popover"} > diff --git a/src/lib/components/popover/PopoverButton.svelte b/src/lib/components/popover/PopoverButton.svelte index 29be1770..065f71b8 100644 --- a/src/lib/components/popover/PopoverButton.svelte +++ b/src/lib/components/popover/PopoverButton.svelte @@ -211,7 +211,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"PopoverButton"} + componentName={"PopoverButton"} bind:el={$ourStore} on:click={handleClick} on:keydown={handleKeyDown} diff --git a/src/lib/components/popover/PopoverGroup.svelte b/src/lib/components/popover/PopoverGroup.svelte index 062062c9..551cf64d 100644 --- a/src/lib/components/popover/PopoverGroup.svelte +++ b/src/lib/components/popover/PopoverGroup.svelte @@ -87,7 +87,7 @@ {as} use={[...use, forwardEvents]} {slotProps} - name={"PopoverGroup"} + componentName={"PopoverGroup"} bind:el={groupRef} > diff --git a/src/lib/components/popover/PopoverOverlay.svelte b/src/lib/components/popover/PopoverOverlay.svelte index e378debd..a78dcc81 100644 --- a/src/lib/components/popover/PopoverOverlay.svelte +++ b/src/lib/components/popover/PopoverOverlay.svelte @@ -52,7 +52,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"PopoverOverlay"} + componentName={"PopoverOverlay"} on:click={handleClick} aria-hidden {visible} diff --git a/src/lib/components/popover/PopoverPanel.svelte b/src/lib/components/popover/PopoverPanel.svelte index 30ce9b97..2829718f 100644 --- a/src/lib/components/popover/PopoverPanel.svelte +++ b/src/lib/components/popover/PopoverPanel.svelte @@ -165,7 +165,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"PopoverPanel"} + componentName={"PopoverPanel"} bind:el={$panelStore} on:keydown={handleKeydown} {visible} diff --git a/src/lib/components/radio-group/RadioGroup.svelte b/src/lib/components/radio-group/RadioGroup.svelte index df110103..21950cd8 100644 --- a/src/lib/components/radio-group/RadioGroup.svelte +++ b/src/lib/components/radio-group/RadioGroup.svelte @@ -228,7 +228,7 @@ {as} use={[...use, forwardEvents]} {slotProps} - name={"RadioGroup"} + componentName={"RadioGroup"} bind:el={radioGroupRef} aria-labelledby={labelledby} aria-describedby={describedby} diff --git a/src/lib/components/radio-group/RadioGroupOption.svelte b/src/lib/components/radio-group/RadioGroupOption.svelte index a94045a7..a8eb939e 100644 --- a/src/lib/components/radio-group/RadioGroupOption.svelte +++ b/src/lib/components/radio-group/RadioGroupOption.svelte @@ -10,6 +10,8 @@ value: unknown; /** Whether the `RadioGroupOption` is disabled */ disabled?: boolean; + /** The name used when using this component inside a form. */ + name?: string; }; @@ -35,6 +37,7 @@ export let use: HTMLActionArray = []; export let value: unknown; export let disabled: boolean = false; + export let name: string | null = null; /***** Events *****/ const forwardEvents = forwardEventsBuilder(get_current_component()); @@ -88,6 +91,7 @@ "aria-checked": checked ? ("true" as const) : ("false" as const), "aria-disabled": isDisabled ? true : undefined, tabIndex: tabIndex, + name, }; $: slotProps = { @@ -104,7 +108,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"RadioGroupOption"} + componentName={"RadioGroupOption"} bind:el={optionRef} aria-labelledby={labelledby} aria-describedby={describedby} diff --git a/src/lib/components/radio-group/radio-group.test.ts b/src/lib/components/radio-group/radio-group.test.ts index 6d1d9a50..bff46b83 100644 --- a/src/lib/components/radio-group/radio-group.test.ts +++ b/src/lib/components/radio-group/radio-group.test.ts @@ -771,3 +771,37 @@ describe('Mouse interactions', () => { expect(changeFn).toHaveBeenCalledTimes(1) }) }) + +describe("`name` attribute", () => { + it('should set the `name` to "radio-option-name"', async () => { + render(svelte` + + Pizza Delivery + Pickup + Home delivery + Dine in + + `); + + let options = getRadioGroupOptions(); + for (let option of options) + expect(option).toHaveAttribute("name", "radio-option-name"); + + }); + + it('should not set the name if no "name" prop is passed', async () => { + render(svelte` + + Pizza Delivery + Pickup + Home delivery + Dine in + + `); + + let options = getRadioGroupOptions(); + for (let option of options) + expect(option).not.toHaveAttribute("name"); + + }); +}); diff --git a/src/lib/components/switch/Switch.svelte b/src/lib/components/switch/Switch.svelte index c03c9f4c..667b0911 100644 --- a/src/lib/components/switch/Switch.svelte +++ b/src/lib/components/switch/Switch.svelte @@ -5,6 +5,8 @@ > = TPassThroughProps & { /** Whether the switch is checked */ checked: boolean; + /** The name used when using this component inside a form. */ + name?: string; }; @@ -30,6 +32,7 @@ export let as: SupportedAs = "button"; export let use: HTMLActionArray = []; export let checked = false; + export let name: string | null = null; /***** Events *****/ const forwardEvents = forwardEventsBuilder(get_current_component(), [ @@ -73,6 +76,7 @@ role: "switch", type: resolveButtonType({ type: $$props.type, as }, $switchStore), tabIndex: 0, + name, "aria-checked": checked, "aria-labelledby": $labelContext?.labelIds, "aria-describedby": $descriptionContext?.descriptionIds, @@ -88,7 +92,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"Switch"} + componentName={"Switch"} bind:el={$switchStore} on:click={handleClick} on:keyup={handleKeyUp} @@ -102,7 +106,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"Switch"} + componentName={"Switch"} on:click={handleClick} on:keyup={handleKeyUp} on:keypress={handleKeyPress} diff --git a/src/lib/components/switch/SwitchGroup.svelte b/src/lib/components/switch/SwitchGroup.svelte index e6f2b322..d0800c35 100644 --- a/src/lib/components/switch/SwitchGroup.svelte +++ b/src/lib/components/switch/SwitchGroup.svelte @@ -59,7 +59,7 @@ {as} use={[...use, forwardEvents]} {slotProps} - name={"SwitchGroup"} + componentName={"SwitchGroup"} > diff --git a/src/lib/components/switch/switch.test.ts b/src/lib/components/switch/switch.test.ts index 93a68e1d..18a2976a 100644 --- a/src/lib/components/switch/switch.test.ts +++ b/src/lib/components/switch/switch.test.ts @@ -89,6 +89,24 @@ describe("Rendering", () => { expect(getSwitch()).not.toHaveAttribute("type"); }); }); + + describe("`name` attribute", () => { + it('should set the `name` to "switch-name"', async () => { + render(svelte` + Trigger + `); + + expect(getSwitch()).toHaveAttribute("name", "switch-name"); + }); + + it('should not set the name if no "name" prop is passed', async () => { + render(svelte` + Trigger + `); + + expect(getSwitch()).not.toHaveAttribute("name"); + }); + }); }); describe("Render composition", () => { diff --git a/src/lib/components/tabs/Tab.svelte b/src/lib/components/tabs/Tab.svelte index f2cc3327..be844856 100644 --- a/src/lib/components/tabs/Tab.svelte +++ b/src/lib/components/tabs/Tab.svelte @@ -126,7 +126,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"Tab"} + componentName={"Tab"} bind:el={tabRef} on:keydown={handleKeyDown} on:click={handleSelection} diff --git a/src/lib/components/tabs/TabGroup.svelte b/src/lib/components/tabs/TabGroup.svelte index acb64b23..c0822b08 100644 --- a/src/lib/components/tabs/TabGroup.svelte +++ b/src/lib/components/tabs/TabGroup.svelte @@ -200,7 +200,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"TabGroup"} + componentName={"TabGroup"} > diff --git a/src/lib/components/tabs/TabList.svelte b/src/lib/components/tabs/TabList.svelte index 04a551cd..a2a963b9 100644 --- a/src/lib/components/tabs/TabList.svelte +++ b/src/lib/components/tabs/TabList.svelte @@ -42,7 +42,7 @@ {slotProps} bind:el={$listRef} use={[...use, forwardEvents]} - name={"TabList"} + componentName={"TabList"} > diff --git a/src/lib/components/tabs/TabPanel.svelte b/src/lib/components/tabs/TabPanel.svelte index 8e38342c..c2634ce0 100644 --- a/src/lib/components/tabs/TabPanel.svelte +++ b/src/lib/components/tabs/TabPanel.svelte @@ -60,7 +60,7 @@ {...{ ...$$restProps, ...propsWeControl }} {as} use={[...use, forwardEvents]} - name={"TabPanel"} + componentName={"TabPanel"} {slotProps} bind:el={$elementRef} visible={selected} diff --git a/src/lib/components/tabs/TabPanels.svelte b/src/lib/components/tabs/TabPanels.svelte index d16794df..b457481d 100644 --- a/src/lib/components/tabs/TabPanels.svelte +++ b/src/lib/components/tabs/TabPanels.svelte @@ -34,7 +34,7 @@ {as} {slotProps} use={[...use, forwardEvents]} - name={"TabPanels"} + componentName={"TabPanels"} > diff --git a/src/lib/components/transitions/TransitionChild.svelte b/src/lib/components/transitions/TransitionChild.svelte index cacd15f7..bfae595c 100644 --- a/src/lib/components/transitions/TransitionChild.svelte +++ b/src/lib/components/transitions/TransitionChild.svelte @@ -241,7 +241,7 @@ {as} use={[...use, forwardEvents]} slotProps={{}} - name={"TransitionChild"} + componentName={"TransitionChild"} bind:el={container} class={classes} visible={state === TreeStates.Visible} diff --git a/src/lib/utils/Render.svelte b/src/lib/utils/Render.svelte index b6326b27..4a2a6ed8 100644 --- a/src/lib/utils/Render.svelte +++ b/src/lib/utils/Render.svelte @@ -18,7 +18,7 @@ type TAsProp = $$Generic; type $$Props = TRenderProps; - export let name: string; + export let componentName: string; export let as: TAsProp; export let slotProps: TSlotProps; @@ -40,12 +40,14 @@ undefined; if (!as) { - throw new Error(`<${name}> did not provide an \`as\` value to `); + throw new Error( + `<${componentName}> did not provide an \`as\` value to ` + ); } if (!isValidElement(as)) { throw new Error( - `<${name}> has an invalid or unsupported \`as\` prop: ${as}` + `<${componentName}> has an invalid or unsupported \`as\` prop: ${as}` ); } diff --git a/src/routes/docs/listbox.svx b/src/routes/docs/listbox.svx index 8167bcc5..4d90f73f 100644 --- a/src/routes/docs/listbox.svx +++ b/src/routes/docs/listbox.svx @@ -490,6 +490,7 @@ The main listbox component. | `disabled` | `false` | `boolean` | Whether the entire `Listbox` and its children should be disabled | | `horizontal` | `false` | `boolean` | Whether the entire `Listbox` should be oriented horizontally instead of vertically | | `value` | -- | `T` | The selected value | +| `name` | -- | `string` | The name used when using this component inside a form. | | Slot prop | Type | Description | | ---------- | --------- | -------------------------------------- | diff --git a/src/routes/docs/radio-group.svx b/src/routes/docs/radio-group.svx index d78b9cd1..da22e752 100644 --- a/src/routes/docs/radio-group.svx +++ b/src/routes/docs/radio-group.svx @@ -200,6 +200,7 @@ The wrapper component for each selectable option. | `as` | `div` | `string` | The element the `RadioGroupOption` should render as | | `disabled` | `false` | `boolean` | Whether the `RadioGroupOption` is disabled | | `value` | -- | `T` \| `undefined` | The value of the `RadioGroupOption`; the type should match the type of the `value` prop in the `RadioGroup` | +| `name` | -- | `string` | The name used when using this component inside a form. | | Slot prop | Type | Description | | ---------- | --------- | ---------------------------------------------------------- | diff --git a/src/routes/docs/switch.svx b/src/routes/docs/switch.svx index 5c717d56..70c92a66 100644 --- a/src/routes/docs/switch.svx +++ b/src/routes/docs/switch.svx @@ -274,10 +274,12 @@ For a full reference on all accessibility features implemented in `Switch`, see The main switch component. -| Prop | Default | Type | Description | -| --------- | -------- | --------- | ----------------------------------------- | -| `as` | `button` | `string` | The element the `Switch` should render as | -| `checked` | `false` | `boolean` | Whether the switch is checked | +| Prop | Default | Type | Description | +| --------- | -------- | --------- | -------------------------------------------------------| +| `as` | `button` | `string` | The element the `Switch` should render as | +| `checked` | `false` | `boolean` | Whether the switch is checked | +| `name` | -- | `string` | The name used when using this component inside a form. | + | Slot prop | Type | Description | | --------- | --------- | ----------------------------- |