Skip to content

Commit

Permalink
popover visual testing
Browse files Browse the repository at this point in the history
  • Loading branch information
huntabyte committed Jan 19, 2025
1 parent 093b866 commit e659564
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/floating-ui-svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/svelte": "^5.2.6",
"@testing-library/user-event": "^14.5.2",
"bits-ui": "1.0.0-next.78",
"clsx": "^2.1.1",
"csstype": "^3.1.3",
"lucide-svelte": "^0.469.0",
"resize-observer-polyfill": "^1.5.1",
"svelte": "^5.17.3",
"tailwindcss": "4.0.0-beta.9",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<script lang="ts">
import Button from "../button.svelte";
import Popover from "./popover.svelte";
import { Checkbox } from "bits-ui";
import Check from "lucide-svelte/icons/check";
let modal = $state(true);
</script>

<h1 class="text-5xl font-bold mb-8">Popover</h1>
<div
class="grid place-items-center border border-slate-400 rounded lg:w-[40rem] h-[20rem] mb-4">
<Popover {modal} bubbles={true}>
{#snippet children(ref, props)}
<Button bind:ref={ref.current} {...props}>My button</Button>
{/snippet}
{#snippet content({ labelId, descriptionId, close })}
<h2 id={labelId} class="text-2xl font-bold mb-2">Title</h2>
<p id={descriptionId} class="mb-2">Description</p>
<Popover {modal} bubbles={true}>
{#snippet content({ labelId, descriptionId, close })}
<h2 id={labelId} class="text-2xl font-bold mb-2">Title</h2>
<p id={descriptionId} class="mb-2">Description</p>
<Popover {modal} bubbles={false}>
{#snippet children(ref, props)}
<Button bind:ref={ref.current} {...props}
>My button</Button>
{/snippet}
{#snippet content({ labelId, descriptionId, close })}
<h2 id={labelId} class="text-2xl font-bold mb-2">
Title
</h2>
<p id={descriptionId} class="mb-2">Description</p>
<button onclick={close} class="font-bold">
Close
</button>
{/snippet}
</Popover>
<button onclick={close} class="font-bold"> Close </button>
{/snippet}
{#snippet children(ref, props)}
<Button bind:ref={ref.current} {...props}>My button</Button>
{/snippet}
</Popover>

<button onclick={close} class="font-bold"> Close </button>
{/snippet}
</Popover>
</div>

<label class="flex items-center">
<Checkbox.Root
class="bg-slate-900 text-white rounded w-5 h-5 mr-2 grid place-items-center shadow"
checked={modal}
onCheckedChange={(value) => (modal = value)}>
{#snippet children({ checked })}
{#if checked}
<Check class="size-5" />
{/if}
{/snippet}
</Checkbox.Root>
Modal focus management
</label>
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<script lang="ts">
import type { Placement } from "@floating-ui/utils";
import type { Snippet } from "svelte";
import {
box,
type WritableBox,
} from "../../../../src/internal/box.svelte.js";
import {
useClick,
useDismiss,
useFloating,
useFloatingNodeId,
useId,
useInteractions,
useRole,
} from "../../../../src/index.js";
import { autoUpdate, flip, offset, shift } from "@floating-ui/dom";
import FloatingNode from "../../../../src/components/floating-tree/floating-node.svelte";
import FloatingPortal from "../../../../src/components/floating-portal/floating-portal.svelte";
import FloatingFocusManager from "../../../../src/components/floating-focus-manager/floating-focus-manager.svelte";
let {
content,
placement,
children,
modal = true,
bubbles = true,
}: {
content: Snippet<
[
{
close: () => void;
labelId: string;
descriptionId: string;
},
]
>;
placement?: Placement;
modal?: boolean;
children?: Snippet<
[ref: WritableBox<Element | null>, props: Record<string, unknown>]
>;
bubbles?: boolean;
} = $props();
let open = $state(false);
const nodeId = useFloatingNodeId();
const ref = box<Element | null>(null);
const f = useFloating({
reference: () => ref.current,
onReferenceChange: (v) => {
ref.current = v;
},
open: () => open,
onOpenChange: (v) => {
open = v;
},
nodeId,
placement: () => placement,
middleware: [offset(10), flip(), shift()],
whileElementsMounted: autoUpdate,
});
const id = useId();
const labelId = `${id}-label`;
const descriptionId = `${id}-description`;
const ints = useInteractions([
useClick(f.context),
useRole(f.context),
useDismiss(f.context, { bubbles: () => bubbles }),
]);
</script>

<FloatingNode id={nodeId}>
{@render children?.(
ref,
ints.getReferenceProps({ "data-open": open ? "" : undefined })
)}

{#if open}
<FloatingPortal>
<FloatingFocusManager context={f.context} {modal}>
<div
class="bg-white border border-slate-900/10 shadow-md rounded px-4 py-6 bg-clip-padding"
bind:this={f.floating}
style={f.floatingStyles}
aria-labelledby={labelId}
aria-describedby={descriptionId}
{...ints.getFloatingProps()}>
{@render content({
labelId,
descriptionId,
close: () => (open = false),
})}
</div>
</FloatingFocusManager>
</FloatingPortal>
{/if}
</FloatingNode>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script lang="ts">
import Main from "../../components/popover/main.svelte";
</script>

<Main />
69 changes: 69 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e659564

Please sign in to comment.