bits-ui 2.8.0 → 2.8.2
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 +6 -1
- package/dist/bits/accordion/accordion.svelte.js +15 -5
- package/dist/bits/alert-dialog/components/alert-dialog-content.svelte +6 -9
- package/dist/bits/aspect-ratio/aspect-ratio.svelte.d.ts +2 -1
- package/dist/bits/aspect-ratio/aspect-ratio.svelte.js +3 -1
- package/dist/bits/avatar/avatar.svelte.d.ts +4 -1
- package/dist/bits/avatar/avatar.svelte.js +9 -3
- package/dist/bits/calendar/calendar.svelte.d.ts +15 -1
- package/dist/bits/calendar/calendar.svelte.js +42 -14
- package/dist/bits/calendar/components/calendar-next-button.svelte +3 -1
- package/dist/bits/calendar/components/calendar-prev-button.svelte +3 -1
- package/dist/bits/checkbox/checkbox.svelte.d.ts +4 -1
- package/dist/bits/checkbox/checkbox.svelte.js +9 -3
- package/dist/bits/collapsible/collapsible.svelte.d.ts +4 -1
- package/dist/bits/collapsible/collapsible.svelte.js +9 -3
- package/dist/bits/command/command.svelte.d.ts +13 -1
- package/dist/bits/command/command.svelte.js +36 -12
- package/dist/bits/context-menu/components/context-menu-content.svelte +1 -1
- package/dist/bits/date-field/date-field.svelte.d.ts +8 -2
- package/dist/bits/date-field/date-field.svelte.js +18 -6
- package/dist/bits/date-range-field/date-range-field.svelte.d.ts +3 -1
- package/dist/bits/date-range-field/date-range-field.svelte.js +6 -2
- package/dist/bits/dialog/components/dialog-content.svelte +5 -7
- package/dist/bits/dialog/dialog.svelte.d.ts +9 -1
- package/dist/bits/dialog/dialog.svelte.js +33 -18
- package/dist/bits/dropdown-menu/components/dropdown-menu-content.svelte +3 -2
- package/dist/bits/label/label.svelte.d.ts +2 -1
- package/dist/bits/label/label.svelte.js +3 -1
- package/dist/bits/link-preview/link-preview.svelte.d.ts +3 -1
- package/dist/bits/link-preview/link-preview.svelte.js +6 -2
- package/dist/bits/menu/menu.svelte.d.ts +12 -1
- package/dist/bits/menu/menu.svelte.js +38 -26
- package/dist/bits/menubar/components/menubar-trigger.svelte +4 -3
- package/dist/bits/menubar/menubar.svelte.d.ts +4 -3
- package/dist/bits/menubar/menubar.svelte.js +9 -6
- package/dist/bits/meter/meter.svelte.d.ts +2 -1
- package/dist/bits/meter/meter.svelte.js +3 -1
- package/dist/bits/navigation-menu/components/navigation-menu-link.svelte +2 -1
- package/dist/bits/navigation-menu/components/navigation-menu-trigger.svelte +2 -1
- package/dist/bits/navigation-menu/navigation-menu.svelte.d.ts +14 -3
- package/dist/bits/navigation-menu/navigation-menu.svelte.js +33 -13
- package/dist/bits/pagination/pagination.svelte.d.ts +4 -1
- package/dist/bits/pagination/pagination.svelte.js +9 -3
- package/dist/bits/pin-input/pin-input.svelte.d.ts +4 -1
- package/dist/bits/pin-input/pin-input.svelte.js +8 -3
- package/dist/bits/popover/popover.svelte.d.ts +4 -1
- package/dist/bits/popover/popover.svelte.js +9 -3
- package/dist/bits/progress/progress.svelte.d.ts +2 -1
- package/dist/bits/progress/progress.svelte.js +3 -1
- package/dist/bits/radio-group/radio-group.svelte.d.ts +3 -1
- package/dist/bits/radio-group/radio-group.svelte.js +6 -2
- package/dist/bits/range-calendar/range-calendar.svelte.d.ts +4 -1
- package/dist/bits/range-calendar/range-calendar.svelte.js +9 -3
- package/dist/bits/rating-group/rating-group.svelte.d.ts +3 -1
- package/dist/bits/rating-group/rating-group.svelte.js +6 -2
- package/dist/bits/scroll-area/scroll-area.svelte.d.ts +8 -1
- package/dist/bits/scroll-area/scroll-area.svelte.js +20 -7
- package/dist/bits/select/select.svelte.d.ts +10 -1
- package/dist/bits/select/select.svelte.js +27 -9
- package/dist/bits/separator/separator.svelte.d.ts +2 -1
- package/dist/bits/separator/separator.svelte.js +3 -1
- package/dist/bits/slider/slider.svelte.d.ts +7 -1
- package/dist/bits/slider/slider.svelte.js +18 -6
- package/dist/bits/switch/switch.svelte.d.ts +3 -1
- package/dist/bits/switch/switch.svelte.js +6 -2
- package/dist/bits/tabs/tabs.svelte.d.ts +5 -1
- package/dist/bits/tabs/tabs.svelte.js +12 -4
- package/dist/bits/time-field/time-field.svelte.d.ts +7 -1
- package/dist/bits/time-field/time-field.svelte.js +18 -6
- package/dist/bits/time-range-field/time-range-field.svelte.d.ts +3 -1
- package/dist/bits/time-range-field/time-range-field.svelte.js +6 -2
- package/dist/bits/toggle/toggle.svelte.d.ts +2 -1
- package/dist/bits/toggle/toggle.svelte.js +3 -1
- package/dist/bits/toggle-group/toggle-group.svelte.d.ts +3 -1
- package/dist/bits/toggle-group/toggle-group.svelte.js +6 -2
- package/dist/bits/toolbar/toolbar.svelte.d.ts +6 -1
- package/dist/bits/toolbar/toolbar.svelte.js +15 -5
- package/dist/bits/tooltip/tooltip.svelte.d.ts +3 -1
- package/dist/bits/tooltip/tooltip.svelte.js +6 -2
- package/dist/bits/utilities/floating-layer/use-floating-layer.svelte.d.ts +9 -0
- package/dist/bits/utilities/floating-layer/use-floating-layer.svelte.js +6 -3
- package/dist/bits/utilities/focus-scope/focus-scope-manager.d.ts +12 -0
- package/dist/bits/utilities/focus-scope/focus-scope-manager.js +40 -0
- package/dist/bits/utilities/focus-scope/focus-scope.svelte +6 -8
- package/dist/bits/utilities/focus-scope/focus-scope.svelte.d.ts +1 -0
- package/dist/bits/utilities/focus-scope/focus-scope.svelte.js +204 -0
- package/dist/bits/utilities/focus-scope/types.d.ts +2 -6
- package/dist/bits/utilities/popper-layer/popper-layer-inner.svelte +2 -2
- package/dist/internal/focus.js +1 -1
- package/dist/internal/should-enable-focus-trap.d.ts +5 -0
- package/dist/internal/should-enable-focus-trap.js +5 -0
- package/dist/internal/types.d.ts +2 -1
- package/package.json +2 -2
- package/dist/bits/utilities/focus-scope/focus-scope-stack.svelte.d.ts +0 -14
- package/dist/bits/utilities/focus-scope/focus-scope-stack.svelte.js +0 -50
- package/dist/bits/utilities/focus-scope/use-focus-scope.svelte.d.ts +0 -49
- package/dist/bits/utilities/focus-scope/use-focus-scope.svelte.js +0 -218
- package/dist/internal/should-trap-focus.d.ts +0 -6
- package/dist/internal/should-trap-focus.js +0 -5
|
@@ -2,7 +2,6 @@ import { attachRef, box, } from "svelte-toolbelt";
|
|
|
2
2
|
import { Context } from "runed";
|
|
3
3
|
import { createBitsAttrs, getAriaExpanded, getDataOpenClosed } from "../../internal/attrs.js";
|
|
4
4
|
import { kbd } from "../../internal/kbd.js";
|
|
5
|
-
import { untrack } from "svelte";
|
|
6
5
|
import { OpenChangeComplete } from "../../internal/open-change-complete.js";
|
|
7
6
|
const dialogAttrs = createBitsAttrs({
|
|
8
7
|
component: "dialog",
|
|
@@ -58,9 +57,14 @@ export class DialogTriggerState {
|
|
|
58
57
|
}
|
|
59
58
|
opts;
|
|
60
59
|
root;
|
|
60
|
+
attachment;
|
|
61
61
|
constructor(opts, root) {
|
|
62
62
|
this.opts = opts;
|
|
63
63
|
this.root = root;
|
|
64
|
+
this.attachment = attachRef(this.opts.ref, (v) => {
|
|
65
|
+
this.root.triggerNode = v;
|
|
66
|
+
this.root.triggerId = v?.id;
|
|
67
|
+
});
|
|
64
68
|
this.onclick = this.onclick.bind(this);
|
|
65
69
|
this.onkeydown = this.onkeydown.bind(this);
|
|
66
70
|
}
|
|
@@ -89,10 +93,7 @@ export class DialogTriggerState {
|
|
|
89
93
|
onclick: this.onclick,
|
|
90
94
|
disabled: this.opts.disabled.current ? true : undefined,
|
|
91
95
|
...this.root.sharedProps,
|
|
92
|
-
...
|
|
93
|
-
this.root.triggerNode = v;
|
|
94
|
-
this.root.triggerId = v?.id;
|
|
95
|
-
})),
|
|
96
|
+
...this.attachment,
|
|
96
97
|
}));
|
|
97
98
|
}
|
|
98
99
|
export class DialogCloseState {
|
|
@@ -101,9 +102,11 @@ export class DialogCloseState {
|
|
|
101
102
|
}
|
|
102
103
|
opts;
|
|
103
104
|
root;
|
|
105
|
+
attachment;
|
|
104
106
|
constructor(opts, root) {
|
|
105
107
|
this.opts = opts;
|
|
106
108
|
this.root = root;
|
|
109
|
+
this.attachment = attachRef(this.opts.ref);
|
|
107
110
|
this.onclick = this.onclick.bind(this);
|
|
108
111
|
this.onkeydown = this.onkeydown.bind(this);
|
|
109
112
|
}
|
|
@@ -130,7 +133,7 @@ export class DialogCloseState {
|
|
|
130
133
|
disabled: this.opts.disabled.current ? true : undefined,
|
|
131
134
|
tabindex: 0,
|
|
132
135
|
...this.root.sharedProps,
|
|
133
|
-
...
|
|
136
|
+
...this.attachment,
|
|
134
137
|
}));
|
|
135
138
|
}
|
|
136
139
|
export class DialogActionState {
|
|
@@ -139,15 +142,17 @@ export class DialogActionState {
|
|
|
139
142
|
}
|
|
140
143
|
opts;
|
|
141
144
|
root;
|
|
145
|
+
attachment;
|
|
142
146
|
constructor(opts, root) {
|
|
143
147
|
this.opts = opts;
|
|
144
148
|
this.root = root;
|
|
149
|
+
this.attachment = attachRef(this.opts.ref);
|
|
145
150
|
}
|
|
146
151
|
props = $derived.by(() => ({
|
|
147
152
|
id: this.opts.id.current,
|
|
148
153
|
[this.root.getBitsAttr("action")]: "",
|
|
149
154
|
...this.root.sharedProps,
|
|
150
|
-
...
|
|
155
|
+
...this.attachment,
|
|
151
156
|
}));
|
|
152
157
|
}
|
|
153
158
|
export class DialogTitleState {
|
|
@@ -156,9 +161,11 @@ export class DialogTitleState {
|
|
|
156
161
|
}
|
|
157
162
|
opts;
|
|
158
163
|
root;
|
|
164
|
+
attachment;
|
|
159
165
|
constructor(opts, root) {
|
|
160
166
|
this.opts = opts;
|
|
161
167
|
this.root = root;
|
|
168
|
+
this.attachment = attachRef(this.opts.ref, (v) => (this.root.titleId = v?.id));
|
|
162
169
|
}
|
|
163
170
|
props = $derived.by(() => ({
|
|
164
171
|
id: this.opts.id.current,
|
|
@@ -166,7 +173,7 @@ export class DialogTitleState {
|
|
|
166
173
|
"aria-level": this.opts.level.current,
|
|
167
174
|
[this.root.getBitsAttr("title")]: "",
|
|
168
175
|
...this.root.sharedProps,
|
|
169
|
-
...
|
|
176
|
+
...this.attachment,
|
|
170
177
|
}));
|
|
171
178
|
}
|
|
172
179
|
export class DialogDescriptionState {
|
|
@@ -175,18 +182,20 @@ export class DialogDescriptionState {
|
|
|
175
182
|
}
|
|
176
183
|
opts;
|
|
177
184
|
root;
|
|
185
|
+
attachment;
|
|
178
186
|
constructor(opts, root) {
|
|
179
187
|
this.opts = opts;
|
|
180
188
|
this.root = root;
|
|
189
|
+
this.attachment = attachRef(this.opts.ref, (v) => {
|
|
190
|
+
this.root.descriptionNode = v;
|
|
191
|
+
this.root.descriptionId = v?.id;
|
|
192
|
+
});
|
|
181
193
|
}
|
|
182
194
|
props = $derived.by(() => ({
|
|
183
195
|
id: this.opts.id.current,
|
|
184
196
|
[this.root.getBitsAttr("description")]: "",
|
|
185
197
|
...this.root.sharedProps,
|
|
186
|
-
...
|
|
187
|
-
this.root.descriptionNode = v;
|
|
188
|
-
this.root.descriptionId = v?.id;
|
|
189
|
-
}),
|
|
198
|
+
...this.attachment,
|
|
190
199
|
}));
|
|
191
200
|
}
|
|
192
201
|
export class DialogContentState {
|
|
@@ -195,9 +204,14 @@ export class DialogContentState {
|
|
|
195
204
|
}
|
|
196
205
|
opts;
|
|
197
206
|
root;
|
|
207
|
+
attachment;
|
|
198
208
|
constructor(opts, root) {
|
|
199
209
|
this.opts = opts;
|
|
200
210
|
this.root = root;
|
|
211
|
+
this.attachment = attachRef(this.opts.ref, (v) => {
|
|
212
|
+
this.root.contentNode = v;
|
|
213
|
+
this.root.contentId = v?.id;
|
|
214
|
+
});
|
|
201
215
|
}
|
|
202
216
|
snippetProps = $derived.by(() => ({ open: this.root.opts.open.current }));
|
|
203
217
|
props = $derived.by(() => ({
|
|
@@ -213,10 +227,7 @@ export class DialogContentState {
|
|
|
213
227
|
},
|
|
214
228
|
tabindex: this.root.opts.variant.current === "alert-dialog" ? -1 : undefined,
|
|
215
229
|
...this.root.sharedProps,
|
|
216
|
-
...
|
|
217
|
-
this.root.contentNode = v;
|
|
218
|
-
this.root.contentId = v?.id;
|
|
219
|
-
}),
|
|
230
|
+
...this.attachment,
|
|
220
231
|
}));
|
|
221
232
|
}
|
|
222
233
|
export class DialogOverlayState {
|
|
@@ -225,9 +236,11 @@ export class DialogOverlayState {
|
|
|
225
236
|
}
|
|
226
237
|
opts;
|
|
227
238
|
root;
|
|
239
|
+
attachment;
|
|
228
240
|
constructor(opts, root) {
|
|
229
241
|
this.opts = opts;
|
|
230
242
|
this.root = root;
|
|
243
|
+
this.attachment = attachRef(this.opts.ref);
|
|
231
244
|
}
|
|
232
245
|
snippetProps = $derived.by(() => ({ open: this.root.opts.open.current }));
|
|
233
246
|
props = $derived.by(() => ({
|
|
@@ -237,7 +250,7 @@ export class DialogOverlayState {
|
|
|
237
250
|
pointerEvents: "auto",
|
|
238
251
|
},
|
|
239
252
|
...this.root.sharedProps,
|
|
240
|
-
...
|
|
253
|
+
...this.attachment,
|
|
241
254
|
}));
|
|
242
255
|
}
|
|
243
256
|
export class AlertDialogCancelState {
|
|
@@ -246,9 +259,11 @@ export class AlertDialogCancelState {
|
|
|
246
259
|
}
|
|
247
260
|
opts;
|
|
248
261
|
root;
|
|
262
|
+
attachment;
|
|
249
263
|
constructor(opts, root) {
|
|
250
264
|
this.opts = opts;
|
|
251
265
|
this.root = root;
|
|
266
|
+
this.attachment = attachRef(this.opts.ref, (v) => (this.root.cancelNode = v));
|
|
252
267
|
this.onclick = this.onclick.bind(this);
|
|
253
268
|
this.onkeydown = this.onkeydown.bind(this);
|
|
254
269
|
}
|
|
@@ -274,6 +289,6 @@ export class AlertDialogCancelState {
|
|
|
274
289
|
onkeydown: this.onkeydown,
|
|
275
290
|
tabindex: 0,
|
|
276
291
|
...this.root.sharedProps,
|
|
277
|
-
...
|
|
292
|
+
...this.attachment,
|
|
278
293
|
}));
|
|
279
294
|
}
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
onEscapeKeydown = noop,
|
|
21
21
|
onCloseAutoFocus = noop,
|
|
22
22
|
forceMount = false,
|
|
23
|
+
trapFocus = false,
|
|
23
24
|
...restProps
|
|
24
25
|
}: DropdownMenuContentProps = $props();
|
|
25
26
|
|
|
@@ -57,7 +58,7 @@
|
|
|
57
58
|
enabled={contentState.parentMenu.opts.open.current}
|
|
58
59
|
onInteractOutside={handleInteractOutside}
|
|
59
60
|
onEscapeKeydown={handleEscapeKeydown}
|
|
60
|
-
trapFocus
|
|
61
|
+
{trapFocus}
|
|
61
62
|
{loop}
|
|
62
63
|
forceMount={true}
|
|
63
64
|
{id}
|
|
@@ -85,7 +86,7 @@
|
|
|
85
86
|
open={contentState.parentMenu.opts.open.current}
|
|
86
87
|
onInteractOutside={handleInteractOutside}
|
|
87
88
|
onEscapeKeydown={handleEscapeKeydown}
|
|
88
|
-
trapFocus
|
|
89
|
+
{trapFocus}
|
|
89
90
|
{loop}
|
|
90
91
|
forceMount={false}
|
|
91
92
|
{id}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { BitsMouseEvent, WithRefOpts } from "../../internal/types.js";
|
|
1
|
+
import type { BitsMouseEvent, RefAttachment, WithRefOpts } from "../../internal/types.js";
|
|
2
2
|
interface LabelRootStateOpts extends WithRefOpts {
|
|
3
3
|
}
|
|
4
4
|
export declare class LabelRootState {
|
|
5
5
|
static create(opts: LabelRootStateOpts): LabelRootState;
|
|
6
6
|
readonly opts: LabelRootStateOpts;
|
|
7
|
+
readonly attachment: RefAttachment;
|
|
7
8
|
constructor(opts: LabelRootStateOpts);
|
|
8
9
|
onmousedown(e: BitsMouseEvent): void;
|
|
9
10
|
readonly props: {
|
|
@@ -9,8 +9,10 @@ export class LabelRootState {
|
|
|
9
9
|
return new LabelRootState(opts);
|
|
10
10
|
}
|
|
11
11
|
opts;
|
|
12
|
+
attachment;
|
|
12
13
|
constructor(opts) {
|
|
13
14
|
this.opts = opts;
|
|
15
|
+
this.attachment = attachRef(this.opts.ref);
|
|
14
16
|
this.onmousedown = this.onmousedown.bind(this);
|
|
15
17
|
}
|
|
16
18
|
onmousedown(e) {
|
|
@@ -21,6 +23,6 @@ export class LabelRootState {
|
|
|
21
23
|
id: this.opts.id.current,
|
|
22
24
|
[labelAttrs.root]: "",
|
|
23
25
|
onmousedown: this.onmousedown,
|
|
24
|
-
...
|
|
26
|
+
...this.attachment,
|
|
25
27
|
}));
|
|
26
28
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DOMContext, type ReadableBoxedValues, type WritableBoxedValues } from "svelte-toolbelt";
|
|
2
|
-
import type { BitsFocusEvent, BitsPointerEvent, OnChangeFn, WithRefOpts } from "../../internal/types.js";
|
|
2
|
+
import type { BitsFocusEvent, BitsPointerEvent, OnChangeFn, RefAttachment, WithRefOpts } from "../../internal/types.js";
|
|
3
3
|
interface LinkPreviewRootStateOpts extends WritableBoxedValues<{
|
|
4
4
|
open: boolean;
|
|
5
5
|
}>, ReadableBoxedValues<{
|
|
@@ -32,6 +32,7 @@ export declare class LinkPreviewTriggerState {
|
|
|
32
32
|
static create(opts: LinkPreviewTriggerStateOpts): LinkPreviewTriggerState;
|
|
33
33
|
readonly opts: LinkPreviewTriggerStateOpts;
|
|
34
34
|
readonly root: LinkPreviewRootState;
|
|
35
|
+
readonly attachment: RefAttachment;
|
|
35
36
|
constructor(opts: LinkPreviewTriggerStateOpts, root: LinkPreviewRootState);
|
|
36
37
|
onpointerenter(e: BitsPointerEvent): void;
|
|
37
38
|
onpointerleave(e: BitsPointerEvent): void;
|
|
@@ -59,6 +60,7 @@ export declare class LinkPreviewContentState {
|
|
|
59
60
|
static create(opts: LinkPreviewContentStateOpts): LinkPreviewContentState;
|
|
60
61
|
readonly opts: LinkPreviewContentStateOpts;
|
|
61
62
|
readonly root: LinkPreviewRootState;
|
|
63
|
+
readonly attachment: RefAttachment;
|
|
62
64
|
constructor(opts: LinkPreviewContentStateOpts, root: LinkPreviewRootState);
|
|
63
65
|
onpointerdown(e: BitsPointerEvent): void;
|
|
64
66
|
onpointerenter(e: BitsPointerEvent): void;
|
|
@@ -107,9 +107,11 @@ export class LinkPreviewTriggerState {
|
|
|
107
107
|
}
|
|
108
108
|
opts;
|
|
109
109
|
root;
|
|
110
|
+
attachment;
|
|
110
111
|
constructor(opts, root) {
|
|
111
112
|
this.opts = opts;
|
|
112
113
|
this.root = root;
|
|
114
|
+
this.attachment = attachRef(this.opts.ref, (v) => (this.root.triggerNode = v));
|
|
113
115
|
this.root.domContext = new DOMContext(opts.ref);
|
|
114
116
|
this.onpointerenter = this.onpointerenter.bind(this);
|
|
115
117
|
this.onpointerleave = this.onpointerleave.bind(this);
|
|
@@ -148,7 +150,7 @@ export class LinkPreviewTriggerState {
|
|
|
148
150
|
onfocus: this.onfocus,
|
|
149
151
|
onblur: this.onblur,
|
|
150
152
|
onpointerleave: this.onpointerleave,
|
|
151
|
-
...
|
|
153
|
+
...this.attachment,
|
|
152
154
|
}));
|
|
153
155
|
}
|
|
154
156
|
export class LinkPreviewContentState {
|
|
@@ -157,9 +159,11 @@ export class LinkPreviewContentState {
|
|
|
157
159
|
}
|
|
158
160
|
opts;
|
|
159
161
|
root;
|
|
162
|
+
attachment;
|
|
160
163
|
constructor(opts, root) {
|
|
161
164
|
this.opts = opts;
|
|
162
165
|
this.root = root;
|
|
166
|
+
this.attachment = attachRef(this.opts.ref, (v) => (this.root.contentNode = v));
|
|
163
167
|
this.root.domContext = new DOMContext(opts.ref);
|
|
164
168
|
this.onpointerdown = this.onpointerdown.bind(this);
|
|
165
169
|
this.onpointerenter = this.onpointerenter.bind(this);
|
|
@@ -221,7 +225,7 @@ export class LinkPreviewContentState {
|
|
|
221
225
|
onpointerdown: this.onpointerdown,
|
|
222
226
|
onpointerenter: this.onpointerenter,
|
|
223
227
|
onfocusout: this.onfocusout,
|
|
224
|
-
...
|
|
228
|
+
...this.attachment,
|
|
225
229
|
}));
|
|
226
230
|
popperProps = {
|
|
227
231
|
onInteractOutside: this.onInteractOutside,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DOMContext, type ReadableBoxedValues, type WritableBoxedValues } from "svelte-toolbelt";
|
|
2
2
|
import { Context } from "runed";
|
|
3
3
|
import { CustomEventDispatcher } from "../../internal/events.js";
|
|
4
|
-
import type { AnyFn, BitsFocusEvent, BitsKeyboardEvent, BitsMouseEvent, BitsPointerEvent, OnChangeFn, WithRefOpts } from "../../internal/types.js";
|
|
4
|
+
import type { AnyFn, BitsFocusEvent, BitsKeyboardEvent, BitsMouseEvent, BitsPointerEvent, OnChangeFn, RefAttachment, WithRefOpts } from "../../internal/types.js";
|
|
5
5
|
import type { Direction } from "../../shared/index.js";
|
|
6
6
|
import { IsUsingKeyboard } from "../../index.js";
|
|
7
7
|
import type { KeyboardEventHandler, PointerEventHandler } from "svelte/elements";
|
|
@@ -58,6 +58,7 @@ export declare class MenuContentState {
|
|
|
58
58
|
readonly parentMenu: MenuMenuState;
|
|
59
59
|
readonly rovingFocusGroup: RovingFocusGroup;
|
|
60
60
|
readonly domContext: DOMContext;
|
|
61
|
+
readonly attachment: RefAttachment;
|
|
61
62
|
search: string;
|
|
62
63
|
mounted: boolean;
|
|
63
64
|
constructor(opts: MenuContentStateOpts, parentMenu: MenuMenuState);
|
|
@@ -99,6 +100,7 @@ declare class MenuItemSharedState {
|
|
|
99
100
|
#private;
|
|
100
101
|
readonly opts: MenuItemSharedStateOpts;
|
|
101
102
|
readonly content: MenuContentState;
|
|
103
|
+
readonly attachment: RefAttachment;
|
|
102
104
|
constructor(opts: MenuItemSharedStateOpts, content: MenuContentState);
|
|
103
105
|
onpointermove(e: BitsPointerEvent): void;
|
|
104
106
|
onpointerleave(e: BitsPointerEvent): void;
|
|
@@ -163,6 +165,7 @@ export declare class MenuSubTriggerState {
|
|
|
163
165
|
readonly item: MenuItemSharedState;
|
|
164
166
|
readonly content: MenuContentState;
|
|
165
167
|
readonly submenu: MenuMenuState;
|
|
168
|
+
readonly attachment: RefAttachment;
|
|
166
169
|
constructor(opts: MenuSubTriggerStateOpts, item: MenuItemSharedState, content: MenuContentState, submenu: MenuMenuState);
|
|
167
170
|
onpointermove(e: BitsPointerEvent): void;
|
|
168
171
|
onpointerleave(e: BitsPointerEvent): void;
|
|
@@ -236,6 +239,7 @@ export declare class MenuGroupState {
|
|
|
236
239
|
static create(opts: MenuGroupStateOpts): MenuGroupState | MenuRadioGroupState;
|
|
237
240
|
readonly opts: MenuGroupStateOpts;
|
|
238
241
|
readonly root: MenuRootState;
|
|
242
|
+
readonly attachment: RefAttachment;
|
|
239
243
|
groupHeadingId: string | undefined;
|
|
240
244
|
constructor(opts: MenuGroupStateOpts, root: MenuRootState);
|
|
241
245
|
readonly props: {
|
|
@@ -250,6 +254,7 @@ export declare class MenuGroupHeadingState {
|
|
|
250
254
|
static create(opts: MenuGroupHeadingStateOpts): MenuGroupHeadingState;
|
|
251
255
|
readonly opts: MenuGroupHeadingStateOpts;
|
|
252
256
|
readonly group: MenuGroupState | MenuRadioGroupState | MenuCheckboxGroupState;
|
|
257
|
+
readonly attachment: RefAttachment;
|
|
253
258
|
constructor(opts: MenuGroupHeadingStateOpts, group: MenuGroupState | MenuRadioGroupState | MenuCheckboxGroupState);
|
|
254
259
|
readonly props: {
|
|
255
260
|
readonly id: string;
|
|
@@ -262,6 +267,7 @@ export declare class MenuSeparatorState {
|
|
|
262
267
|
static create(opts: MenuSeparatorStateOpts): MenuSeparatorState;
|
|
263
268
|
readonly opts: MenuSeparatorStateOpts;
|
|
264
269
|
readonly root: MenuRootState;
|
|
270
|
+
readonly attachment: RefAttachment;
|
|
265
271
|
constructor(opts: MenuSeparatorStateOpts, root: MenuRootState);
|
|
266
272
|
readonly props: {
|
|
267
273
|
readonly id: string;
|
|
@@ -284,6 +290,7 @@ export declare class MenuRadioGroupState {
|
|
|
284
290
|
static create(opts: MenuRadioGroupStateOpts): MenuGroupState | MenuRadioGroupState;
|
|
285
291
|
readonly opts: MenuRadioGroupStateOpts;
|
|
286
292
|
readonly content: MenuContentState;
|
|
293
|
+
readonly attachment: RefAttachment;
|
|
287
294
|
groupHeadingId: string | null;
|
|
288
295
|
root: MenuRootState;
|
|
289
296
|
constructor(opts: MenuRadioGroupStateOpts, content: MenuContentState);
|
|
@@ -304,6 +311,7 @@ export declare class MenuRadioItemState {
|
|
|
304
311
|
readonly opts: MenuRadioItemStateOpts;
|
|
305
312
|
readonly item: MenuItemState;
|
|
306
313
|
readonly group: MenuRadioGroupState;
|
|
314
|
+
readonly attachment: RefAttachment;
|
|
307
315
|
readonly isChecked: boolean;
|
|
308
316
|
constructor(opts: MenuRadioItemStateOpts, item: MenuItemState, group: MenuRadioGroupState);
|
|
309
317
|
selectValue(): void;
|
|
@@ -336,6 +344,7 @@ export declare class DropdownMenuTriggerState {
|
|
|
336
344
|
static create(opts: DropdownMenuTriggerStateOpts): DropdownMenuTriggerState;
|
|
337
345
|
readonly opts: DropdownMenuTriggerStateOpts;
|
|
338
346
|
readonly parentMenu: MenuMenuState;
|
|
347
|
+
readonly attachment: RefAttachment;
|
|
339
348
|
constructor(opts: DropdownMenuTriggerStateOpts, parentMenu: MenuMenuState);
|
|
340
349
|
onpointerdown: PointerEventHandler<HTMLElement>;
|
|
341
350
|
onpointerup: PointerEventHandler<HTMLElement>;
|
|
@@ -362,6 +371,7 @@ export declare class ContextMenuTriggerState {
|
|
|
362
371
|
static create(opts: ContextMenuTriggerStateOpts): ContextMenuTriggerState;
|
|
363
372
|
readonly opts: ContextMenuTriggerStateOpts;
|
|
364
373
|
readonly parentMenu: MenuMenuState;
|
|
374
|
+
readonly attachment: RefAttachment;
|
|
365
375
|
virtualElement: import("svelte-toolbelt").WritableBox<{
|
|
366
376
|
getBoundingClientRect: () => DOMRect;
|
|
367
377
|
}>;
|
|
@@ -396,6 +406,7 @@ export declare class MenuCheckboxGroupState {
|
|
|
396
406
|
readonly opts: MenuCheckboxGroupStateOpts;
|
|
397
407
|
readonly content: MenuContentState;
|
|
398
408
|
readonly root: MenuRootState;
|
|
409
|
+
readonly attachment: RefAttachment;
|
|
399
410
|
groupHeadingId: string | null;
|
|
400
411
|
constructor(opts: MenuCheckboxGroupStateOpts, content: MenuContentState);
|
|
401
412
|
addValue(checkboxValue: string | undefined): void;
|
|
@@ -8,9 +8,7 @@ import { kbd } from "../../internal/kbd.js";
|
|
|
8
8
|
import { createBitsAttrs, getAriaChecked, getAriaDisabled, getAriaExpanded, getAriaOrientation, getDataDisabled, getDataOpenClosed, } from "../../internal/attrs.js";
|
|
9
9
|
import { IsUsingKeyboard } from "../../index.js";
|
|
10
10
|
import { getTabbableFrom } from "../../internal/tabbable.js";
|
|
11
|
-
import { FocusScopeContext } from "../utilities/focus-scope/use-focus-scope.svelte.js";
|
|
12
11
|
import { isTabbable } from "tabbable";
|
|
13
|
-
import { untrack } from "svelte";
|
|
14
12
|
import { DOMTypeahead } from "../../internal/dom-typeahead.svelte.js";
|
|
15
13
|
import { RovingFocusGroup } from "../../internal/roving-focus-group.js";
|
|
16
14
|
import { GraceArea } from "../../internal/grace-area.svelte.js";
|
|
@@ -47,11 +45,6 @@ export const menuAttrs = createBitsAttrs({
|
|
|
47
45
|
export class MenuRootState {
|
|
48
46
|
static create(opts) {
|
|
49
47
|
const root = new MenuRootState(opts);
|
|
50
|
-
FocusScopeContext.set({
|
|
51
|
-
get ignoreCloseAutoFocus() {
|
|
52
|
-
return root.ignoreCloseAutoFocus;
|
|
53
|
-
},
|
|
54
|
-
});
|
|
55
48
|
return MenuRootContext.set(root);
|
|
56
49
|
}
|
|
57
50
|
opts;
|
|
@@ -112,6 +105,7 @@ export class MenuContentState {
|
|
|
112
105
|
parentMenu;
|
|
113
106
|
rovingFocusGroup;
|
|
114
107
|
domContext;
|
|
108
|
+
attachment;
|
|
115
109
|
search = $state("");
|
|
116
110
|
#timer = 0;
|
|
117
111
|
#handleTypeaheadSearch;
|
|
@@ -121,6 +115,11 @@ export class MenuContentState {
|
|
|
121
115
|
this.opts = opts;
|
|
122
116
|
this.parentMenu = parentMenu;
|
|
123
117
|
this.domContext = new DOMContext(opts.ref);
|
|
118
|
+
this.attachment = attachRef(this.opts.ref, (v) => {
|
|
119
|
+
if (this.parentMenu.contentNode !== v) {
|
|
120
|
+
this.parentMenu.contentNode = v;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
124
123
|
parentMenu.contentId = opts.id;
|
|
125
124
|
this.#isSub = opts.isSub ?? false;
|
|
126
125
|
this.onkeydown = this.onkeydown.bind(this);
|
|
@@ -196,9 +195,8 @@ export class MenuContentState {
|
|
|
196
195
|
rootMenu = rootMenu.parentMenu;
|
|
197
196
|
}
|
|
198
197
|
// if for some unforeseen reason the root menu has no trigger, we bail
|
|
199
|
-
if (!rootMenu.triggerNode)
|
|
198
|
+
if (!rootMenu.triggerNode)
|
|
200
199
|
return;
|
|
201
|
-
}
|
|
202
200
|
// cancel default tab behavior
|
|
203
201
|
e.preventDefault();
|
|
204
202
|
// find the next/previous tabbable
|
|
@@ -327,13 +325,7 @@ export class MenuContentState {
|
|
|
327
325
|
style: {
|
|
328
326
|
pointerEvents: "auto",
|
|
329
327
|
},
|
|
330
|
-
...
|
|
331
|
-
untrack(() => {
|
|
332
|
-
if (this.parentMenu.contentNode !== v) {
|
|
333
|
-
this.parentMenu.contentNode = v;
|
|
334
|
-
}
|
|
335
|
-
});
|
|
336
|
-
}),
|
|
328
|
+
...this.attachment,
|
|
337
329
|
}));
|
|
338
330
|
popperProps = {
|
|
339
331
|
onCloseAutoFocus: (e) => this.onCloseAutoFocus(e),
|
|
@@ -342,10 +334,12 @@ export class MenuContentState {
|
|
|
342
334
|
class MenuItemSharedState {
|
|
343
335
|
opts;
|
|
344
336
|
content;
|
|
337
|
+
attachment;
|
|
345
338
|
#isFocused = $state(false);
|
|
346
339
|
constructor(opts, content) {
|
|
347
340
|
this.opts = opts;
|
|
348
341
|
this.content = content;
|
|
342
|
+
this.attachment = attachRef(this.opts.ref);
|
|
349
343
|
this.onpointermove = this.onpointermove.bind(this);
|
|
350
344
|
this.onpointerleave = this.onpointerleave.bind(this);
|
|
351
345
|
this.onfocus = this.onfocus.bind(this);
|
|
@@ -403,7 +397,7 @@ class MenuItemSharedState {
|
|
|
403
397
|
onpointerleave: this.onpointerleave,
|
|
404
398
|
onfocus: this.onfocus,
|
|
405
399
|
onblur: this.onblur,
|
|
406
|
-
...
|
|
400
|
+
...this.attachment,
|
|
407
401
|
}));
|
|
408
402
|
}
|
|
409
403
|
export class MenuItemState {
|
|
@@ -491,12 +485,14 @@ export class MenuSubTriggerState {
|
|
|
491
485
|
item;
|
|
492
486
|
content;
|
|
493
487
|
submenu;
|
|
488
|
+
attachment;
|
|
494
489
|
#openTimer = null;
|
|
495
490
|
constructor(opts, item, content, submenu) {
|
|
496
491
|
this.opts = opts;
|
|
497
492
|
this.item = item;
|
|
498
493
|
this.content = content;
|
|
499
494
|
this.submenu = submenu;
|
|
495
|
+
this.attachment = attachRef(this.opts.ref, (v) => (this.submenu.triggerNode = v));
|
|
500
496
|
this.onpointerleave = this.onpointerleave.bind(this);
|
|
501
497
|
this.onpointermove = this.onpointermove.bind(this);
|
|
502
498
|
this.onkeydown = this.onkeydown.bind(this);
|
|
@@ -576,7 +572,7 @@ export class MenuSubTriggerState {
|
|
|
576
572
|
onpointermove: this.onpointermove,
|
|
577
573
|
onpointerleave: this.onpointerleave,
|
|
578
574
|
onkeydown: this.onkeydown,
|
|
579
|
-
...
|
|
575
|
+
...this.attachment,
|
|
580
576
|
}, this.item.props));
|
|
581
577
|
}
|
|
582
578
|
export class MenuCheckboxItemState {
|
|
@@ -634,17 +630,19 @@ export class MenuGroupState {
|
|
|
634
630
|
}
|
|
635
631
|
opts;
|
|
636
632
|
root;
|
|
633
|
+
attachment;
|
|
637
634
|
groupHeadingId = $state(undefined);
|
|
638
635
|
constructor(opts, root) {
|
|
639
636
|
this.opts = opts;
|
|
640
637
|
this.root = root;
|
|
638
|
+
this.attachment = attachRef(this.opts.ref);
|
|
641
639
|
}
|
|
642
640
|
props = $derived.by(() => ({
|
|
643
641
|
id: this.opts.id.current,
|
|
644
642
|
role: "group",
|
|
645
643
|
"aria-labelledby": this.groupHeadingId,
|
|
646
644
|
[this.root.getBitsAttr("group")]: "",
|
|
647
|
-
...
|
|
645
|
+
...this.attachment,
|
|
648
646
|
}));
|
|
649
647
|
}
|
|
650
648
|
export class MenuGroupHeadingState {
|
|
@@ -660,15 +658,17 @@ export class MenuGroupHeadingState {
|
|
|
660
658
|
}
|
|
661
659
|
opts;
|
|
662
660
|
group;
|
|
661
|
+
attachment;
|
|
663
662
|
constructor(opts, group) {
|
|
664
663
|
this.opts = opts;
|
|
665
664
|
this.group = group;
|
|
665
|
+
this.attachment = attachRef(this.opts.ref, (v) => (this.group.groupHeadingId = v?.id));
|
|
666
666
|
}
|
|
667
667
|
props = $derived.by(() => ({
|
|
668
668
|
id: this.opts.id.current,
|
|
669
669
|
role: "group",
|
|
670
670
|
[this.group.root.getBitsAttr("group-heading")]: "",
|
|
671
|
-
...
|
|
671
|
+
...this.attachment,
|
|
672
672
|
}));
|
|
673
673
|
}
|
|
674
674
|
export class MenuSeparatorState {
|
|
@@ -677,15 +677,17 @@ export class MenuSeparatorState {
|
|
|
677
677
|
}
|
|
678
678
|
opts;
|
|
679
679
|
root;
|
|
680
|
+
attachment;
|
|
680
681
|
constructor(opts, root) {
|
|
681
682
|
this.opts = opts;
|
|
682
683
|
this.root = root;
|
|
684
|
+
this.attachment = attachRef(this.opts.ref);
|
|
683
685
|
}
|
|
684
686
|
props = $derived.by(() => ({
|
|
685
687
|
id: this.opts.id.current,
|
|
686
688
|
role: "group",
|
|
687
689
|
[this.root.getBitsAttr("separator")]: "",
|
|
688
|
-
...
|
|
690
|
+
...this.attachment,
|
|
689
691
|
}));
|
|
690
692
|
}
|
|
691
693
|
export class MenuArrowState {
|
|
@@ -706,12 +708,14 @@ export class MenuRadioGroupState {
|
|
|
706
708
|
}
|
|
707
709
|
opts;
|
|
708
710
|
content;
|
|
711
|
+
attachment;
|
|
709
712
|
groupHeadingId = $state(null);
|
|
710
713
|
root;
|
|
711
714
|
constructor(opts, content) {
|
|
712
715
|
this.opts = opts;
|
|
713
716
|
this.content = content;
|
|
714
717
|
this.root = content.parentMenu.root;
|
|
718
|
+
this.attachment = attachRef(this.opts.ref);
|
|
715
719
|
}
|
|
716
720
|
setValue(v) {
|
|
717
721
|
this.opts.value.current = v;
|
|
@@ -721,7 +725,7 @@ export class MenuRadioGroupState {
|
|
|
721
725
|
[this.root.getBitsAttr("radio-group")]: "",
|
|
722
726
|
role: "group",
|
|
723
727
|
"aria-labelledby": this.groupHeadingId,
|
|
724
|
-
...
|
|
728
|
+
...this.attachment,
|
|
725
729
|
}));
|
|
726
730
|
}
|
|
727
731
|
export class MenuRadioItemState {
|
|
@@ -734,11 +738,13 @@ export class MenuRadioItemState {
|
|
|
734
738
|
opts;
|
|
735
739
|
item;
|
|
736
740
|
group;
|
|
741
|
+
attachment;
|
|
737
742
|
isChecked = $derived.by(() => this.group.opts.value.current === this.opts.value.current);
|
|
738
743
|
constructor(opts, item, group) {
|
|
739
744
|
this.opts = opts;
|
|
740
745
|
this.item = item;
|
|
741
746
|
this.group = group;
|
|
747
|
+
this.attachment = attachRef(this.opts.ref);
|
|
742
748
|
}
|
|
743
749
|
selectValue() {
|
|
744
750
|
this.group.setValue(this.opts.value.current);
|
|
@@ -749,7 +755,7 @@ export class MenuRadioItemState {
|
|
|
749
755
|
role: "menuitemradio",
|
|
750
756
|
"aria-checked": getAriaChecked(this.isChecked, false),
|
|
751
757
|
"data-state": getCheckedState(this.isChecked),
|
|
752
|
-
...
|
|
758
|
+
...this.attachment,
|
|
753
759
|
}));
|
|
754
760
|
}
|
|
755
761
|
export class DropdownMenuTriggerState {
|
|
@@ -758,9 +764,11 @@ export class DropdownMenuTriggerState {
|
|
|
758
764
|
}
|
|
759
765
|
opts;
|
|
760
766
|
parentMenu;
|
|
767
|
+
attachment;
|
|
761
768
|
constructor(opts, parentMenu) {
|
|
762
769
|
this.opts = opts;
|
|
763
770
|
this.parentMenu = parentMenu;
|
|
771
|
+
this.attachment = attachRef(this.opts.ref, (v) => (this.parentMenu.triggerNode = v));
|
|
764
772
|
}
|
|
765
773
|
onpointerdown = (e) => {
|
|
766
774
|
if (this.opts.disabled.current)
|
|
@@ -814,7 +822,7 @@ export class DropdownMenuTriggerState {
|
|
|
814
822
|
onpointerdown: this.onpointerdown,
|
|
815
823
|
onpointerup: this.onpointerup,
|
|
816
824
|
onkeydown: this.onkeydown,
|
|
817
|
-
...
|
|
825
|
+
...this.attachment,
|
|
818
826
|
}));
|
|
819
827
|
}
|
|
820
828
|
export class ContextMenuTriggerState {
|
|
@@ -823,6 +831,7 @@ export class ContextMenuTriggerState {
|
|
|
823
831
|
}
|
|
824
832
|
opts;
|
|
825
833
|
parentMenu;
|
|
834
|
+
attachment;
|
|
826
835
|
#point = $state({ x: 0, y: 0 });
|
|
827
836
|
virtualElement = box({
|
|
828
837
|
getBoundingClientRect: () => DOMRect.fromRect({ width: 0, height: 0, ...this.#point }),
|
|
@@ -831,6 +840,7 @@ export class ContextMenuTriggerState {
|
|
|
831
840
|
constructor(opts, parentMenu) {
|
|
832
841
|
this.opts = opts;
|
|
833
842
|
this.parentMenu = parentMenu;
|
|
843
|
+
this.attachment = attachRef(this.opts.ref, (v) => (this.parentMenu.triggerNode = v));
|
|
834
844
|
this.oncontextmenu = this.oncontextmenu.bind(this);
|
|
835
845
|
this.onpointerdown = this.onpointerdown.bind(this);
|
|
836
846
|
this.onpointermove = this.onpointermove.bind(this);
|
|
@@ -899,7 +909,7 @@ export class ContextMenuTriggerState {
|
|
|
899
909
|
onpointercancel: this.onpointercancel,
|
|
900
910
|
onpointerup: this.onpointerup,
|
|
901
911
|
oncontextmenu: this.oncontextmenu,
|
|
902
|
-
...
|
|
912
|
+
...this.attachment,
|
|
903
913
|
}));
|
|
904
914
|
}
|
|
905
915
|
export class MenuCheckboxGroupState {
|
|
@@ -909,11 +919,13 @@ export class MenuCheckboxGroupState {
|
|
|
909
919
|
opts;
|
|
910
920
|
content;
|
|
911
921
|
root;
|
|
922
|
+
attachment;
|
|
912
923
|
groupHeadingId = $state(null);
|
|
913
924
|
constructor(opts, content) {
|
|
914
925
|
this.opts = opts;
|
|
915
926
|
this.content = content;
|
|
916
927
|
this.root = content.parentMenu.root;
|
|
928
|
+
this.attachment = attachRef(this.opts.ref);
|
|
917
929
|
}
|
|
918
930
|
addValue(checkboxValue) {
|
|
919
931
|
if (!checkboxValue)
|
|
@@ -939,7 +951,7 @@ export class MenuCheckboxGroupState {
|
|
|
939
951
|
[this.root.getBitsAttr("checkbox-group")]: "",
|
|
940
952
|
role: "group",
|
|
941
953
|
"aria-labelledby": this.groupHeadingId,
|
|
942
|
-
...
|
|
954
|
+
...this.attachment,
|
|
943
955
|
}));
|
|
944
956
|
}
|
|
945
957
|
export class MenuSubmenuState {
|