@pzerelles/headlessui-svelte 2.1.2-next.31 → 2.1.2-next.33

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