bits-ui 2.11.8 → 2.12.0

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.
@@ -20,10 +20,15 @@ export declare class DialogRootState {
20
20
  triggerId: string | undefined;
21
21
  descriptionId: string | undefined;
22
22
  cancelNode: HTMLElement | null;
23
- constructor(opts: DialogRootStateOpts);
23
+ nestedOpenCount: number;
24
+ readonly depth: number;
25
+ readonly parent: DialogRootState | null;
26
+ constructor(opts: DialogRootStateOpts, parent: DialogRootState | null);
24
27
  handleOpen(): void;
25
28
  handleClose(): void;
26
29
  getBitsAttr: typeof dialogAttrs.getAttr;
30
+ incrementNested(): void;
31
+ decrementNested(): void;
27
32
  readonly sharedProps: {
28
33
  readonly "data-state": "open" | "closed";
29
34
  };
@@ -137,8 +142,12 @@ export declare class DialogContentState {
137
142
  readonly style: {
138
143
  readonly pointerEvents: "auto";
139
144
  readonly outline: "none" | undefined;
145
+ readonly "--bits-dialog-depth": number;
146
+ readonly "--bits-dialog-nested-count": number;
140
147
  };
141
148
  readonly tabindex: -1 | undefined;
149
+ readonly "data-nested-open": "" | undefined;
150
+ readonly "data-nested": "" | undefined;
142
151
  };
143
152
  }
144
153
  interface DialogOverlayStateOpts extends WithRefOpts {
@@ -157,7 +166,11 @@ export declare class DialogOverlayState {
157
166
  readonly id: string;
158
167
  readonly style: {
159
168
  readonly pointerEvents: "auto";
169
+ readonly "--bits-dialog-depth": number;
170
+ readonly "--bits-dialog-nested-count": number;
160
171
  };
172
+ readonly "data-nested-open": "" | undefined;
173
+ readonly "data-nested": "" | undefined;
161
174
  };
162
175
  }
163
176
  interface AlertDialogCancelStateOpts extends WithRefOpts, ReadableBoxedValues<{
@@ -1,6 +1,6 @@
1
- import { attachRef, boxWith, } from "svelte-toolbelt";
1
+ import { attachRef, boxWith, onDestroyEffect, } from "svelte-toolbelt";
2
2
  import { Context, watch } from "runed";
3
- import { createBitsAttrs, boolToStr, getDataOpenClosed } from "../../internal/attrs.js";
3
+ import { createBitsAttrs, boolToStr, getDataOpenClosed, boolToEmptyStrOrUndef, } from "../../internal/attrs.js";
4
4
  import { kbd } from "../../internal/kbd.js";
5
5
  import { OpenChangeComplete } from "../../internal/open-change-complete.js";
6
6
  const dialogAttrs = createBitsAttrs({
@@ -10,7 +10,8 @@ const dialogAttrs = createBitsAttrs({
10
10
  const DialogRootContext = new Context("Dialog.Root | AlertDialog.Root");
11
11
  export class DialogRootState {
12
12
  static create(opts) {
13
- return DialogRootContext.set(new DialogRootState(opts));
13
+ const parent = DialogRootContext.getOr(null);
14
+ return DialogRootContext.set(new DialogRootState(opts, parent));
14
15
  }
15
16
  opts;
16
17
  triggerNode = $state(null);
@@ -21,8 +22,13 @@ export class DialogRootState {
21
22
  triggerId = $state(undefined);
22
23
  descriptionId = $state(undefined);
23
24
  cancelNode = $state(null);
24
- constructor(opts) {
25
+ nestedOpenCount = $state(0);
26
+ depth;
27
+ parent;
28
+ constructor(opts, parent) {
25
29
  this.opts = opts;
30
+ this.parent = parent;
31
+ this.depth = parent ? parent.depth + 1 : 0;
26
32
  this.handleOpen = this.handleOpen.bind(this);
27
33
  this.handleClose = this.handleClose.bind(this);
28
34
  new OpenChangeComplete({
@@ -33,6 +39,21 @@ export class DialogRootState {
33
39
  this.opts.onOpenChangeComplete.current(this.opts.open.current);
34
40
  },
35
41
  });
42
+ watch(() => this.opts.open.current, (isOpen) => {
43
+ if (!this.parent)
44
+ return;
45
+ if (isOpen) {
46
+ this.parent.incrementNested();
47
+ }
48
+ else {
49
+ this.parent.decrementNested();
50
+ }
51
+ }, { lazy: true });
52
+ onDestroyEffect(() => {
53
+ if (this.opts.open.current) {
54
+ this.parent?.decrementNested();
55
+ }
56
+ });
36
57
  }
37
58
  handleOpen() {
38
59
  if (this.opts.open.current)
@@ -47,6 +68,16 @@ export class DialogRootState {
47
68
  getBitsAttr = (part) => {
48
69
  return dialogAttrs.getAttr(part, this.opts.variant.current);
49
70
  };
71
+ incrementNested() {
72
+ this.nestedOpenCount++;
73
+ this.parent?.incrementNested();
74
+ }
75
+ decrementNested() {
76
+ if (this.nestedOpenCount === 0)
77
+ return;
78
+ this.nestedOpenCount--;
79
+ this.parent?.decrementNested();
80
+ }
50
81
  sharedProps = $derived.by(() => ({
51
82
  "data-state": getDataOpenClosed(this.opts.open.current),
52
83
  }));
@@ -231,8 +262,12 @@ export class DialogContentState {
231
262
  style: {
232
263
  pointerEvents: "auto",
233
264
  outline: this.root.opts.variant.current === "alert-dialog" ? "none" : undefined,
265
+ "--bits-dialog-depth": this.root.depth,
266
+ "--bits-dialog-nested-count": this.root.nestedOpenCount,
234
267
  },
235
268
  tabindex: this.root.opts.variant.current === "alert-dialog" ? -1 : undefined,
269
+ "data-nested-open": boolToEmptyStrOrUndef(this.root.nestedOpenCount > 0),
270
+ "data-nested": boolToEmptyStrOrUndef(this.root.parent !== null),
236
271
  ...this.root.sharedProps,
237
272
  ...this.attachment,
238
273
  }));
@@ -255,7 +290,11 @@ export class DialogOverlayState {
255
290
  [this.root.getBitsAttr("overlay")]: "",
256
291
  style: {
257
292
  pointerEvents: "auto",
293
+ "--bits-dialog-depth": this.root.depth,
294
+ "--bits-dialog-nested-count": this.root.nestedOpenCount,
258
295
  },
296
+ "data-nested-open": boolToEmptyStrOrUndef(this.root.nestedOpenCount > 0),
297
+ "data-nested": boolToEmptyStrOrUndef(this.root.parent !== null),
259
298
  ...this.root.sharedProps,
260
299
  ...this.attachment,
261
300
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bits-ui",
3
- "version": "2.11.8",
3
+ "version": "2.12.0",
4
4
  "license": "MIT",
5
5
  "repository": "github:huntabyte/bits-ui",
6
6
  "funding": "https://github.com/sponsors/huntabyte",