bits-ui 2.14.0 → 2.14.1
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/bits/accordion/accordion.svelte.d.ts +5 -1
- package/dist/bits/accordion/accordion.svelte.js +21 -2
- package/dist/bits/accordion/components/accordion-content.svelte +12 -24
- package/dist/bits/alert-dialog/components/alert-dialog-content.svelte +50 -62
- package/dist/bits/collapsible/collapsible.svelte.d.ts +4 -1
- package/dist/bits/collapsible/collapsible.svelte.js +15 -2
- package/dist/bits/collapsible/components/collapsible-content.svelte +12 -24
- package/dist/bits/context-menu/components/context-menu-content-static.svelte +2 -0
- package/dist/bits/context-menu/components/context-menu-content.svelte +2 -0
- package/dist/bits/date-field/date-field.svelte.js +5 -3
- package/dist/bits/dialog/components/dialog-content.svelte +44 -57
- package/dist/bits/dialog/components/dialog-overlay.svelte +9 -12
- package/dist/bits/dialog/dialog.svelte.d.ts +6 -0
- package/dist/bits/dialog/dialog.svelte.js +17 -3
- package/dist/bits/dropdown-menu/components/dropdown-menu-content-static.svelte +2 -0
- package/dist/bits/dropdown-menu/components/dropdown-menu-content.svelte +2 -0
- package/dist/bits/link-preview/components/link-preview-content-static.svelte +2 -0
- package/dist/bits/link-preview/components/link-preview-content.svelte +2 -0
- package/dist/bits/link-preview/link-preview.svelte.d.ts +3 -0
- package/dist/bits/link-preview/link-preview.svelte.js +6 -2
- package/dist/bits/menu/components/menu-content-static.svelte +2 -0
- package/dist/bits/menu/components/menu-content.svelte +2 -0
- package/dist/bits/menu/components/menu-sub-content-static.svelte +2 -0
- package/dist/bits/menu/components/menu-sub-content.svelte +2 -0
- package/dist/bits/menu/menu.svelte.d.ts +3 -0
- package/dist/bits/menu/menu.svelte.js +6 -2
- package/dist/bits/popover/components/popover-content-static.svelte +2 -0
- package/dist/bits/popover/components/popover-content.svelte +2 -0
- package/dist/bits/popover/components/popover-overlay.svelte +9 -12
- package/dist/bits/popover/popover.svelte.d.ts +6 -0
- package/dist/bits/popover/popover.svelte.js +16 -3
- package/dist/bits/select/components/select-content-static.svelte +2 -0
- package/dist/bits/select/components/select-content.svelte +2 -0
- package/dist/bits/select/select.svelte.d.ts +3 -0
- package/dist/bits/select/select.svelte.js +6 -2
- package/dist/bits/tooltip/components/tooltip-content-static.svelte +2 -0
- package/dist/bits/tooltip/components/tooltip-content.svelte +2 -0
- package/dist/bits/tooltip/tooltip.svelte.d.ts +3 -0
- package/dist/bits/tooltip/tooltip.svelte.js +6 -2
- package/dist/bits/utilities/popper-layer/popper-layer-inner.svelte +1 -1
- package/dist/bits/utilities/popper-layer/popper-layer-inner.svelte.d.ts +1 -1
- package/dist/bits/utilities/popper-layer/popper-layer.svelte +43 -45
- package/dist/bits/utilities/popper-layer/types.d.ts +4 -0
- package/dist/internal/animations-complete.js +7 -15
- package/dist/internal/date-time/field/helpers.js +3 -1
- package/dist/internal/date-time/field/time-helpers.js +4 -1
- package/dist/internal/presence-manager.svelte.d.ts +14 -0
- package/dist/internal/presence-manager.svelte.js +34 -0
- package/dist/internal/should-enable-focus-trap.d.ts +1 -2
- package/dist/internal/should-enable-focus-trap.js +2 -2
- package/package.json +2 -2
- package/dist/internal/open-change-complete.d.ts +0 -13
- package/dist/internal/open-change-complete.js +0 -24
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ReadableBoxedValues, type WritableBoxedValues } from "svelte-toolbelt";
|
|
2
2
|
import type { BitsKeyboardEvent, BitsMouseEvent, OnChangeFn, RefAttachment, WithRefOpts } from "../../internal/types.js";
|
|
3
|
+
import { PresenceManager } from "../../internal/presence-manager.svelte.js";
|
|
3
4
|
type DialogVariant = "alert-dialog" | "dialog";
|
|
4
5
|
declare const dialogAttrs: import("../../internal/attrs.js").CreateBitsAttrsReturn<readonly ["content", "trigger", "overlay", "title", "description", "close", "cancel", "action"]>;
|
|
5
6
|
interface DialogRootStateOpts extends WritableBoxedValues<{
|
|
@@ -14,6 +15,7 @@ export declare class DialogRootState {
|
|
|
14
15
|
readonly opts: DialogRootStateOpts;
|
|
15
16
|
triggerNode: HTMLElement | null;
|
|
16
17
|
contentNode: HTMLElement | null;
|
|
18
|
+
overlayNode: HTMLElement | null;
|
|
17
19
|
descriptionNode: HTMLElement | null;
|
|
18
20
|
contentId: string | undefined;
|
|
19
21
|
titleId: string | undefined;
|
|
@@ -23,6 +25,8 @@ export declare class DialogRootState {
|
|
|
23
25
|
nestedOpenCount: number;
|
|
24
26
|
readonly depth: number;
|
|
25
27
|
readonly parent: DialogRootState | null;
|
|
28
|
+
contentPresence: PresenceManager;
|
|
29
|
+
overlayPresence: PresenceManager;
|
|
26
30
|
constructor(opts: DialogRootStateOpts, parent: DialogRootState | null);
|
|
27
31
|
handleOpen(): void;
|
|
28
32
|
handleClose(): void;
|
|
@@ -149,6 +153,7 @@ export declare class DialogContentState {
|
|
|
149
153
|
readonly "data-nested-open": "" | undefined;
|
|
150
154
|
readonly "data-nested": "" | undefined;
|
|
151
155
|
};
|
|
156
|
+
get shouldRender(): boolean;
|
|
152
157
|
}
|
|
153
158
|
interface DialogOverlayStateOpts extends WithRefOpts {
|
|
154
159
|
}
|
|
@@ -172,6 +177,7 @@ export declare class DialogOverlayState {
|
|
|
172
177
|
readonly "data-nested-open": "" | undefined;
|
|
173
178
|
readonly "data-nested": "" | undefined;
|
|
174
179
|
};
|
|
180
|
+
get shouldRender(): boolean;
|
|
175
181
|
}
|
|
176
182
|
interface AlertDialogCancelStateOpts extends WithRefOpts, ReadableBoxedValues<{
|
|
177
183
|
disabled: boolean;
|
|
@@ -2,7 +2,7 @@ import { attachRef, boxWith, onDestroyEffect, } from "svelte-toolbelt";
|
|
|
2
2
|
import { Context, watch } from "runed";
|
|
3
3
|
import { createBitsAttrs, boolToStr, getDataOpenClosed, boolToEmptyStrOrUndef, } from "../../internal/attrs.js";
|
|
4
4
|
import { kbd } from "../../internal/kbd.js";
|
|
5
|
-
import {
|
|
5
|
+
import { PresenceManager } from "../../internal/presence-manager.svelte.js";
|
|
6
6
|
const dialogAttrs = createBitsAttrs({
|
|
7
7
|
component: "dialog",
|
|
8
8
|
parts: ["content", "trigger", "overlay", "title", "description", "close", "cancel", "action"],
|
|
@@ -16,6 +16,7 @@ export class DialogRootState {
|
|
|
16
16
|
opts;
|
|
17
17
|
triggerNode = $state(null);
|
|
18
18
|
contentNode = $state(null);
|
|
19
|
+
overlayNode = $state(null);
|
|
19
20
|
descriptionNode = $state(null);
|
|
20
21
|
contentId = $state(undefined);
|
|
21
22
|
titleId = $state(undefined);
|
|
@@ -25,13 +26,15 @@ export class DialogRootState {
|
|
|
25
26
|
nestedOpenCount = $state(0);
|
|
26
27
|
depth;
|
|
27
28
|
parent;
|
|
29
|
+
contentPresence;
|
|
30
|
+
overlayPresence;
|
|
28
31
|
constructor(opts, parent) {
|
|
29
32
|
this.opts = opts;
|
|
30
33
|
this.parent = parent;
|
|
31
34
|
this.depth = parent ? parent.depth + 1 : 0;
|
|
32
35
|
this.handleOpen = this.handleOpen.bind(this);
|
|
33
36
|
this.handleClose = this.handleClose.bind(this);
|
|
34
|
-
new
|
|
37
|
+
this.contentPresence = new PresenceManager({
|
|
35
38
|
ref: boxWith(() => this.contentNode),
|
|
36
39
|
open: this.opts.open,
|
|
37
40
|
enabled: true,
|
|
@@ -39,6 +42,11 @@ export class DialogRootState {
|
|
|
39
42
|
this.opts.onOpenChangeComplete.current(this.opts.open.current);
|
|
40
43
|
},
|
|
41
44
|
});
|
|
45
|
+
this.overlayPresence = new PresenceManager({
|
|
46
|
+
ref: boxWith(() => this.overlayNode),
|
|
47
|
+
open: this.opts.open,
|
|
48
|
+
enabled: true,
|
|
49
|
+
});
|
|
42
50
|
watch(() => this.opts.open.current, (isOpen) => {
|
|
43
51
|
if (!this.parent)
|
|
44
52
|
return;
|
|
@@ -271,6 +279,9 @@ export class DialogContentState {
|
|
|
271
279
|
...this.root.sharedProps,
|
|
272
280
|
...this.attachment,
|
|
273
281
|
}));
|
|
282
|
+
get shouldRender() {
|
|
283
|
+
return this.root.contentPresence.shouldRender;
|
|
284
|
+
}
|
|
274
285
|
}
|
|
275
286
|
export class DialogOverlayState {
|
|
276
287
|
static create(opts) {
|
|
@@ -282,7 +293,7 @@ export class DialogOverlayState {
|
|
|
282
293
|
constructor(opts, root) {
|
|
283
294
|
this.opts = opts;
|
|
284
295
|
this.root = root;
|
|
285
|
-
this.attachment = attachRef(this.opts.ref);
|
|
296
|
+
this.attachment = attachRef(this.opts.ref, (v) => (this.root.overlayNode = v));
|
|
286
297
|
}
|
|
287
298
|
snippetProps = $derived.by(() => ({ open: this.root.opts.open.current }));
|
|
288
299
|
props = $derived.by(() => ({
|
|
@@ -298,6 +309,9 @@ export class DialogOverlayState {
|
|
|
298
309
|
...this.root.sharedProps,
|
|
299
310
|
...this.attachment,
|
|
300
311
|
}));
|
|
312
|
+
get shouldRender() {
|
|
313
|
+
return this.root.overlayPresence.shouldRender;
|
|
314
|
+
}
|
|
301
315
|
}
|
|
302
316
|
export class AlertDialogCancelState {
|
|
303
317
|
static create(opts) {
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
forceMount={true}
|
|
63
63
|
isStatic
|
|
64
64
|
{id}
|
|
65
|
+
shouldRender={contentState.shouldRender}
|
|
65
66
|
>
|
|
66
67
|
{#snippet popper({ props })}
|
|
67
68
|
{@const finalProps = mergeProps(props, {
|
|
@@ -89,6 +90,7 @@
|
|
|
89
90
|
forceMount={false}
|
|
90
91
|
isStatic
|
|
91
92
|
{id}
|
|
93
|
+
shouldRender={contentState.shouldRender}
|
|
92
94
|
>
|
|
93
95
|
{#snippet popper({ props })}
|
|
94
96
|
{@const finalProps = mergeProps(props, {
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
{loop}
|
|
69
69
|
forceMount={true}
|
|
70
70
|
{id}
|
|
71
|
+
shouldRender={contentState.shouldRender}
|
|
71
72
|
>
|
|
72
73
|
{#snippet popper({ props, wrapperProps })}
|
|
73
74
|
{@const finalProps = mergeProps(props, {
|
|
@@ -96,6 +97,7 @@
|
|
|
96
97
|
{loop}
|
|
97
98
|
forceMount={false}
|
|
98
99
|
{id}
|
|
100
|
+
shouldRender={contentState.shouldRender}
|
|
99
101
|
>
|
|
100
102
|
{#snippet popper({ props, wrapperProps })}
|
|
101
103
|
{@const finalProps = mergeProps(props, {
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
loop={false}
|
|
48
48
|
preventScroll={false}
|
|
49
49
|
forceMount={true}
|
|
50
|
+
shouldRender={contentState.shouldRender}
|
|
50
51
|
>
|
|
51
52
|
{#snippet popper({ props })}
|
|
52
53
|
{@const mergedProps = mergeProps(props, {
|
|
@@ -74,6 +75,7 @@
|
|
|
74
75
|
loop={false}
|
|
75
76
|
preventScroll={false}
|
|
76
77
|
forceMount={false}
|
|
78
|
+
shouldRender={contentState.shouldRender}
|
|
77
79
|
>
|
|
78
80
|
{#snippet popper({ props })}
|
|
79
81
|
{@const mergedProps = mergeProps(props, {
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
loop={false}
|
|
66
66
|
preventScroll={false}
|
|
67
67
|
forceMount={true}
|
|
68
|
+
shouldRender={contentState.shouldRender}
|
|
68
69
|
>
|
|
69
70
|
{#snippet popper({ props, wrapperProps })}
|
|
70
71
|
{@const mergedProps = mergeProps(props, {
|
|
@@ -93,6 +94,7 @@
|
|
|
93
94
|
loop={false}
|
|
94
95
|
preventScroll={false}
|
|
95
96
|
forceMount={false}
|
|
97
|
+
shouldRender={contentState.shouldRender}
|
|
96
98
|
>
|
|
97
99
|
{#snippet popper({ props, wrapperProps })}
|
|
98
100
|
{@const mergedProps = mergeProps(props, {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DOMContext, type ReadableBoxedValues, type WritableBoxedValues } from "svelte-toolbelt";
|
|
2
2
|
import type { BitsFocusEvent, BitsPointerEvent, OnChangeFn, RefAttachment, WithRefOpts } from "../../internal/types.js";
|
|
3
|
+
import { PresenceManager } from "../../internal/presence-manager.svelte.js";
|
|
3
4
|
interface LinkPreviewRootStateOpts extends WritableBoxedValues<{
|
|
4
5
|
open: boolean;
|
|
5
6
|
}>, ReadableBoxedValues<{
|
|
@@ -18,6 +19,7 @@ export declare class LinkPreviewRootState {
|
|
|
18
19
|
timeout: number | null;
|
|
19
20
|
contentNode: HTMLElement | null;
|
|
20
21
|
contentMounted: boolean;
|
|
22
|
+
contentPresence: PresenceManager;
|
|
21
23
|
triggerNode: HTMLElement | null;
|
|
22
24
|
isOpening: boolean;
|
|
23
25
|
domContext: DOMContext;
|
|
@@ -70,6 +72,7 @@ export declare class LinkPreviewContentState {
|
|
|
70
72
|
onEscapeKeydown: (e: KeyboardEvent) => void;
|
|
71
73
|
onOpenAutoFocus: (e: Event) => void;
|
|
72
74
|
onCloseAutoFocus: (e: Event) => void;
|
|
75
|
+
get shouldRender(): boolean;
|
|
73
76
|
readonly snippetProps: {
|
|
74
77
|
open: boolean;
|
|
75
78
|
};
|
|
@@ -5,7 +5,7 @@ import { createBitsAttrs, boolToStr, getDataOpenClosed } from "../../internal/at
|
|
|
5
5
|
import { isElement, isFocusVisible, isTouch } from "../../internal/is.js";
|
|
6
6
|
import { getTabbableCandidates } from "../../internal/focus.js";
|
|
7
7
|
import { GraceArea } from "../../internal/grace-area.svelte.js";
|
|
8
|
-
import {
|
|
8
|
+
import { PresenceManager } from "../../internal/presence-manager.svelte.js";
|
|
9
9
|
const linkPreviewAttrs = createBitsAttrs({
|
|
10
10
|
component: "link-preview",
|
|
11
11
|
parts: ["content", "trigger"],
|
|
@@ -22,12 +22,13 @@ export class LinkPreviewRootState {
|
|
|
22
22
|
timeout = null;
|
|
23
23
|
contentNode = $state(null);
|
|
24
24
|
contentMounted = $state(false);
|
|
25
|
+
contentPresence;
|
|
25
26
|
triggerNode = $state(null);
|
|
26
27
|
isOpening = false;
|
|
27
28
|
domContext = new DOMContext(() => null);
|
|
28
29
|
constructor(opts) {
|
|
29
30
|
this.opts = opts;
|
|
30
|
-
new
|
|
31
|
+
this.contentPresence = new PresenceManager({
|
|
31
32
|
ref: boxWith(() => this.contentNode),
|
|
32
33
|
open: this.opts.open,
|
|
33
34
|
onComplete: () => {
|
|
@@ -216,6 +217,9 @@ export class LinkPreviewContentState {
|
|
|
216
217
|
onCloseAutoFocus = (e) => {
|
|
217
218
|
e.preventDefault();
|
|
218
219
|
};
|
|
220
|
+
get shouldRender() {
|
|
221
|
+
return this.root.contentPresence.shouldRender;
|
|
222
|
+
}
|
|
219
223
|
snippetProps = $derived.by(() => ({ open: this.root.opts.open.current }));
|
|
220
224
|
props = $derived.by(() => ({
|
|
221
225
|
id: this.opts.id.current,
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
forceMount={true}
|
|
66
66
|
isStatic
|
|
67
67
|
{id}
|
|
68
|
+
shouldRender={contentState.shouldRender}
|
|
68
69
|
>
|
|
69
70
|
{#snippet popper({ props })}
|
|
70
71
|
{@const finalProps = mergeProps(props, {
|
|
@@ -95,6 +96,7 @@
|
|
|
95
96
|
forceMount={false}
|
|
96
97
|
isStatic
|
|
97
98
|
{id}
|
|
99
|
+
shouldRender={contentState.shouldRender}
|
|
98
100
|
>
|
|
99
101
|
{#snippet popper({ props })}
|
|
100
102
|
{@const finalProps = mergeProps(props, {
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
{loop}
|
|
70
70
|
forceMount={true}
|
|
71
71
|
{id}
|
|
72
|
+
shouldRender={contentState.shouldRender}
|
|
72
73
|
>
|
|
73
74
|
{#snippet popper({ props, wrapperProps })}
|
|
74
75
|
{@const finalProps = mergeProps(props, {
|
|
@@ -100,6 +101,7 @@
|
|
|
100
101
|
{loop}
|
|
101
102
|
forceMount={false}
|
|
102
103
|
{id}
|
|
104
|
+
shouldRender={contentState.shouldRender}
|
|
103
105
|
>
|
|
104
106
|
{#snippet popper({ props, wrapperProps })}
|
|
105
107
|
{@const finalProps = mergeProps(props, {
|
|
@@ -120,6 +120,7 @@
|
|
|
120
120
|
{loop}
|
|
121
121
|
{trapFocus}
|
|
122
122
|
isStatic
|
|
123
|
+
shouldRender={subContentState.shouldRender}
|
|
123
124
|
>
|
|
124
125
|
{#snippet popper({ props })}
|
|
125
126
|
{@const finalProps = mergeProps(props, mergedProps, {
|
|
@@ -150,6 +151,7 @@
|
|
|
150
151
|
{loop}
|
|
151
152
|
{trapFocus}
|
|
152
153
|
isStatic
|
|
154
|
+
shouldRender={subContentState.shouldRender}
|
|
153
155
|
>
|
|
154
156
|
{#snippet popper({ props })}
|
|
155
157
|
{@const finalProps = mergeProps(props, mergedProps, {
|
|
@@ -121,6 +121,7 @@
|
|
|
121
121
|
preventScroll={false}
|
|
122
122
|
{loop}
|
|
123
123
|
{trapFocus}
|
|
124
|
+
shouldRender={subContentState.shouldRender}
|
|
124
125
|
>
|
|
125
126
|
{#snippet popper({ props, wrapperProps })}
|
|
126
127
|
{@const finalProps = mergeProps(props, mergedProps, {
|
|
@@ -156,6 +157,7 @@
|
|
|
156
157
|
preventScroll={false}
|
|
157
158
|
{loop}
|
|
158
159
|
{trapFocus}
|
|
160
|
+
shouldRender={subContentState.shouldRender}
|
|
159
161
|
>
|
|
160
162
|
{#snippet popper({ props, wrapperProps })}
|
|
161
163
|
{@const finalProps = mergeProps(props, mergedProps, {
|
|
@@ -6,6 +6,7 @@ import type { Direction } from "../../shared/index.js";
|
|
|
6
6
|
import { IsUsingKeyboard } from "../../index.js";
|
|
7
7
|
import type { KeyboardEventHandler, PointerEventHandler, MouseEventHandler } from "svelte/elements";
|
|
8
8
|
import { RovingFocusGroup } from "../../internal/roving-focus-group.js";
|
|
9
|
+
import { PresenceManager } from "../../internal/presence-manager.svelte.js";
|
|
9
10
|
export declare const CONTEXT_MENU_TRIGGER_ATTR = "data-context-menu-trigger";
|
|
10
11
|
export declare const CONTEXT_MENU_CONTENT_ATTR = "data-context-menu-content";
|
|
11
12
|
export declare const MenuCheckboxGroupContext: Context<MenuCheckboxGroupState>;
|
|
@@ -40,6 +41,7 @@ export declare class MenuMenuState {
|
|
|
40
41
|
readonly parentMenu: MenuMenuState | null;
|
|
41
42
|
contentId: ReadableBox<string>;
|
|
42
43
|
contentNode: HTMLElement | null;
|
|
44
|
+
contentPresence: PresenceManager;
|
|
43
45
|
triggerNode: HTMLElement | null;
|
|
44
46
|
constructor(opts: MenuMenuStateOpts, root: MenuRootState, parentMenu: MenuMenuState | null);
|
|
45
47
|
toggleOpen(): void;
|
|
@@ -72,6 +74,7 @@ export declare class MenuContentState {
|
|
|
72
74
|
onItemLeave(e: BitsPointerEvent): void;
|
|
73
75
|
onTriggerLeave(): boolean;
|
|
74
76
|
handleInteractOutside(e: PointerEvent): void;
|
|
77
|
+
get shouldRender(): boolean;
|
|
75
78
|
readonly snippetProps: {
|
|
76
79
|
open: boolean;
|
|
77
80
|
};
|
|
@@ -12,7 +12,7 @@ import { isTabbable } from "tabbable";
|
|
|
12
12
|
import { DOMTypeahead } from "../../internal/dom-typeahead.svelte.js";
|
|
13
13
|
import { RovingFocusGroup } from "../../internal/roving-focus-group.js";
|
|
14
14
|
import { GraceArea } from "../../internal/grace-area.svelte.js";
|
|
15
|
-
import {
|
|
15
|
+
import { PresenceManager } from "../../internal/presence-manager.svelte.js";
|
|
16
16
|
export const CONTEXT_MENU_TRIGGER_ATTR = "data-context-menu-trigger";
|
|
17
17
|
export const CONTEXT_MENU_CONTENT_ATTR = "data-context-menu-content";
|
|
18
18
|
const MenuRootContext = new Context("Menu.Root");
|
|
@@ -68,12 +68,13 @@ export class MenuMenuState {
|
|
|
68
68
|
parentMenu;
|
|
69
69
|
contentId = boxWith(() => "");
|
|
70
70
|
contentNode = $state(null);
|
|
71
|
+
contentPresence;
|
|
71
72
|
triggerNode = $state(null);
|
|
72
73
|
constructor(opts, root, parentMenu) {
|
|
73
74
|
this.opts = opts;
|
|
74
75
|
this.root = root;
|
|
75
76
|
this.parentMenu = parentMenu;
|
|
76
|
-
new
|
|
77
|
+
this.contentPresence = new PresenceManager({
|
|
77
78
|
ref: boxWith(() => this.contentNode),
|
|
78
79
|
open: this.opts.open,
|
|
79
80
|
onComplete: () => {
|
|
@@ -306,6 +307,9 @@ export class MenuContentState {
|
|
|
306
307
|
e.preventDefault();
|
|
307
308
|
}
|
|
308
309
|
}
|
|
310
|
+
get shouldRender() {
|
|
311
|
+
return this.parentMenu.contentPresence.shouldRender;
|
|
312
|
+
}
|
|
309
313
|
snippetProps = $derived.by(() => ({ open: this.parentMenu.opts.open.current }));
|
|
310
314
|
props = $derived.by(() => ({
|
|
311
315
|
id: this.opts.id.current,
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
loop
|
|
52
52
|
forceMount={true}
|
|
53
53
|
{onCloseAutoFocus}
|
|
54
|
+
shouldRender={contentState.shouldRender}
|
|
54
55
|
>
|
|
55
56
|
{#snippet popper({ props })}
|
|
56
57
|
{@const finalProps = mergeProps(props, {
|
|
@@ -78,6 +79,7 @@
|
|
|
78
79
|
loop
|
|
79
80
|
forceMount={false}
|
|
80
81
|
{onCloseAutoFocus}
|
|
82
|
+
shouldRender={contentState.shouldRender}
|
|
81
83
|
>
|
|
82
84
|
{#snippet popper({ props })}
|
|
83
85
|
{@const finalProps = mergeProps(props, {
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
forceMount={true}
|
|
53
53
|
{customAnchor}
|
|
54
54
|
{onCloseAutoFocus}
|
|
55
|
+
shouldRender={contentState.shouldRender}
|
|
55
56
|
>
|
|
56
57
|
{#snippet popper({ props, wrapperProps })}
|
|
57
58
|
{@const finalProps = mergeProps(props, {
|
|
@@ -81,6 +82,7 @@
|
|
|
81
82
|
forceMount={false}
|
|
82
83
|
{customAnchor}
|
|
83
84
|
{onCloseAutoFocus}
|
|
85
|
+
shouldRender={contentState.shouldRender}
|
|
84
86
|
>
|
|
85
87
|
{#snippet popper({ props, wrapperProps })}
|
|
86
88
|
{@const finalProps = mergeProps(props, {
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import { PopoverOverlayState } from "../popover.svelte.js";
|
|
4
4
|
import type { PopoverOverlayProps } from "../types.js";
|
|
5
5
|
import { createId } from "../../../internal/create-id.js";
|
|
6
|
-
import PresenceLayer from "../../utilities/presence-layer/presence-layer.svelte";
|
|
7
6
|
|
|
8
7
|
const uid = $props.id();
|
|
9
8
|
|
|
@@ -27,14 +26,12 @@
|
|
|
27
26
|
const mergedProps = $derived(mergeProps(restProps, overlayState.props));
|
|
28
27
|
</script>
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
{#
|
|
32
|
-
{
|
|
33
|
-
|
|
34
|
-
{
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
{/snippet}
|
|
40
|
-
</PresenceLayer>
|
|
29
|
+
{#if overlayState.shouldRender || forceMount}
|
|
30
|
+
{#if child}
|
|
31
|
+
{@render child({ props: mergeProps(mergedProps), ...overlayState.snippetProps })}
|
|
32
|
+
{:else}
|
|
33
|
+
<div {...mergeProps(mergedProps)}>
|
|
34
|
+
{@render children?.(overlayState.snippetProps)}
|
|
35
|
+
</div>
|
|
36
|
+
{/if}
|
|
37
|
+
{/if}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type ReadableBoxedValues, type WritableBoxedValues } from "svelte-toolbelt";
|
|
2
2
|
import type { BitsKeyboardEvent, BitsMouseEvent, BitsPointerEvent, OnChangeFn, RefAttachment, WithRefOpts } from "../../internal/types.js";
|
|
3
3
|
import type { Measurable } from "../../internal/floating-svelte/types.js";
|
|
4
|
+
import { PresenceManager } from "../../internal/presence-manager.svelte.js";
|
|
4
5
|
interface PopoverRootStateOpts extends WritableBoxedValues<{
|
|
5
6
|
open: boolean;
|
|
6
7
|
}>, ReadableBoxedValues<{
|
|
@@ -11,7 +12,10 @@ export declare class PopoverRootState {
|
|
|
11
12
|
static create(opts: PopoverRootStateOpts): PopoverRootState;
|
|
12
13
|
readonly opts: PopoverRootStateOpts;
|
|
13
14
|
contentNode: HTMLElement | null;
|
|
15
|
+
contentPresence: PresenceManager;
|
|
14
16
|
triggerNode: HTMLElement | null;
|
|
17
|
+
overlayNode: HTMLElement | null;
|
|
18
|
+
overlayPresence: PresenceManager;
|
|
15
19
|
constructor(opts: PopoverRootStateOpts);
|
|
16
20
|
toggleOpen(): void;
|
|
17
21
|
handleClose(): void;
|
|
@@ -54,6 +58,7 @@ export declare class PopoverContentState {
|
|
|
54
58
|
constructor(opts: PopoverContentStateOpts, root: PopoverRootState);
|
|
55
59
|
onInteractOutside: (e: PointerEvent) => void;
|
|
56
60
|
onEscapeKeydown: (e: KeyboardEvent) => void;
|
|
61
|
+
get shouldRender(): boolean;
|
|
57
62
|
readonly snippetProps: {
|
|
58
63
|
open: boolean;
|
|
59
64
|
};
|
|
@@ -95,6 +100,7 @@ export declare class PopoverOverlayState {
|
|
|
95
100
|
readonly root: PopoverRootState;
|
|
96
101
|
readonly attachment: RefAttachment;
|
|
97
102
|
constructor(opts: PopoverOverlayStateOpts, root: PopoverRootState);
|
|
103
|
+
get shouldRender(): boolean;
|
|
98
104
|
readonly snippetProps: {
|
|
99
105
|
open: boolean;
|
|
100
106
|
};
|
|
@@ -3,7 +3,7 @@ import { Context } from "runed";
|
|
|
3
3
|
import { kbd } from "../../internal/kbd.js";
|
|
4
4
|
import { createBitsAttrs, boolToStr, getDataOpenClosed } from "../../internal/attrs.js";
|
|
5
5
|
import { isElement } from "../../internal/is.js";
|
|
6
|
-
import {
|
|
6
|
+
import { PresenceManager } from "../../internal/presence-manager.svelte.js";
|
|
7
7
|
const popoverAttrs = createBitsAttrs({
|
|
8
8
|
component: "popover",
|
|
9
9
|
parts: ["root", "trigger", "content", "close", "overlay"],
|
|
@@ -15,16 +15,23 @@ export class PopoverRootState {
|
|
|
15
15
|
}
|
|
16
16
|
opts;
|
|
17
17
|
contentNode = $state(null);
|
|
18
|
+
contentPresence;
|
|
18
19
|
triggerNode = $state(null);
|
|
20
|
+
overlayNode = $state(null);
|
|
21
|
+
overlayPresence;
|
|
19
22
|
constructor(opts) {
|
|
20
23
|
this.opts = opts;
|
|
21
|
-
new
|
|
24
|
+
this.contentPresence = new PresenceManager({
|
|
22
25
|
ref: boxWith(() => this.contentNode),
|
|
23
26
|
open: this.opts.open,
|
|
24
27
|
onComplete: () => {
|
|
25
28
|
this.opts.onOpenChangeComplete.current(this.opts.open.current);
|
|
26
29
|
},
|
|
27
30
|
});
|
|
31
|
+
this.overlayPresence = new PresenceManager({
|
|
32
|
+
ref: boxWith(() => this.overlayNode),
|
|
33
|
+
open: this.opts.open,
|
|
34
|
+
});
|
|
28
35
|
}
|
|
29
36
|
toggleOpen() {
|
|
30
37
|
this.opts.open.current = !this.opts.open.current;
|
|
@@ -124,6 +131,9 @@ export class PopoverContentState {
|
|
|
124
131
|
return;
|
|
125
132
|
this.root.handleClose();
|
|
126
133
|
};
|
|
134
|
+
get shouldRender() {
|
|
135
|
+
return this.root.contentPresence.shouldRender;
|
|
136
|
+
}
|
|
127
137
|
snippetProps = $derived.by(() => ({ open: this.root.opts.open.current }));
|
|
128
138
|
props = $derived.by(() => ({
|
|
129
139
|
id: this.opts.id.current,
|
|
@@ -182,7 +192,10 @@ export class PopoverOverlayState {
|
|
|
182
192
|
constructor(opts, root) {
|
|
183
193
|
this.opts = opts;
|
|
184
194
|
this.root = root;
|
|
185
|
-
this.attachment = attachRef(this.opts.ref);
|
|
195
|
+
this.attachment = attachRef(this.opts.ref, (v) => (this.root.overlayNode = v));
|
|
196
|
+
}
|
|
197
|
+
get shouldRender() {
|
|
198
|
+
return this.root.overlayPresence.shouldRender;
|
|
186
199
|
}
|
|
187
200
|
snippetProps = $derived.by(() => ({ open: this.root.opts.open.current }));
|
|
188
201
|
props = $derived.by(() => ({
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
{id}
|
|
45
45
|
{preventScroll}
|
|
46
46
|
forceMount={true}
|
|
47
|
+
shouldRender={contentState.shouldRender}
|
|
47
48
|
>
|
|
48
49
|
{#snippet popper({ props })}
|
|
49
50
|
{@const finalProps = mergeProps(props, { style: contentState.props.style })}
|
|
@@ -66,6 +67,7 @@
|
|
|
66
67
|
{id}
|
|
67
68
|
{preventScroll}
|
|
68
69
|
forceMount={false}
|
|
70
|
+
shouldRender={contentState.shouldRender}
|
|
69
71
|
>
|
|
70
72
|
{#snippet popper({ props })}
|
|
71
73
|
{@const finalProps = mergeProps(props, { style: contentState.props.style })}
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
{id}
|
|
46
46
|
{preventScroll}
|
|
47
47
|
forceMount={true}
|
|
48
|
+
shouldRender={contentState.shouldRender}
|
|
48
49
|
>
|
|
49
50
|
{#snippet popper({ props, wrapperProps })}
|
|
50
51
|
{@const finalProps = mergeProps(props, { style: contentState.props.style })}
|
|
@@ -69,6 +70,7 @@
|
|
|
69
70
|
{id}
|
|
70
71
|
{preventScroll}
|
|
71
72
|
forceMount={false}
|
|
73
|
+
shouldRender={contentState.shouldRender}
|
|
72
74
|
>
|
|
73
75
|
{#snippet popper({ props, wrapperProps })}
|
|
74
76
|
{@const finalProps = mergeProps(props, { style: contentState.props.style })}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Previous } from "runed";
|
|
2
2
|
import { DOMContext, type ReadableBoxedValues, type WritableBoxedValues, type Box } from "svelte-toolbelt";
|
|
3
3
|
import type { BitsEvent, BitsFocusEvent, BitsKeyboardEvent, BitsMouseEvent, BitsPointerEvent, OnChangeFn, WithRefOpts, RefAttachment } from "../../internal/types.js";
|
|
4
|
+
import { PresenceManager } from "../../internal/presence-manager.svelte.js";
|
|
4
5
|
export declare const INTERACTION_KEYS: string[];
|
|
5
6
|
export declare const FIRST_KEYS: string[];
|
|
6
7
|
export declare const LAST_KEYS: string[];
|
|
@@ -32,6 +33,7 @@ declare abstract class SelectBaseRootState {
|
|
|
32
33
|
touchedInput: boolean;
|
|
33
34
|
inputNode: HTMLElement | null;
|
|
34
35
|
contentNode: HTMLElement | null;
|
|
36
|
+
contentPresence: PresenceManager;
|
|
35
37
|
viewportNode: HTMLElement | null;
|
|
36
38
|
triggerNode: HTMLElement | null;
|
|
37
39
|
valueId: string;
|
|
@@ -204,6 +206,7 @@ export declare class SelectContentState {
|
|
|
204
206
|
onEscapeKeydown: (e: KeyboardEvent) => void;
|
|
205
207
|
onOpenAutoFocus: (e: Event) => void;
|
|
206
208
|
onCloseAutoFocus: (e: Event) => void;
|
|
209
|
+
get shouldRender(): boolean;
|
|
207
210
|
readonly snippetProps: {
|
|
208
211
|
open: boolean;
|
|
209
212
|
};
|
|
@@ -10,7 +10,7 @@ import { createBitsAttrs } from "../../internal/attrs.js";
|
|
|
10
10
|
import { getFloatingContentCSSVars } from "../../internal/floating-svelte/floating-utils.svelte.js";
|
|
11
11
|
import { DataTypeahead } from "../../internal/data-typeahead.svelte.js";
|
|
12
12
|
import { DOMTypeahead } from "../../internal/dom-typeahead.svelte.js";
|
|
13
|
-
import {
|
|
13
|
+
import { PresenceManager } from "../../internal/presence-manager.svelte.js";
|
|
14
14
|
// prettier-ignore
|
|
15
15
|
export const INTERACTION_KEYS = [kbd.ARROW_LEFT, kbd.ESCAPE, kbd.ARROW_RIGHT, kbd.SHIFT, kbd.CAPS_LOCK, kbd.CONTROL, kbd.ALT, kbd.META, kbd.ENTER, kbd.F1, kbd.F2, kbd.F3, kbd.F4, kbd.F5, kbd.F6, kbd.F7, kbd.F8, kbd.F9, kbd.F10, kbd.F11, kbd.F12];
|
|
16
16
|
export const FIRST_KEYS = [kbd.ARROW_DOWN, kbd.PAGE_UP, kbd.HOME];
|
|
@@ -45,6 +45,7 @@ class SelectBaseRootState {
|
|
|
45
45
|
touchedInput = $state(false);
|
|
46
46
|
inputNode = $state(null);
|
|
47
47
|
contentNode = $state(null);
|
|
48
|
+
contentPresence;
|
|
48
49
|
viewportNode = $state(null);
|
|
49
50
|
triggerNode = $state(null);
|
|
50
51
|
valueId = $state("");
|
|
@@ -70,7 +71,7 @@ class SelectBaseRootState {
|
|
|
70
71
|
constructor(opts) {
|
|
71
72
|
this.opts = opts;
|
|
72
73
|
this.isCombobox = opts.isCombobox;
|
|
73
|
-
new
|
|
74
|
+
this.contentPresence = new PresenceManager({
|
|
74
75
|
ref: boxWith(() => this.contentNode),
|
|
75
76
|
open: this.opts.open,
|
|
76
77
|
onComplete: () => {
|
|
@@ -749,6 +750,9 @@ export class SelectContentState {
|
|
|
749
750
|
onCloseAutoFocus = (e) => {
|
|
750
751
|
e.preventDefault();
|
|
751
752
|
};
|
|
753
|
+
get shouldRender() {
|
|
754
|
+
return this.root.contentPresence.shouldRender;
|
|
755
|
+
}
|
|
752
756
|
snippetProps = $derived.by(() => ({ open: this.root.opts.open.current }));
|
|
753
757
|
props = $derived.by(() => ({
|
|
754
758
|
id: this.opts.id.current,
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
forceMount={true}
|
|
48
48
|
ref={contentState.opts.ref}
|
|
49
49
|
tooltip={true}
|
|
50
|
+
shouldRender={contentState.shouldRender}
|
|
50
51
|
>
|
|
51
52
|
{#snippet popper({ props })}
|
|
52
53
|
{@const mergedProps = mergeProps(props, {
|
|
@@ -74,6 +75,7 @@
|
|
|
74
75
|
preventScroll={false}
|
|
75
76
|
forceMount={false}
|
|
76
77
|
ref={contentState.opts.ref}
|
|
78
|
+
shouldRender={contentState.shouldRender}
|
|
77
79
|
>
|
|
78
80
|
{#snippet popper({ props })}
|
|
79
81
|
{@const mergedProps = mergeProps(props, {
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
forceMount={true}
|
|
68
68
|
ref={contentState.opts.ref}
|
|
69
69
|
tooltip={true}
|
|
70
|
+
shouldRender={contentState.shouldRender}
|
|
70
71
|
>
|
|
71
72
|
{#snippet popper({ props, wrapperProps })}
|
|
72
73
|
{@const mergedProps = mergeProps(props, {
|
|
@@ -95,6 +96,7 @@
|
|
|
95
96
|
forceMount={false}
|
|
96
97
|
ref={contentState.opts.ref}
|
|
97
98
|
tooltip={true}
|
|
99
|
+
shouldRender={contentState.shouldRender}
|
|
98
100
|
>
|
|
99
101
|
{#snippet popper({ props, wrapperProps })}
|
|
100
102
|
{@const mergedProps = mergeProps(props, {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DOMContext, type WritableBoxedValues, type ReadableBoxedValues } from "svelte-toolbelt";
|
|
2
2
|
import type { OnChangeFn, RefAttachment, WithRefOpts } from "../../internal/types.js";
|
|
3
3
|
import type { FocusEventHandler, MouseEventHandler, PointerEventHandler } from "svelte/elements";
|
|
4
|
+
import { PresenceManager } from "../../internal/presence-manager.svelte.js";
|
|
4
5
|
export declare const tooltipAttrs: import("../../internal/attrs.js").CreateBitsAttrsReturn<readonly ["content", "trigger"]>;
|
|
5
6
|
interface TooltipProviderStateOpts extends ReadableBoxedValues<{
|
|
6
7
|
delayDuration: number;
|
|
@@ -44,6 +45,7 @@ export declare class TooltipRootState {
|
|
|
44
45
|
readonly disabled: boolean;
|
|
45
46
|
readonly ignoreNonKeyboardFocus: boolean;
|
|
46
47
|
contentNode: HTMLElement | null;
|
|
48
|
+
contentPresence: PresenceManager;
|
|
47
49
|
triggerNode: HTMLElement | null;
|
|
48
50
|
readonly stateAttr: string;
|
|
49
51
|
constructor(opts: TooltipRootStateOpts, provider: TooltipProviderState);
|
|
@@ -97,6 +99,7 @@ export declare class TooltipContentState {
|
|
|
97
99
|
onEscapeKeydown: (e: KeyboardEvent) => void;
|
|
98
100
|
onOpenAutoFocus: (e: Event) => void;
|
|
99
101
|
onCloseAutoFocus: (e: Event) => void;
|
|
102
|
+
get shouldRender(): boolean;
|
|
100
103
|
readonly snippetProps: {
|
|
101
104
|
open: boolean;
|
|
102
105
|
};
|