Skip to content

Commit cf7e61d

Browse files
committed
further
1 parent f10821a commit cf7e61d

25 files changed

+122
-182
lines changed

packages/bits-ui/src/lib/bits/accordion/accordion.svelte.ts

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import type { Orientation } from "$lib/shared/index.js";
1919
import { createBitsAttrs } from "$lib/internal/attrs.js";
2020
import { RovingFocusGroup } from "$lib/internal/roving-focus-group.js";
2121
import { on } from "svelte/events";
22-
import { OpenChangeComplete } from "$lib/internal/open-change-complete.js";
22+
import { PresenceManager } from "$lib/internal/presence-manager.svelte.js";
2323

2424
const accordionAttrs = createBitsAttrs({
2525
component: "accordion",
@@ -186,31 +186,17 @@ export class AccordionItemState {
186186
);
187187
readonly attachment: RefAttachment;
188188
contentNode = $state<HTMLElement | null>(null);
189-
contentShouldRender = $state(false);
189+
contentPresence: PresenceManager;
190190

191191
constructor(opts: AccordionItemStateOpts) {
192192
this.opts = opts;
193193
this.root = opts.rootState;
194-
this.contentShouldRender = this.root.includesItem(this.opts.value.current);
195194
this.updateValue = this.updateValue.bind(this);
196195
this.attachment = attachRef(this.opts.ref);
197196

198-
watch(
199-
() => this.isActive,
200-
(isActive) => {
201-
if (!isActive) return;
202-
this.contentShouldRender = true;
203-
}
204-
);
205-
206-
new OpenChangeComplete({
197+
this.contentPresence = new PresenceManager({
207198
ref: boxWith(() => this.contentNode),
208199
open: boxWith(() => this.isActive),
209-
onComplete: () => {
210-
if (!this.isActive) {
211-
this.contentShouldRender = false;
212-
}
213-
},
214200
});
215201
}
216202

@@ -377,6 +363,10 @@ export class AccordionContentState {
377363
});
378364
};
379365

366+
get shouldRender() {
367+
return this.item.contentPresence.shouldRender;
368+
}
369+
380370
readonly snippetProps = $derived.by(() => ({ open: this.item.isActive }));
381371

382372
readonly props = $derived.by(
@@ -395,14 +385,14 @@ export class AccordionContentState {
395385
this.opts.hiddenUntilFound.current && !this.item.isActive
396386
? "until-found"
397387
: undefined,
398-
...(this.opts.hiddenUntilFound.current && !this.item.contentShouldRender
388+
...(this.opts.hiddenUntilFound.current && !this.shouldRender
399389
? {}
400390
: {
401391
hidden: this.opts.hiddenUntilFound.current
402-
? !this.item.contentShouldRender
392+
? !this.shouldRender
403393
: this.opts.forceMount.current
404394
? undefined
405-
: !this.item.contentShouldRender,
395+
: !this.shouldRender,
406396
}),
407397
...this.attachment,
408398
}) as const

packages/bits-ui/src/lib/bits/alert-dialog/components/alert-dialog-content.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
const mergedProps = $derived(mergeProps(restProps, contentState.props));
4141
</script>
4242

43-
{#if contentState.root.contentMounted || forceMount}
43+
{#if contentState.shouldRender || forceMount}
4444
<FocusScope
4545
ref={contentState.opts.ref}
4646
loop

packages/bits-ui/src/lib/bits/collapsible/collapsible.svelte.ts

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import type {
2020
RefAttachment,
2121
WithRefOpts,
2222
} from "$lib/internal/types.js";
23-
import { OpenChangeComplete } from "$lib/internal/open-change-complete.js";
2423
import { on } from "svelte/events";
24+
import { PresenceManager } from "$lib/internal/presence-manager.svelte.js";
2525

2626
const collapsibleAttrs = createBitsAttrs({
2727
component: "collapsible",
@@ -48,30 +48,18 @@ export class CollapsibleRootState {
4848
readonly opts: CollapsibleRootStateOpts;
4949
readonly attachment: RefAttachment;
5050
contentNode = $state<HTMLElement | null>(null);
51-
contentShouldRender = $state(false);
51+
contentPresence: PresenceManager;
5252
contentId = $state<string | undefined>(undefined);
5353

5454
constructor(opts: CollapsibleRootStateOpts) {
5555
this.opts = opts;
56-
this.contentShouldRender = opts.open.current;
5756
this.toggleOpen = this.toggleOpen.bind(this);
5857
this.attachment = attachRef(this.opts.ref);
5958

60-
watch(
61-
() => this.opts.open.current,
62-
(isOpen) => {
63-
if (!isOpen) return;
64-
this.contentShouldRender = true;
65-
}
66-
);
67-
68-
new OpenChangeComplete({
59+
this.contentPresence = new PresenceManager({
6960
ref: boxWith(() => this.contentNode),
7061
open: this.opts.open,
7162
onComplete: () => {
72-
if (!this.opts.open.current) {
73-
this.contentShouldRender = false;
74-
}
7563
this.opts.onOpenChangeComplete.current(this.opts.open.current);
7664
},
7765
});
@@ -189,6 +177,10 @@ export class CollapsibleContentState {
189177
});
190178
}
191179

180+
get shouldRender() {
181+
return this.root.contentPresence.shouldRender;
182+
}
183+
192184
readonly snippetProps = $derived.by(() => ({
193185
open: this.root.opts.open.current,
194186
}));
@@ -212,14 +204,14 @@ export class CollapsibleContentState {
212204
"data-state": getDataOpenClosed(this.root.opts.open.current),
213205
"data-disabled": boolToEmptyStrOrUndef(this.root.opts.disabled.current),
214206
[collapsibleAttrs.content]: "",
215-
...(this.opts.hiddenUntilFound.current && !this.root.contentShouldRender
207+
...(this.opts.hiddenUntilFound.current && !this.shouldRender
216208
? {}
217209
: {
218210
hidden: this.opts.hiddenUntilFound.current
219-
? !this.root.contentShouldRender
211+
? !this.shouldRender
220212
: this.opts.forceMount.current
221213
? undefined
222-
: !this.root.contentShouldRender,
214+
: !this.shouldRender,
223215
}),
224216
...this.attachment,
225217
}) as const

packages/bits-ui/src/lib/bits/context-menu/components/context-menu-content-static.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
{loop}
8080
{forceMount}
8181
{id}
82-
shouldRender={contentState.parentMenu.contentMounted}
82+
shouldRender={contentState.shouldRender}
8383
>
8484
{#snippet popper({ props })}
8585
{@const finalProps = mergeProps(props, {
@@ -112,7 +112,7 @@
112112
{loop}
113113
forceMount={false}
114114
{id}
115-
shouldRender={contentState.parentMenu.contentMounted}
115+
shouldRender={contentState.shouldRender}
116116
>
117117
{#snippet popper({ props })}
118118
{@const finalProps = mergeProps(props, {

packages/bits-ui/src/lib/bits/context-menu/components/context-menu-content.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
{trapFocus}
8787
{loop}
8888
{id}
89-
shouldRender={contentState.parentMenu.contentMounted}
89+
shouldRender={contentState.shouldRender}
9090
>
9191
{#snippet popper({ props, wrapperProps })}
9292
{@const finalProps = mergeProps(props, {
@@ -120,7 +120,7 @@
120120
{trapFocus}
121121
{loop}
122122
{id}
123-
shouldRender={contentState.parentMenu.contentMounted}
123+
shouldRender={contentState.shouldRender}
124124
>
125125
{#snippet popper({ props, wrapperProps })}
126126
{@const finalProps = mergeProps(props, {

packages/bits-ui/src/lib/bits/dialog/components/dialog-content.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
const mergedProps = $derived(mergeProps(restProps, contentState.props));
3939
</script>
4040

41-
{#if contentState.root.contentMounted || forceMount}
41+
{#if contentState.shouldRender || forceMount}
4242
<FocusScope
4343
ref={contentState.opts.ref}
4444
loop

packages/bits-ui/src/lib/bits/dialog/components/dialog-overlay.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
const mergedProps = $derived(mergeProps(restProps, overlayState.props));
2727
</script>
2828

29-
{#if overlayState.root.overlayMounted || forceMount}
29+
{#if overlayState.shouldRender || forceMount}
3030
{#if child}
3131
{@render child({ props: mergeProps(mergedProps), ...overlayState.snippetProps })}
3232
{:else}

packages/bits-ui/src/lib/bits/dialog/dialog.svelte.ts

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import type {
2020
WithRefOpts,
2121
} from "$lib/internal/types.js";
2222
import { kbd } from "$lib/internal/kbd.js";
23-
import { OpenChangeComplete } from "$lib/internal/open-change-complete.js";
23+
import { PresenceManager } from "$lib/internal/presence-manager.svelte.js";
2424

2525
type DialogVariant = "alert-dialog" | "dialog";
2626

@@ -59,47 +59,29 @@ export class DialogRootState {
5959
nestedOpenCount = $state(0);
6060
readonly depth: number;
6161
readonly parent: DialogRootState | null;
62-
contentMounted = $state(false);
63-
overlayMounted = $state(false);
62+
contentPresence: PresenceManager;
63+
overlayPresence: PresenceManager;
6464

6565
constructor(opts: DialogRootStateOpts, parent: DialogRootState | null) {
6666
this.opts = opts;
67-
this.contentMounted = opts.open.current;
6867
this.parent = parent;
6968
this.depth = parent ? parent.depth + 1 : 0;
7069
this.handleOpen = this.handleOpen.bind(this);
7170
this.handleClose = this.handleClose.bind(this);
7271

73-
watch(
74-
() => this.opts.open.current,
75-
(isOpen) => {
76-
if (!isOpen) return;
77-
this.contentMounted = true;
78-
this.overlayMounted = true;
79-
}
80-
);
81-
82-
new OpenChangeComplete({
72+
this.contentPresence = new PresenceManager({
8373
ref: boxWith(() => this.contentNode),
8474
open: this.opts.open,
8575
enabled: true,
8676
onComplete: () => {
8777
this.opts.onOpenChangeComplete.current(this.opts.open.current);
88-
if (!this.opts.open.current) {
89-
this.contentMounted = false;
90-
}
9178
},
9279
});
9380

94-
new OpenChangeComplete({
81+
this.overlayPresence = new PresenceManager({
9582
ref: boxWith(() => this.overlayNode),
9683
open: this.opts.open,
9784
enabled: true,
98-
onComplete: () => {
99-
if (!this.opts.open.current) {
100-
this.overlayMounted = false;
101-
}
102-
},
10385
});
10486

10587
watch(
@@ -406,6 +388,10 @@ export class DialogContentState {
406388
...this.attachment,
407389
}) as const
408390
);
391+
392+
get shouldRender() {
393+
return this.root.contentPresence.shouldRender;
394+
}
409395
}
410396

411397
interface DialogOverlayStateOpts extends WithRefOpts {}
@@ -442,6 +428,10 @@ export class DialogOverlayState {
442428
...this.attachment,
443429
}) as const
444430
);
431+
432+
get shouldRender() {
433+
return this.root.overlayPresence.shouldRender;
434+
}
445435
}
446436

447437
interface AlertDialogCancelStateOpts

packages/bits-ui/src/lib/bits/link-preview/components/link-preview-content-static.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
loop={false}
4848
preventScroll={false}
4949
forceMount={true}
50-
shouldRender={contentState.root.contentShouldRender}
50+
shouldRender={contentState.shouldRender}
5151
>
5252
{#snippet popper({ props })}
5353
{@const mergedProps = mergeProps(props, {
@@ -75,7 +75,7 @@
7575
loop={false}
7676
preventScroll={false}
7777
forceMount={false}
78-
shouldRender={contentState.root.contentShouldRender}
78+
shouldRender={contentState.shouldRender}
7979
>
8080
{#snippet popper({ props })}
8181
{@const mergedProps = mergeProps(props, {

packages/bits-ui/src/lib/bits/link-preview/components/link-preview-content.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
loop={false}
6666
preventScroll={false}
6767
forceMount={true}
68-
shouldRender={contentState.root.contentShouldRender}
68+
shouldRender={contentState.shouldRender}
6969
>
7070
{#snippet popper({ props, wrapperProps })}
7171
{@const mergedProps = mergeProps(props, {
@@ -94,7 +94,7 @@
9494
loop={false}
9595
preventScroll={false}
9696
forceMount={false}
97-
shouldRender={contentState.root.contentShouldRender}
97+
shouldRender={contentState.shouldRender}
9898
>
9999
{#snippet popper({ props, wrapperProps })}
100100
{@const mergedProps = mergeProps(props, {

0 commit comments

Comments
 (0)