@pzerelles/headlessui-svelte 2.1.2-next.23 → 2.1.2-next.24

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 (127) hide show
  1. package/dist/button/Button.svelte +84 -54
  2. package/dist/button/Button.svelte.d.ts +7 -4
  3. package/dist/checkbox/Checkbox.svelte +173 -120
  4. package/dist/checkbox/Checkbox.svelte.d.ts +7 -4
  5. package/dist/close-button/CloseButton.svelte +12 -6
  6. package/dist/close-button/CloseButton.svelte.d.ts +13 -10
  7. package/dist/combobox/Combobox.svelte +50 -3
  8. package/dist/data-interactive/DataInteractive.svelte +55 -29
  9. package/dist/data-interactive/DataInteractive.svelte.d.ts +7 -5
  10. package/dist/description/Description.svelte +31 -21
  11. package/dist/description/Description.svelte.d.ts +7 -4
  12. package/dist/dialog/Dialog.svelte +358 -38
  13. package/dist/dialog/Dialog.svelte.d.ts +10 -7
  14. package/dist/dialog/DialogBackdrop.svelte +30 -13
  15. package/dist/dialog/DialogBackdrop.svelte.d.ts +7 -4
  16. package/dist/dialog/DialogPanel.svelte +49 -26
  17. package/dist/dialog/DialogPanel.svelte.d.ts +7 -4
  18. package/dist/dialog/DialogTitle.svelte +38 -23
  19. package/dist/dialog/DialogTitle.svelte.d.ts +7 -4
  20. package/dist/field/Field.svelte +50 -28
  21. package/dist/field/Field.svelte.d.ts +7 -4
  22. package/dist/fieldset/Fieldset.svelte +50 -29
  23. package/dist/fieldset/Fieldset.svelte.d.ts +7 -4
  24. package/dist/focus-trap/FocusTrap.svelte +419 -283
  25. package/dist/focus-trap/FocusTrap.svelte.d.ts +7 -4
  26. package/dist/input/Input.svelte +84 -53
  27. package/dist/input/Input.svelte.d.ts +7 -4
  28. package/dist/internal/FloatingProvider.svelte +14 -9
  29. package/dist/internal/FocusSentinel.svelte +16 -8
  30. package/dist/internal/ForcePortalRoot.svelte +7 -3
  31. package/dist/internal/FormFields.svelte +47 -34
  32. package/dist/internal/FormFieldsProvider.svelte +9 -5
  33. package/dist/internal/FormResolver.svelte +20 -15
  34. package/dist/internal/Hidden.svelte +50 -29
  35. package/dist/internal/Hidden.svelte.d.ts +7 -4
  36. package/dist/internal/MainTreeProvider.svelte +89 -36
  37. package/dist/internal/Portal.svelte +18 -14
  38. package/dist/internal/floating-provider.svelte.js +1 -1
  39. package/dist/internal/floating.svelte.d.ts +5 -5
  40. package/dist/internal/floating.svelte.js +17 -17
  41. package/dist/label/Label.svelte +93 -58
  42. package/dist/label/Label.svelte.d.ts +7 -4
  43. package/dist/legend/Legend.svelte +12 -3
  44. package/dist/listbox/Listbox.svelte +525 -387
  45. package/dist/listbox/Listbox.svelte.d.ts +7 -5
  46. package/dist/listbox/ListboxButton.svelte +173 -127
  47. package/dist/listbox/ListboxButton.svelte.d.ts +7 -5
  48. package/dist/listbox/ListboxOption.svelte +170 -129
  49. package/dist/listbox/ListboxOption.svelte.d.ts +7 -5
  50. package/dist/listbox/ListboxOptions.svelte +400 -304
  51. package/dist/listbox/ListboxOptions.svelte.d.ts +7 -5
  52. package/dist/listbox/ListboxSelectedOption.svelte +38 -15
  53. package/dist/listbox/ListboxSelectedOption.svelte.d.ts +7 -4
  54. package/dist/listbox/index.d.ts +4 -4
  55. package/dist/listbox/index.js +1 -1
  56. package/dist/menu/Menu.svelte +78 -51
  57. package/dist/menu/Menu.svelte.d.ts +7 -5
  58. package/dist/menu/MenuButton.svelte +157 -117
  59. package/dist/menu/MenuButton.svelte.d.ts +7 -5
  60. package/dist/menu/MenuHeading.svelte +32 -14
  61. package/dist/menu/MenuHeading.svelte.d.ts +7 -5
  62. package/dist/menu/MenuItem.svelte +142 -107
  63. package/dist/menu/MenuItem.svelte.d.ts +8 -8
  64. package/dist/menu/MenuItems.svelte +301 -229
  65. package/dist/menu/MenuItems.svelte.d.ts +7 -5
  66. package/dist/menu/MenuSection.svelte +24 -9
  67. package/dist/menu/MenuSection.svelte.d.ts +7 -5
  68. package/dist/menu/MenuSeparator.svelte +17 -4
  69. package/dist/menu/MenuSeparator.svelte.d.ts +7 -6
  70. package/dist/menu/index.d.ts +7 -7
  71. package/dist/popover/Popover.svelte +216 -150
  72. package/dist/popover/Popover.svelte.d.ts +7 -4
  73. package/dist/popover/PopoverBackdrop.svelte +67 -41
  74. package/dist/popover/PopoverBackdrop.svelte.d.ts +7 -4
  75. package/dist/popover/PopoverButton.svelte +292 -212
  76. package/dist/popover/PopoverButton.svelte.d.ts +7 -4
  77. package/dist/popover/PopoverGroup.svelte +62 -35
  78. package/dist/popover/PopoverGroup.svelte.d.ts +7 -4
  79. package/dist/popover/PopoverPanel.svelte +311 -229
  80. package/dist/popover/PopoverPanel.svelte.d.ts +7 -4
  81. package/dist/portal/InternalPortal.svelte +141 -85
  82. package/dist/portal/InternalPortal.svelte.d.ts +7 -4
  83. package/dist/portal/Portal.svelte +5 -2
  84. package/dist/portal/PortalGroup.svelte +30 -9
  85. package/dist/portal/PortalGroup.svelte.d.ts +7 -4
  86. package/dist/select/Select.svelte +98 -68
  87. package/dist/select/Select.svelte.d.ts +7 -4
  88. package/dist/switch/Switch.svelte +179 -132
  89. package/dist/switch/Switch.svelte.d.ts +7 -4
  90. package/dist/switch/SwitchGroup.svelte +44 -31
  91. package/dist/switch/SwitchGroup.svelte.d.ts +7 -4
  92. package/dist/tabs/Tab.svelte +194 -143
  93. package/dist/tabs/Tab.svelte.d.ts +7 -4
  94. package/dist/tabs/TabGroup.svelte +81 -214
  95. package/dist/tabs/TabGroup.svelte.d.ts +7 -24
  96. package/dist/tabs/TabList.svelte +31 -11
  97. package/dist/tabs/TabList.svelte.d.ts +7 -4
  98. package/dist/tabs/TabPanel.svelte +67 -43
  99. package/dist/tabs/TabPanel.svelte.d.ts +7 -4
  100. package/dist/tabs/TabPanels.svelte +18 -7
  101. package/dist/tabs/TabPanels.svelte.d.ts +7 -4
  102. package/dist/tabs/context.svelte.d.ts +31 -0
  103. package/dist/tabs/context.svelte.js +134 -0
  104. package/dist/textarea/Textarea.svelte +84 -53
  105. package/dist/textarea/Textarea.svelte.d.ts +7 -4
  106. package/dist/transition/InternalTransitionChild.svelte +259 -170
  107. package/dist/transition/InternalTransitionChild.svelte.d.ts +7 -4
  108. package/dist/transition/Transition.svelte +96 -66
  109. package/dist/transition/Transition.svelte.d.ts +7 -4
  110. package/dist/transition/TransitionChild.svelte +31 -11
  111. package/dist/transition/TransitionChild.svelte.d.ts +7 -4
  112. package/dist/utils/ElementOrComponent.svelte +43 -23
  113. package/dist/utils/ElementOrComponent.svelte.d.ts +10 -4
  114. package/dist/utils/Generic.svelte +36 -22
  115. package/dist/utils/Generic.svelte.d.ts +7 -4
  116. package/dist/utils/StableCollection.svelte +54 -36
  117. package/dist/utils/floating-ui/svelte/components/FloatingNode.svelte +27 -12
  118. package/dist/utils/floating-ui/svelte/components/FloatingTree.svelte +88 -44
  119. package/dist/utils/floating-ui/svelte/hooks/useFloating.svelte.js +7 -7
  120. package/dist/utils/floating-ui/svelte/hooks/useFloatingRootContext.svelte.js +1 -1
  121. package/dist/utils/floating-ui/svelte/types.d.ts +4 -4
  122. package/dist/utils/floating-ui/svelte-dom/types.d.ts +2 -2
  123. package/dist/utils/floating-ui/svelte-dom/useFloating.svelte.js +6 -6
  124. package/dist/utils/types.d.ts +11 -4
  125. package/package.json +1 -1
  126. package/dist/dialog/InternalDialog.svelte +0 -233
  127. package/dist/dialog/InternalDialog.svelte.d.ts +0 -42
@@ -0,0 +1,31 @@
1
+ import type { MutableRefObject } from "../utils/ref.svelte.js";
2
+ export declare enum Direction {
3
+ Forwards = 0,
4
+ Backwards = 1
5
+ }
6
+ export declare enum Ordering {
7
+ Less = -1,
8
+ Equal = 0,
9
+ Greater = 1
10
+ }
11
+ export type TabsContext = {
12
+ info: {
13
+ isControlled: boolean;
14
+ };
15
+ selectedIndex: number;
16
+ orientation: "horizontal" | "vertical";
17
+ activation: "manual" | "auto";
18
+ tabs: MutableRefObject<HTMLElement | undefined>[];
19
+ panels: MutableRefObject<HTMLElement | undefined>[];
20
+ registerTab: (tab: MutableRefObject<HTMLElement | undefined>) => () => void;
21
+ registerPanel: (panel: MutableRefObject<HTMLElement | undefined>) => () => void;
22
+ change: (index: number) => void;
23
+ };
24
+ export declare function useTabs(component: string): TabsContext;
25
+ export declare const createTabContext: (props: {
26
+ vertical: boolean;
27
+ manual: boolean;
28
+ selectedIndex: number | undefined;
29
+ defaultIndex: number;
30
+ change: (index: number) => void;
31
+ }) => TabsContext;
@@ -0,0 +1,134 @@
1
+ import { sortByDomNode } from "../utils/focus-management.js";
2
+ import { match } from "../utils/match.js";
3
+ import { getContext, setContext } from "svelte";
4
+ export var Direction;
5
+ (function (Direction) {
6
+ Direction[Direction["Forwards"] = 0] = "Forwards";
7
+ Direction[Direction["Backwards"] = 1] = "Backwards";
8
+ })(Direction || (Direction = {}));
9
+ export var Ordering;
10
+ (function (Ordering) {
11
+ Ordering[Ordering["Less"] = -1] = "Less";
12
+ Ordering[Ordering["Equal"] = 0] = "Equal";
13
+ Ordering[Ordering["Greater"] = 1] = "Greater";
14
+ })(Ordering || (Ordering = {}));
15
+ export function useTabs(component) {
16
+ const context = getContext("TabsContext");
17
+ if (!context) {
18
+ const err = new Error(`<${component} /> is missing a parent <TabGroup /> component.`);
19
+ if (Error.captureStackTrace)
20
+ Error.captureStackTrace(err, useTabs);
21
+ throw err;
22
+ }
23
+ return context;
24
+ }
25
+ export const createTabContext = (props) => {
26
+ let _selectedIndex = $state($state.snapshot(props.selectedIndex ?? props.defaultIndex));
27
+ let tabs = $state.raw([]);
28
+ let panels = $state.raw([]);
29
+ const isControlled = $derived(props.selectedIndex !== undefined);
30
+ const context = {
31
+ info: {
32
+ get isControlled() {
33
+ return isControlled;
34
+ },
35
+ },
36
+ get orientation() {
37
+ return props.vertical ? "vertical" : "horizontal";
38
+ },
39
+ get activation() {
40
+ return props.manual ? "manual" : "auto";
41
+ },
42
+ get selectedIndex() {
43
+ return _selectedIndex;
44
+ },
45
+ set selectedIndex(index) {
46
+ if (index === _selectedIndex)
47
+ return;
48
+ tabs = sortByDomNode(tabs, (tab) => tab.current ?? null);
49
+ panels = sortByDomNode(panels, (panel) => panel.current ?? null);
50
+ const focusableTabs = tabs.filter((tab) => !tab?.current?.hasAttribute("disabled"));
51
+ if (
52
+ // Underflow
53
+ index < 0 ||
54
+ // Overflow
55
+ index > tabs.length - 1) {
56
+ const direction = match(Math.sign(index - _selectedIndex), {
57
+ [Ordering.Less]: () => Direction.Backwards,
58
+ [Ordering.Equal]: () => {
59
+ return match(Math.sign(index), {
60
+ [Ordering.Less]: () => Direction.Forwards,
61
+ [Ordering.Equal]: () => Direction.Forwards,
62
+ [Ordering.Greater]: () => Direction.Backwards,
63
+ });
64
+ },
65
+ [Ordering.Greater]: () => Direction.Forwards,
66
+ });
67
+ // If there are no focusable tabs then.
68
+ // We won't change the selected index
69
+ // because it's likely the user is
70
+ // lazy loading tabs and there's
71
+ // nothing to focus on yet
72
+ if (focusableTabs.length === 0)
73
+ return;
74
+ const nextSelectedIndex = match(direction, {
75
+ [Direction.Forwards]: () => tabs.findIndex((tab) => tab === focusableTabs[0]),
76
+ [Direction.Backwards]: () => tabs.findIndex((tab) => tab === focusableTabs[focusableTabs.length - 1]),
77
+ });
78
+ if (nextSelectedIndex !== -1)
79
+ _selectedIndex = nextSelectedIndex;
80
+ return;
81
+ }
82
+ // Middle
83
+ const before = tabs.slice(0, index);
84
+ const after = tabs.slice(index);
85
+ const next = [...after, ...before].find((tab) => focusableTabs.some((_tab) => _tab === tab));
86
+ if (!next)
87
+ return;
88
+ let selectedIndex = tabs.findIndex((tab) => tab === next) ?? _selectedIndex;
89
+ if (selectedIndex === -1)
90
+ selectedIndex = _selectedIndex;
91
+ if (selectedIndex !== _selectedIndex)
92
+ _selectedIndex = selectedIndex;
93
+ },
94
+ get tabs() {
95
+ return tabs;
96
+ },
97
+ get panels() {
98
+ return panels;
99
+ },
100
+ registerTab(tab) {
101
+ const unregisterTab = (tab) => {
102
+ tabs = tabs.filter((_tab) => _tab !== tab);
103
+ };
104
+ if (tabs.some((_tab) => _tab === tab))
105
+ return () => unregisterTab(tab);
106
+ tabs = sortByDomNode([...tabs, tab], (tab) => tab.current ?? null);
107
+ const activeTab = tabs[_selectedIndex];
108
+ // When the component is uncontrolled, then we want to maintain the actively
109
+ // selected tab even if new tabs are inserted or removed before the active
110
+ // tab.
111
+ //
112
+ // When the component is controlled, then we don't want to do this and
113
+ // instead we want to select the tab based on the `selectedIndex` prop.
114
+ if (isControlled) {
115
+ const selectedIndex = tabs.findIndex((tab) => tab === activeTab);
116
+ if (selectedIndex !== _selectedIndex)
117
+ _selectedIndex = selectedIndex;
118
+ }
119
+ return () => unregisterTab(tab);
120
+ },
121
+ registerPanel(panel) {
122
+ const unregisterPanel = (panel) => {
123
+ panels = panels.filter((_panel) => _panel !== panel);
124
+ };
125
+ if (!panels.some((_panel) => _panel === panel)) {
126
+ panels = sortByDomNode([...panels, panel], (panel) => panel.current ?? null);
127
+ }
128
+ return () => unregisterPanel(panel);
129
+ },
130
+ change: props.change,
131
+ };
132
+ setContext("TabsContext", context);
133
+ return context;
134
+ };
@@ -1,59 +1,90 @@
1
- <script lang="ts" module>const DEFAULT_TEXTAREA_TAG = "textarea";
2
- </script>
1
+ <script lang="ts" module>
2
+ import type { ElementType, Props, PropsOf } from "../utils/types.js"
3
3
 
4
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_TEXTAREA_TAG, TValue = string">import { htmlid } from "../utils/id.js";
5
- import { useDisabled } from "../hooks/use-disabled.js";
6
- import { useProvidedId } from "../utils/id.js";
7
- import { useLabelledBy } from "../label/context.svelte.js";
8
- import { useDescribedBy } from "../description/context.svelte.js";
9
- import { useHover } from "../hooks/use-hover.svelte.js";
10
- import { useFocusRing } from "../hooks/use-focus-ring.svelte.js";
11
- import { mergeProps } from "../utils/render.js";
12
- import ElementOrComponent from "../utils/ElementOrComponent.svelte";
13
- const internalId = htmlid();
14
- const providedId = useProvidedId();
15
- const providedDisabled = useDisabled();
16
- let {
17
- ref = $bindable(),
18
- value = $bindable(),
19
- id = providedId || `headlessui-input-${internalId}`,
20
- disabled: theirDisabled = false,
21
- autofocus = false,
22
- invalid = false,
23
- ...theirProps
24
- } = $props();
25
- const disabled = $derived(providedDisabled.current || theirDisabled);
26
- const labelledBy = useLabelledBy();
27
- const describedBy = useDescribedBy();
28
- const { isFocusVisible: focus, focusProps } = $derived(
29
- useFocusRing({
30
- get autofocus() {
31
- return autofocus;
32
- }
33
- })
34
- );
35
- const { isHovered: hover, hoverProps } = $derived(
36
- useHover({
37
- get disabled() {
38
- return disabled;
39
- }
40
- })
41
- );
42
- const ourProps = $derived(
43
- mergeProps(
4
+ const DEFAULT_TEXTAREA_TAG = "textarea" as const
5
+
6
+ type TextareaRenderPropArg = {
7
+ disabled: boolean
8
+ hover: boolean
9
+ focus: boolean
10
+ autofocus: boolean
11
+ invalid: boolean
12
+ }
13
+ type TextareaPropsWeControl = "aria-labelledby" | "aria-describedby"
14
+
15
+ export type TextareaProps<TTag extends ElementType = typeof DEFAULT_TEXTAREA_TAG, TValue = string> = Props<
16
+ TTag,
17
+ TextareaRenderPropArg,
18
+ TextareaPropsWeControl,
44
19
  {
45
- id,
46
- "aria-labelledby": labelledBy?.value,
47
- "aria-describedby": describedBy?.value,
48
- "aria-invalid": invalid ? "" : void 0,
49
- disabled: disabled || void 0,
50
- autofocus
51
- },
52
- focusProps,
53
- hoverProps
20
+ value?: TValue
21
+ disabled?: boolean
22
+ invalid?: boolean
23
+ autofocus?: boolean
24
+ }
25
+ >
26
+ </script>
27
+
28
+ <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_TEXTAREA_TAG, TValue = string">
29
+ import { htmlid } from "../utils/id.js"
30
+ import { useDisabled } from "../hooks/use-disabled.js"
31
+ import { useProvidedId } from "../utils/id.js"
32
+ import { useLabelledBy } from "../label/context.svelte.js"
33
+ import { useDescribedBy } from "../description/context.svelte.js"
34
+ import { useHover } from "../hooks/use-hover.svelte.js"
35
+ import { useFocusRing } from "../hooks/use-focus-ring.svelte.js"
36
+ import { mergeProps } from "../utils/render.js"
37
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte"
38
+
39
+ const internalId = htmlid()
40
+ const providedId = useProvidedId()
41
+ const providedDisabled = useDisabled()
42
+
43
+ let {
44
+ ref = $bindable(),
45
+ value = $bindable(),
46
+ id = (providedId || `headlessui-input-${internalId}`) as PropsOf<TTag>["id"],
47
+ disabled: theirDisabled = false,
48
+ autofocus = false as PropsOf<TTag>["autofocus"],
49
+ invalid = false,
50
+ ...theirProps
51
+ }: { as?: TTag; value?: TValue } & TextareaProps<TTag, TValue> = $props()
52
+ const disabled = $derived(providedDisabled.current || theirDisabled)
53
+
54
+ const labelledBy = useLabelledBy()
55
+ const describedBy = useDescribedBy()
56
+
57
+ const { isFocusVisible: focus, focusProps } = $derived(
58
+ useFocusRing({
59
+ get autofocus() {
60
+ return autofocus
61
+ },
62
+ })
54
63
  )
55
- );
56
- const slot = $derived({ disabled, invalid, hover, focus, autofocus });
64
+ const { isHovered: hover, hoverProps } = $derived(
65
+ useHover({
66
+ get disabled() {
67
+ return disabled
68
+ },
69
+ })
70
+ )
71
+
72
+ const ourProps = $derived(
73
+ mergeProps(
74
+ {
75
+ id,
76
+ "aria-labelledby": labelledBy?.value,
77
+ "aria-describedby": describedBy?.value,
78
+ "aria-invalid": invalid ? "" : undefined,
79
+ disabled: disabled || undefined,
80
+ autofocus,
81
+ },
82
+ focusProps,
83
+ hoverProps
84
+ )
85
+ )
86
+
87
+ const slot = $derived({ disabled, invalid, hover, focus, autofocus } satisfies TextareaRenderPropArg)
57
88
  </script>
58
89
 
59
90
  <ElementOrComponent
@@ -18,11 +18,14 @@ declare class __sveltets_Render<TTag extends ElementType = typeof DEFAULT_TEXTAR
18
18
  props(): {
19
19
  as?: TTag | undefined;
20
20
  value?: TValue | undefined;
21
- } & (Exclude<keyof PropsOf<TTag>, ("as" | "children" | "refName" | "class") | "invalid" | "disabled" | "autofocus" | "value" | TextareaPropsWeControl> extends infer T extends keyof PropsOf<TTag> ? { [P in T]: PropsOf<TTag>[P]; } : never) & {
22
- children?: import("svelte").Snippet<[TextareaRenderPropArg, Record<string, any>]> | undefined;
21
+ } & (Exclude<keyof PropsOf<TTag>, ("as" | "children" | "class") | "invalid" | "disabled" | "autofocus" | "value" | TextareaPropsWeControl> extends infer T extends keyof PropsOf<TTag> ? { [P in T]: PropsOf<TTag>[P]; } : never) & {
22
+ children?: import("svelte").Snippet<[{
23
+ slot: TextareaRenderPropArg;
24
+ props: Record<string, any>;
25
+ }]> | undefined;
23
26
  ref?: HTMLElement;
24
- } & (true extends (PropsOf<TTag> extends infer T_1 ? T_1 extends PropsOf<TTag> ? T_1 extends never ? never : "class" extends infer T_2 ? T_2 extends "class" ? T_2 extends keyof T_1 ? true : never : never : never : never : never) ? {
25
- class?: PropsOf<TTag>["class"] | ((bag: TextareaRenderPropArg) => string) | undefined;
27
+ } & (true extends (import("svelte/elements.js").SvelteHTMLElements[TTag] extends infer T_1 ? T_1 extends import("svelte/elements.js").SvelteHTMLElements[TTag] ? T_1 extends never ? never : "class" extends infer T_2 ? T_2 extends "class" ? T_2 extends keyof T_1 ? true : never : never : never : never : never) ? {
28
+ class?: string | ((bag: TextareaRenderPropArg) => string) | null | undefined;
26
29
  } : {}) & {
27
30
  value?: TValue | undefined;
28
31
  disabled?: boolean;