@pzerelles/headlessui-svelte 2.0.0-next.1 → 2.1.1-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/dist/button/Button.svelte +65 -0
  2. package/dist/button/Button.svelte.d.ts +39 -0
  3. package/dist/button/index.d.ts +1 -0
  4. package/dist/button/index.js +1 -0
  5. package/dist/checkbox/Checkbox.svelte +60 -46
  6. package/dist/checkbox/Checkbox.svelte.d.ts +1 -1
  7. package/dist/close-button/CloseButton.svelte +10 -0
  8. package/dist/close-button/CloseButton.svelte.d.ts +25 -0
  9. package/dist/close-button/index.d.ts +1 -0
  10. package/dist/close-button/index.js +1 -0
  11. package/dist/combobox/Combobox.svelte +6 -0
  12. package/dist/combobox/Combobox.svelte.d.ts +50 -0
  13. package/dist/description/Description.svelte +50 -32
  14. package/dist/description/Description.svelte.d.ts +14 -5
  15. package/dist/field/Field.svelte +9 -9
  16. package/dist/fieldset/Fieldset.svelte +9 -9
  17. package/dist/hooks/document-overflow/adjust-scrollbar-padding.d.ts +2 -0
  18. package/dist/hooks/document-overflow/adjust-scrollbar-padding.js +18 -0
  19. package/dist/hooks/document-overflow/handle-ios-locking.d.ts +6 -0
  20. package/dist/hooks/document-overflow/handle-ios-locking.js +134 -0
  21. package/dist/hooks/document-overflow/overflow-store.d.ts +19 -0
  22. package/dist/hooks/document-overflow/overflow-store.js +76 -0
  23. package/dist/hooks/document-overflow/prevent-scroll.d.ts +2 -0
  24. package/dist/hooks/document-overflow/prevent-scroll.js +7 -0
  25. package/dist/hooks/document-overflow/use-document-overflow.svelte.d.ts +7 -0
  26. package/dist/hooks/document-overflow/use-document-overflow.svelte.js +27 -0
  27. package/dist/hooks/use-active-press.svelte.d.ts +14 -0
  28. package/dist/{actions/activePress.svelte.js → hooks/use-active-press.svelte.js} +33 -39
  29. package/dist/hooks/use-by-comparator.d.ts +2 -0
  30. package/dist/hooks/use-by-comparator.js +15 -0
  31. package/dist/hooks/use-controllable.svelte.d.ts +6 -0
  32. package/dist/hooks/use-controllable.svelte.js +34 -0
  33. package/dist/hooks/use-did-element-move.svelte.d.ts +6 -0
  34. package/dist/hooks/use-did-element-move.svelte.js +27 -0
  35. package/dist/hooks/use-disabled.d.ts +3 -0
  36. package/dist/hooks/use-disabled.js +9 -0
  37. package/dist/hooks/use-element-size.svelte.d.ts +7 -0
  38. package/dist/hooks/use-element-size.svelte.js +36 -0
  39. package/dist/hooks/use-flags.svelte.d.ts +8 -0
  40. package/dist/hooks/use-flags.svelte.js +18 -0
  41. package/dist/hooks/use-focus-ring.svelte.d.ts +10 -0
  42. package/dist/hooks/use-focus-ring.svelte.js +24 -0
  43. package/dist/hooks/use-hover.svelte.d.ts +26 -0
  44. package/dist/hooks/use-hover.svelte.js +124 -0
  45. package/dist/hooks/use-id.d.ts +1 -0
  46. package/dist/hooks/use-id.js +1 -0
  47. package/dist/hooks/use-inert-others.svelte.d.ts +32 -0
  48. package/dist/hooks/use-inert-others.svelte.js +114 -0
  49. package/dist/hooks/use-is-top-layer.svelte.d.ts +29 -0
  50. package/dist/hooks/use-is-top-layer.svelte.js +82 -0
  51. package/dist/hooks/use-on-disappear.svelte.d.ts +12 -0
  52. package/dist/hooks/use-on-disappear.svelte.js +38 -0
  53. package/dist/hooks/use-outside-click.svelte.d.ts +10 -0
  54. package/dist/hooks/use-outside-click.svelte.js +150 -0
  55. package/dist/hooks/use-reducer.d.ts +4 -0
  56. package/dist/hooks/use-reducer.js +11 -0
  57. package/dist/hooks/use-resolve-button-type.svelte.d.ts +10 -0
  58. package/dist/hooks/use-resolve-button-type.svelte.js +19 -0
  59. package/dist/hooks/use-scroll-lock.svelte.d.ts +5 -0
  60. package/dist/hooks/use-scroll-lock.svelte.js +24 -0
  61. package/dist/hooks/use-sync-refs.d.ts +7 -0
  62. package/dist/hooks/use-sync-refs.js +22 -0
  63. package/dist/hooks/use-text-value.svelte.d.ts +3 -0
  64. package/dist/hooks/use-text-value.svelte.js +20 -0
  65. package/dist/hooks/use-tracked-pointer.d.ts +4 -0
  66. package/dist/hooks/use-tracked-pointer.js +26 -0
  67. package/dist/hooks/use-transition.svelte.d.ts +20 -0
  68. package/dist/hooks/use-transition.svelte.js +252 -0
  69. package/dist/index.d.ts +4 -0
  70. package/dist/index.js +4 -0
  71. package/dist/internal/FocusSentinel.svelte +45 -0
  72. package/dist/internal/FocusSentinel.svelte.d.ts +17 -0
  73. package/dist/internal/FormFields.svelte +2 -4
  74. package/dist/internal/FormFields.svelte.d.ts +5 -6
  75. package/dist/internal/FormResolver.svelte +11 -16
  76. package/dist/internal/FormResolver.svelte.d.ts +2 -3
  77. package/dist/internal/Hidden.svelte +8 -8
  78. package/dist/internal/Hidden.svelte.d.ts +28 -19
  79. package/dist/internal/HoistFormFields.svelte.d.ts +1 -1
  80. package/dist/internal/Portal.svelte.d.ts +1 -1
  81. package/dist/internal/floating.svelte.d.ts +57 -0
  82. package/dist/internal/floating.svelte.js +477 -0
  83. package/dist/internal/frozen.svelte.d.ts +6 -0
  84. package/dist/internal/frozen.svelte.js +18 -0
  85. package/dist/internal/id.d.ts +8 -0
  86. package/dist/internal/id.js +11 -0
  87. package/dist/internal/open-closed.d.ts +14 -0
  88. package/dist/internal/open-closed.js +17 -0
  89. package/dist/internal/portal-force-root.svelte.d.ts +6 -0
  90. package/dist/internal/portal-force-root.svelte.js +11 -0
  91. package/dist/label/Label.svelte +53 -32
  92. package/dist/label/Label.svelte.d.ts +14 -5
  93. package/dist/legend/Legend.svelte.d.ts +1 -2
  94. package/dist/listbox/Listbox.svelte +451 -0
  95. package/dist/listbox/Listbox.svelte.d.ts +107 -0
  96. package/dist/listbox/ListboxButton.svelte +141 -0
  97. package/dist/listbox/ListboxButton.svelte.d.ts +41 -0
  98. package/dist/listbox/ListboxOption.svelte +138 -0
  99. package/dist/listbox/ListboxOption.svelte.d.ts +39 -0
  100. package/dist/listbox/ListboxOptions.svelte +267 -0
  101. package/dist/listbox/ListboxOptions.svelte.d.ts +39 -0
  102. package/dist/listbox/ListboxSelectedOption.svelte +25 -0
  103. package/dist/listbox/ListboxSelectedOption.svelte.d.ts +30 -0
  104. package/dist/listbox/index.d.ts +5 -0
  105. package/dist/listbox/index.js +5 -0
  106. package/dist/portal/InternalPortal.svelte +108 -0
  107. package/dist/portal/InternalPortal.svelte.d.ts +34 -0
  108. package/dist/portal/Portal.svelte +11 -0
  109. package/dist/portal/Portal.svelte.d.ts +23 -0
  110. package/dist/portal/PortalGroup.svelte +15 -0
  111. package/dist/portal/PortalGroup.svelte.d.ts +31 -0
  112. package/dist/switch/Switch.svelte +149 -0
  113. package/dist/switch/Switch.svelte.d.ts +44 -0
  114. package/dist/switch/SwitchGroup.svelte +38 -0
  115. package/dist/switch/SwitchGroup.svelte.d.ts +27 -0
  116. package/dist/switch/index.d.ts +2 -0
  117. package/dist/switch/index.js +2 -0
  118. package/dist/tabs/Button.svelte +65 -0
  119. package/dist/tabs/Button.svelte.d.ts +39 -0
  120. package/dist/tabs/Tab.svelte +161 -0
  121. package/dist/tabs/Tab.svelte.d.ts +36 -0
  122. package/dist/tabs/TabGroup.svelte +244 -0
  123. package/dist/tabs/TabGroup.svelte.d.ts +54 -0
  124. package/dist/tabs/TabList.svelte +18 -0
  125. package/dist/tabs/TabList.svelte.d.ts +28 -0
  126. package/dist/tabs/TabPanel.svelte +63 -0
  127. package/dist/tabs/TabPanel.svelte.d.ts +34 -0
  128. package/dist/tabs/TabPanels.svelte +13 -0
  129. package/dist/tabs/TabPanels.svelte.d.ts +27 -0
  130. package/dist/tabs/index.d.ts +5 -0
  131. package/dist/tabs/index.js +5 -0
  132. package/dist/test-utils/accessability-assertions.d.ts +271 -0
  133. package/dist/test-utils/accessability-assertions.js +1572 -0
  134. package/dist/test-utils/fake-pointer.d.ts +24 -0
  135. package/dist/test-utils/fake-pointer.js +48 -0
  136. package/dist/test-utils/interactions.d.ts +61 -0
  137. package/dist/test-utils/interactions.js +453 -0
  138. package/dist/test-utils/suppress-console-logs.d.ts +7 -0
  139. package/dist/test-utils/suppress-console-logs.js +17 -0
  140. package/dist/utils/StableCollection.svelte +43 -0
  141. package/dist/utils/StableCollection.svelte.d.ts +19 -0
  142. package/dist/utils/calculate-active-index.d.ts +25 -0
  143. package/dist/utils/calculate-active-index.js +74 -0
  144. package/dist/utils/close.d.ts +2 -0
  145. package/dist/utils/close.js +3 -0
  146. package/dist/utils/default-map.d.ts +5 -0
  147. package/dist/utils/default-map.js +15 -0
  148. package/dist/utils/disposables.d.ts +14 -12
  149. package/dist/utils/disposables.js +13 -10
  150. package/dist/utils/dom.d.ts +0 -2
  151. package/dist/utils/dom.js +2 -4
  152. package/dist/utils/env.d.ts +17 -0
  153. package/dist/utils/env.js +39 -0
  154. package/dist/utils/focus-management.d.ts +44 -0
  155. package/dist/utils/focus-management.js +242 -0
  156. package/dist/utils/focusVisible.svelte.d.ts +3 -3
  157. package/dist/utils/focusVisible.svelte.js +52 -41
  158. package/dist/utils/get-text-value.d.ts +1 -0
  159. package/dist/utils/get-text-value.js +71 -0
  160. package/dist/utils/id.d.ts +1 -1
  161. package/dist/utils/match.d.ts +1 -0
  162. package/dist/utils/match.js +13 -0
  163. package/dist/utils/once.d.ts +1 -0
  164. package/dist/utils/once.js +9 -0
  165. package/dist/utils/owner.d.ts +1 -0
  166. package/dist/utils/owner.js +8 -0
  167. package/dist/utils/platform.d.ts +2 -0
  168. package/dist/utils/platform.js +17 -0
  169. package/dist/utils/ref.svelte.d.ts +4 -0
  170. package/dist/utils/ref.svelte.js +4 -0
  171. package/dist/utils/render.d.ts +31 -0
  172. package/dist/utils/render.js +56 -0
  173. package/dist/utils/store.d.ts +11 -0
  174. package/dist/utils/store.js +20 -0
  175. package/dist/utils/types.d.ts +27 -0
  176. package/dist/utils/types.js +6 -0
  177. package/package.json +28 -21
  178. package/dist/actions/activePress.svelte.d.ts +0 -8
  179. package/dist/actions/focusRing.svelte.d.ts +0 -9
  180. package/dist/actions/focusRing.svelte.js +0 -34
  181. package/dist/utils/disabled.d.ts +0 -3
  182. package/dist/utils/disabled.js +0 -2
@@ -0,0 +1,149 @@
1
+ <script lang="ts" context="module">const DEFAULT_SWITCH_TAG = "button";
2
+ </script>
3
+
4
+ <script lang="ts" generics="TTag extends ElementType">import { useId } from "../hooks/use-id.js";
5
+ import { useDisabled } from "../hooks/use-disabled.js";
6
+ import { useProvidedId } from "../internal/id.js";
7
+ import { getContext } from "svelte";
8
+ import { useControllable } from "../hooks/use-controllable.svelte.js";
9
+ import { useDisposables } from "../utils/disposables.js";
10
+ import { attemptSubmit } from "../utils/form.js";
11
+ import { useLabelledBy } from "../label/Label.svelte";
12
+ import { useDescribedBy } from "../description/Description.svelte";
13
+ import { mergeProps } from "../utils/render.js";
14
+ import { useResolveButtonType } from "../hooks/use-resolve-button-type.svelte.js";
15
+ import { useFocusRing } from "../hooks/use-focus-ring.svelte.js";
16
+ import { useHover } from "../hooks/use-hover.svelte.js";
17
+ import { useActivePress } from "../hooks/use-active-press.svelte.js";
18
+ import { stateFromSlot } from "../utils/state.js";
19
+ import FormFields from "../internal/FormFields.svelte";
20
+ const internalId = useId();
21
+ let providedId = useProvidedId();
22
+ let { value: providedDisabled } = $derived(useDisabled());
23
+ let {
24
+ as = DEFAULT_SWITCH_TAG,
25
+ id: ownId,
26
+ disabled: ownDisabled,
27
+ defaultChecked,
28
+ checked = $bindable(defaultChecked),
29
+ onchange,
30
+ name,
31
+ value,
32
+ form,
33
+ autofocus = false,
34
+ tabIndex,
35
+ children,
36
+ ...theirProps
37
+ } = $props();
38
+ const id = $derived(ownId || providedId || `headlessui-switch-${internalId}`);
39
+ const disabled = $derived(ownDisabled || providedDisabled || false);
40
+ const groupContext = getContext("GroupContext");
41
+ let ref = $state(null);
42
+ $effect(() => {
43
+ if (groupContext) groupContext.switchElement = ref;
44
+ });
45
+ $inspect(providedDisabled);
46
+ const d = useDisposables();
47
+ let changing = $state(false);
48
+ const toggle = () => {
49
+ changing = true;
50
+ checked = !checked;
51
+ onchange?.(checked);
52
+ d.nextFrame(() => {
53
+ changing = false;
54
+ });
55
+ };
56
+ const handleClick = (event) => {
57
+ event.preventDefault();
58
+ toggle();
59
+ };
60
+ const handleKeyUp = (event) => {
61
+ if (event.key === " ") {
62
+ event.preventDefault();
63
+ toggle();
64
+ } else if (event.key === "Enter") {
65
+ attemptSubmit(event.currentTarget);
66
+ }
67
+ };
68
+ const handleKeyPress = (event) => event.preventDefault();
69
+ let labelledBy = useLabelledBy();
70
+ let describedBy = useDescribedBy();
71
+ const { isFocusVisible: focus, focusProps } = $derived(
72
+ useFocusRing({
73
+ get autofocus() {
74
+ return autofocus;
75
+ }
76
+ })
77
+ );
78
+ const { isHovered: hover, hoverProps } = $derived(
79
+ useHover({
80
+ get disabled() {
81
+ return disabled;
82
+ }
83
+ })
84
+ );
85
+ const { pressed: active, pressProps } = $derived(
86
+ useActivePress({
87
+ get disabled() {
88
+ return disabled;
89
+ }
90
+ })
91
+ );
92
+ const slot = $derived({
93
+ checked,
94
+ disabled,
95
+ hover,
96
+ focus,
97
+ active,
98
+ autofocus,
99
+ changing
100
+ });
101
+ const buttonType = useResolveButtonType({
102
+ get props() {
103
+ return { type: theirProps.type, as };
104
+ },
105
+ get ref() {
106
+ return { current: ref };
107
+ }
108
+ });
109
+ const ourProps = $derived(
110
+ mergeProps(
111
+ {
112
+ id,
113
+ role: "switch",
114
+ type: buttonType.type,
115
+ tabIndex: tabIndex === -1 ? 0 : tabIndex ?? 0,
116
+ "aria-checked": checked,
117
+ "aria-labelledby": labelledBy.value,
118
+ "aria-describedby": describedBy.value,
119
+ disabled: disabled || void 0,
120
+ autofocus,
121
+ onclick: handleClick,
122
+ onkeyup: handleKeyUp,
123
+ onkeypress: handleKeyPress
124
+ },
125
+ focusProps,
126
+ hoverProps,
127
+ pressProps,
128
+ stateFromSlot(slot)
129
+ )
130
+ );
131
+ const reset = () => {
132
+ if (defaultChecked === void 0) return;
133
+ checked = defaultChecked;
134
+ return onchange?.(checked);
135
+ };
136
+ </script>
137
+
138
+ {#if name}
139
+ <FormFields
140
+ {disabled}
141
+ data={{ [name]: value || "on" }}
142
+ overrides={{ type: "checkbox", checked }}
143
+ {form}
144
+ onReset={reset}
145
+ />
146
+ {/if}
147
+ <svelte:element this={as} {...ourProps} {...theirProps}>
148
+ {#if children}{@render children(slot)}{/if}
149
+ </svelte:element>
@@ -0,0 +1,44 @@
1
+ import type { ElementType, Props } from "../utils/types.js";
2
+ declare const DEFAULT_SWITCH_TAG: "button";
3
+ type SwitchRenderPropArg = {
4
+ checked: boolean;
5
+ hover: boolean;
6
+ focus: boolean;
7
+ active: boolean;
8
+ autofocus: boolean;
9
+ changing: boolean;
10
+ disabled: boolean;
11
+ };
12
+ type SwitchPropsWeControl = "aria-checked" | "aria-describedby" | "aria-labelledby" | "role";
13
+ export type SwitchProps<TTag extends ElementType = typeof DEFAULT_SWITCH_TAG> = Props<TTag, SwitchRenderPropArg, SwitchPropsWeControl, {
14
+ checked?: boolean;
15
+ defaultChecked?: boolean;
16
+ onchange?(checked: boolean): void;
17
+ name?: string;
18
+ value?: string;
19
+ form?: string;
20
+ autofocus?: boolean;
21
+ disabled?: boolean;
22
+ tabIndex?: number;
23
+ }>;
24
+ declare class __sveltets_Render<TTag extends ElementType> {
25
+ props(): SwitchProps<TTag>;
26
+ events(): {} & {
27
+ [evt: string]: CustomEvent<any>;
28
+ };
29
+ slots(): {};
30
+ bindings(): "checked";
31
+ exports(): {};
32
+ }
33
+ interface $$IsomorphicComponent {
34
+ new <TTag extends ElementType>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TTag>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TTag>['props']>, ReturnType<__sveltets_Render<TTag>['events']>, ReturnType<__sveltets_Render<TTag>['slots']>> & {
35
+ $$bindings?: ReturnType<__sveltets_Render<TTag>['bindings']>;
36
+ } & ReturnType<__sveltets_Render<TTag>['exports']>;
37
+ <TTag extends ElementType>(internal: unknown, props: ReturnType<__sveltets_Render<TTag>['props']> & {
38
+ $$events?: ReturnType<__sveltets_Render<TTag>['events']>;
39
+ }): ReturnType<__sveltets_Render<TTag>['exports']>;
40
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
41
+ }
42
+ declare const Switch: $$IsomorphicComponent;
43
+ type Switch<TTag extends ElementType> = InstanceType<typeof Switch<TTag>>;
44
+ export default Switch;
@@ -0,0 +1,38 @@
1
+ <script lang="ts" context="module">const DEFAULT_GROUP_TAG = "svelte:fragment";
2
+ </script>
3
+
4
+ <script lang="ts" generics="TTag extends ElementType">import { setContext } from "svelte";
5
+ import { useLabels } from "../label/Label.svelte";
6
+ import { useDescriptions } from "../description/Description.svelte";
7
+ let switchElement = $state(null);
8
+ useLabels({
9
+ name: "SwitchGroup",
10
+ props: {
11
+ get htmlFor() {
12
+ return switchElement?.id;
13
+ },
14
+ onclick: (event) => {
15
+ if (!switchElement) return;
16
+ if (event.currentTarget instanceof HTMLLabelElement) {
17
+ event.preventDefault();
18
+ }
19
+ switchElement.click();
20
+ switchElement.focus({ preventScroll: true });
21
+ }
22
+ }
23
+ });
24
+ useDescriptions();
25
+ setContext("GroupContext", {
26
+ get switchElement() {
27
+ return switchElement;
28
+ },
29
+ set switchElement(element) {
30
+ switchElement = element;
31
+ }
32
+ });
33
+ const { as = DEFAULT_GROUP_TAG, children, ...theirProps } = $props();
34
+ </script>
35
+
36
+ <svelte:element this={as} {...theirProps}>
37
+ {#if children}{@render children({})}{/if}
38
+ </svelte:element>
@@ -0,0 +1,27 @@
1
+ import type { ElementType, Props } from "../utils/types.js";
2
+ declare const DEFAULT_GROUP_TAG = "svelte:fragment";
3
+ export type SwitchGroupProps<TTag extends ElementType = typeof DEFAULT_GROUP_TAG> = Props<TTag>;
4
+ export type GroupContext = {
5
+ switchElement: HTMLButtonElement | null;
6
+ };
7
+ declare class __sveltets_Render<TTag extends ElementType> {
8
+ props(): SwitchGroupProps<TTag>;
9
+ events(): {} & {
10
+ [evt: string]: CustomEvent<any>;
11
+ };
12
+ slots(): {};
13
+ bindings(): "";
14
+ exports(): {};
15
+ }
16
+ interface $$IsomorphicComponent {
17
+ new <TTag extends ElementType>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TTag>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TTag>['props']>, ReturnType<__sveltets_Render<TTag>['events']>, ReturnType<__sveltets_Render<TTag>['slots']>> & {
18
+ $$bindings?: ReturnType<__sveltets_Render<TTag>['bindings']>;
19
+ } & ReturnType<__sveltets_Render<TTag>['exports']>;
20
+ <TTag extends ElementType>(internal: unknown, props: ReturnType<__sveltets_Render<TTag>['props']> & {
21
+ $$events?: ReturnType<__sveltets_Render<TTag>['events']>;
22
+ }): ReturnType<__sveltets_Render<TTag>['exports']>;
23
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
24
+ }
25
+ declare const SwitchGroup: $$IsomorphicComponent;
26
+ type SwitchGroup<TTag extends ElementType> = InstanceType<typeof SwitchGroup<TTag>>;
27
+ export default SwitchGroup;
@@ -0,0 +1,2 @@
1
+ export { default as Switch, type SwitchProps } from "./Switch.svelte";
2
+ export { default as SwitchGroup, type SwitchGroupProps } from "./SwitchGroup.svelte";
@@ -0,0 +1,2 @@
1
+ export { default as Switch } from "./Switch.svelte";
2
+ export { default as SwitchGroup } from "./SwitchGroup.svelte";
@@ -0,0 +1,65 @@
1
+ <script lang="ts" context="module">const DEFAULT_BUTTON_TAG = "button";
2
+ </script>
3
+
4
+ <script lang="ts" generics="TTag extends keyof SvelteHTMLElements, TType">import { useActivePress } from "../hooks/use-active-press.svelte.js";
5
+ import { useFocusRing } from "../hooks/use-focus-ring.svelte.js";
6
+ import { useDisabled } from "../hooks/use-disabled.js";
7
+ import { stateFromSlot } from "../utils/state.js";
8
+ import { useHover } from "../hooks/use-hover.svelte.js";
9
+ import { mergeProps } from "../utils/render.js";
10
+ const providedDisabled = useDisabled();
11
+ let {
12
+ as,
13
+ disabled: ownDisabled = false,
14
+ autofocus = false,
15
+ type = "button",
16
+ children,
17
+ ...theirProps
18
+ } = $props();
19
+ const disabled = $derived(providedDisabled.value || ownDisabled);
20
+ const { isHovered: hover, hoverProps } = $derived(
21
+ useHover({
22
+ get disabled() {
23
+ return disabled;
24
+ }
25
+ })
26
+ );
27
+ const { pressed: active, pressProps } = $derived(
28
+ useActivePress({
29
+ get disabled() {
30
+ return disabled;
31
+ }
32
+ })
33
+ );
34
+ const { isFocusVisible: focus, focusProps } = $derived(
35
+ useFocusRing({
36
+ get autofocus() {
37
+ return autofocus;
38
+ }
39
+ })
40
+ );
41
+ const slot = $derived({
42
+ disabled,
43
+ hover,
44
+ focus,
45
+ active,
46
+ autofocus
47
+ });
48
+ const ownProps = $derived(
49
+ mergeProps(
50
+ {
51
+ type,
52
+ disabled: disabled || void 0,
53
+ autofocus
54
+ },
55
+ focusProps,
56
+ hoverProps,
57
+ pressProps,
58
+ stateFromSlot(slot)
59
+ )
60
+ );
61
+ </script>
62
+
63
+ <svelte:element this={as ?? DEFAULT_BUTTON_TAG} {...ownProps} {...theirProps}>
64
+ {#if children}{@render children(slot)}{/if}
65
+ </svelte:element>
@@ -0,0 +1,39 @@
1
+ import type { SvelteHTMLElements } from "svelte/elements";
2
+ export type ButtonProps<TTag extends keyof SvelteHTMLElements = typeof DEFAULT_BUTTON_TAG> = SvelteHTMLElements[TTag] & {
3
+ as?: TTag;
4
+ disabled?: boolean;
5
+ autofocus?: boolean;
6
+ type?: "button" | "submit" | "reset";
7
+ children?: Snippet<[
8
+ {
9
+ disabled: boolean;
10
+ hover: boolean;
11
+ focus: boolean;
12
+ active: boolean;
13
+ autofocus: boolean;
14
+ }
15
+ ]>;
16
+ };
17
+ declare const DEFAULT_BUTTON_TAG: "button";
18
+ import type { Snippet } from "svelte";
19
+ declare class __sveltets_Render<TTag extends keyof SvelteHTMLElements, TType> {
20
+ props(): ButtonProps<TTag>;
21
+ events(): {} & {
22
+ [evt: string]: CustomEvent<any>;
23
+ };
24
+ slots(): {};
25
+ bindings(): "";
26
+ exports(): {};
27
+ }
28
+ interface $$IsomorphicComponent {
29
+ new <TTag extends keyof SvelteHTMLElements, TType>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TTag, TType>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TTag, TType>['props']>, ReturnType<__sveltets_Render<TTag, TType>['events']>, ReturnType<__sveltets_Render<TTag, TType>['slots']>> & {
30
+ $$bindings?: ReturnType<__sveltets_Render<TTag, TType>['bindings']>;
31
+ } & ReturnType<__sveltets_Render<TTag, TType>['exports']>;
32
+ <TTag extends keyof SvelteHTMLElements, TType>(internal: unknown, props: ReturnType<__sveltets_Render<TTag, TType>['props']> & {
33
+ $$events?: ReturnType<__sveltets_Render<TTag, TType>['events']>;
34
+ }): ReturnType<__sveltets_Render<TTag, TType>['exports']>;
35
+ z_$$bindings?: ReturnType<__sveltets_Render<any, any>['bindings']>;
36
+ }
37
+ declare const Button: $$IsomorphicComponent;
38
+ type Button<TTag extends keyof SvelteHTMLElements, TType> = InstanceType<typeof Button<TTag, TType>>;
39
+ export default Button;
@@ -0,0 +1,161 @@
1
+ <script lang="ts" context="module">const DEFAULT_TAB_TAG = "button";
2
+ </script>
3
+
4
+ <script lang="ts" generics="TTag extends ElementType">import { useId } from "../hooks/use-id.js";
5
+ import { useActions, useData } from "./TabGroup.svelte";
6
+ import { useStableCollectionIndex } from "../utils/StableCollection.svelte";
7
+ import { Focus, focusIn, FocusResult } from "../utils/focus-management.js";
8
+ import { getOwnerDocument } from "../utils/owner.js";
9
+ import { match } from "../utils/match.js";
10
+ import { microTask } from "../utils/microTask.js";
11
+ import { useActivePress } from "../hooks/use-active-press.svelte.js";
12
+ import { useFocusRing } from "../hooks/use-focus-ring.svelte.js";
13
+ import { useResolveButtonType } from "../hooks/use-resolve-button-type.svelte.js";
14
+ import { stateFromSlot } from "../utils/state.js";
15
+ import { onMount } from "svelte";
16
+ import { useHover } from "../hooks/use-hover.svelte.js";
17
+ import { mergeProps } from "../utils/render.js";
18
+ const internalId = useId();
19
+ const {
20
+ as,
21
+ id = `headlessui-tabs-tab-${internalId}`,
22
+ disabled = false,
23
+ autofocus = false,
24
+ children,
25
+ ...theirProps
26
+ } = $props();
27
+ const data = useData("Tab");
28
+ const { orientation, activation, selectedIndex, tabs, panels } = $derived(data);
29
+ const actions = useActions("Tab");
30
+ let ref = $state();
31
+ const tabRef = $derived({ current: ref });
32
+ onMount(() => actions.registerTab(tabRef));
33
+ const mySSRIndex = useStableCollectionIndex("tabs");
34
+ const myIndex = $derived.by(() => {
35
+ const index = tabs.findIndex((tab) => $state.is(tab, tabRef));
36
+ return index === -1 ? mySSRIndex : index;
37
+ });
38
+ const selected = $derived(myIndex === selectedIndex);
39
+ const activateUsing = $derived((cb) => {
40
+ let result = cb();
41
+ if (result === FocusResult.Success && activation === "auto") {
42
+ let newTab = getOwnerDocument(ref)?.activeElement;
43
+ let idx = data.tabs.findIndex((tab) => tab.current === newTab);
44
+ if (idx !== -1) actions.change(idx);
45
+ }
46
+ return result;
47
+ });
48
+ const handleKeyDown = (event) => {
49
+ let list = tabs.map((tab) => tab.current).filter(Boolean);
50
+ if (event.key === " " || event.key === "Enter") {
51
+ event.preventDefault();
52
+ event.stopPropagation();
53
+ actions.change(myIndex);
54
+ return;
55
+ }
56
+ switch (event.key) {
57
+ case "Home":
58
+ case "PageUp":
59
+ event.preventDefault();
60
+ event.stopPropagation();
61
+ return activateUsing(() => focusIn(list, Focus.First));
62
+ case "End":
63
+ case "PageDown":
64
+ event.preventDefault();
65
+ event.stopPropagation();
66
+ return activateUsing(() => focusIn(list, Focus.Last));
67
+ }
68
+ let result = activateUsing(() => {
69
+ return match(orientation, {
70
+ vertical() {
71
+ if (event.key === "ArrowUp") return focusIn(list, Focus.Previous | Focus.WrapAround);
72
+ if (event.key === "ArrowDown") return focusIn(list, Focus.Next | Focus.WrapAround);
73
+ return FocusResult.Error;
74
+ },
75
+ horizontal() {
76
+ if (event.key === "ArrowLeft") return focusIn(list, Focus.Previous | Focus.WrapAround);
77
+ if (event.key === "ArrowRight") return focusIn(list, Focus.Next | Focus.WrapAround);
78
+ return FocusResult.Error;
79
+ }
80
+ });
81
+ });
82
+ if (result === FocusResult.Success) {
83
+ return event.preventDefault();
84
+ }
85
+ };
86
+ let ready = $state(false);
87
+ const handleSelection = () => {
88
+ if (ready) return;
89
+ ready = true;
90
+ ref?.focus({ preventScroll: true });
91
+ actions.change(myIndex);
92
+ microTask(() => {
93
+ ready = false;
94
+ });
95
+ };
96
+ const handleMouseDown = (event) => {
97
+ event.preventDefault();
98
+ };
99
+ const { isHovered: hover, hoverProps } = $derived(
100
+ useHover({
101
+ get disabled() {
102
+ return disabled;
103
+ }
104
+ })
105
+ );
106
+ const { pressed: active, pressProps } = $derived(
107
+ useActivePress({
108
+ get disabled() {
109
+ return disabled;
110
+ }
111
+ })
112
+ );
113
+ const { isFocusVisible: focus, focusProps } = $derived(
114
+ useFocusRing({
115
+ get autofocus() {
116
+ return autofocus;
117
+ }
118
+ })
119
+ );
120
+ const slot = $derived({
121
+ selected,
122
+ hover,
123
+ active,
124
+ focus,
125
+ autofocus,
126
+ disabled
127
+ });
128
+ const resolvedType = useResolveButtonType({
129
+ get props() {
130
+ return { type: theirProps.type, as };
131
+ },
132
+ get ref() {
133
+ return tabRef;
134
+ }
135
+ });
136
+ const ourProps = $derived(
137
+ mergeProps(
138
+ {
139
+ onkeydown: handleKeyDown,
140
+ onmousedown: handleMouseDown,
141
+ onclick: handleSelection,
142
+ id,
143
+ role: "tab",
144
+ type: resolvedType.type,
145
+ "aria-controls": panels[myIndex]?.current?.id,
146
+ "aria-selected": selected,
147
+ tabIndex: selected ? 0 : -1,
148
+ disabled: disabled || void 0,
149
+ autofocus
150
+ },
151
+ focusProps,
152
+ hoverProps,
153
+ pressProps,
154
+ stateFromSlot(slot)
155
+ )
156
+ );
157
+ </script>
158
+
159
+ <svelte:element this={as ?? DEFAULT_TAB_TAG} bind:this={ref} {...ourProps} {...theirProps}>
160
+ {#if children}{@render children(slot)}{/if}
161
+ </svelte:element>
@@ -0,0 +1,36 @@
1
+ import type { ElementType, Props } from "../utils/types.js";
2
+ declare const DEFAULT_TAB_TAG: "button";
3
+ type TabRenderPropArg = {
4
+ hover: boolean;
5
+ focus: boolean;
6
+ active: boolean;
7
+ autofocus: boolean;
8
+ selected: boolean;
9
+ disabled: boolean;
10
+ };
11
+ type TabPropsWeControl = "aria-controls" | "aria-selected" | "role" | "tabIndex";
12
+ export type TabProps<TTag extends ElementType = typeof DEFAULT_TAB_TAG> = Props<TTag, TabRenderPropArg, TabPropsWeControl, {
13
+ autofocus?: boolean;
14
+ disabled?: boolean;
15
+ }>;
16
+ declare class __sveltets_Render<TTag extends ElementType> {
17
+ props(): TabProps<TTag>;
18
+ events(): {} & {
19
+ [evt: string]: CustomEvent<any>;
20
+ };
21
+ slots(): {};
22
+ bindings(): "";
23
+ exports(): {};
24
+ }
25
+ interface $$IsomorphicComponent {
26
+ new <TTag extends ElementType>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TTag>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TTag>['props']>, ReturnType<__sveltets_Render<TTag>['events']>, ReturnType<__sveltets_Render<TTag>['slots']>> & {
27
+ $$bindings?: ReturnType<__sveltets_Render<TTag>['bindings']>;
28
+ } & ReturnType<__sveltets_Render<TTag>['exports']>;
29
+ <TTag extends ElementType>(internal: unknown, props: ReturnType<__sveltets_Render<TTag>['props']> & {
30
+ $$events?: ReturnType<__sveltets_Render<TTag>['events']>;
31
+ }): ReturnType<__sveltets_Render<TTag>['exports']>;
32
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
33
+ }
34
+ declare const Tab: $$IsomorphicComponent;
35
+ type Tab<TTag extends ElementType> = InstanceType<typeof Tab<TTag>>;
36
+ export default Tab;