@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,105 +1,75 @@
1
- <script lang="ts" module>
2
- import { State, useOpenClosed } from "../internal/open-closed.js"
3
- import type { ElementType } from "../utils/types.js"
4
- import { setContext, untrack, type Component } from "svelte"
5
- import {
6
- type TransitionChildProps,
7
- DEFAULT_TRANSITION_CHILD_TAG,
8
- TransitionChildRenderFeatures,
9
- } from "./TransitionChild.svelte"
10
-
11
- export type TransitionRootProps<TTag extends ElementType = typeof DEFAULT_TRANSITION_CHILD_TAG> =
12
- TransitionChildProps<TTag> & {
13
- show?: boolean
14
- appear?: boolean
15
- }
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";
16
7
  </script>
17
8
 
18
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_TRANSITION_CHILD_TAG">
19
- import InternalTransitionChild, { shouldForwardRef } from "./InternalTransitionChild.svelte"
20
- import ElementOrComponent from "../utils/ElementOrComponent.svelte"
21
- import {
22
- hasChildren,
23
- TreeStates,
24
- useNesting,
25
- type NestingContextValues,
26
- type TransitionContextValues,
27
- } from "./context.svelte.js"
28
-
29
- let { ref = $bindable(), show, ..._props }: { as?: TTag } & TransitionRootProps<TTag> = $props()
30
- const { appear = false, unmount = true, ...theirProps } = $derived(_props)
31
- const requiresRef = shouldForwardRef(_props)
32
-
33
- const usesOpenClosedState = useOpenClosed()
34
-
35
- if (show === undefined && usesOpenClosedState !== null) {
36
- show = (usesOpenClosedState.value & State.Open) === State.Open
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;
37
31
  }
38
-
39
- if (show === undefined) {
40
- throw new Error("A <Transition /> is used but it is missing a `show={true | false}` prop.")
32
+ });
33
+ let initial = $state(true);
34
+ let changes = $state([show]);
35
+ $effect(() => {
36
+ if (untrack(() => initial) === false) {
37
+ return;
41
38
  }
42
-
43
- let _state = $state(show ? TreeStates.Visible : TreeStates.Hidden)
44
-
45
- const nestingBag = useNesting({
46
- done: () => {
47
- if (show) return
48
- _state = TreeStates.Hidden
49
- },
50
- })
51
-
52
- let initial = $state(true)
53
-
54
- // Change the `initial` value
55
- let changes = $state([show])
56
- $effect(() => {
57
- // We can skip this effect
58
- if (untrack(() => initial) === false) {
59
- return
60
- }
61
-
62
- // Track the changes
63
- if (changes[changes.length - 1] !== show) {
64
- changes.push(show)
65
- initial = false
66
- }
67
- })
68
-
69
- $effect(() => {
70
- if (show) {
71
- _state = TreeStates.Visible
72
- } else if (!hasChildren(nestingBag) && untrack(() => ref)) {
73
- _state = TreeStates.Hidden
74
- }
75
- })
76
-
77
- const sharedProps = $derived({ unmount })
78
-
79
- const beforeEnter = () => {
80
- if (initial) initial = false
81
- _props.beforeEnter?.()
39
+ if (changes[changes.length - 1] !== show) {
40
+ changes.push(show);
41
+ initial = false;
82
42
  }
83
-
84
- const beforeLeave = () => {
85
- if (initial) initial = false
86
- _props.beforeLeave?.()
43
+ });
44
+ $effect(() => {
45
+ if (show) {
46
+ _state = TreeStates.Visible;
47
+ } else if (!hasChildren(nestingBag) && untrack(() => ref)) {
48
+ _state = TreeStates.Hidden;
87
49
  }
88
-
89
- setContext<NestingContextValues>("NestingContext", nestingBag)
90
- setContext<TransitionContextValues>("TransitionContext", {
91
- get show() {
92
- return show
93
- },
94
- get appear() {
95
- return appear
96
- },
97
- get initial() {
98
- return initial
99
- },
100
- })
101
-
102
- const InternalChild = InternalTransitionChild<any>
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;
70
+ }
71
+ });
72
+ const InternalChild = InternalTransitionChild;
103
73
  </script>
104
74
 
105
75
  {#snippet children()}
@@ -1,36 +1,16 @@
1
- <script lang="ts" module>
2
- import type { ElementType, Props } from "../utils/types.js"
3
- import { RenderFeatures, type PropsForFeatures } from "../utils/render.js"
4
- import type { TransitionEvents, TransitionClasses } from "./context.svelte.js"
5
-
6
- type TransitionChildPropsWeControl = never
7
-
8
- export type TransitionChildProps<TTag extends ElementType> = Props<
9
- TTag,
10
- TransitionChildRenderPropArg,
11
- TransitionChildPropsWeControl,
12
- PropsForFeatures<typeof TransitionChildRenderFeatures> &
13
- TransitionClasses &
14
- TransitionEvents & { transition?: boolean; appear?: boolean }
15
- >
16
-
17
- export const DEFAULT_TRANSITION_CHILD_TAG = "svelte:fragment"
18
- export type TransitionChildRenderPropArg = HTMLElement
19
- export const TransitionChildRenderFeatures = RenderFeatures.RenderStrategy
1
+ <script lang="ts" module>import { RenderFeatures } from "../utils/render.js";
2
+ export const DEFAULT_TRANSITION_CHILD_TAG = "svelte:fragment";
3
+ export const TransitionChildRenderFeatures = RenderFeatures.RenderStrategy;
20
4
  </script>
21
5
 
22
- <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_TRANSITION_CHILD_TAG">
23
- import { useOpenClosed } from "../internal/open-closed.js"
24
- import { getContext } from "svelte"
25
- import InternalTransitionChild from "./InternalTransitionChild.svelte"
26
- import Transition from "./Transition.svelte"
27
-
28
- const hasTransitionContext = !!getContext("TransitionContext")
29
- const hasOpenClosedContext = useOpenClosed() !== null
30
-
31
- let { ref = $bindable(), as, ...props }: { as?: TTag } & TransitionChildProps<TTag> = $props()
32
-
33
- const TransitionRootOrChild = !hasTransitionContext && hasOpenClosedContext ? Transition : InternalTransitionChild
6
+ <script lang="ts" generics="TTag extends ElementType = typeof DEFAULT_TRANSITION_CHILD_TAG">import { useOpenClosed } from "../internal/open-closed.js";
7
+ import { getContext } from "svelte";
8
+ import InternalTransitionChild from "./InternalTransitionChild.svelte";
9
+ import Transition from "./Transition.svelte";
10
+ const hasTransitionContext = !!getContext("TransitionContext");
11
+ const hasOpenClosedContext = useOpenClosed() !== null;
12
+ let { ref = $bindable(), as, ...props } = $props();
13
+ const TransitionRootOrChild = !hasTransitionContext && hasOpenClosedContext ? Transition : InternalTransitionChild;
34
14
  </script>
35
15
 
36
16
  <TransitionRootOrChild bind:ref {...props} />
@@ -1,10 +1,6 @@
1
- <script lang="ts">
2
- import { provideDisabled } from "../hooks/use-disabled.js"
3
- import type { Snippet } from "svelte"
4
-
5
- const { disabled, children }: { disabled?: boolean; children?: Snippet } = $props()
6
-
7
- provideDisabled(() => disabled ?? false)
1
+ <script lang="ts">import { provideDisabled } from "../hooks/use-disabled.js";
2
+ const { disabled, children } = $props();
3
+ provideDisabled(() => disabled ?? false);
8
4
  </script>
9
5
 
10
6
  {@render children?.()}
@@ -1,46 +1,26 @@
1
- <script lang="ts" generics="TFeature extends RenderFeatures, TTag extends ElementType, TSlot, TValue">
2
- import type { ElementType, Props } from "./types.js"
3
- import { mergePropsAdvanced, RenderFeatures, type PropsForFeatures } from "./render.js"
4
- import Generic from "./Generic.svelte"
5
-
6
- let {
7
- ourProps,
8
- theirProps,
9
- slots,
10
- slot = slots,
11
- defaultTag,
12
- features,
13
- visible = true,
14
- name,
15
- ref = $bindable(),
16
- value = $bindable(),
17
- checked = $bindable(),
18
- }: {
19
- ourProps?: Expand<Props<any, TSlot> & PropsForFeatures<TFeature>>
20
- theirProps: Expand<{ as?: TTag } & Props<any, TSlot, any>>
21
- slot?: TSlot
22
- slots?: TSlot
23
- defaultTag: ElementType
24
- features?: TFeature
25
- visible?: boolean
26
- name: string
27
- ref?: HTMLElement
28
- value?: TValue
29
- checked?: boolean
30
- } = $props()
31
-
32
- const featureFlags = $derived(features ?? RenderFeatures.None)
33
- const { static: isStatic = false, unmount = true, ...rest } = $derived(mergePropsAdvanced(theirProps, ourProps ?? {}))
34
- const render = $derived(
35
- visible ||
36
- (featureFlags & RenderFeatures.Static && isStatic) ||
37
- (featureFlags & RenderFeatures.RenderStrategy && !unmount)
38
- )
39
- const hiddenProps = $derived(
40
- !visible && !(featureFlags & RenderFeatures.Static) && featureFlags & RenderFeatures.RenderStrategy && !unmount
41
- ? { hidden: true, style: "display: none;" }
42
- : {}
43
- )
1
+ <script lang="ts" generics="TFeature extends RenderFeatures, TTag extends ElementType, TSlot, TValue">import { mergePropsAdvanced, RenderFeatures } from "./render.js";
2
+ import Generic from "./Generic.svelte";
3
+ let {
4
+ ourProps,
5
+ theirProps,
6
+ slots,
7
+ slot = slots,
8
+ defaultTag,
9
+ features,
10
+ visible = true,
11
+ name,
12
+ ref = $bindable(),
13
+ value = $bindable(),
14
+ checked = $bindable()
15
+ } = $props();
16
+ const featureFlags = $derived(features ?? RenderFeatures.None);
17
+ const { static: isStatic = false, unmount = true, ...rest } = $derived(mergePropsAdvanced(theirProps, ourProps ?? {}));
18
+ const render = $derived(
19
+ visible || featureFlags & RenderFeatures.Static && isStatic || featureFlags & RenderFeatures.RenderStrategy && !unmount
20
+ );
21
+ const hiddenProps = $derived(
22
+ !visible && !(featureFlags & RenderFeatures.Static) && featureFlags & RenderFeatures.RenderStrategy && !unmount ? { hidden: true, style: "display: none;" } : {}
23
+ );
44
24
  </script>
45
25
 
46
26
  {#if render}<Generic {...rest} {...hiddenProps} {slot} tag={defaultTag} bind:ref bind:value bind:checked />{/if}
@@ -1,30 +1,19 @@
1
- <script lang="ts" generics="TTag extends ElementType, TSlot, TValue">
2
- import { stateFromSlot } from "./state.js"
3
- import type { ElementType, Props } from "./types.js"
4
-
5
- let {
6
- slot = {} as TSlot,
7
- tag,
8
- ref = $bindable(),
9
- value = $bindable(),
10
- checked = $bindable(),
11
- children,
12
- as = tag as TTag,
13
- unmount,
14
- static: isStatic,
15
- ...props
16
- }: {
17
- as?: TTag
18
- slot: TSlot
19
- tag: ElementType
20
- ref?: HTMLElement
21
- value?: TValue
22
- checked?: boolean
23
- } & Props<TTag, TSlot> = $props()
24
-
25
- const resolvedClass = $derived(
26
- typeof props.class === "function" ? props.class(slot) : (props.class as string | undefined)
27
- )
1
+ <script lang="ts" generics="TTag extends ElementType, TSlot, TValue">import { stateFromSlot } from "./state.js";
2
+ let {
3
+ slot = {},
4
+ tag,
5
+ ref = $bindable(),
6
+ value = $bindable(),
7
+ checked = $bindable(),
8
+ children,
9
+ as = tag,
10
+ unmount,
11
+ static: isStatic,
12
+ ...props
13
+ } = $props();
14
+ const resolvedClass = $derived(
15
+ typeof props.class === "function" ? props.class(slot) : props.class
16
+ );
28
17
  </script>
29
18
 
30
19
  {#if as === "svelte:fragment"}
@@ -1,61 +1,43 @@
1
- <script lang="ts" module>
2
- import { useId } from "../hooks/use-id.js"
3
- import { getContext, setContext, type Snippet } from "svelte"
4
-
5
- type CollectionKey = string | symbol
6
- type CollectionItem = [number, () => void]
7
- type Collection = ReturnType<typeof createCollection>
8
-
9
- function createCollection() {
10
- return {
11
- /** @type {Map<string, Map<string, number>>} */
12
- groups: new Map(),
13
-
14
- get(group: string, key: CollectionKey): CollectionItem {
15
- let list = this.groups.get(group)
16
- if (!list) {
17
- list = new Map()
18
- this.groups.set(group, list)
19
- }
20
-
21
- let renders = list.get(key) ?? 0
22
- // FIXME: This is a side-effect during render. `release` is only called in
23
- // an effect cleanup so we may never release if we had to render multiple
24
- // times before commit e.g. when a sibling suspends.
25
- list.set(key, renders + 1)
26
-
27
- let index = Array.from(list.keys()).indexOf(key)
28
- function release() {
29
- let renders = list.get(key)
30
- if (renders > 1) {
31
- list.set(key, renders - 1)
32
- } else {
33
- list.delete(key)
34
- }
1
+ <script lang="ts" module>import { useId } from "../hooks/use-id.js";
2
+ import { getContext, setContext } from "svelte";
3
+ function createCollection() {
4
+ return {
5
+ /** @type {Map<string, Map<string, number>>} */
6
+ groups: /* @__PURE__ */ new Map(),
7
+ get(group, key) {
8
+ let list = this.groups.get(group);
9
+ if (!list) {
10
+ list = /* @__PURE__ */ new Map();
11
+ this.groups.set(group, list);
12
+ }
13
+ let renders = list.get(key) ?? 0;
14
+ list.set(key, renders + 1);
15
+ let index = Array.from(list.keys()).indexOf(key);
16
+ function release() {
17
+ let renders2 = list.get(key);
18
+ if (renders2 > 1) {
19
+ list.set(key, renders2 - 1);
20
+ } else {
21
+ list.delete(key);
35
22
  }
36
-
37
- return [index, release]
38
- },
23
+ }
24
+ return [index, release];
39
25
  }
40
- }
41
-
42
- export function useStableCollectionIndex(group: string) {
43
- let collection = getContext<Collection>("StableCollection")
44
- if (!collection) throw new Error("You must wrap your component in a <StableCollection>")
45
-
46
- let key = useId()
47
- let [idx, cleanupIdx] = collection.get(group, key)
48
-
49
- $effect(() => cleanupIdx)
50
- return idx
51
- }
26
+ };
27
+ }
28
+ export function useStableCollectionIndex(group) {
29
+ let collection = getContext("StableCollection");
30
+ if (!collection) throw new Error("You must wrap your component in a <StableCollection>");
31
+ let key = useId();
32
+ let [idx, cleanupIdx] = collection.get(group, key);
33
+ $effect(() => cleanupIdx);
34
+ return idx;
35
+ }
52
36
  </script>
53
37
 
54
- <script lang="ts">
55
- const collection = createCollection()
56
- setContext<Collection>("StableCollection", collection)
57
-
58
- let { children }: { children: Snippet } = $props()
38
+ <script lang="ts">const collection = createCollection();
39
+ setContext("StableCollection", collection);
40
+ let { children } = $props();
59
41
  </script>
60
42
 
61
43
  {#if children}{@render children()}{/if}
@@ -1,32 +1,17 @@
1
- <script lang="ts" module>
2
- import type { Snippet } from "svelte"
1
+ <script lang="ts" module></script>
3
2
 
4
- export interface FloatingNodeProps {
5
- children?: Snippet
6
- id: string
3
+ <script lang="ts">import { setContext } from "svelte";
4
+ import { useFloatingParentNodeId } from "./FloatingTree.svelte";
5
+ const { children, id } = $props();
6
+ const parentId = useFloatingParentNodeId();
7
+ setContext("FloatingNodeContext", {
8
+ get id() {
9
+ return id;
10
+ },
11
+ get parentId() {
12
+ return parentId.value;
7
13
  }
8
- </script>
9
-
10
- <script lang="ts">
11
- /**
12
- * Provides parent node context for nested floating elements.
13
- * @see https://floating-ui.com/docs/FloatingTree
14
- */
15
- import { setContext } from "svelte"
16
- import type { FloatingNodeType } from "../types.js"
17
- import { useFloatingParentNodeId } from "./FloatingTree.svelte"
18
-
19
- const { children, id }: FloatingNodeProps = $props()
20
-
21
- const parentId = useFloatingParentNodeId()
22
- setContext<FloatingNodeType>("FloatingNodeContext", {
23
- get id() {
24
- return id
25
- },
26
- get parentId() {
27
- return parentId.value
28
- },
29
- })
14
+ });
30
15
  </script>
31
16
 
32
17
  {#if children}{@render children()}{/if}
@@ -1,94 +1,50 @@
1
- <script lang="ts" module>
2
- import { getContext, type Snippet } from "svelte"
3
- import { useId } from "../hooks/useId.svelte.js"
4
- import type { FloatingNodeType, FloatingTreeType, ReferenceType } from "../types.js"
5
- import { createPubSub } from "../utils/createPubSub.js"
6
- import type { MutableRefObject } from "../../../ref.svelte.js"
7
-
8
- //const FloatingNodeContext = React.createContext<FloatingNodeType | null>(null)
9
- //const FloatingTreeContext = React.createContext<FloatingTreeType | null>(null)
10
-
11
- /**
12
- * Returns the parent node id for nested floating elements, if available.
13
- * Returns `null` for top-level floating elements.
14
- */
15
- export const useFloatingParentNodeId = (): { readonly value: string | null } => {
16
- const context = getContext<FloatingNodeType>("FloatingNodeContext")
17
- return {
18
- get value() {
19
- return context?.id ?? null
20
- },
1
+ <script lang="ts" module>import { getContext } from "svelte";
2
+ import { useId } from "../hooks/useId.svelte.js";
3
+ import { createPubSub } from "../utils/createPubSub.js";
4
+ export const useFloatingParentNodeId = () => {
5
+ const context = getContext("FloatingNodeContext");
6
+ return {
7
+ get value() {
8
+ return context?.id ?? null;
21
9
  }
22
- }
23
-
24
- /**
25
- * Returns the nearest floating tree context, if available.
26
- */
27
- export const useFloatingTree = <RT extends ReferenceType = ReferenceType>(): FloatingTreeType<RT> | null =>
28
- getContext<FloatingTreeType<RT>>("FloatingTreeContext") ?? null
29
-
30
- /**
31
- * Registers a node into the `FloatingTree`, returning its id.
32
- * @see https://floating-ui.com/docs/FloatingTree
33
- */
34
- export function useFloatingNodeId(options: { customParentId?: string }): string {
35
- const { customParentId } = $derived(options)
36
- const id = useId()
37
- const tree = useFloatingTree()
38
- const reactParentId = useFloatingParentNodeId()
39
- const parentId = $derived(customParentId || reactParentId.value)
40
-
41
- $effect(() => {
42
- const node = { id, parentId }
43
- tree?.addNode(node)
44
- return () => {
45
- tree?.removeNode(node)
46
- }
47
- }) //, [tree, id, parentId])
48
-
49
- return id
50
- }
51
-
52
- export interface FloatingTreeProps {
53
- children?: Snippet
54
- }
10
+ };
11
+ };
12
+ export const useFloatingTree = () => getContext("FloatingTreeContext") ?? null;
13
+ export function useFloatingNodeId(options) {
14
+ const { customParentId } = $derived(options);
15
+ const id = useId();
16
+ const tree = useFloatingTree();
17
+ const reactParentId = useFloatingParentNodeId();
18
+ const parentId = $derived(customParentId || reactParentId.value);
19
+ $effect(() => {
20
+ const node = { id, parentId };
21
+ tree?.addNode(node);
22
+ return () => {
23
+ tree?.removeNode(node);
24
+ };
25
+ });
26
+ return id;
27
+ }
55
28
  </script>
56
29
 
57
- <script lang="ts">
58
- /**
59
- * Provides context for nested floating elements when they are not children of
60
- * each other on the DOM.
61
- * This is not necessary in all cases, except when there must be explicit communication between parent and child floating elements. It is necessary for:
62
- * - The `bubbles` option in the `useDismiss()` Hook
63
- * - Nested virtual list navigation
64
- * - Nested floating elements that each open on hover
65
- * - Custom communication between parent and child floating elements
66
- * @see https://floating-ui.com/docs/FloatingTree
67
- */
68
- import { setContext } from "svelte"
69
-
70
- const { children }: FloatingTreeProps = $props()
71
-
72
- const nodesRef = $state<MutableRefObject<Array<FloatingNodeType>>>({ current: [] })
73
-
74
- const addNode = (node: FloatingNodeType) => {
75
- nodesRef.current = [...nodesRef.current, node]
76
- }
77
-
78
- const removeNode = (node: FloatingNodeType) => {
79
- nodesRef.current = nodesRef.current.filter((n) => n !== node)
80
- }
81
-
82
- const events = createPubSub()
83
-
84
- setContext<FloatingTreeType<ReferenceType>>("FloatingTreeContext", {
85
- get nodesRef() {
86
- return nodesRef
87
- },
88
- addNode,
89
- removeNode,
90
- events,
91
- })
30
+ <script lang="ts">import { setContext } from "svelte";
31
+ const { children } = $props();
32
+ const nodesRef = $state({ current: [] });
33
+ const addNode = (node) => {
34
+ nodesRef.current = [...nodesRef.current, node];
35
+ };
36
+ const removeNode = (node) => {
37
+ nodesRef.current = nodesRef.current.filter((n) => n !== node);
38
+ };
39
+ const events = createPubSub();
40
+ setContext("FloatingTreeContext", {
41
+ get nodesRef() {
42
+ return nodesRef;
43
+ },
44
+ addNode,
45
+ removeNode,
46
+ events
47
+ });
92
48
  </script>
93
49
 
94
50
  {#if children}{@render children()}{/if}