@pzerelles/headlessui-svelte 2.1.2-next.4 → 2.1.2-next.40
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.
- package/dist/button/Button.svelte +15 -18
- package/dist/button/Button.svelte.d.ts +8 -36
- package/dist/button/index.d.ts +1 -1
- package/dist/button/index.js +1 -1
- package/dist/checkbox/Checkbox.svelte +30 -26
- package/dist/checkbox/Checkbox.svelte.d.ts +17 -38
- package/dist/checkbox/index.d.ts +1 -1
- package/dist/checkbox/index.js +1 -1
- package/dist/close-button/CloseButton.svelte +4 -7
- package/dist/close-button/CloseButton.svelte.d.ts +3 -46
- package/dist/close-button/index.d.ts +1 -0
- package/dist/close-button/index.js +1 -0
- package/dist/data-interactive/DataInteractive.svelte +6 -22
- package/dist/data-interactive/DataInteractive.svelte.d.ts +9 -34
- package/dist/data-interactive/index.d.ts +1 -1
- package/dist/data-interactive/index.js +1 -1
- package/dist/description/Description.svelte +28 -23
- package/dist/description/Description.svelte.d.ts +9 -30
- package/dist/description/context.svelte.js +14 -16
- package/dist/description/index.d.ts +1 -1
- package/dist/dialog/Dialog.svelte +315 -31
- package/dist/dialog/Dialog.svelte.d.ts +7 -45
- package/dist/dialog/DialogBackdrop.svelte +11 -14
- package/dist/dialog/DialogBackdrop.svelte.d.ts +8 -33
- package/dist/dialog/DialogPanel.svelte +23 -19
- package/dist/dialog/DialogPanel.svelte.d.ts +8 -34
- package/dist/dialog/DialogTitle.svelte +17 -8
- package/dist/dialog/DialogTitle.svelte.d.ts +9 -30
- package/dist/dialog/context.svelte.js +2 -2
- package/dist/dialog/index.d.ts +4 -4
- package/dist/dialog/index.js +4 -4
- package/dist/field/Field.svelte +27 -26
- package/dist/field/Field.svelte.d.ts +7 -34
- package/dist/field/index.d.ts +1 -1
- package/dist/fieldset/Fieldset.svelte +14 -20
- package/dist/fieldset/Fieldset.svelte.d.ts +8 -35
- package/dist/fieldset/index.d.ts +1 -1
- package/dist/focus-trap/FocusTrap.svelte +30 -54
- package/dist/focus-trap/FocusTrap.svelte.d.ts +10 -52
- package/dist/focus-trap/FocusTrapFeatures.d.ts +14 -0
- package/dist/focus-trap/FocusTrapFeatures.js +15 -0
- package/dist/hooks/use-controllable.svelte.js +2 -1
- package/dist/hooks/use-did-element-move.svelte.js +5 -10
- package/dist/hooks/use-disabled.d.ts +6 -1
- package/dist/hooks/use-disabled.js +10 -5
- package/dist/hooks/use-event-listener.svelte.d.ts +1 -1
- package/dist/hooks/use-event-listener.svelte.js +3 -1
- package/dist/hooks/use-inert-others.svelte.js +10 -10
- package/dist/hooks/use-resolve-button-type.svelte.js +0 -1
- package/dist/hooks/use-root-containers.svelte.d.ts +2 -2
- package/dist/hooks/use-root-containers.svelte.js +5 -5
- package/dist/hooks/use-tab-direction.svelte.js +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +5 -2
- package/dist/input/Input.svelte +28 -21
- package/dist/input/Input.svelte.d.ts +16 -33
- package/dist/input/index.d.ts +1 -1
- package/dist/input/index.js +1 -1
- package/dist/internal/FloatingProvider.svelte +17 -0
- package/dist/internal/FloatingProvider.svelte.d.ts +8 -0
- package/dist/internal/FocusSentinel.svelte +33 -32
- package/dist/internal/FocusSentinel.svelte.d.ts +4 -18
- package/dist/internal/ForcePortalRoot.svelte.d.ts +4 -18
- package/dist/internal/FormFields.svelte +18 -13
- package/dist/internal/FormFields.svelte.d.ts +4 -18
- package/dist/internal/FormFieldsProvider.svelte +17 -0
- package/dist/internal/FormFieldsProvider.svelte.d.ts +7 -0
- package/dist/internal/FormResolver.svelte +6 -2
- package/dist/internal/FormResolver.svelte.d.ts +4 -18
- package/dist/internal/Hidden.svelte +10 -10
- package/dist/internal/Hidden.svelte.d.ts +6 -33
- package/dist/internal/MainTreeProvider.svelte +1 -1
- package/dist/internal/MainTreeProvider.svelte.d.ts +4 -18
- package/dist/internal/Portal.svelte.d.ts +4 -18
- package/dist/internal/floating-provider.svelte.d.ts +3 -0
- package/dist/internal/floating-provider.svelte.js +206 -0
- package/dist/internal/floating.svelte.d.ts +46 -22
- package/dist/internal/floating.svelte.js +90 -272
- package/dist/internal/form-fields.svelte.d.ts +10 -0
- package/dist/internal/form-fields.svelte.js +23 -0
- package/dist/label/Label.svelte +17 -13
- package/dist/label/Label.svelte.d.ts +8 -33
- package/dist/label/context.svelte.js +1 -1
- package/dist/label/index.d.ts +1 -1
- package/dist/legend/Legend.svelte +21 -15
- package/dist/legend/Legend.svelte.d.ts +9 -34
- package/dist/listbox/Listbox.svelte +79 -163
- package/dist/listbox/Listbox.svelte.d.ts +16 -101
- package/dist/listbox/ListboxButton.svelte +24 -29
- package/dist/listbox/ListboxButton.svelte.d.ts +8 -38
- package/dist/listbox/ListboxOption.svelte +33 -27
- package/dist/listbox/ListboxOption.svelte.d.ts +16 -32
- package/dist/listbox/ListboxOptions.svelte +126 -73
- package/dist/listbox/ListboxOptions.svelte.d.ts +8 -43
- package/dist/listbox/ListboxSelectedOption.svelte +24 -26
- package/dist/listbox/ListboxSelectedOption.svelte.d.ts +14 -39
- package/dist/listbox/context.svelte.d.ts +76 -0
- package/dist/listbox/context.svelte.js +36 -0
- package/dist/listbox/index.d.ts +5 -5
- package/dist/listbox/index.js +4 -4
- package/dist/menu/Menu.svelte +22 -266
- package/dist/menu/Menu.svelte.d.ts +7 -37
- package/dist/menu/MenuButton.svelte +22 -24
- package/dist/menu/MenuButton.svelte.d.ts +8 -39
- package/dist/menu/MenuHeading.svelte +12 -16
- package/dist/menu/MenuHeading.svelte.d.ts +7 -36
- package/dist/menu/MenuItem.svelte +18 -23
- package/dist/menu/MenuItem.svelte.d.ts +9 -39
- package/dist/menu/MenuItems.svelte +33 -34
- package/dist/menu/MenuItems.svelte.d.ts +8 -43
- package/dist/menu/MenuSection.svelte +9 -12
- package/dist/menu/MenuSection.svelte.d.ts +7 -33
- package/dist/menu/MenuSeparator.svelte +9 -12
- package/dist/menu/MenuSeparator.svelte.d.ts +7 -33
- package/dist/menu/context.svelte.d.ts +2 -1
- package/dist/menu/context.svelte.js +212 -2
- package/dist/menu/index.d.ts +7 -7
- package/dist/menu/index.js +3 -3
- package/dist/popover/Popover.svelte +225 -0
- package/dist/popover/Popover.svelte.d.ts +15 -0
- package/dist/popover/PopoverBackdrop.svelte +83 -0
- package/dist/popover/PopoverBackdrop.svelte.d.ts +17 -0
- package/dist/popover/PopoverButton.svelte +324 -0
- package/dist/popover/PopoverButton.svelte.d.ts +21 -0
- package/dist/popover/PopoverGroup.svelte +66 -0
- package/dist/popover/PopoverGroup.svelte.d.ts +9 -0
- package/dist/popover/PopoverPanel.svelte +359 -0
- package/dist/popover/PopoverPanel.svelte.d.ts +22 -0
- package/dist/popover/context.svelte.d.ts +51 -0
- package/dist/popover/context.svelte.js +108 -0
- package/dist/popover/index.d.ts +5 -0
- package/dist/popover/index.js +5 -0
- package/dist/portal/InternalPortal.svelte +17 -17
- package/dist/portal/InternalPortal.svelte.d.ts +6 -33
- package/dist/portal/Portal.svelte +7 -6
- package/dist/portal/Portal.svelte.d.ts +3 -22
- package/dist/portal/PortalGroup.svelte +6 -14
- package/dist/portal/PortalGroup.svelte.d.ts +5 -34
- package/dist/radio-group/Radio.svelte +135 -0
- package/dist/radio-group/Radio.svelte.d.ts +35 -0
- package/dist/radio-group/RadioGroup.svelte +223 -0
- package/dist/radio-group/RadioGroup.svelte.d.ts +34 -0
- package/dist/radio-group/RadioOption.svelte +138 -0
- package/dist/radio-group/RadioOption.svelte.d.ts +37 -0
- package/dist/radio-group/contest.svelte.d.ts +30 -0
- package/dist/radio-group/contest.svelte.js +40 -0
- package/dist/radio-group/index.d.ts +3 -0
- package/dist/radio-group/index.js +3 -0
- package/dist/select/Select.svelte +103 -0
- package/dist/select/Select.svelte.d.ts +21 -0
- package/dist/select/index.d.ts +1 -0
- package/dist/select/index.js +1 -0
- package/dist/switch/Switch.svelte +27 -28
- package/dist/switch/Switch.svelte.d.ts +9 -42
- package/dist/switch/SwitchGroup.svelte +5 -5
- package/dist/switch/SwitchGroup.svelte.d.ts +8 -30
- package/dist/switch/index.d.ts +1 -1
- package/dist/switch/index.js +1 -1
- package/dist/tabs/Tab.svelte +26 -29
- package/dist/tabs/Tab.svelte.d.ts +8 -36
- package/dist/tabs/TabGroup.svelte +42 -264
- package/dist/tabs/TabGroup.svelte.d.ts +7 -57
- package/dist/tabs/TabList.svelte +13 -16
- package/dist/tabs/TabList.svelte.d.ts +8 -31
- package/dist/tabs/TabPanel.svelte +19 -19
- package/dist/tabs/TabPanel.svelte.d.ts +8 -38
- package/dist/tabs/TabPanels.svelte +11 -9
- package/dist/tabs/TabPanels.svelte.d.ts +8 -30
- package/dist/tabs/context.svelte.d.ts +31 -0
- package/dist/tabs/context.svelte.js +134 -0
- package/dist/tabs/index.d.ts +5 -5
- package/dist/tabs/index.js +4 -4
- package/dist/textarea/Textarea.svelte +23 -19
- package/dist/textarea/Textarea.svelte.d.ts +18 -30
- package/dist/textarea/index.d.ts +1 -1
- package/dist/textarea/index.js +1 -1
- package/dist/transition/InternalTransitionChild.svelte +19 -12
- package/dist/transition/InternalTransitionChild.svelte.d.ts +4 -35
- package/dist/transition/Transition.svelte +16 -17
- package/dist/transition/Transition.svelte.d.ts +8 -38
- package/dist/transition/TransitionChild.svelte +13 -12
- package/dist/transition/TransitionChild.svelte.d.ts +11 -38
- package/dist/transition/context.svelte.js +9 -9
- package/dist/transition/index.d.ts +2 -2
- package/dist/transition/index.js +2 -2
- package/dist/utils/DisabledProvider.svelte +10 -0
- package/dist/utils/DisabledProvider.svelte.d.ts +8 -0
- package/dist/utils/ElementOrComponent.svelte +57 -14
- package/dist/utils/ElementOrComponent.svelte.d.ts +19 -29
- package/dist/utils/StableCollection.svelte.d.ts +4 -18
- package/dist/utils/floating-ui/svelte/components/FloatingNode.svelte +32 -0
- package/dist/utils/floating-ui/svelte/components/FloatingNode.svelte.d.ts +8 -0
- package/dist/utils/floating-ui/svelte/components/FloatingTree.svelte +94 -0
- package/dist/utils/floating-ui/svelte/components/FloatingTree.svelte.d.ts +26 -0
- package/dist/utils/floating-ui/svelte/hooks/useFloating.svelte.d.ts +6 -0
- package/dist/utils/floating-ui/svelte/hooks/useFloating.svelte.js +158 -0
- package/dist/utils/floating-ui/svelte/hooks/useFloatingRootContext.svelte.d.ts +11 -0
- package/dist/utils/floating-ui/svelte/hooks/useFloatingRootContext.svelte.js +53 -0
- package/dist/utils/floating-ui/svelte/hooks/useId.svelte.d.ts +9 -0
- package/dist/utils/floating-ui/svelte/hooks/useId.svelte.js +28 -0
- package/dist/utils/floating-ui/svelte/hooks/useInteractions.svelte.d.ts +23 -0
- package/dist/utils/floating-ui/svelte/hooks/useInteractions.svelte.js +72 -0
- package/dist/utils/floating-ui/svelte/index.d.ts +5 -0
- package/dist/utils/floating-ui/svelte/index.js +5 -0
- package/dist/utils/floating-ui/svelte/inner.svelte.d.ts +83 -0
- package/dist/utils/floating-ui/svelte/inner.svelte.js +178 -0
- package/dist/utils/floating-ui/svelte/types.d.ts +114 -0
- package/dist/utils/floating-ui/svelte/utils/createPubSub.d.ts +5 -0
- package/dist/utils/floating-ui/svelte/utils/createPubSub.js +14 -0
- package/dist/utils/floating-ui/svelte/utils/getFloatingFocusElement.d.ts +2 -0
- package/dist/utils/floating-ui/svelte/utils/getFloatingFocusElement.js +13 -0
- package/dist/utils/floating-ui/svelte/utils/log.d.ts +2 -0
- package/dist/utils/floating-ui/svelte/utils/log.js +19 -0
- package/dist/utils/floating-ui/svelte/utils.d.ts +19 -0
- package/dist/utils/floating-ui/svelte/utils.js +136 -0
- package/dist/utils/floating-ui/svelte-dom/arrow.d.ts +22 -0
- package/dist/utils/floating-ui/svelte-dom/arrow.js +29 -0
- package/dist/utils/floating-ui/svelte-dom/index.d.ts +2 -0
- package/dist/utils/floating-ui/svelte-dom/index.js +2 -0
- package/dist/utils/floating-ui/svelte-dom/types.d.ts +80 -0
- package/dist/utils/floating-ui/svelte-dom/types.js +3 -0
- package/dist/utils/floating-ui/svelte-dom/useFloating.svelte.d.ts +6 -0
- package/dist/utils/floating-ui/svelte-dom/useFloating.svelte.js +182 -0
- package/dist/utils/floating-ui/svelte-dom/utils/deepEqual.d.ts +1 -0
- package/dist/utils/floating-ui/svelte-dom/utils/deepEqual.js +50 -0
- package/dist/utils/floating-ui/svelte-dom/utils/getDPR.d.ts +1 -0
- package/dist/utils/floating-ui/svelte-dom/utils/getDPR.js +7 -0
- package/dist/utils/floating-ui/svelte-dom/utils/roundByDPR.d.ts +1 -0
- package/dist/utils/floating-ui/svelte-dom/utils/roundByDPR.js +5 -0
- package/dist/utils/floating-ui/svelte-dom/utils/useLatestRef.d.ts +4 -0
- package/dist/utils/floating-ui/svelte-dom/utils/useLatestRef.js +7 -0
- package/dist/utils/id.d.ts +1 -1
- package/dist/utils/id.js +1 -1
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/state.js +4 -4
- package/dist/utils/style.d.ts +2 -0
- package/dist/utils/style.js +6 -0
- package/dist/utils/types.d.ts +12 -18
- package/package.json +33 -32
- package/dist/combobox/Combobox.svelte +0 -53
- package/dist/combobox/Combobox.svelte.d.ts +0 -50
- package/dist/dialog/InternalDialog.svelte +0 -294
- package/dist/dialog/InternalDialog.svelte.d.ts +0 -42
- package/dist/internal/HoistFormFields.svelte +0 -14
- package/dist/internal/HoistFormFields.svelte.d.ts +0 -21
- package/dist/internal/id.d.ts +0 -8
- package/dist/internal/id.js +0 -11
- package/dist/utils/Generic.svelte +0 -56
- package/dist/utils/Generic.svelte.d.ts +0 -35
- package/dist/utils/alternative-types.d.ts +0 -21
- /package/dist/utils/{alternative-types.js → floating-ui/svelte/types.js} +0 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { Props } from "../utils/types.js"
|
|
3
|
+
import { RenderFeatures } from "../utils/render.js"
|
|
4
|
+
|
|
5
|
+
const DEFAULT_PANEL_TAG = "div" as const
|
|
6
|
+
export type PanelRenderPropArg = {
|
|
7
|
+
open: boolean
|
|
8
|
+
close: (focusableElement?: HTMLElement) => void
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const PanelRenderFeatures = RenderFeatures.RenderStrategy | RenderFeatures.Static
|
|
12
|
+
|
|
13
|
+
type PanelPropsWeControl = "tabIndex"
|
|
14
|
+
|
|
15
|
+
export type PopoverPanelOwnProps = {
|
|
16
|
+
element?: HTMLElement
|
|
17
|
+
id?: string
|
|
18
|
+
focus?: boolean
|
|
19
|
+
anchor?: AnchorProps
|
|
20
|
+
portal?: boolean
|
|
21
|
+
modal?: boolean
|
|
22
|
+
transition?: boolean
|
|
23
|
+
|
|
24
|
+
// ItemsRenderFeatures
|
|
25
|
+
static?: boolean
|
|
26
|
+
unmount?: boolean
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type PopoverPanelProps = Props<typeof DEFAULT_PANEL_TAG, PanelRenderPropArg, PopoverPanelOwnProps>
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<script lang="ts">
|
|
33
|
+
import { useId } from "../hooks/use-id.js"
|
|
34
|
+
import ElementOrComponent from "../utils/ElementOrComponent.svelte"
|
|
35
|
+
import { mergeProps } from "../utils/render.js"
|
|
36
|
+
import {
|
|
37
|
+
useFloatingPanel,
|
|
38
|
+
useFloatingPanelProps,
|
|
39
|
+
useResolvedAnchor,
|
|
40
|
+
type AnchorProps,
|
|
41
|
+
} from "../internal/floating.svelte.js"
|
|
42
|
+
import {
|
|
43
|
+
type PopoverAPIContext,
|
|
44
|
+
type PopoverPanelContext,
|
|
45
|
+
PopoverStates,
|
|
46
|
+
usePopoverAPIContext,
|
|
47
|
+
usePopoverContext,
|
|
48
|
+
} from "./context.svelte.js"
|
|
49
|
+
import { getOwnerDocument } from "../utils/owner.js"
|
|
50
|
+
import { clearOpenClosedContext, State, useOpenClosed } from "../internal/open-closed.js"
|
|
51
|
+
import { transitionDataAttributes, useTransition } from "../hooks/use-transition.svelte.js"
|
|
52
|
+
import { useOnDisappear } from "../hooks/use-on-disappear.svelte.js"
|
|
53
|
+
import { useScrollLock } from "../hooks/use-scroll-lock.svelte.js"
|
|
54
|
+
import { Focus, focusIn, FocusResult, getFocusableElements } from "../utils/focus-management.js"
|
|
55
|
+
import { useElementSize } from "../hooks/use-element-size.svelte.js"
|
|
56
|
+
import { useTabDirection, Direction as TabDirection } from "../hooks/use-tab-direction.svelte.js"
|
|
57
|
+
import { match } from "../utils/match.js"
|
|
58
|
+
import { microTask } from "../utils/microTask.js"
|
|
59
|
+
import { setContext, untrack } from "svelte"
|
|
60
|
+
import Portal from "../portal/Portal.svelte"
|
|
61
|
+
import Hidden, { HiddenFeatures } from "../internal/Hidden.svelte"
|
|
62
|
+
|
|
63
|
+
let internalId = useId()
|
|
64
|
+
let {
|
|
65
|
+
element = $bindable(),
|
|
66
|
+
id = `headlessui-popover-panel-${internalId}`,
|
|
67
|
+
focus = false,
|
|
68
|
+
anchor: rawAnchor,
|
|
69
|
+
portal: theirPortal = false,
|
|
70
|
+
modal = false,
|
|
71
|
+
transition = false,
|
|
72
|
+
...theirProps
|
|
73
|
+
}: PopoverPanelProps = $props()
|
|
74
|
+
|
|
75
|
+
const context = usePopoverContext("PopoverPanel")
|
|
76
|
+
const api = usePopoverAPIContext("PopoverPanel")
|
|
77
|
+
const { close, isPortalled } = $derived(api)
|
|
78
|
+
|
|
79
|
+
const beforePanelSentinelId = `headlessui-focus-sentinel-before-${internalId}`
|
|
80
|
+
const afterPanelSentinelId = `headlessui-focus-sentinel-after-${internalId}`
|
|
81
|
+
|
|
82
|
+
const resolvedAnchor = useResolvedAnchor({
|
|
83
|
+
get anchor() {
|
|
84
|
+
return rawAnchor
|
|
85
|
+
},
|
|
86
|
+
})
|
|
87
|
+
const { anchor } = $derived(resolvedAnchor)
|
|
88
|
+
const floatingPanel = useFloatingPanel({
|
|
89
|
+
get placement() {
|
|
90
|
+
return anchor
|
|
91
|
+
},
|
|
92
|
+
})
|
|
93
|
+
const { setFloating, styles } = $derived(floatingPanel)
|
|
94
|
+
const getFloatingPanelProps = useFloatingPanelProps()
|
|
95
|
+
|
|
96
|
+
// Always enable `portal` functionality, when `anchor` is enabled
|
|
97
|
+
const portal = $derived(!!anchor || theirPortal)
|
|
98
|
+
|
|
99
|
+
$effect(() => {
|
|
100
|
+
if (anchor) setFloating(element ?? null)
|
|
101
|
+
untrack(() => context.setPanel(element))
|
|
102
|
+
})
|
|
103
|
+
const ownerDocument = $derived(getOwnerDocument(element))
|
|
104
|
+
|
|
105
|
+
$effect(() => {
|
|
106
|
+
id
|
|
107
|
+
return untrack(() => {
|
|
108
|
+
context.setPanelId(id)
|
|
109
|
+
return () => {
|
|
110
|
+
context.setPanelId(undefined)
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
const usesOpenClosedState = useOpenClosed()
|
|
116
|
+
const _transition = useTransition({
|
|
117
|
+
get enabled() {
|
|
118
|
+
return transition
|
|
119
|
+
},
|
|
120
|
+
get element() {
|
|
121
|
+
return element
|
|
122
|
+
},
|
|
123
|
+
get show() {
|
|
124
|
+
return usesOpenClosedState !== null
|
|
125
|
+
? (usesOpenClosedState.value & State.Open) === State.Open
|
|
126
|
+
: context.popoverState === PopoverStates.Open
|
|
127
|
+
},
|
|
128
|
+
})
|
|
129
|
+
const { visible, data: transitionData } = $derived(_transition)
|
|
130
|
+
|
|
131
|
+
// Ensure we close the popover as soon as the button becomes hidden
|
|
132
|
+
useOnDisappear({
|
|
133
|
+
get enabled() {
|
|
134
|
+
return visible
|
|
135
|
+
},
|
|
136
|
+
get ref() {
|
|
137
|
+
return context.button
|
|
138
|
+
},
|
|
139
|
+
ondisappear: () => {
|
|
140
|
+
context.closePopover()
|
|
141
|
+
},
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
// Enable scroll locking when the popover is visible, and `modal` is enabled
|
|
145
|
+
const scrollLockEnabled = $derived(context.__demoMode ? false : modal && visible)
|
|
146
|
+
useScrollLock({
|
|
147
|
+
get enabled() {
|
|
148
|
+
return scrollLockEnabled
|
|
149
|
+
},
|
|
150
|
+
get ownerDocument() {
|
|
151
|
+
return ownerDocument
|
|
152
|
+
},
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
const handleKeyDown = (event: KeyboardEvent) => {
|
|
156
|
+
switch (event.key) {
|
|
157
|
+
case "Escape":
|
|
158
|
+
if (context.popoverState !== PopoverStates.Open) return
|
|
159
|
+
if (!element) return
|
|
160
|
+
if (ownerDocument?.activeElement && !element.contains(ownerDocument.activeElement)) {
|
|
161
|
+
return
|
|
162
|
+
}
|
|
163
|
+
event.preventDefault()
|
|
164
|
+
event.stopPropagation()
|
|
165
|
+
context.closePopover()
|
|
166
|
+
context.button?.focus()
|
|
167
|
+
break
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Unlink on "unmount" children
|
|
172
|
+
$effect(() => {
|
|
173
|
+
if (theirProps.static) return
|
|
174
|
+
|
|
175
|
+
if (context.popoverState === PopoverStates.Closed && (theirProps.unmount ?? true)) {
|
|
176
|
+
context.setPanel(undefined)
|
|
177
|
+
}
|
|
178
|
+
}) //, [state.popoverState, props.unmount, props.static, dispatch])
|
|
179
|
+
|
|
180
|
+
// Move focus within panel
|
|
181
|
+
$effect(() => {
|
|
182
|
+
if (context.__demoMode) return
|
|
183
|
+
if (!focus) return
|
|
184
|
+
if (context.popoverState !== PopoverStates.Open) return
|
|
185
|
+
if (!element) return
|
|
186
|
+
|
|
187
|
+
const activeElement = ownerDocument?.activeElement as HTMLElement
|
|
188
|
+
if (element.contains(activeElement)) return // Already focused within Dialog
|
|
189
|
+
|
|
190
|
+
focusIn(element, Focus.First)
|
|
191
|
+
}) //, [state.__demoMode, focus, internalPanelRef.current, state.popoverState])
|
|
192
|
+
|
|
193
|
+
const slot = $derived({
|
|
194
|
+
open: context.popoverState === PopoverStates.Open,
|
|
195
|
+
close,
|
|
196
|
+
} satisfies PanelRenderPropArg)
|
|
197
|
+
|
|
198
|
+
const buttonSize = useElementSize({
|
|
199
|
+
get element() {
|
|
200
|
+
return context.button ?? null
|
|
201
|
+
},
|
|
202
|
+
unit: true,
|
|
203
|
+
})
|
|
204
|
+
const ourProps: Record<string, any> = $derived(
|
|
205
|
+
mergeProps(anchor ? getFloatingPanelProps() : {}, {
|
|
206
|
+
id,
|
|
207
|
+
onkeydown: handleKeyDown,
|
|
208
|
+
onblur:
|
|
209
|
+
focus && context.popoverState === PopoverStates.Open
|
|
210
|
+
? (event: FocusEvent) => {
|
|
211
|
+
let el = event.relatedTarget as HTMLElement
|
|
212
|
+
if (!el) return
|
|
213
|
+
if (!element) return
|
|
214
|
+
if (element.contains(el)) return
|
|
215
|
+
|
|
216
|
+
context.closePopover()
|
|
217
|
+
|
|
218
|
+
if (context.beforePanelSentinel?.contains?.(el) || context.afterPanelSentinel?.contains?.(el)) {
|
|
219
|
+
el.focus({ preventScroll: true })
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
: undefined,
|
|
223
|
+
tabIndex: -1,
|
|
224
|
+
style: [theirProps.style, styles, `--button-width: ${buttonSize.width}`].filter(Boolean).join("; "),
|
|
225
|
+
...transitionDataAttributes(transitionData),
|
|
226
|
+
})
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
const direction = useTabDirection()
|
|
230
|
+
const handleBeforeFocus = () => {
|
|
231
|
+
let el = element as HTMLElement
|
|
232
|
+
if (!el) return
|
|
233
|
+
|
|
234
|
+
function run() {
|
|
235
|
+
match(direction.current, {
|
|
236
|
+
[TabDirection.Forwards]: () => {
|
|
237
|
+
// Try to focus the first thing in the panel. But if that fails (e.g.: there are no
|
|
238
|
+
// focusable elements, then we can move outside of the panel)
|
|
239
|
+
let result = focusIn(el, Focus.First)
|
|
240
|
+
if (result === FocusResult.Error) {
|
|
241
|
+
context.afterPanelSentinel?.focus()
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
[TabDirection.Backwards]: () => {
|
|
245
|
+
// Coming from the PopoverPanel (which is portalled to somewhere else). Let's redirect
|
|
246
|
+
// the focus to the PopoverButton again.
|
|
247
|
+
context.button?.focus({ preventScroll: true })
|
|
248
|
+
},
|
|
249
|
+
})
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// TODO: Cleanup once we are using real browser tests
|
|
253
|
+
if (process.env.NODE_ENV === "test") {
|
|
254
|
+
microTask(run)
|
|
255
|
+
} else {
|
|
256
|
+
run()
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const handleAfterFocus = () => {
|
|
261
|
+
let el = element as HTMLElement
|
|
262
|
+
if (!el) return
|
|
263
|
+
|
|
264
|
+
function run() {
|
|
265
|
+
match(direction.current, {
|
|
266
|
+
[TabDirection.Forwards]: () => {
|
|
267
|
+
if (!context.button) return
|
|
268
|
+
|
|
269
|
+
const elements = getFocusableElements()
|
|
270
|
+
|
|
271
|
+
const idx = elements.indexOf(context.button)
|
|
272
|
+
const before = elements.slice(0, idx + 1)
|
|
273
|
+
const after = elements.slice(idx + 1)
|
|
274
|
+
|
|
275
|
+
const combined = [...after, ...before]
|
|
276
|
+
|
|
277
|
+
// Ignore sentinel buttons and items inside the panel
|
|
278
|
+
for (const element of combined.slice()) {
|
|
279
|
+
if (element.dataset.headlessuiFocusGuard === "true" || element?.contains(element)) {
|
|
280
|
+
let idx = combined.indexOf(element)
|
|
281
|
+
if (idx !== -1) combined.splice(idx, 1)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
focusIn(combined, Focus.First, { sorted: false })
|
|
286
|
+
},
|
|
287
|
+
[TabDirection.Backwards]: () => {
|
|
288
|
+
// Try to focus the first thing in the panel. But if that fails (e.g.: there are no
|
|
289
|
+
// focusable elements, then we can move outside of the panel)
|
|
290
|
+
let result = focusIn(el, Focus.Previous)
|
|
291
|
+
if (result === FocusResult.Error) {
|
|
292
|
+
context.button?.focus()
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
})
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// TODO: Cleanup once we are using real browser tests
|
|
299
|
+
if (process.env.NODE_ENV === "test") {
|
|
300
|
+
microTask(run)
|
|
301
|
+
} else {
|
|
302
|
+
run()
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
clearOpenClosedContext()
|
|
307
|
+
setContext<PopoverPanelContext>("PopoverPanelContext", {
|
|
308
|
+
get value() {
|
|
309
|
+
return id
|
|
310
|
+
},
|
|
311
|
+
})
|
|
312
|
+
setContext<PopoverAPIContext>("PopoverAPIContext", {
|
|
313
|
+
get close() {
|
|
314
|
+
return close
|
|
315
|
+
},
|
|
316
|
+
get isPortalled() {
|
|
317
|
+
return isPortalled
|
|
318
|
+
},
|
|
319
|
+
})
|
|
320
|
+
</script>
|
|
321
|
+
|
|
322
|
+
<Portal enabled={portal ? theirProps.static || visible : false}>
|
|
323
|
+
{#if visible && isPortalled}
|
|
324
|
+
<Hidden asChild id={beforePanelSentinelId} features={HiddenFeatures.Focusable}>
|
|
325
|
+
{#snippet children({ props })}
|
|
326
|
+
<button
|
|
327
|
+
{...props}
|
|
328
|
+
type="button"
|
|
329
|
+
data-headlessui-focus-guard
|
|
330
|
+
onfocus={handleBeforeFocus}
|
|
331
|
+
bind:this={context.beforePanelSentinel}>‌</button
|
|
332
|
+
>
|
|
333
|
+
{/snippet}
|
|
334
|
+
</Hidden>
|
|
335
|
+
{/if}
|
|
336
|
+
<ElementOrComponent
|
|
337
|
+
{ourProps}
|
|
338
|
+
{theirProps}
|
|
339
|
+
slots={slot}
|
|
340
|
+
defaultTag={DEFAULT_PANEL_TAG}
|
|
341
|
+
features={PanelRenderFeatures}
|
|
342
|
+
{visible}
|
|
343
|
+
name="PopoverPanel"
|
|
344
|
+
bind:element
|
|
345
|
+
/>
|
|
346
|
+
{#if visible && isPortalled}
|
|
347
|
+
<Hidden asChild id={afterPanelSentinelId} features={HiddenFeatures.Focusable}>
|
|
348
|
+
{#snippet children({ props })}
|
|
349
|
+
<button
|
|
350
|
+
{...props}
|
|
351
|
+
type="button"
|
|
352
|
+
data-headlessui-focus-guard
|
|
353
|
+
onfocus={handleAfterFocus}
|
|
354
|
+
bind:this={context.afterPanelSentinel}>‌</button
|
|
355
|
+
>
|
|
356
|
+
{/snippet}
|
|
357
|
+
</Hidden>
|
|
358
|
+
{/if}
|
|
359
|
+
</Portal>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Props } from "../utils/types.js";
|
|
2
|
+
declare const DEFAULT_PANEL_TAG: "div";
|
|
3
|
+
export type PanelRenderPropArg = {
|
|
4
|
+
open: boolean;
|
|
5
|
+
close: (focusableElement?: HTMLElement) => void;
|
|
6
|
+
};
|
|
7
|
+
export type PopoverPanelOwnProps = {
|
|
8
|
+
element?: HTMLElement;
|
|
9
|
+
id?: string;
|
|
10
|
+
focus?: boolean;
|
|
11
|
+
anchor?: AnchorProps;
|
|
12
|
+
portal?: boolean;
|
|
13
|
+
modal?: boolean;
|
|
14
|
+
transition?: boolean;
|
|
15
|
+
static?: boolean;
|
|
16
|
+
unmount?: boolean;
|
|
17
|
+
};
|
|
18
|
+
export type PopoverPanelProps = Props<typeof DEFAULT_PANEL_TAG, PanelRenderPropArg, PopoverPanelOwnProps>;
|
|
19
|
+
import { type AnchorProps } from "../internal/floating.svelte.js";
|
|
20
|
+
declare const PopoverPanel: import("svelte").Component<PopoverPanelProps, {}, "element">;
|
|
21
|
+
type PopoverPanel = ReturnType<typeof PopoverPanel>;
|
|
22
|
+
export default PopoverPanel;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { MouseEventHandler } from "svelte/elements";
|
|
2
|
+
export type MouseEvent<T extends EventTarget> = Parameters<MouseEventHandler<T>>[0];
|
|
3
|
+
export declare enum PopoverStates {
|
|
4
|
+
Open = 0,
|
|
5
|
+
Closed = 1
|
|
6
|
+
}
|
|
7
|
+
export interface StateDefinition {
|
|
8
|
+
popoverState: PopoverStates;
|
|
9
|
+
buttons: symbol[];
|
|
10
|
+
button?: HTMLElement;
|
|
11
|
+
buttonId?: string;
|
|
12
|
+
panel?: HTMLElement;
|
|
13
|
+
panelId?: string;
|
|
14
|
+
beforePanelSentinel?: HTMLButtonElement;
|
|
15
|
+
afterPanelSentinel?: HTMLButtonElement;
|
|
16
|
+
afterButtonSentinel?: HTMLButtonElement;
|
|
17
|
+
__demoMode: boolean;
|
|
18
|
+
}
|
|
19
|
+
interface ActionDefinition {
|
|
20
|
+
togglePopover(): void;
|
|
21
|
+
closePopover(): void;
|
|
22
|
+
setButton(button: HTMLElement): void;
|
|
23
|
+
setButtonId(buttonId: string | undefined): void;
|
|
24
|
+
setPanel(panel?: HTMLElement): void;
|
|
25
|
+
setPanelId(panelId?: string): void;
|
|
26
|
+
}
|
|
27
|
+
export type PopoverContext = StateDefinition & ActionDefinition;
|
|
28
|
+
export declare const createPopoverContext: (initialState: StateDefinition) => PopoverContext;
|
|
29
|
+
export declare function usePopoverContext(component: string): PopoverContext;
|
|
30
|
+
export type PopoverAPIContext = {
|
|
31
|
+
close(focusableElement?: HTMLElement | MouseEvent<HTMLElement>): void;
|
|
32
|
+
isPortalled: boolean;
|
|
33
|
+
};
|
|
34
|
+
export declare function usePopoverAPIContext(component: string): PopoverAPIContext;
|
|
35
|
+
export type PopoverGroupContext = {
|
|
36
|
+
registerPopover(registerBag: PopoverRegisterBag): void;
|
|
37
|
+
unregisterPopover(registerBag: PopoverRegisterBag): void;
|
|
38
|
+
isFocusWithinPopoverGroup(): boolean;
|
|
39
|
+
closeOthers(buttonId: string): void;
|
|
40
|
+
};
|
|
41
|
+
export declare function usePopoverGroupContext(): PopoverGroupContext | undefined;
|
|
42
|
+
export type PopoverPanelContext = {
|
|
43
|
+
value: string;
|
|
44
|
+
};
|
|
45
|
+
export declare function usePopoverPanelContext(): PopoverPanelContext | undefined;
|
|
46
|
+
export interface PopoverRegisterBag {
|
|
47
|
+
buttonId?: string;
|
|
48
|
+
panelId?: string;
|
|
49
|
+
close(): void;
|
|
50
|
+
}
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { getContext, setContext } from "svelte";
|
|
2
|
+
export var PopoverStates;
|
|
3
|
+
(function (PopoverStates) {
|
|
4
|
+
PopoverStates[PopoverStates["Open"] = 0] = "Open";
|
|
5
|
+
PopoverStates[PopoverStates["Closed"] = 1] = "Closed";
|
|
6
|
+
})(PopoverStates || (PopoverStates = {}));
|
|
7
|
+
export const createPopoverContext = (initialState) => {
|
|
8
|
+
const _state = $state(initialState);
|
|
9
|
+
const context = {
|
|
10
|
+
get popoverState() {
|
|
11
|
+
return _state.popoverState;
|
|
12
|
+
},
|
|
13
|
+
get buttons() {
|
|
14
|
+
return _state.buttons;
|
|
15
|
+
},
|
|
16
|
+
get button() {
|
|
17
|
+
return _state.button;
|
|
18
|
+
},
|
|
19
|
+
get buttonId() {
|
|
20
|
+
return _state.buttonId;
|
|
21
|
+
},
|
|
22
|
+
get panel() {
|
|
23
|
+
return _state.panel;
|
|
24
|
+
},
|
|
25
|
+
get panelId() {
|
|
26
|
+
return _state.panelId;
|
|
27
|
+
},
|
|
28
|
+
get beforePanelSentinel() {
|
|
29
|
+
return _state.beforePanelSentinel;
|
|
30
|
+
},
|
|
31
|
+
set beforePanelSentinel(value) {
|
|
32
|
+
_state.beforePanelSentinel = value;
|
|
33
|
+
},
|
|
34
|
+
get afterPanelSentinel() {
|
|
35
|
+
return _state.afterPanelSentinel;
|
|
36
|
+
},
|
|
37
|
+
set afterPanelSentinel(value) {
|
|
38
|
+
_state.afterPanelSentinel = value;
|
|
39
|
+
},
|
|
40
|
+
get afterButtonSentinel() {
|
|
41
|
+
return _state.afterButtonSentinel;
|
|
42
|
+
},
|
|
43
|
+
set afterButtonSentinel(value) {
|
|
44
|
+
_state.afterButtonSentinel = value;
|
|
45
|
+
},
|
|
46
|
+
get __demoMode() {
|
|
47
|
+
return _state.__demoMode;
|
|
48
|
+
},
|
|
49
|
+
togglePopover() {
|
|
50
|
+
_state.__demoMode = false;
|
|
51
|
+
_state.popoverState = _state.popoverState === PopoverStates.Closed ? PopoverStates.Open : PopoverStates.Closed;
|
|
52
|
+
},
|
|
53
|
+
closePopover() {
|
|
54
|
+
if (_state.popoverState === PopoverStates.Closed)
|
|
55
|
+
return;
|
|
56
|
+
_state.__demoMode = false;
|
|
57
|
+
_state.popoverState = PopoverStates.Closed;
|
|
58
|
+
},
|
|
59
|
+
setButton(button) {
|
|
60
|
+
if (_state.button === button)
|
|
61
|
+
return;
|
|
62
|
+
_state.button = button;
|
|
63
|
+
},
|
|
64
|
+
setButtonId(buttonId) {
|
|
65
|
+
if (_state.buttonId === buttonId)
|
|
66
|
+
return;
|
|
67
|
+
_state.buttonId = buttonId;
|
|
68
|
+
},
|
|
69
|
+
setPanel(panel) {
|
|
70
|
+
if (_state.panel === panel)
|
|
71
|
+
return;
|
|
72
|
+
_state.panel = panel;
|
|
73
|
+
},
|
|
74
|
+
setPanelId(panelId) {
|
|
75
|
+
if (_state.panelId === panelId)
|
|
76
|
+
return;
|
|
77
|
+
_state.panelId = panelId;
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
setContext("PopoverContext", context);
|
|
81
|
+
return context;
|
|
82
|
+
};
|
|
83
|
+
export function usePopoverContext(component) {
|
|
84
|
+
const context = getContext("PopoverContext");
|
|
85
|
+
if (!context) {
|
|
86
|
+
const err = new Error(`<${component} /> is missing a parent <Popover /> component.`);
|
|
87
|
+
if (Error.captureStackTrace)
|
|
88
|
+
Error.captureStackTrace(err, usePopoverContext);
|
|
89
|
+
throw err;
|
|
90
|
+
}
|
|
91
|
+
return context;
|
|
92
|
+
}
|
|
93
|
+
export function usePopoverAPIContext(component) {
|
|
94
|
+
const context = getContext("PopoverAPIContext");
|
|
95
|
+
if (!context) {
|
|
96
|
+
const err = new Error(`<${component} /> is missing a parent <Popover /> component.`);
|
|
97
|
+
if (Error.captureStackTrace)
|
|
98
|
+
Error.captureStackTrace(err, usePopoverAPIContext);
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
return context;
|
|
102
|
+
}
|
|
103
|
+
export function usePopoverGroupContext() {
|
|
104
|
+
return getContext("PopoverGroupContext");
|
|
105
|
+
}
|
|
106
|
+
export function usePopoverPanelContext() {
|
|
107
|
+
return getContext("PopoverPanelContext");
|
|
108
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as Popover, type PopoverProps, type PopoverRenderPropArg as PopoverSlot, type PopoverOwnProps, } from "./Popover.svelte";
|
|
2
|
+
export { default as PopoverBackdrop, type PopoverBackdropProps, type BackdropRenderPropArg as PopoverBackdropSlot, type PopoverBackdropOwnProps, } from "./PopoverBackdrop.svelte";
|
|
3
|
+
export { default as PopoverButton, type PopoverButtonProps, type PopoverButtonSlot, type PopoverButtonOwnProps, } from "./PopoverButton.svelte";
|
|
4
|
+
export { default as PopoverGroup, type PopoverGroupProps, type PopoverGroupOwnProps } from "./PopoverGroup.svelte";
|
|
5
|
+
export { default as PopoverPanel, type PopoverPanelProps, type PanelRenderPropArg as PopoverPanelSlot, type PopoverPanelOwnProps, } from "./PopoverPanel.svelte";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as Popover, } from "./Popover.svelte";
|
|
2
|
+
export { default as PopoverBackdrop, } from "./PopoverBackdrop.svelte";
|
|
3
|
+
export { default as PopoverButton, } from "./PopoverButton.svelte";
|
|
4
|
+
export { default as PopoverGroup } from "./PopoverGroup.svelte";
|
|
5
|
+
export { default as PopoverPanel, } from "./PopoverPanel.svelte";
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { getOwnerDocument } from "../utils/owner.js"
|
|
4
4
|
import { getContext, onMount, setContext } from "svelte"
|
|
5
5
|
import { env } from "../utils/env.js"
|
|
6
|
-
import type {
|
|
6
|
+
import type { Props } from "../utils/types.js"
|
|
7
7
|
import type { PortalGroupContext } from "./PortalGroup.svelte"
|
|
8
8
|
|
|
9
9
|
function usePortalTarget(options: { element: HTMLElement | null }): { readonly target: HTMLElement | null } {
|
|
@@ -93,27 +93,27 @@
|
|
|
93
93
|
// ---
|
|
94
94
|
|
|
95
95
|
export const DEFAULT_PORTAL_TAG = "div"
|
|
96
|
-
type PortalRenderPropArg = {}
|
|
96
|
+
export type PortalRenderPropArg = {}
|
|
97
97
|
type PortalPropsWeControl = never
|
|
98
98
|
|
|
99
|
-
export type PortalProps
|
|
100
|
-
|
|
99
|
+
export type PortalProps = Props<
|
|
100
|
+
typeof DEFAULT_PORTAL_TAG,
|
|
101
101
|
PortalRenderPropArg,
|
|
102
|
-
PortalPropsWeControl,
|
|
103
102
|
{
|
|
103
|
+
element?: HTMLElement
|
|
104
104
|
enabled?: boolean
|
|
105
105
|
}
|
|
106
106
|
>
|
|
107
107
|
</script>
|
|
108
108
|
|
|
109
|
-
<script lang="ts"
|
|
109
|
+
<script lang="ts">
|
|
110
110
|
import ElementOrComponent from "../utils/ElementOrComponent.svelte"
|
|
111
111
|
|
|
112
|
-
let {
|
|
112
|
+
let { element = $bindable(), ...theirProps }: PortalProps = $props()
|
|
113
113
|
|
|
114
114
|
const portalTarget = usePortalTarget({
|
|
115
115
|
get element() {
|
|
116
|
-
return
|
|
116
|
+
return element ?? null
|
|
117
117
|
},
|
|
118
118
|
})
|
|
119
119
|
const { target } = $derived(portalTarget)
|
|
@@ -121,24 +121,24 @@
|
|
|
121
121
|
//const ready = useServerHandoffComplete()
|
|
122
122
|
|
|
123
123
|
$effect(() => {
|
|
124
|
-
if (!target || !
|
|
124
|
+
if (!target || !element) return
|
|
125
125
|
|
|
126
126
|
// Element already exists in target, always calling target.appendChild(element) will cause a
|
|
127
127
|
// brief unmount/remount.
|
|
128
|
-
if (
|
|
129
|
-
|
|
130
|
-
target.appendChild(
|
|
128
|
+
if (element.parentNode !== target) {
|
|
129
|
+
element.setAttribute("data-headlessui-portal", "")
|
|
130
|
+
target.appendChild(element)
|
|
131
131
|
}
|
|
132
132
|
})
|
|
133
133
|
|
|
134
134
|
onMount(() => {
|
|
135
|
-
if (parent) parent.register(
|
|
135
|
+
if (parent) parent.register(element!)
|
|
136
136
|
|
|
137
137
|
return () => {
|
|
138
|
-
if (!target || !
|
|
138
|
+
if (!target || !element) return
|
|
139
139
|
|
|
140
|
-
if (
|
|
141
|
-
target.removeChild(
|
|
140
|
+
if (element instanceof Node && target.contains(element)) {
|
|
141
|
+
target.removeChild(element)
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
if (target.childNodes.length <= 0) {
|
|
@@ -149,5 +149,5 @@
|
|
|
149
149
|
</script>
|
|
150
150
|
|
|
151
151
|
{#if target}
|
|
152
|
-
<ElementOrComponent {theirProps} defaultTag={DEFAULT_PORTAL_TAG} name="InternalPortal" bind:
|
|
152
|
+
<ElementOrComponent {theirProps} defaultTag={DEFAULT_PORTAL_TAG} name="InternalPortal" bind:element />
|
|
153
153
|
{/if}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Props } from "../utils/types.js";
|
|
2
2
|
type PortalParentContext = {
|
|
3
3
|
register: (portal: HTMLElement) => () => void;
|
|
4
4
|
unregister: (portal: HTMLElement) => void;
|
|
@@ -6,38 +6,11 @@ type PortalParentContext = {
|
|
|
6
6
|
};
|
|
7
7
|
export declare function useNestedPortals(): PortalParentContext;
|
|
8
8
|
export declare const DEFAULT_PORTAL_TAG = "div";
|
|
9
|
-
type PortalRenderPropArg = {};
|
|
10
|
-
type
|
|
11
|
-
|
|
9
|
+
export type PortalRenderPropArg = {};
|
|
10
|
+
export type PortalProps = Props<typeof DEFAULT_PORTAL_TAG, PortalRenderPropArg, {
|
|
11
|
+
element?: HTMLElement;
|
|
12
12
|
enabled?: boolean;
|
|
13
13
|
}>;
|
|
14
|
-
declare
|
|
15
|
-
|
|
16
|
-
as?: TTag | undefined;
|
|
17
|
-
} & (Exclude<keyof import("../utils/types.js").PropsOf<TTag>, ("as" | "children" | "refName" | "class") | "enabled"> extends infer T extends keyof import("../utils/types.js").PropsOf<TTag> ? { [P in T]: import("../utils/types.js").PropsOf<TTag>[P]; } : never) & {
|
|
18
|
-
children?: import("../utils/types.js").Children<PortalRenderPropArg> | undefined;
|
|
19
|
-
ref?: HTMLElement;
|
|
20
|
-
} & (true extends (import("../utils/types.js").PropsOf<TTag> extends infer T_1 ? T_1 extends import("../utils/types.js").PropsOf<TTag> ? T_1 extends never ? never : "class" extends infer T_2 ? T_2 extends "class" ? T_2 extends keyof T_1 ? true : never : never : never : never : never) ? {
|
|
21
|
-
class?: import("../utils/types.js").PropsOf<TTag>["class"] | ((bag: PortalRenderPropArg) => string) | undefined;
|
|
22
|
-
} : {}) & {
|
|
23
|
-
enabled?: boolean;
|
|
24
|
-
};
|
|
25
|
-
events(): {} & {
|
|
26
|
-
[evt: string]: CustomEvent<any>;
|
|
27
|
-
};
|
|
28
|
-
slots(): {};
|
|
29
|
-
bindings(): "ref";
|
|
30
|
-
exports(): {};
|
|
31
|
-
}
|
|
32
|
-
interface $$IsomorphicComponent {
|
|
33
|
-
new <TTag extends ElementType = typeof DEFAULT_PORTAL_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']>> & {
|
|
34
|
-
$$bindings?: ReturnType<__sveltets_Render<TTag>['bindings']>;
|
|
35
|
-
} & ReturnType<__sveltets_Render<TTag>['exports']>;
|
|
36
|
-
<TTag extends ElementType = typeof DEFAULT_PORTAL_TAG>(internal: unknown, props: ReturnType<__sveltets_Render<TTag>['props']> & {
|
|
37
|
-
$$events?: ReturnType<__sveltets_Render<TTag>['events']>;
|
|
38
|
-
}): ReturnType<__sveltets_Render<TTag>['exports']>;
|
|
39
|
-
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
40
|
-
}
|
|
41
|
-
declare const InternalPortal: $$IsomorphicComponent;
|
|
42
|
-
type InternalPortal<TTag extends ElementType = typeof DEFAULT_PORTAL_TAG> = InstanceType<typeof InternalPortal<TTag>>;
|
|
14
|
+
declare const InternalPortal: import("svelte").Component<PortalProps, {}, "element">;
|
|
15
|
+
type InternalPortal = ReturnType<typeof InternalPortal>;
|
|
43
16
|
export default InternalPortal;
|