Skip to content

Commit cc7c431

Browse files
committed
more tests
1 parent fd6d3a2 commit cc7c431

File tree

10 files changed

+388
-45
lines changed

10 files changed

+388
-45
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { HTMLAttributes } from "svelte/elements";
2+
import { FOCUSABLE_ATTRIBUTE } from "../internal/get-floating-focus-element.js";
23

34
const ACTIVE_KEY = "active";
45
const SELECTED_KEY = "selected";
@@ -44,7 +45,10 @@ function mergeProps<Key extends keyof ElementProps>(
4445
}
4546

4647
return {
47-
...(elementKey === "floating" && { tabindex: -1 }),
48+
...(elementKey === "floating" && {
49+
tabindex: -1,
50+
[FOCUSABLE_ATTRIBUTE]: "",
51+
}),
4852
...domUserProps,
4953
...propsList
5054
.map((value) => {

packages/floating-ui-svelte/src/internal/get-floating-focus-element.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ export function getFloatingFocusElement(
88
// This indicates the floating element is acting as a positioning wrapper, and
99
// so focus should be managed on the child element with the event handlers and
1010
// aria props.
11-
return floatingElement.hasAttribute(FOCUSABLE_ATTRIBUTE)
11+
const res = floatingElement.hasAttribute(FOCUSABLE_ATTRIBUTE)
1212
? floatingElement
1313
: floatingElement.querySelector(`[${FOCUSABLE_ATTRIBUTE}]`) ||
14-
floatingElement;
14+
floatingElement;
15+
console.log(res);
16+
return res as HTMLElement;
1517
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<script lang="ts">
2+
import FloatingFocusManager from "../../../../src/components/floating-focus-manager/floating-focus-manager.svelte";
3+
import {
4+
useDismiss,
5+
useFloating,
6+
useInteractions,
7+
} from "../../../../src/index.js";
8+
9+
let {
10+
open,
11+
onOpenChange,
12+
}: { open: boolean; onOpenChange: (v: boolean) => void } = $props();
13+
14+
const f = useFloating({
15+
open,
16+
onOpenChange,
17+
});
18+
19+
const ints = useInteractions([useDismiss(f.context)]);
20+
</script>
21+
22+
<FloatingFocusManager context={f.context}>
23+
<div bind:this={f.floating} {...ints.getFloatingProps()}>
24+
<button data-testid="child-reference"> child reference </button>
25+
</div>
26+
</FloatingFocusManager>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<script lang="ts">
2+
import FloatingFocusManager from "../../../../src/components/floating-focus-manager/floating-focus-manager.svelte";
3+
import {
4+
useClick,
5+
useDismiss,
6+
useFloating,
7+
useInteractions,
8+
} from "../../../../src/index.js";
9+
import ConnectedDrawer from "./connected-drawer.svelte";
10+
11+
let open = $state(false);
12+
let isDrawerOpen = $state(false);
13+
14+
const f = useFloating({
15+
open: () => open,
16+
onOpenChange: (v) => {
17+
open = v;
18+
},
19+
});
20+
21+
const ints = useInteractions([useClick(f.context), useDismiss(f.context)]);
22+
</script>
23+
24+
<button
25+
bind:this={f.reference}
26+
data-testid="parent-reference"
27+
{...ints.getReferenceProps()}>ref</button>
28+
{#if open}
29+
<FloatingFocusManager context={f.context}>
30+
<div bind:this={f.floating} {...ints.getFloatingProps()}>
31+
Parent Floating
32+
<button
33+
data-testid="parent-floating-reference"
34+
onclick={() => {
35+
isDrawerOpen = true;
36+
open = false;
37+
}}>parent floating ref</button>
38+
</div>
39+
</FloatingFocusManager>
40+
{/if}
41+
{#if isDrawerOpen}
42+
<ConnectedDrawer
43+
open={isDrawerOpen}
44+
onOpenChange={(v) => (isDrawerOpen = v)} />
45+
{/if}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<script lang="ts">
2+
import FloatingFocusManager from "../../../../src/components/floating-focus-manager/floating-focus-manager.svelte";
3+
import {
4+
useFloating,
5+
useInteractions,
6+
useRole,
7+
} from "../../../../src/index.js";
8+
9+
let open = $state(false);
10+
11+
const f = useFloating({
12+
open: () => open,
13+
onOpenChange: (v) => {
14+
open = v;
15+
},
16+
});
17+
18+
const ints = useInteractions([useRole(f.context)]);
19+
</script>
20+
21+
<button
22+
bind:this={f.reference}
23+
{...ints.getReferenceProps({
24+
onclick: () => (open = !open),
25+
})}>
26+
ref
27+
</button>
28+
29+
{#if open}
30+
<FloatingFocusManager context={f.context}>
31+
<div bind:this={f.floating} data-testid="outer">
32+
<div {...ints.getFloatingProps()} data-testid="inner"></div>
33+
</div>
34+
</FloatingFocusManager>
35+
{/if}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<script lang="ts">
2+
import FloatingFocusManager from "../../../../src/components/floating-focus-manager/floating-focus-manager.svelte";
3+
import {
4+
useClick,
5+
useFloating,
6+
useInteractions,
7+
} from "../../../../src/index.js";
8+
9+
let { restoreFocus = true }: { restoreFocus?: boolean } = $props();
10+
11+
let open = $state(false);
12+
let removedIndex = $state(0);
13+
14+
const f = useFloating({
15+
open: () => open,
16+
onOpenChange: (v) => {
17+
open = v;
18+
},
19+
});
20+
21+
const ints = useInteractions([useClick(f.context)]);
22+
</script>
23+
24+
<button
25+
bind:this={f.reference}
26+
{...ints.getReferenceProps()}
27+
data-testid="reference">ref</button>
28+
{#if open}
29+
<FloatingFocusManager context={f.context} initialFocus={1} {restoreFocus}>
30+
<div
31+
bind:this={f.floating}
32+
{...ints.getFloatingProps()}
33+
data-testid="floating">
34+
{#if removedIndex < 3}
35+
<button onclick={() => (removedIndex = removedIndex + 1)}>
36+
three
37+
</button>
38+
{/if}
39+
{#if removedIndex < 1}
40+
<button onclick={() => (removedIndex = removedIndex + 1)}>
41+
one
42+
</button>
43+
{/if}
44+
{#if removedIndex < 2}
45+
<button onclick={() => (removedIndex = removedIndex + 1)}>
46+
two
47+
</button>
48+
{/if}
49+
</div>
50+
</FloatingFocusManager>
51+
{/if}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<script lang="ts">
2+
import FloatingFocusManager from "../../../../src/components/floating-focus-manager/floating-focus-manager.svelte";
3+
import {
4+
useClick,
5+
useDismiss,
6+
useFloating,
7+
useInteractions,
8+
useRole,
9+
} from "../../../../src/index.js";
10+
11+
let open = $state(false);
12+
13+
const f = useFloating({
14+
open: () => open,
15+
onOpenChange: (v) => {
16+
open = v;
17+
},
18+
});
19+
20+
const ints = useInteractions([
21+
useRole(f.context),
22+
useDismiss(f.context),
23+
useClick(f.context),
24+
]);
25+
</script>
26+
27+
<div class="App">
28+
<!-- svelte-ignore a11y_role_has_required_aria_props -->
29+
<input
30+
bind:this={f.reference}
31+
{...ints.getReferenceProps()}
32+
data-testid="input"
33+
role="combobox" />
34+
{#if open}
35+
<FloatingFocusManager context={f.context}>
36+
<div
37+
bind:this={f.floating}
38+
style={f.floatingStyles}
39+
{...ints.getFloatingProps()}>
40+
<button>one</button>
41+
<button>two</button>
42+
</div>
43+
</FloatingFocusManager>
44+
{/if}
45+
</div>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<script lang="ts">
2+
import FloatingFocusManager from "../../../../src/components/floating-focus-manager/floating-focus-manager.svelte";
3+
import FloatingPortal from "../../../../src/components/floating-portal/floating-portal.svelte";
4+
import {
5+
useClick,
6+
useDismiss,
7+
useFloating,
8+
useInteractions,
9+
useRole,
10+
} from "../../../../src/index.js";
11+
12+
let open = $state(false);
13+
14+
const f = useFloating({
15+
open: () => open,
16+
onOpenChange: (v) => {
17+
open = v;
18+
},
19+
});
20+
21+
const ints = useInteractions([
22+
useRole(f.context),
23+
useDismiss(f.context),
24+
useClick(f.context),
25+
]);
26+
</script>
27+
28+
<div class="App">
29+
<!-- svelte-ignore a11y_role_has_required_aria_props -->
30+
<input
31+
bind:this={f.reference}
32+
{...ints.getReferenceProps()}
33+
data-testid="input"
34+
role="combobox" />
35+
{#if open}
36+
<FloatingPortal>
37+
<FloatingFocusManager
38+
context={f.context}
39+
initialFocus={-1}
40+
modal={false}>
41+
<div
42+
bind:this={f.floating}
43+
style={f.floatingStyles}
44+
{...ints.getFloatingProps()}>
45+
<button>one</button>
46+
<button>two</button>
47+
</div>
48+
</FloatingFocusManager>
49+
</FloatingPortal>
50+
{/if}
51+
<button>outside</button>
52+
</div>

0 commit comments

Comments
 (0)