@pzerelles/headlessui-svelte 2.1.2-next.7 → 2.1.2-next.8

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 (55) hide show
  1. package/dist/button/Button.svelte +54 -84
  2. package/dist/checkbox/Checkbox.svelte +120 -174
  3. package/dist/close-button/CloseButton.svelte +6 -12
  4. package/dist/combobox/Combobox.svelte +3 -50
  5. package/dist/data-interactive/DataInteractive.svelte +29 -57
  6. package/dist/description/Description.svelte +21 -32
  7. package/dist/dialog/Dialog.svelte +34 -69
  8. package/dist/dialog/DialogBackdrop.svelte +12 -29
  9. package/dist/dialog/DialogPanel.svelte +26 -49
  10. package/dist/dialog/DialogTitle.svelte +23 -38
  11. package/dist/dialog/InternalDialog.svelte +202 -263
  12. package/dist/field/Field.svelte +26 -49
  13. package/dist/fieldset/Fieldset.svelte +29 -50
  14. package/dist/focus-trap/FocusTrap.svelte +283 -419
  15. package/dist/input/Input.svelte +53 -84
  16. package/dist/internal/FocusSentinel.svelte +8 -16
  17. package/dist/internal/ForcePortalRoot.svelte +3 -7
  18. package/dist/internal/FormFields.svelte +20 -31
  19. package/dist/internal/FormResolver.svelte +15 -20
  20. package/dist/internal/Hidden.svelte +23 -44
  21. package/dist/internal/HoistFormFields.svelte +4 -7
  22. package/dist/internal/MainTreeProvider.svelte +36 -89
  23. package/dist/internal/Portal.svelte +14 -18
  24. package/dist/label/Label.svelte +57 -91
  25. package/dist/legend/Legend.svelte +3 -18
  26. package/dist/listbox/Listbox.svelte +396 -588
  27. package/dist/listbox/ListboxButton.svelte +127 -176
  28. package/dist/listbox/ListboxOption.svelte +125 -166
  29. package/dist/listbox/ListboxOptions.svelte +244 -340
  30. package/dist/listbox/ListboxSelectedOption.svelte +15 -38
  31. package/dist/menu/Menu.svelte +218 -307
  32. package/dist/menu/MenuButton.svelte +115 -157
  33. package/dist/menu/MenuHeading.svelte +14 -34
  34. package/dist/menu/MenuItem.svelte +107 -145
  35. package/dist/menu/MenuItems.svelte +224 -298
  36. package/dist/menu/MenuSection.svelte +9 -26
  37. package/dist/menu/MenuSeparator.svelte +4 -20
  38. package/dist/portal/InternalPortal.svelte +85 -141
  39. package/dist/portal/Portal.svelte +2 -5
  40. package/dist/portal/PortalGroup.svelte +9 -30
  41. package/dist/switch/Switch.svelte +132 -179
  42. package/dist/switch/SwitchGroup.svelte +31 -44
  43. package/dist/tabs/Tab.svelte +143 -195
  44. package/dist/tabs/TabGroup.svelte +205 -292
  45. package/dist/tabs/TabList.svelte +11 -31
  46. package/dist/tabs/TabPanel.svelte +43 -68
  47. package/dist/tabs/TabPanels.svelte +7 -18
  48. package/dist/textarea/Textarea.svelte +53 -84
  49. package/dist/transition/InternalTransitionChild.svelte +170 -259
  50. package/dist/transition/Transition.svelte +66 -96
  51. package/dist/transition/TransitionChild.svelte +11 -31
  52. package/dist/utils/ElementOrComponent.svelte +23 -44
  53. package/dist/utils/Generic.svelte +17 -29
  54. package/dist/utils/StableCollection.svelte +36 -54
  55. package/package.json +1 -1
@@ -1,270 +1,209 @@
1
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_DIALOG_TAG">
2
- import { useId } from "../hooks/use-id.js"
3
- import { useMainTreeNode, useRootContainers } from "../hooks/use-root-containers.svelte.js"
4
- import { clearOpenClosedContext, State, useOpenClosed } from "../internal/open-closed.js"
5
- import { useNestedPortals } from "../portal/InternalPortal.svelte"
6
- import { getOwnerDocument } from "../utils/owner.js"
7
- import { DEFAULT_DIALOG_TAG, DialogRenderFeatures, type DialogProps, type DialogRenderPropArg } from "./Dialog.svelte"
8
- import { useInertOthers } from "../hooks/use-inert-others.svelte.js"
9
- import { useOutsideClick } from "../hooks/use-outside-click.svelte.js"
10
- import { useEscape } from "../hooks/use-escape.svelte.js"
11
- import { useScrollLock } from "../hooks/use-scroll-lock.svelte.js"
12
- import { useOnDisappear } from "../hooks/use-on-disappear.svelte.js"
13
- import { setContext } from "svelte"
14
- import { useIsTouchDevice } from "../hooks/use-is-touch-device.svelte.js"
15
- import FocusTrap, { FocusTrapFeatures } from "../focus-trap/FocusTrap.svelte"
16
- import Portal from "../portal/Portal.svelte"
17
- import PortalGroup from "../portal/PortalGroup.svelte"
18
- import ForcePortalRoot from "../internal/ForcePortalRoot.svelte"
19
- import { createCloseContext } from "../internal/close-provider.js"
20
- import ElementOrComponent from "../utils/ElementOrComponent.svelte"
21
- import type { ElementType } from "../utils/types.js"
22
- import { DialogStates, type DialogContext, type StateDefinition } from "./context.svelte.js"
23
- import { useDescriptions } from "../description/context.svelte.js"
24
-
25
- const internalId = useId()
26
- let {
27
- ref = $bindable(),
28
- id = `headlessui-dialog-${internalId}`,
29
- open: theirOpen,
30
- onclose,
31
- initialFocus,
32
- role: theirRole = "dialog",
33
- autofocus = true,
34
- __demoMode = false,
35
- unmount = false,
36
- ...theirProps
37
- }: { as?: TTag } & DialogProps<TTag> = $props()
38
-
39
- let didWarnOnRole = $state(false)
40
-
41
- const role = $derived.by(() => {
42
- if (theirRole === "dialog" || theirRole === "alertdialog") {
43
- return theirRole
44
- }
45
-
46
- if (!didWarnOnRole) {
47
- didWarnOnRole = true
48
- console.warn(
49
- `Invalid role [${theirRole}] passed to <Dialog />. Only \`dialog\` and and \`alertdialog\` are supported. Using \`dialog\` instead.`
50
- )
1
+ <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_DIALOG_TAG">import { useId } from "../hooks/use-id.js";
2
+ import { useMainTreeNode, useRootContainers } from "../hooks/use-root-containers.svelte.js";
3
+ import { clearOpenClosedContext, State, useOpenClosed } from "../internal/open-closed.js";
4
+ import { useNestedPortals } from "../portal/InternalPortal.svelte";
5
+ import { getOwnerDocument } from "../utils/owner.js";
6
+ import { DEFAULT_DIALOG_TAG, DialogRenderFeatures } from "./Dialog.svelte";
7
+ import { useInertOthers } from "../hooks/use-inert-others.svelte.js";
8
+ import { useOutsideClick } from "../hooks/use-outside-click.svelte.js";
9
+ import { useEscape } from "../hooks/use-escape.svelte.js";
10
+ import { useScrollLock } from "../hooks/use-scroll-lock.svelte.js";
11
+ import { useOnDisappear } from "../hooks/use-on-disappear.svelte.js";
12
+ import { setContext } from "svelte";
13
+ import { useIsTouchDevice } from "../hooks/use-is-touch-device.svelte.js";
14
+ import FocusTrap, { FocusTrapFeatures } from "../focus-trap/FocusTrap.svelte";
15
+ import Portal from "../portal/Portal.svelte";
16
+ import PortalGroup from "../portal/PortalGroup.svelte";
17
+ import ForcePortalRoot from "../internal/ForcePortalRoot.svelte";
18
+ import { createCloseContext } from "../internal/close-provider.js";
19
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte";
20
+ import { DialogStates } from "./context.svelte.js";
21
+ import { useDescriptions } from "../description/context.svelte.js";
22
+ const internalId = useId();
23
+ let {
24
+ ref = $bindable(),
25
+ id = `headlessui-dialog-${internalId}`,
26
+ open: theirOpen,
27
+ onclose,
28
+ initialFocus,
29
+ role: theirRole = "dialog",
30
+ autofocus = true,
31
+ __demoMode = false,
32
+ unmount = false,
33
+ ...theirProps
34
+ } = $props();
35
+ let didWarnOnRole = $state(false);
36
+ const role = $derived.by(() => {
37
+ if (theirRole === "dialog" || theirRole === "alertdialog") {
38
+ return theirRole;
39
+ }
40
+ if (!didWarnOnRole) {
41
+ didWarnOnRole = true;
42
+ console.warn(
43
+ `Invalid role [${theirRole}] passed to <Dialog />. Only \`dialog\` and and \`alertdialog\` are supported. Using \`dialog\` instead.`
44
+ );
45
+ }
46
+ return "dialog";
47
+ });
48
+ const usesOpenClosedState = useOpenClosed();
49
+ const open = $derived(
50
+ theirOpen === void 0 && usesOpenClosedState !== null ? (usesOpenClosedState.value & State.Open) === State.Open : theirOpen
51
+ );
52
+ const ownerDocument = $derived(getOwnerDocument(ref));
53
+ const dialogState = $derived(open ? DialogStates.Open : DialogStates.Closed);
54
+ let _state = $state({
55
+ titleId: null,
56
+ panelRef: null
57
+ });
58
+ const close = $derived(() => onclose(false));
59
+ const setTitleId = (id2) => _state.titleId = id2;
60
+ const enabled = $derived(dialogState === DialogStates.Open);
61
+ const nestedPortals = useNestedPortals();
62
+ const { portals } = $derived(nestedPortals);
63
+ const defaultContainer = {
64
+ get current() {
65
+ return _state.panelRef ?? ref;
66
+ }
67
+ };
68
+ const mainTreeNode = useMainTreeNode();
69
+ let { resolvedContainers: resolvedRootContainers } = $derived(
70
+ useRootContainers({
71
+ get mainTreeNode() {
72
+ return mainTreeNode.node;
73
+ },
74
+ get portals() {
75
+ return portals;
76
+ },
77
+ get defaultContainers() {
78
+ return defaultContainer.current ? [defaultContainer.current] : [];
51
79
  }
52
-
53
- return "dialog"
54
80
  })
55
-
56
- const usesOpenClosedState = useOpenClosed()
57
- // Update the `open` prop based on the open closed state
58
- const open = $derived(
59
- theirOpen === undefined && usesOpenClosedState !== null
60
- ? (usesOpenClosedState.value & State.Open) === State.Open
61
- : theirOpen
62
- )
63
-
64
- const ownerDocument = $derived(getOwnerDocument(ref))
65
-
66
- const dialogState = $derived(open ? DialogStates.Open : DialogStates.Closed)
67
-
68
- let _state = $state({
69
- titleId: null,
70
- panelRef: null,
71
- } as StateDefinition)
72
-
73
- const close = $derived(() => onclose(false))
74
-
75
- const setTitleId = (id: string | null) => (_state.titleId = id)
76
-
77
- const enabled = $derived(dialogState === DialogStates.Open)
78
- const nestedPortals = useNestedPortals()
79
- const { portals } = $derived(nestedPortals)
80
-
81
- // We use this because reading these values during initial render(s)
82
- // can result in `null` rather then the actual elements
83
- // This doesn't happen when using certain components like a
84
- // `<Dialog.Title>` because they cause the parent to re-render
85
- const defaultContainer: { readonly current: HTMLElement | undefined } = {
86
- get current() {
87
- return _state.panelRef ?? ref
88
- },
81
+ );
82
+ const isClosing = $derived(
83
+ usesOpenClosedState !== null ? (usesOpenClosedState.value & State.Closing) === State.Closing : false
84
+ );
85
+ const inertOthersEnabled = $derived(__demoMode ? false : isClosing ? false : enabled);
86
+ useInertOthers({
87
+ get enabled() {
88
+ return inertOthersEnabled;
89
+ },
90
+ elements: {
91
+ get allowed() {
92
+ return [
93
+ // Allow the headlessui-portal of the Dialog to be interactive. This
94
+ // contains the current dialog and the necessary focus guard elements.
95
+ ref?.closest("[data-headlessui-portal]") ?? null
96
+ ];
97
+ },
98
+ get disallowed() {
99
+ return [
100
+ // Disallow the "main" tree root node
101
+ mainTreeNode.node?.closest("body > *:not(#headlessui-portal-root)") ?? null
102
+ ];
103
+ }
89
104
  }
90
-
91
- const mainTreeNode = useMainTreeNode()
92
- let { resolvedContainers: resolvedRootContainers } = $derived(
93
- useRootContainers({
94
- get mainTreeNode() {
95
- return mainTreeNode.node
96
- },
97
- get portals() {
98
- return portals
99
- },
100
- get defaultContainers() {
101
- return defaultContainer.current ? [defaultContainer.current] : []
102
- },
103
- })
104
- )
105
-
106
- // When the `Dialog` is wrapped in a `Transition` (or another Headless UI component that exposes
107
- // the OpenClosed state) then we get some information via context about its state. When the
108
- // `Transition` is about to close, then the `State.Closing` state will be exposed. This allows us
109
- // to enable/disable certain functionality in the `Dialog` upfront instead of waiting until the
110
- // `Transition` is done transitioning.
111
- const isClosing = $derived(
112
- usesOpenClosedState !== null ? (usesOpenClosedState.value & State.Closing) === State.Closing : false
113
- )
114
-
115
- // Ensure other elements can't be interacted with
116
- const inertOthersEnabled = $derived(__demoMode ? false : isClosing ? false : enabled)
117
- useInertOthers({
118
- get enabled() {
119
- return inertOthersEnabled
120
- },
121
- elements: {
122
- get allowed() {
123
- return [
124
- // Allow the headlessui-portal of the Dialog to be interactive. This
125
- // contains the current dialog and the necessary focus guard elements.
126
- ref?.closest<HTMLElement>("[data-headlessui-portal]") ?? null,
127
- ]
128
- },
129
- get disallowed() {
130
- return [
131
- // Disallow the "main" tree root node
132
- mainTreeNode.node?.closest<HTMLElement>("body > *:not(#headlessui-portal-root)") ?? null,
133
- ]
134
- },
135
- },
136
- })
137
-
138
- // Close Dialog on outside click
139
- useOutsideClick({
140
- get enabled() {
141
- return enabled
142
- },
143
- get containers() {
144
- return resolvedRootContainers
145
- },
146
- cb(event) {
147
- event.preventDefault()
148
- close()
149
- },
150
- })
151
-
152
- // Handle `Escape` to close
153
- useEscape({
154
- get enabled() {
155
- return enabled
156
- },
157
- get view() {
158
- return ownerDocument?.defaultView ?? null
159
- },
160
- cb(event) {
161
- event.preventDefault()
162
- event.stopPropagation()
163
-
164
- // Ensure that we blur the current activeElement to prevent maintaining
165
- // focus and potentially scrolling the page to the end (because the Dialog
166
- // is rendered in a Portal at the end of the document.body and the browser
167
- // tries to keep the focused element in view)
168
- //
169
- // Typically only happens in Safari.
170
- if (
171
- document.activeElement &&
172
- "blur" in document.activeElement &&
173
- typeof document.activeElement.blur === "function"
174
- ) {
175
- document.activeElement.blur()
176
- }
177
-
178
- close()
179
- },
180
- })
181
-
182
- // Scroll lock
183
- const scrollLockEnabled = $derived(__demoMode ? false : isClosing ? false : enabled)
184
- useScrollLock({
185
- get enabled() {
186
- return scrollLockEnabled
187
- },
188
- get ownerDocument() {
189
- return ownerDocument
190
- },
191
- resolveAllowedContainers() {
192
- return resolvedRootContainers
193
- },
194
- })
195
-
196
- // Ensure we close the dialog as soon as the dialog itself becomes hidden
197
- useOnDisappear({
198
- get enabled() {
199
- return enabled
200
- },
201
- get ref() {
202
- return ref
203
- },
204
- get ondisappear() {
205
- return close
206
- },
207
- })
208
-
209
- const describedby = useDescriptions()
210
-
211
- setContext<DialogContext>("DialogContext", {
212
- get titleId() {
213
- return _state.titleId
214
- },
215
- get panelRef() {
216
- return _state.panelRef
217
- },
218
- get dialogState() {
219
- return dialogState
220
- },
221
- get close() {
222
- return close
223
- },
224
- get unmount() {
225
- return unmount
226
- },
227
- setTitleId,
228
- })
229
-
230
- const slot = $derived({ open: dialogState === DialogStates.Open } satisfies DialogRenderPropArg)
231
-
232
- const ourProps = $derived({
233
- id,
234
- role,
235
- tabIndex: -1,
236
- "aria-modal": __demoMode ? undefined : dialogState === DialogStates.Open ? true : undefined,
237
- "aria-labelledby": _state.titleId,
238
- "aria-describedby": describedby.value,
239
- unmount,
240
- })
241
-
242
- const shouldMoveFocusInside = !useIsTouchDevice().value
243
- const focusTrapFeatures = $derived.by(() => {
244
- let focusTrapFeatures = FocusTrapFeatures.None
245
-
246
- if (enabled && !__demoMode) {
247
- focusTrapFeatures |= FocusTrapFeatures.RestoreFocus
248
- focusTrapFeatures |= FocusTrapFeatures.TabLock
249
-
250
- if (autofocus) {
251
- focusTrapFeatures |= FocusTrapFeatures.AutoFocus
252
- }
253
-
254
- if (shouldMoveFocusInside) {
255
- focusTrapFeatures |= FocusTrapFeatures.InitialFocus
256
- }
105
+ });
106
+ useOutsideClick({
107
+ get enabled() {
108
+ return enabled;
109
+ },
110
+ get containers() {
111
+ return resolvedRootContainers;
112
+ },
113
+ cb(event) {
114
+ event.preventDefault();
115
+ close();
116
+ }
117
+ });
118
+ useEscape({
119
+ get enabled() {
120
+ return enabled;
121
+ },
122
+ get view() {
123
+ return ownerDocument?.defaultView ?? null;
124
+ },
125
+ cb(event) {
126
+ event.preventDefault();
127
+ event.stopPropagation();
128
+ if (document.activeElement && "blur" in document.activeElement && typeof document.activeElement.blur === "function") {
129
+ document.activeElement.blur();
257
130
  }
258
-
259
- return focusTrapFeatures
260
- })
261
-
262
- clearOpenClosedContext()
263
- createCloseContext({
264
- get close() {
265
- return close
266
- },
267
- })
131
+ close();
132
+ }
133
+ });
134
+ const scrollLockEnabled = $derived(__demoMode ? false : isClosing ? false : enabled);
135
+ useScrollLock({
136
+ get enabled() {
137
+ return scrollLockEnabled;
138
+ },
139
+ get ownerDocument() {
140
+ return ownerDocument;
141
+ },
142
+ resolveAllowedContainers() {
143
+ return resolvedRootContainers;
144
+ }
145
+ });
146
+ useOnDisappear({
147
+ get enabled() {
148
+ return enabled;
149
+ },
150
+ get ref() {
151
+ return ref;
152
+ },
153
+ get ondisappear() {
154
+ return close;
155
+ }
156
+ });
157
+ const describedby = useDescriptions();
158
+ setContext("DialogContext", {
159
+ get titleId() {
160
+ return _state.titleId;
161
+ },
162
+ get panelRef() {
163
+ return _state.panelRef;
164
+ },
165
+ get dialogState() {
166
+ return dialogState;
167
+ },
168
+ get close() {
169
+ return close;
170
+ },
171
+ get unmount() {
172
+ return unmount;
173
+ },
174
+ setTitleId
175
+ });
176
+ const slot = $derived({ open: dialogState === DialogStates.Open });
177
+ const ourProps = $derived({
178
+ id,
179
+ role,
180
+ tabIndex: -1,
181
+ "aria-modal": __demoMode ? void 0 : dialogState === DialogStates.Open ? true : void 0,
182
+ "aria-labelledby": _state.titleId,
183
+ "aria-describedby": describedby.value,
184
+ unmount
185
+ });
186
+ const shouldMoveFocusInside = !useIsTouchDevice().value;
187
+ const focusTrapFeatures = $derived.by(() => {
188
+ let focusTrapFeatures2 = FocusTrapFeatures.None;
189
+ if (enabled && !__demoMode) {
190
+ focusTrapFeatures2 |= FocusTrapFeatures.RestoreFocus;
191
+ focusTrapFeatures2 |= FocusTrapFeatures.TabLock;
192
+ if (autofocus) {
193
+ focusTrapFeatures2 |= FocusTrapFeatures.AutoFocus;
194
+ }
195
+ if (shouldMoveFocusInside) {
196
+ focusTrapFeatures2 |= FocusTrapFeatures.InitialFocus;
197
+ }
198
+ }
199
+ return focusTrapFeatures2;
200
+ });
201
+ clearOpenClosedContext();
202
+ createCloseContext({
203
+ get close() {
204
+ return close;
205
+ }
206
+ });
268
207
  </script>
269
208
 
270
209
  <ForcePortalRoot force={true}>
@@ -1,54 +1,31 @@
1
- <script lang="ts" module>
2
- import type { ElementType, Props } from "../utils/types.js"
3
-
4
- let DEFAULT_FIELD_TAG = "div" as const
5
-
6
- type FieldRenderPropArg = {}
7
- type FieldPropsWeControl = never
8
-
9
- export type FieldProps<TTag extends ElementType = typeof DEFAULT_FIELD_TAG> = Props<
10
- TTag,
11
- FieldRenderPropArg,
12
- FieldPropsWeControl,
13
- {
14
- disabled?: boolean
15
- }
16
- >
1
+ <script lang="ts" module>let DEFAULT_FIELD_TAG = "div";
17
2
  </script>
18
3
 
19
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_FIELD_TAG">
20
- import { useDisabled } from "../hooks/use-disabled.js"
21
- import { createIdContext } from "../utils/id.js"
22
- import { stateFromSlot } from "../utils/state.js"
23
- import { nanoid } from "nanoid"
24
- import { setContext, type Snippet } from "svelte"
25
- import { useLabels } from "../label/context.svelte.js"
26
- import { useDescriptions } from "../description/context.svelte.js"
27
- import ElementOrComponent from "../utils/ElementOrComponent.svelte"
28
-
29
- let { ref = $bindable(), disabled: ownDisabled = false, ...theirProps }: { as?: TTag } & FieldProps<TTag> = $props()
30
-
31
- const inputId = `headlessui-control-${nanoid(8)}`
32
- createIdContext(inputId)
33
-
34
- useLabels()
35
- useDescriptions()
36
-
37
- const providedDisabled = useDisabled()
38
- const disabled = $derived(providedDisabled.value || ownDisabled)
39
-
40
- setContext("DisabledContext", {
41
- get value() {
42
- return disabled
43
- },
44
- })
45
-
46
- const slot = $derived({ disabled })
47
-
48
- const ourProps = $derived({
49
- disabled: disabled || undefined,
50
- "aria-disabled": disabled || undefined,
51
- })
4
+ <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_FIELD_TAG">import { useDisabled } from "../hooks/use-disabled.js";
5
+ import { createIdContext } from "../utils/id.js";
6
+ import { stateFromSlot } from "../utils/state.js";
7
+ import { nanoid } from "nanoid";
8
+ import { setContext } from "svelte";
9
+ import { useLabels } from "../label/context.svelte.js";
10
+ import { useDescriptions } from "../description/context.svelte.js";
11
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte";
12
+ let { ref = $bindable(), disabled: ownDisabled = false, ...theirProps } = $props();
13
+ const inputId = `headlessui-control-${nanoid(8)}`;
14
+ createIdContext(inputId);
15
+ useLabels();
16
+ useDescriptions();
17
+ const providedDisabled = useDisabled();
18
+ const disabled = $derived(providedDisabled.value || ownDisabled);
19
+ setContext("DisabledContext", {
20
+ get value() {
21
+ return disabled;
22
+ }
23
+ });
24
+ const slot = $derived({ disabled });
25
+ const ourProps = $derived({
26
+ disabled: disabled || void 0,
27
+ "aria-disabled": disabled || void 0
28
+ });
52
29
  </script>
53
30
 
54
31
  <ElementOrComponent {ourProps} {theirProps} {slot} defaultTag={DEFAULT_FIELD_TAG} name="Field" bind:ref />
@@ -1,55 +1,34 @@
1
- <script lang="ts" module>
2
- import type { ElementType, Props } from "../utils/types.js"
3
- let DEFAULT_FIELDSET_TAG = "fieldset" as const
4
-
5
- type FieldsetRenderPropArg = {}
6
- type FieldsetPropsWeControl = "aria-labelledby" | "aria-disabled" | "role"
7
-
8
- export type FieldsetProps<TTag extends ElementType = typeof DEFAULT_FIELDSET_TAG> = Props<
9
- TTag,
10
- FieldsetRenderPropArg,
11
- FieldsetPropsWeControl,
12
- {
13
- disabled?: boolean
14
- }
15
- >
1
+ <script lang="ts" module>let DEFAULT_FIELDSET_TAG = "fieldset";
16
2
  </script>
17
3
 
18
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_FIELDSET_TAG">
19
- import { setContext } from "svelte"
20
- import { useDisabled } from "../hooks/use-disabled.js"
21
- import { useLabels } from "../label/context.svelte.js"
22
- import ElementOrComponent from "../utils/ElementOrComponent.svelte"
23
-
24
- let {
25
- ref = $bindable(),
26
- disabled: ownDisabled = false,
27
- ...theirProps
28
- }: { as?: TTag } & FieldsetProps<TTag> = $props()
29
-
30
- const providedDisabled = useDisabled()
31
- const disabled = $derived(providedDisabled.value || ownDisabled)
32
-
33
- setContext("DisabledContext", {
34
- get value() {
35
- return disabled
36
- },
37
- })
38
-
39
- const labelledBy = useLabels()
40
- const slot = $derived({ disabled })
41
- const ourProps = $derived(
42
- (theirProps.as ?? DEFAULT_FIELDSET_TAG) === "fieldset"
43
- ? {
44
- "aria-labelledby": labelledBy.value,
45
- disabled: disabled || undefined,
46
- }
47
- : {
48
- role: "group",
49
- "aria-labelledby": labelledBy.value,
50
- "aria-disabled": disabled || undefined,
51
- }
52
- )
4
+ <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_FIELDSET_TAG">import { setContext } from "svelte";
5
+ import { useDisabled } from "../hooks/use-disabled.js";
6
+ import { useLabels } from "../label/context.svelte.js";
7
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte";
8
+ let {
9
+ ref = $bindable(),
10
+ disabled: ownDisabled = false,
11
+ ...theirProps
12
+ } = $props();
13
+ const providedDisabled = useDisabled();
14
+ const disabled = $derived(providedDisabled.value || ownDisabled);
15
+ setContext("DisabledContext", {
16
+ get value() {
17
+ return disabled;
18
+ }
19
+ });
20
+ const labelledBy = useLabels();
21
+ const slot = $derived({ disabled });
22
+ const ourProps = $derived(
23
+ (theirProps.as ?? DEFAULT_FIELDSET_TAG) === "fieldset" ? {
24
+ "aria-labelledby": labelledBy.value,
25
+ disabled: disabled || void 0
26
+ } : {
27
+ role: "group",
28
+ "aria-labelledby": labelledBy.value,
29
+ "aria-disabled": disabled || void 0
30
+ }
31
+ );
53
32
  </script>
54
33
 
55
34
  <ElementOrComponent {ourProps} {theirProps} {slot} defaultTag={DEFAULT_FIELDSET_TAG} name="Fieldset" bind:ref />