Skip to content

Commit

Permalink
Merge pull request #112 from skeletonlabs/dev
Browse files Browse the repository at this point in the history
Merge for doc updates - May 22, 2024
  • Loading branch information
endigo9740 authored May 22, 2024
2 parents 6292b89 + 08abb26 commit 70dfe32
Show file tree
Hide file tree
Showing 11 changed files with 255 additions and 56 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Floating UI Svelte

A Floating UI wrapper for Svelte.
Svelte bindings for [Floating UI](https://github.com/floating-ui/floating-ui). Based on [Floating UI React](https://floating-ui.com/docs/react).

## Attribution

Based on [Floating UI](https://github.com/floating-ui/floating-ui) and [Floating UI React](https://floating-ui.com/docs/react). Maintained by [Hugo Korte](https://github.com/Hugos68), [Skeleton Labs](https://www.skeletonlabs.co/), and the [Svelte community](https://svelte.dev/).
Maintained by [Hugo Korte](https://github.com/Hugos68), [Skeleton Labs](https://www.skeletonlabs.co/), and the [Svelte community](https://svelte.dev/).

## License

Expand Down
8 changes: 6 additions & 2 deletions src/app.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -125,16 +125,20 @@ footer .anchor {

/* Preview Examples */
.preview {
@apply border-2 border-dashed border-surface-500/30 p-10 flex justify-center items-center rounded-3xl;
@apply bg-surface-100 dark:bg-surface-900 ring-inset p-10 flex justify-center items-center rounded-lg;
}

/* Floating (required) */
.floating {
@apply w-max absolute top-0 left-0 z-10;
}

.popover-neutral {
@apply bg-surface-500 text-white p-8 max-w-sm rounded shadow-xl;
}

/* Buttons */
.btn-cta {
.btn-gradient {
@apply flex items-center gap-2;
@apply py-3 px-6 rounded shadow-lg;
@apply bg-gradient-to-br from-red-300 via-violet-300 to-cyan-400;
Expand Down
6 changes: 3 additions & 3 deletions src/docs/components/Navigation/Navigation.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@
</a>
</header>
<!-- Nav List -->
<div class="p-4 py-8 pb-32">
<div class="p-8 pt-0 pb-32">
{#each navigation as section}
<nav>
<span class="block font-bold text-white p-4">{section.label}</span>
<ul class="border-l border-surface-500/50 ml-4">
<span class="block font-bold text-white py-4">{section.label}</span>
<ul class="border-l border-surface-500/50">
{#each section.links as link}
<li>
<a
Expand Down
1 change: 0 additions & 1 deletion src/routes/(inner)/api/floating-arrow/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ const floating = useFloating({
<FloatingArrow
bind:this="{arrowRef}"
context="{floating.context}"
classes="fill-surface-500"
/>
</div>
`}
Expand Down
50 changes: 34 additions & 16 deletions src/routes/(inner)/docs/getting-started/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import CodeBlock from '$docs/components/CodeBlock/CodeBlock.svelte';
import SsrRaw from './ssr.svelte?raw';
import SsrRaw from './ExampleSsr.svelte?raw';
</script>

<div class="space-y-10">
Expand All @@ -14,16 +14,19 @@
</header>
<!-- Supports -->
<section class="space-y-8">
<h2 class="h2">Support</h2>
<!-- prettier-ignore -->
<h2 class="h2">Requirements</h2>
<p>
Supports <u>Svelte v5</u> projects created with <a class="anchor" href="https://kit.svelte.dev/" target="_blank">SvelteKit</a>, <a class="anchor" href="https://vitejs.dev/" target="_blank">Vite/Svelte</a>, or <a class="anchor" href="https://astro.build/" target="_blank">Astro</a>.
Supports projects created using <a class="anchor" href="https://svelte.dev/" target="_blank">
Svelte v5
</a>.
</p>
</section>
<!-- Install -->
<section class="space-y-8">
<h2 class="h2">Install</h2>
<p>To install Floating UI, use your package manager of choice.</p>
<p>
Install <strong class="highlight">Floating UI Svelte</strong> using your package manager of choice.
</p>
<CodeBlock
lang="bash"
code={`
Expand All @@ -32,17 +35,24 @@ npm install @skeletonlabs/floating-ui-svelte
# yarn install @skeletonlabs/floating-ui-svelte
# bun install @skeletonlabs/floating-ui-svelte
`}
highlight={1}
/>
</section>
<!-- Usage -->
<section class="space-y-8">
<h2 class="h2">Usage</h2>
<h3 class="h3">Making elements "float</h3>
<h3 class="h3">Floating UI Features</h3>
<!-- prettier-ignore -->
<p>
Floating UI Svelte exposes all Floating UI <a href="https://floating-ui.com/docs/middleware" target="_blank" class="anchor">middleware</a>, types, etc. You do not need to install <code class="code">@floating-ui/dom</code> seperately.
</p>
<CodeBlock
lang="ts"
code={`import { flip, type Strategy } from '@skeletonlabs/floating-ui-svelte';`}
/>
<h3 class="h3">Making elements "float"</h3>
<p>
The following styles must be applied to any and all floating elements. We recommend using a
class as shown below. Note that Floating UI does not take an opinionated stance on z-index
stacking.
At minimum, the following styles must be applied to ensure floating elements do not disrupt
the flow of the document. This can be handled using a single reusable CSS class.
</p>
<CodeBlock
lang="css"
Expand All @@ -56,16 +66,24 @@ npm install @skeletonlabs/floating-ui-svelte
`}
/>
<CodeBlock lang="html" code={`<div class="floating">Some floating element.</div>`} />
<h3 class="h3">Z-Index Stacking</h3>
<p>
Please be aware that Floating UI does not take an opinionated stance on <a
href="https://floating-ui.com/docs/misc#z-index-stacking"
target="_blank"
class="anchor">z-index stacking</a
>.
</p>
</section>
<!-- Ceveats -->
<!-- Caveats -->
<section class="space-y-8">
<h2 class="h2">Caveats</h2>
<h3 class="h3">SSR</h3>
<h3 class="h3">Server-Side Rendering (SSR)</h3>
<p>
When SSR is enabled and the floating element is visible upon pageload it will first be
positioned in the top left of your screen until the position is calculated. This is usually
not desirable. To prevent this, you can utilize the <kbd class="kbd">isPositioned</kbd> prop
returned from the
When SSR is enabled and the floating element is visible upon page load it will first be
positioned in the top left of your screen. It will remain until the position is calculated. To
prevent this, you may utilize the <kbd class="kbd">isPositioned</kbd>
prop returned from the
<kbd class="kbd"><a class="anchor" href="/api/use-floating">useFloating</a></kbd> hook:
</p>
<CodeBlock lang="svelte" code={SsrRaw} />
Expand Down
162 changes: 162 additions & 0 deletions src/routes/(inner)/examples/popovers/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,173 @@
described in the sections below.
</p>
</header>
<!-- Essentials -->
<section class="space-y-8">
<h2 class="h2">Essentials</h2>
<p>An accessible popover component has the following qualities:</p>
<ul class="ul">
<li>
<span class="highlight">Dynamic anchor positioning</span>: The popover is positioned next to
its reference element, remaining anchored to it while avoiding collisions.
</li>
<li>
<span class="highlight">Events</span>: When the reference element is clicked, it toggles the
popover open or closed.
</li>
<li>
<span class="highlight">Dismissal</span>: When the user presses the
<kbd class="kbd">esc</kbd> key or outside the popover while it is open, it closes.
</li>
<li>
<span class="highlight">Role</span>: The elements are given relevant role and ARIA
attributes to be accessible to screen readers.
</li>
<li>
<span class="highlight">Focus management</span>: Focus is managed for non-modal or modal
behavior.
</li>
</ul>
</section>
<!-- Example -->
<section class="space-y-8">
<h2 class="h2">Example</h2>
<Preview>
{#snippet preview()}<Example />{/snippet}
{#snippet code()}<CodeBlock code={ExampleRaw} lang="svelte" />{/snippet}
</Preview>
</section>
<!-- Open State -->
<section class="space-y-8">
<h2 class="h2">Open State</h2>
<CodeBlock code={`let open = $state(false);`} lang="ts" />
<p>
<code class="code">open</code> determines whether or not the popover is currently open on the screen.
It is used for conditional rendering.
</p>
</section>
<h2 class="h2">Basic Popover</h2>
<!-- useFloating Hook -->
<section class="space-y-8">
<h3 class="h3">useFloating Hook</h3>
<p>
The <a class="anchor" href="/api/use-floating">useFloating</a> hook provides positioning and context
for our popover. We need to pass it some information:
</p>
<CodeBlock code={`const floating = useFloating({ /* ...settings... */ });`} lang="ts" />
<ul class="ul">
<li>
<code class="code">open</code>: The open state from our <code class="code">useState()</code>
Hook above.
</li>
<li>
<code class="code">onOpenChange</code>: A callback function that will be called when the
popover is opened or closed. We’ll use this to update our <code class="code">open</code> state.
</li>
<li>
<code class="code">middleware</code>: Import and pass middleware to the array that ensure
the popover remains on the screen, no matter where it ends up being positioned.
</li>
<li>
<code class="code">whileElementsMounted</code>: Ensure the popover remains anchored to the
reference element by updating the position when necessary, only while both the reference and
floating elements are mounted for performance.
</li>
</ul>
</section>
<!-- Interaction Hooks -->
<section class="space-y-8">
<h3 class="h3">Interaction Hooks</h3>
<p>
The <a class="anchor" href="/api/use-interactions">useInteractions</a> hooks returns an object
containing keys of props that enable the popover to be opened, closed, or accessible to screen
readers. Using the
<code class="code">context</code> that was returned from the Hook, call the interaction Hooks.
</p>
<CodeBlock
code={`
const role = useRole(floating.context);
const click = useClick(floating.context);
const dismiss = useDismiss(floating.context);
const interactions = useInteractions([role, click, dismiss]);
`}
lang="ts"
/>
<ul class="ul">
<li>
<code class="code">useClick()</code>: adds the ability to toggle the popover open or closed
when the reference element is clicked.
</li>
<li>
<code class="code">useDismiss()</code>: adds the ability to dismiss the popover when the
user presses the <kbd class="kbd">esc</kbd> key or presses outside of the popover.
</li>
<li>
<code class="code">useRole()</code>: adds the correct ARIA attributes for a
<code class="code">dialog</code> to the popover and reference elements.
</li>
</ul>
<p>
Finally, <code class="code">useInteractions()</code> merges all of their props into prop getters
which can be used for rendering.
</p>
</section>
<!-- Rendering -->
<section class="space-y-8">
<h3 class="h3">Rendering</h3>
<p>Now we have all the variables and Hooks set up, we can render out our elements.</p>
<CodeBlock
lang="html"
code={`
<!-- Reference Element -->
<button
bind:this={floating.elements.reference}
{...interactions.getReferenceProps()}
class="btn-gradient"
>
Click Me
</button>\n
<!-- Floating Element -->
{#if open}
<div
bind:this={floating.elements.floating}
style={floating.floatingStyles}
{...interactions.getFloatingProps()}
class="floating popover-neutral"
transition:fade={{ duration: 200 }}
>
<p>
You can press the <kbd class="kbd">esc</kbd> key or click outside to
<strong>*dismiss*</strong> this floating element.
</p>
<FloatingArrow bind:ref={elemArrow} context={floating.context} fill="#575969" />
</div>
{/if}
`}
/>
<ul class="ul">
<li>
<code class="code">{`{...getReferenceProps()}`}</code> /
<code class="code">{`{...getFloatingProps()}`}</code>
spreads the props from the interaction Hooks onto the relevant elements. They contain props like
<code class="code">onClick</code>, <code class="code">aria-expanded</code>, etc.
</li>
<!-- TODO: flush out when FloatingManager available. -->
<li class="opacity-50 line-through">
COMING SOON: <code class="code">{`<FloatingFocusManager />`}</code> is a component that manages
focus of the popover for non-modal or modal behavior. It should directly wrap the floating element
and only be rendered when the popover is also rendered.
</li>
</ul>
</section>

<!-- TODO: flush out when FloatingManager available. -->

<!-- Modals and Non-Modal Behavior -->
<section class="space-y-8">
<h3 class="h3">Modals and Non-Modal Behavior</h3>
<div class="alert">Coming Soon.</div>
</section>
<!-- Reusable Popover Component -->
<h2 class="h2">Reusable Popover Component</h2>
<div class="alert">Coming Soon.</div>
</div>
6 changes: 3 additions & 3 deletions src/routes/(inner)/examples/popovers/Example.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<button
bind:this={floating.elements.reference}
{...interactions.getReferenceProps()}
class="btn-cta"
class="btn-gradient"
>
Click Me
</button>
Expand All @@ -52,14 +52,14 @@
bind:this={floating.elements.floating}
style={floating.floatingStyles}
{...interactions.getFloatingProps()}
class="floating bg-surface-500 text-white p-8 max-w-sm rounded shadow-xl"
class="floating popover-neutral"
transition:fade={{ duration: 200 }}
>
<p>
You can press the <kbd class="kbd">esc</kbd> key or click outside to
<strong>*dismiss*</strong> this floating element.
</p>
<FloatingArrow bind:ref={elemArrow} context={floating.context} class="fill-surface-500" />
<FloatingArrow bind:ref={elemArrow} context={floating.context} fill="#575969" />
</div>
{/if}
</div>
Loading

0 comments on commit 70dfe32

Please sign in to comment.