Skip to content

Commit 1553c67

Browse files
committed
lets goooo
1 parent a747eb2 commit 1553c67

File tree

7 files changed

+62
-136
lines changed

7 files changed

+62
-136
lines changed

packages/floating-ui-svelte/src/components/floating-tree/floating-tree.svelte

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,14 @@
1414
1515
let nodes: FloatingNodeType[] = $state.raw([]);
1616
17-
const addNode = (node: FloatingNodeType) => {
18-
nodes = [...nodes, node];
19-
};
20-
21-
const removeNode = (node: FloatingNodeType) => {
22-
nodes = nodes.filter((n) => n !== node);
23-
};
24-
25-
const events = createPubSub();
26-
2717
FloatingTreeContext.set({
28-
addNode,
29-
removeNode,
30-
events,
18+
addNode: (node: FloatingNodeType) => {
19+
nodes = [...nodes, node];
20+
},
21+
removeNode: (node: FloatingNodeType) => {
22+
nodes = nodes.filter((n) => n !== node);
23+
},
24+
events: createPubSub(),
3125
get nodes() {
3226
return nodes;
3327
},

packages/floating-ui-svelte/src/hooks/use-dismiss.svelte.ts

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ import type { FloatingTreeType, MaybeGetter } from "../types.js";
1919
import { useFloatingTree } from "../components/floating-tree/hooks.svelte.js";
2020
import { getChildren } from "../internal/get-children.js";
2121
import { on } from "svelte/events";
22-
import { executeCallbacks } from "../internal/execute-callbacks.js";
2322
import { extract } from "../internal/extract.js";
2423
import { watch } from "../internal/watch.svelte.js";
2524
import type { ElementProps } from "./use-interactions.svelte.js";
25+
import { untrack } from "svelte";
2626

2727
const bubbleHandlerKeys = {
2828
pointerdown: "onpointerdown",
@@ -164,10 +164,11 @@ class DismissInteraction implements ElementProps {
164164

165165
$effect(() => {
166166
if (!this.context.open || !this.#enabled) return;
167-
168-
this.context.data.__escapeKeyBubbles = this.#bubbleOptions.escapeKey;
169-
this.context.data.__outsidePressBubbles =
170-
this.#bubbleOptions.outsidePress;
167+
untrack(() => {
168+
this.context.data.__escapeKeyBubbles = this.#bubbleOptions.escapeKey;
169+
this.context.data.__outsidePressBubbles =
170+
this.#bubbleOptions.outsidePress;
171+
});
171172

172173
let compositionTimeout = -1;
173174

@@ -206,6 +207,7 @@ class DismissInteraction implements ElementProps {
206207
this.#captureOptions.escapeKey
207208
? this.#closeOnEscapeKeyDownCapture
208209
: this.#closeOnEscapeKeyDown,
210+
{ capture: this.#captureOptions.escapeKey },
209211
),
210212
on(doc, "compositionstart", handleCompositionStart),
211213
on(doc, "compositionend", handleCompositionEnd),
@@ -220,6 +222,7 @@ class DismissInteraction implements ElementProps {
220222
this.#captureOptions.outsidePress
221223
? this.#closeOnPressOutsideCapture
222224
: this.#closeOnPressOutside,
225+
{ capture: this.#captureOptions.outsidePress },
223226
),
224227
);
225228
}
@@ -260,7 +263,9 @@ class DismissInteraction implements ElementProps {
260263
}
261264

262265
return () => {
263-
executeCallbacks(...listenersToRemove);
266+
for (const removeListener of listenersToRemove) {
267+
removeListener();
268+
}
264269
window.clearTimeout(compositionTimeout);
265270
};
266271
});
@@ -270,7 +275,7 @@ class DismissInteraction implements ElementProps {
270275
});
271276
}
272277

273-
#closeOnEscapeKeyDown(event: KeyboardEvent) {
278+
#closeOnEscapeKeyDown = (event: KeyboardEvent) => {
274279
if (
275280
!this.context.open ||
276281
!this.#enabled ||
@@ -290,31 +295,27 @@ class DismissInteraction implements ElementProps {
290295
event.stopPropagation();
291296

292297
if (children.length > 0) {
293-
let shouldDismiss = true;
294-
295-
for (const child of children) {
296-
if (child.context?.open && !child.context.data.__escapeKeyBubbles) {
297-
shouldDismiss = false;
298-
break;
299-
}
300-
}
298+
const hasOpenChild = children.some(
299+
(child) =>
300+
child.context?.open && !child.context.data.__escapeKeyBubbles,
301+
);
301302

302-
if (!shouldDismiss) return;
303+
if (hasOpenChild) return;
303304
}
304305
}
305306

306307
this.context.onOpenChange(false, event, "escape-key");
307-
}
308+
};
308309

309-
#closeOnEscapeKeyDownCapture(event: KeyboardEvent) {
310+
#closeOnEscapeKeyDownCapture = (event: KeyboardEvent) => {
310311
const callback = () => {
311312
this.#closeOnEscapeKeyDown(event);
312313
getTarget(event)?.removeEventListener("keydown", callback);
313314
};
314315
getTarget(event)?.addEventListener("keydown", callback);
315-
}
316+
};
316317

317-
#closeOnPressOutside(event: MouseEvent) {
318+
#closeOnPressOutside = (event: MouseEvent) => {
318319
const localInsideTree = this.#insideTree;
319320
this.#insideTree = false;
320321

@@ -373,7 +374,7 @@ class DismissInteraction implements ElementProps {
373374
}
374375

375376
// Check if the click occurred on the scrollbar
376-
if (isHTMLElement(target)) {
377+
if (isHTMLElement(target) && this.context.floating) {
377378
const lastTraversableNode = isLastTraversableNode(target);
378379
const style = getComputedStyle(target);
379380
const scrollRe = /auto|scroll/;
@@ -431,28 +432,24 @@ class DismissInteraction implements ElementProps {
431432
}
432433

433434
if (children.length > 0) {
434-
let shouldDismiss = true;
435-
436-
for (const child of children) {
437-
if (child.context?.open && !child.context.data.__outsidePressBubbles) {
438-
shouldDismiss = false;
439-
break;
440-
}
441-
}
435+
const hasOpenChild = children.some(
436+
(child) =>
437+
child.context?.open && !child.context.data.__outsidePressBubbles,
438+
);
442439

443-
if (!shouldDismiss) return;
440+
if (hasOpenChild) return;
444441
}
445442

446443
this.context.onOpenChange(false, event, "outside-press");
447-
}
444+
};
448445

449-
#closeOnPressOutsideCapture(event: MouseEvent) {
446+
#closeOnPressOutsideCapture = (event: MouseEvent) => {
450447
const callback = () => {
451448
this.#closeOnPressOutside(event);
452449
getTarget(event)?.removeEventListener(this.#outsidePressEvent, callback);
453450
};
454451
getTarget(event)?.addEventListener(this.#outsidePressEvent, callback);
455-
}
452+
};
456453

457454
#reference = $derived.by(() => {
458455
if (!this.#enabled) return {};

packages/floating-ui-svelte/src/internal/dom.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,12 @@ function getTarget(event: Event) {
7979
}
8080

8181
function isEventTargetWithin(event: Event, node: Node | null | undefined) {
82-
if (node == null) {
83-
return false;
84-
}
82+
if (node == null) return false;
8583

8684
if ("composedPath" in event) {
87-
return event.composedPath().includes(node);
85+
return (
86+
event.composedPath().includes(node) || node.contains(event.target as Node)
87+
);
8888
}
8989

9090
// TS thinks `event` is of type never as it assumes all browsers support composedPath, but browsers without shadow dom don't

pnpm-lock.yaml

Lines changed: 13 additions & 74 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sites/floating-ui-svelte.vercel.app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"lucide-svelte": "^0.469.0",
2121
"pagefind": "^1.3.0",
2222
"shiki": "^1.24.4",
23-
"svelte": "^5.16.0",
23+
"svelte": "^5.17.3",
2424
"svelte-check": "^4.1.1",
2525
"tailwindcss": "^3.4.17",
2626
"typescript": "^5.7.2",

0 commit comments

Comments
 (0)