@pzerelles/headlessui-svelte 2.1.2-next.29 → 2.1.2-next.30

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 (67) hide show
  1. package/dist/button/Button.svelte +54 -84
  2. package/dist/checkbox/Checkbox.svelte +120 -173
  3. package/dist/checkbox/Checkbox.svelte.d.ts +1 -1
  4. package/dist/close-button/CloseButton.svelte +6 -12
  5. package/dist/combobox/Combobox.svelte +3 -50
  6. package/dist/data-interactive/DataInteractive.svelte +29 -55
  7. package/dist/description/Description.svelte +21 -31
  8. package/dist/dialog/Dialog.svelte +228 -320
  9. package/dist/dialog/DialogBackdrop.svelte +12 -29
  10. package/dist/dialog/DialogPanel.svelte +25 -48
  11. package/dist/dialog/DialogTitle.svelte +23 -38
  12. package/dist/field/Field.svelte +25 -47
  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/FloatingProvider.svelte +9 -14
  17. package/dist/internal/FocusSentinel.svelte +8 -16
  18. package/dist/internal/ForcePortalRoot.svelte +3 -7
  19. package/dist/internal/FormFields.svelte +34 -47
  20. package/dist/internal/FormFieldsProvider.svelte +5 -9
  21. package/dist/internal/FormResolver.svelte +15 -20
  22. package/dist/internal/Hidden.svelte +29 -50
  23. package/dist/internal/MainTreeProvider.svelte +36 -89
  24. package/dist/internal/Portal.svelte +14 -18
  25. package/dist/label/Label.svelte +58 -93
  26. package/dist/legend/Legend.svelte +3 -12
  27. package/dist/listbox/Listbox.svelte +387 -525
  28. package/dist/listbox/Listbox.svelte.d.ts +1 -1
  29. package/dist/listbox/ListboxButton.svelte +127 -173
  30. package/dist/listbox/ListboxOption.svelte +129 -170
  31. package/dist/listbox/ListboxOptions.svelte +304 -400
  32. package/dist/listbox/ListboxSelectedOption.svelte +15 -38
  33. package/dist/menu/Menu.svelte +51 -78
  34. package/dist/menu/MenuButton.svelte +117 -157
  35. package/dist/menu/MenuHeading.svelte +14 -32
  36. package/dist/menu/MenuItem.svelte +107 -142
  37. package/dist/menu/MenuItems.svelte +229 -301
  38. package/dist/menu/MenuSection.svelte +9 -24
  39. package/dist/menu/MenuSeparator.svelte +4 -17
  40. package/dist/popover/Popover.svelte +150 -216
  41. package/dist/popover/PopoverBackdrop.svelte +41 -67
  42. package/dist/popover/PopoverButton.svelte +212 -292
  43. package/dist/popover/PopoverGroup.svelte +35 -62
  44. package/dist/popover/PopoverPanel.svelte +229 -311
  45. package/dist/portal/InternalPortal.svelte +85 -141
  46. package/dist/portal/Portal.svelte +2 -5
  47. package/dist/portal/PortalGroup.svelte +9 -30
  48. package/dist/select/Select.svelte +68 -98
  49. package/dist/switch/Switch.svelte +132 -179
  50. package/dist/switch/SwitchGroup.svelte +31 -44
  51. package/dist/tabs/Tab.svelte +142 -194
  52. package/dist/tabs/TabGroup.svelte +56 -86
  53. package/dist/tabs/TabGroup.svelte.d.ts +1 -1
  54. package/dist/tabs/TabList.svelte +11 -31
  55. package/dist/tabs/TabPanel.svelte +42 -67
  56. package/dist/tabs/TabPanels.svelte +7 -18
  57. package/dist/textarea/Textarea.svelte +53 -84
  58. package/dist/transition/InternalTransitionChild.svelte +170 -259
  59. package/dist/transition/Transition.svelte +66 -96
  60. package/dist/transition/TransitionChild.svelte +11 -31
  61. package/dist/utils/DisabledProvider.svelte +3 -7
  62. package/dist/utils/ElementOrComponent.svelte +23 -43
  63. package/dist/utils/Generic.svelte +16 -27
  64. package/dist/utils/StableCollection.svelte +36 -54
  65. package/dist/utils/floating-ui/svelte/components/FloatingNode.svelte +12 -27
  66. package/dist/utils/floating-ui/svelte/components/FloatingTree.svelte +44 -88
  67. package/package.json +4 -4
@@ -1,23 +1,12 @@
1
- <script lang="ts" module>
2
- import ElementOrComponent from "../utils/ElementOrComponent.svelte"
3
- import type { ElementType, Props } from "../utils/types.js"
4
- import { useTabs } from "./context.svelte.js"
5
-
6
- let DEFAULT_PANELS_TAG = "div" as const
7
- type PanelsRenderPropArg = {
8
- selectedIndex: number
9
- }
10
-
11
- export type TabPanelsProps<TTag extends ElementType = typeof DEFAULT_PANELS_TAG> = Props<TTag, PanelsRenderPropArg>
1
+ <script lang="ts" module>import ElementOrComponent from "../utils/ElementOrComponent.svelte";
2
+ import { useTabs } from "./context.svelte.js";
3
+ let DEFAULT_PANELS_TAG = "div";
12
4
  </script>
13
5
 
14
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_PANELS_TAG">
15
- const context = useTabs("TabPanels")
16
- const { selectedIndex } = $derived(context)
17
-
18
- const slot = $derived({ selectedIndex } satisfies PanelsRenderPropArg)
19
-
20
- let { ref = $bindable(), ...theirProps }: { as?: TTag } & TabPanelsProps<TTag> = $props()
6
+ <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_PANELS_TAG">const context = useTabs("TabPanels");
7
+ const { selectedIndex } = $derived(context);
8
+ const slot = $derived({ selectedIndex });
9
+ let { ref = $bindable(), ...theirProps } = $props();
21
10
  </script>
22
11
 
23
12
  <ElementOrComponent {theirProps} {slot} defaultTag={DEFAULT_PANELS_TAG} name="TabPanel" bind:ref />
@@ -1,90 +1,59 @@
1
- <script lang="ts" module>
2
- import type { ElementType, Props, PropsOf } from "../utils/types.js"
3
-
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,
19
- {
20
- value?: TValue
21
- disabled?: boolean
22
- invalid?: boolean
23
- autofocus?: boolean
24
- }
25
- >
1
+ <script lang="ts" module>const DEFAULT_TEXTAREA_TAG = "textarea";
26
2
  </script>
27
3
 
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
- })
63
- )
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
- )
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(
44
+ {
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
85
54
  )
86
-
87
- const slot = $derived({ disabled, invalid, hover, focus, autofocus } satisfies TextareaRenderPropArg)
55
+ );
56
+ const slot = $derived({ disabled, invalid, hover, focus, autofocus });
88
57
  </script>
89
58
 
90
59
  <ElementOrComponent
@@ -1,267 +1,178 @@
1
- <script lang="ts" module>
2
- import { compact, RenderStrategy } from "../utils/render.js"
3
- import type { ElementType } from "../utils/types.js"
4
- import { onMount, setContext, untrack } from "svelte"
5
- import {
6
- hasChildren,
7
- TreeStates,
8
- useNesting,
9
- useParentNesting,
10
- useTransitionContext,
11
- type NestingContextValues,
12
- type TransitionDirection,
13
- } from "./context.svelte.js"
14
- import type { TransitionRootProps } from "./Transition.svelte"
15
- import { match } from "../utils/match.js"
16
- import { transitionDataAttributes, useTransition } from "../hooks/use-transition.svelte.js"
17
- import { classNames } from "../utils/class-names.js"
18
- import { createOpenClosedContext, State } from "../internal/open-closed.js"
19
- import ElementOrComponent from "../utils/ElementOrComponent.svelte"
20
- import { DEFAULT_TRANSITION_CHILD_TAG, type TransitionChildProps } from "./TransitionChild.svelte"
21
-
22
- /**
23
- * Check if we should forward the ref to the child element or not. This is to
24
- * prevent crashes when the `as` prop is a Fragment _and_ the component just acts
25
- * as a state container (aka, there is no actual transition happening).
26
- *
27
- * E.g.:
28
- *
29
- * ```tsx
30
- * <Transition show={true}>
31
- * <Transition.Child enter="duration-100"><div>Child 1</div></Transition.Child>
32
- * <Transition.Child enter="duration-200"><div>Child 2</div></Transition.Child>
33
- * </Transition>
34
- * ```
35
- *
36
- * In this scenario, the child components are transitioning, but the
37
- * `Transition` parent, which is a `Fragment`, is not. So we should not forward
38
- * the ref to the `Fragment`.
39
- */
40
- export function shouldForwardRef<TTag extends ElementType = typeof DEFAULT_TRANSITION_CHILD_TAG>(
41
- props: TransitionRootProps<TTag>
42
- ) {
43
- return (
44
- // If we have any of the enter/leave classes
45
- Boolean(props.enter || props.enterFrom || props.enterTo || props.leave || props.leaveFrom || props.leaveTo) ||
46
- // If the `as` prop is not a Fragment
47
- (props.as ?? DEFAULT_TRANSITION_CHILD_TAG) !== "svelte:fragment" ||
48
- // If we have a single child, then we can forward the ref directly
49
- props.children !== undefined
50
- )
51
- }
1
+ <script lang="ts" module>import { compact, RenderStrategy } from "../utils/render.js";
2
+ import { onMount, setContext, untrack } from "svelte";
3
+ import {
4
+ hasChildren,
5
+ TreeStates,
6
+ useNesting,
7
+ useParentNesting,
8
+ useTransitionContext
9
+ } from "./context.svelte.js";
10
+ import { match } from "../utils/match.js";
11
+ import { transitionDataAttributes, useTransition } from "../hooks/use-transition.svelte.js";
12
+ import { classNames } from "../utils/class-names.js";
13
+ import { createOpenClosedContext, State } from "../internal/open-closed.js";
14
+ import ElementOrComponent from "../utils/ElementOrComponent.svelte";
15
+ import { DEFAULT_TRANSITION_CHILD_TAG } from "./TransitionChild.svelte";
16
+ export function shouldForwardRef(props) {
17
+ return (
18
+ // If we have any of the enter/leave classes
19
+ Boolean(props.enter || props.enterFrom || props.enterTo || props.leave || props.leaveFrom || props.leaveTo) || // If the `as` prop is not a Fragment
20
+ (props.as ?? DEFAULT_TRANSITION_CHILD_TAG) !== "svelte:fragment" || // If we have a single child, then we can forward the ref directly
21
+ props.children !== void 0
22
+ );
23
+ }
52
24
  </script>
53
25
 
54
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_TRANSITION_CHILD_TAG">
55
- let { ref = $bindable(), ..._props }: { as?: TTag } & TransitionChildProps<TTag> = $props()
56
- const {
57
- // Whether or not to enable transitions on the current element (by exposing
58
- // transition data). When set to false, the `Transition` component still
59
- // acts as a transition boundary for `TransitionChild` components.
60
- transition = true,
61
-
62
- // Event "handlers"
63
- beforeEnter,
64
- afterEnter,
65
- beforeLeave,
66
- afterLeave,
67
-
68
- // Class names
69
- enter,
70
- enterFrom,
71
- enterTo,
72
- entered,
73
- leave,
74
- leaveFrom,
75
- leaveTo,
76
-
77
- ...theirProps
78
- } = $derived(_props)
79
- let containerElement = $state<HTMLElement>()
80
- let container = $state<{ current: HTMLElement | null }>({ current: null })
81
- const requiresRef = $derived(shouldForwardRef(_props))
82
-
83
- const strategy = $derived((theirProps.unmount ?? true) ? RenderStrategy.Unmount : RenderStrategy.Hidden)
84
-
85
- const _transitionContext = useTransitionContext()
86
- const { show, appear, initial } = $derived(_transitionContext)
87
-
88
- let _state = $state(untrack(() => show) ? TreeStates.Visible : TreeStates.Hidden)
89
-
90
- const parentNesting = useParentNesting()
91
- const { register, unregister } = $derived(parentNesting)
92
-
93
- onMount(() => {
94
- if (requiresRef) {
95
- container.current = ref ?? null
96
- containerElement = ref
97
- }
98
-
99
- return register(container)
100
- })
101
-
102
- $effect(() => {
103
- // If we are in another mode than the Hidden mode then ignore
104
- if (strategy !== RenderStrategy.Hidden) return
105
- if (!container.current) return
106
-
107
- // Make sure that we are visible
108
- if (show && _state !== TreeStates.Visible) {
109
- _state = TreeStates.Visible
110
- return
111
- }
112
-
113
- match(_state, {
114
- [TreeStates.Hidden]: () => unregister(container),
115
- [TreeStates.Visible]: () => register(container),
116
- })
117
- })
118
- //[state, container, register, unregister, show, strategy]
119
-
120
- $effect(() => {
121
- if (!requiresRef) return
122
-
123
- if (_state === TreeStates.Visible && container.current === null) {
124
- throw new Error("Did you forget to passthrough the `ref` to the actual DOM node?")
125
- }
126
- })
127
-
128
- // Skipping initial transition
129
- const skip = $derived(initial && !appear)
130
- const immediate = $derived(appear && show && initial)
131
-
132
- let isTransitioning = $state(false)
133
-
134
- let nesting = useNesting({
135
- done: () => {
136
- // When all children have been unmounted we can only hide ourselves if and
137
- // only if we are not transitioning ourselves. Otherwise we would unmount
138
- // before the transitions are finished.
139
- if (isTransitioning) return
140
-
141
- _state = TreeStates.Hidden
142
- unregister(container)
143
- },
144
- get parent() {
145
- return parentNesting
146
- },
147
- })
148
-
149
- const start = (show: boolean) => {
150
- isTransitioning = true
151
- const direction: TransitionDirection = show ? "enter" : "leave"
152
-
153
- nesting.onStart(container, direction, (direction) => {
154
- if (direction === "enter") beforeEnter?.()
155
- else if (direction === "leave") beforeLeave?.()
156
- })
26
+ <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_TRANSITION_CHILD_TAG">let { ref = $bindable(), ..._props } = $props();
27
+ const {
28
+ // Whether or not to enable transitions on the current element (by exposing
29
+ // transition data). When set to false, the `Transition` component still
30
+ // acts as a transition boundary for `TransitionChild` components.
31
+ transition = true,
32
+ // Event "handlers"
33
+ beforeEnter,
34
+ afterEnter,
35
+ beforeLeave,
36
+ afterLeave,
37
+ // Class names
38
+ enter,
39
+ enterFrom,
40
+ enterTo,
41
+ entered,
42
+ leave,
43
+ leaveFrom,
44
+ leaveTo,
45
+ ...theirProps
46
+ } = $derived(_props);
47
+ let containerElement = $state();
48
+ let container = $state({ current: null });
49
+ const requiresRef = $derived(shouldForwardRef(_props));
50
+ const strategy = $derived(theirProps.unmount ?? true ? RenderStrategy.Unmount : RenderStrategy.Hidden);
51
+ const _transitionContext = useTransitionContext();
52
+ const { show, appear, initial } = $derived(_transitionContext);
53
+ let _state = $state(untrack(() => show) ? TreeStates.Visible : TreeStates.Hidden);
54
+ const parentNesting = useParentNesting();
55
+ const { register, unregister } = $derived(parentNesting);
56
+ onMount(() => {
57
+ if (requiresRef) {
58
+ container.current = ref ?? null;
59
+ containerElement = ref;
157
60
  }
158
-
159
- const end = (show: boolean) => {
160
- let direction: TransitionDirection = show ? "enter" : "leave"
161
-
162
- isTransitioning = false
163
- nesting.onStop(container, direction, (direction) => {
164
- if (direction === "enter") afterEnter?.()
165
- else if (direction === "leave") afterLeave?.()
166
- })
167
-
168
- if (direction === "leave" && !hasChildren(nesting)) {
169
- // When we don't have children anymore we can safely unregister from the
170
- // parent and hide ourselves.
171
- _state = TreeStates.Hidden
172
- unregister(container)
173
- }
61
+ return register(container);
62
+ });
63
+ $effect(() => {
64
+ if (strategy !== RenderStrategy.Hidden) return;
65
+ if (!container.current) return;
66
+ if (show && _state !== TreeStates.Visible) {
67
+ _state = TreeStates.Visible;
68
+ return;
174
69
  }
175
-
176
- $effect(() => {
177
- if (requiresRef && transition) return
178
-
179
- // When we don't transition, then we can complete the transition
180
- // immediately.
181
- untrack(() => start(show))
182
- untrack(() => end(show))
183
- })
184
-
185
- const enabled = $derived.by(() => {
186
- // Should the current component transition? If not, then we can still
187
- // orchestrate the child transitions.
188
- if (!transition) return false
189
-
190
- // If we don't require a ref, then we can't transition.
191
- if (!requiresRef) return false
192
-
193
- // If the server handoff isn't completed yet, we can't transition.
194
- //if (!ready) return false
195
-
196
- // If we start in a `show` state but without the `appear` prop, then we skip
197
- // the initial transition.
198
- if (skip) return false
199
-
200
- return true
201
- })
202
-
203
- // Ignoring the `visible` state because this doesn't handle the hierarchy. If
204
- // a leave transition on the `<Transition>` is done, but there is still a
205
- // child `<TransitionChild>` busy, then `visible` would be `false`, while
206
- // `state` would still be `TreeStates.Visible`.
207
- const _transition = useTransition({
208
- get enabled() {
209
- return enabled
210
- },
211
- get element() {
212
- return containerElement
213
- },
214
- get show() {
215
- return show
216
- },
217
- events: { start, end },
218
- })
219
- const { data: transitionData } = $derived(_transition)
220
-
221
- const ourProps = $derived(
222
- compact({
223
- class:
224
- classNames(
225
- // Incoming classes if any
226
- // all components accept className (but all HTML elements do)
227
- theirProps.class,
228
-
229
- // Apply these classes immediately
230
- immediate && enter,
231
- immediate && enterFrom,
232
-
233
- // Map data attributes to `enter`, `enterFrom` and `enterTo` classes
234
- transitionData.enter && enter,
235
- transitionData.enter && transitionData.closed && enterFrom,
236
- transitionData.enter && !transitionData.closed && enterTo,
237
-
238
- // Map data attributes to `leave`, `leaveFrom` and `leaveTo` classes
239
- transitionData.leave && leave,
240
- transitionData.leave && !transitionData.closed && leaveFrom,
241
- transitionData.leave && transitionData.closed && leaveTo,
242
-
243
- // Map data attributes to `entered` class (backwards compatibility)
244
- !transitionData.transition && show && entered
245
- )?.trim() || undefined, // If `class` is an empty string, we can omit it
246
- ...transitionDataAttributes(transitionData),
247
- })
248
- )
249
-
250
- const openClosedState = $derived.by(() => {
251
- let openClosedState = 0
252
- if (_state === TreeStates.Visible) openClosedState |= State.Open
253
- if (_state === TreeStates.Hidden) openClosedState |= State.Closed
254
- if (transitionData.enter) openClosedState |= State.Opening
255
- if (transitionData.leave) openClosedState |= State.Closing
256
- return openClosedState
257
- })
258
-
259
- createOpenClosedContext({
260
- get value() {
261
- return openClosedState
262
- },
70
+ match(_state, {
71
+ [TreeStates.Hidden]: () => unregister(container),
72
+ [TreeStates.Visible]: () => register(container)
73
+ });
74
+ });
75
+ $effect(() => {
76
+ if (!requiresRef) return;
77
+ if (_state === TreeStates.Visible && container.current === null) {
78
+ throw new Error("Did you forget to passthrough the `ref` to the actual DOM node?");
79
+ }
80
+ });
81
+ const skip = $derived(initial && !appear);
82
+ const immediate = $derived(appear && show && initial);
83
+ let isTransitioning = $state(false);
84
+ let nesting = useNesting({
85
+ done: () => {
86
+ if (isTransitioning) return;
87
+ _state = TreeStates.Hidden;
88
+ unregister(container);
89
+ },
90
+ get parent() {
91
+ return parentNesting;
92
+ }
93
+ });
94
+ const start = (show2) => {
95
+ isTransitioning = true;
96
+ const direction = show2 ? "enter" : "leave";
97
+ nesting.onStart(container, direction, (direction2) => {
98
+ if (direction2 === "enter") beforeEnter?.();
99
+ else if (direction2 === "leave") beforeLeave?.();
100
+ });
101
+ };
102
+ const end = (show2) => {
103
+ let direction = show2 ? "enter" : "leave";
104
+ isTransitioning = false;
105
+ nesting.onStop(container, direction, (direction2) => {
106
+ if (direction2 === "enter") afterEnter?.();
107
+ else if (direction2 === "leave") afterLeave?.();
108
+ });
109
+ if (direction === "leave" && !hasChildren(nesting)) {
110
+ _state = TreeStates.Hidden;
111
+ unregister(container);
112
+ }
113
+ };
114
+ $effect(() => {
115
+ if (requiresRef && transition) return;
116
+ untrack(() => start(show));
117
+ untrack(() => end(show));
118
+ });
119
+ const enabled = $derived.by(() => {
120
+ if (!transition) return false;
121
+ if (!requiresRef) return false;
122
+ if (skip) return false;
123
+ return true;
124
+ });
125
+ const _transition = useTransition({
126
+ get enabled() {
127
+ return enabled;
128
+ },
129
+ get element() {
130
+ return containerElement;
131
+ },
132
+ get show() {
133
+ return show;
134
+ },
135
+ events: { start, end }
136
+ });
137
+ const { data: transitionData } = $derived(_transition);
138
+ const ourProps = $derived(
139
+ compact({
140
+ class: classNames(
141
+ // Incoming classes if any
142
+ // all components accept className (but all HTML elements do)
143
+ theirProps.class,
144
+ // Apply these classes immediately
145
+ immediate && enter,
146
+ immediate && enterFrom,
147
+ // Map data attributes to `enter`, `enterFrom` and `enterTo` classes
148
+ transitionData.enter && enter,
149
+ transitionData.enter && transitionData.closed && enterFrom,
150
+ transitionData.enter && !transitionData.closed && enterTo,
151
+ // Map data attributes to `leave`, `leaveFrom` and `leaveTo` classes
152
+ transitionData.leave && leave,
153
+ transitionData.leave && !transitionData.closed && leaveFrom,
154
+ transitionData.leave && transitionData.closed && leaveTo,
155
+ // Map data attributes to `entered` class (backwards compatibility)
156
+ !transitionData.transition && show && entered
157
+ )?.trim() || void 0,
158
+ // If `class` is an empty string, we can omit it
159
+ ...transitionDataAttributes(transitionData)
263
160
  })
264
- setContext<NestingContextValues>("NestingContext", nesting)
161
+ );
162
+ const openClosedState = $derived.by(() => {
163
+ let openClosedState2 = 0;
164
+ if (_state === TreeStates.Visible) openClosedState2 |= State.Open;
165
+ if (_state === TreeStates.Hidden) openClosedState2 |= State.Closed;
166
+ if (transitionData.enter) openClosedState2 |= State.Opening;
167
+ if (transitionData.leave) openClosedState2 |= State.Closing;
168
+ return openClosedState2;
169
+ });
170
+ createOpenClosedContext({
171
+ get value() {
172
+ return openClosedState;
173
+ }
174
+ });
175
+ setContext("NestingContext", nesting);
265
176
  </script>
266
177
 
267
178
  <ElementOrComponent {ourProps} {theirProps} defaultTag={DEFAULT_TRANSITION_CHILD_TAG} name="TransitionChild" bind:ref />