Copy over a few more playground examples
This commit is contained in:
27
src/routes/disclosure/disclosure.svelte
Normal file
27
src/routes/disclosure/disclosure.svelte
Normal file
@@ -0,0 +1,27 @@
|
||||
<script>
|
||||
import {
|
||||
Disclosure,
|
||||
DisclosureButton,
|
||||
DisclosurePanel,
|
||||
Transition,
|
||||
} from "$lib";
|
||||
</script>
|
||||
|
||||
<div class="flex justify-center w-screen h-full p-12 bg-gray-50">
|
||||
<div class="w-full max-w-xs mx-auto">
|
||||
<Disclosure>
|
||||
<DisclosureButton>Trigger</DisclosureButton>
|
||||
|
||||
<Transition
|
||||
enter="transition duration-1000 ease-out"
|
||||
enterFrom="transform scale-95 opacity-0"
|
||||
enterTo="transform scale-100 opacity-100"
|
||||
leave="transition duration-1000 ease-out"
|
||||
leaveFrom="transform scale-100 opacity-100"
|
||||
leaveTo="transform scale-95 opacity-0"
|
||||
>
|
||||
<DisclosurePanel class="p-4 bg-white mt-4">Content</DisclosurePanel>
|
||||
</Transition>
|
||||
</Disclosure>
|
||||
</div>
|
||||
</div>
|
||||
126
src/routes/listbox/_PeopleList.svelte
Normal file
126
src/routes/listbox/_PeopleList.svelte
Normal file
@@ -0,0 +1,126 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
Listbox,
|
||||
ListboxButton,
|
||||
ListboxLabel,
|
||||
ListboxOption,
|
||||
ListboxOptions,
|
||||
} from "$lib";
|
||||
|
||||
import { onMount } from "svelte";
|
||||
|
||||
function classNames(...classes) {
|
||||
return classes.filter(Boolean).join(" ");
|
||||
}
|
||||
|
||||
let people = [
|
||||
"Wade Cooper",
|
||||
"Arlene Mccoy",
|
||||
"Devon Webb",
|
||||
"Tom Cook",
|
||||
"Tanya Fox",
|
||||
"Hellen Schmidt",
|
||||
"Caroline Schultz",
|
||||
"Mason Heaney",
|
||||
"Claudie Smitham",
|
||||
"Emil Schaefer",
|
||||
];
|
||||
|
||||
let active: string | undefined;
|
||||
if (active === undefined) {
|
||||
active = people[Math.floor(Math.random() * people.length)];
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="w-64">
|
||||
<div class="space-y-1">
|
||||
<Listbox
|
||||
value={active}
|
||||
on:updateValue={(event) => {
|
||||
console.log("value:", event.detail.value);
|
||||
active = event.detail.value;
|
||||
}}
|
||||
>
|
||||
<ListboxLabel class="block text-sm font-medium leading-5 text-gray-700">
|
||||
Assigned to
|
||||
</ListboxLabel>
|
||||
|
||||
<div class="relative">
|
||||
<span class="inline-block w-full rounded-md shadow-sm">
|
||||
<ListboxButton
|
||||
class="relative w-full py-2 pl-3 pr-10 text-left transition duration-150 ease-in-out bg-white border border-gray-300 rounded-md cursor-default focus:outline-none focus:shadow-outline-blue focus:border-blue-300 sm:text-sm sm:leading-5"
|
||||
>
|
||||
<span class="block truncate">{active}</span>
|
||||
<span
|
||||
class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 text-gray-400"
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
d="M7 7l3-3 3 3m0 6l-3 3-3-3"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</ListboxButton>
|
||||
</span>
|
||||
|
||||
<div class="absolute w-full mt-1 bg-white rounded-md shadow-lg">
|
||||
<ListboxOptions
|
||||
class="py-1 overflow-auto text-base leading-6 rounded-md shadow-xs max-h-60 focus:outline-none sm:text-sm sm:leading-5"
|
||||
>
|
||||
{#each people as name (name)}
|
||||
<ListboxOption
|
||||
key={name}
|
||||
value={name}
|
||||
class={({ active }) => {
|
||||
return classNames(
|
||||
"relative py-2 pl-3 cursor-default select-none pr-9 focus:outline-none",
|
||||
active ? "text-white bg-indigo-600" : "text-gray-900"
|
||||
);
|
||||
}}
|
||||
let:active
|
||||
let:selected
|
||||
>
|
||||
<span
|
||||
class={classNames(
|
||||
"block truncate",
|
||||
selected ? "font-semibold" : "font-normal"
|
||||
)}
|
||||
>
|
||||
{name}
|
||||
</span>
|
||||
{#if selected}
|
||||
<span
|
||||
class={classNames(
|
||||
"absolute inset-y-0 right-0 flex items-center pr-4",
|
||||
active ? "text-white" : "text-indigo-600"
|
||||
)}
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
{/if}
|
||||
</ListboxOption>
|
||||
{/each}
|
||||
</ListboxOptions>
|
||||
</div>
|
||||
</div>
|
||||
</Listbox>
|
||||
</div>
|
||||
</div>
|
||||
126
src/routes/listbox/listbox-with-pure-tailwind.svelte
Normal file
126
src/routes/listbox/listbox-with-pure-tailwind.svelte
Normal file
@@ -0,0 +1,126 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
Listbox,
|
||||
ListboxButton,
|
||||
ListboxLabel,
|
||||
ListboxOption,
|
||||
ListboxOptions,
|
||||
} from "$lib";
|
||||
|
||||
import { onMount } from "svelte";
|
||||
|
||||
function classNames(
|
||||
...classes: (false | null | undefined | string)[]
|
||||
): string {
|
||||
return classes.filter(Boolean).join(" ");
|
||||
}
|
||||
let people = [
|
||||
"Wade Cooper",
|
||||
"Arlene Mccoy",
|
||||
"Devon Webb",
|
||||
"Tom Cook",
|
||||
"Tanya Fox",
|
||||
"Hellen Schmidt",
|
||||
"Caroline Schultz",
|
||||
"Mason Heaney",
|
||||
"Claudie Smitham",
|
||||
"Emil Schaefer",
|
||||
];
|
||||
|
||||
// Choose a random person on mount
|
||||
let active = people[Math.floor(Math.random() * people.length)];
|
||||
</script>
|
||||
|
||||
<div class="flex justify-center w-screen h-full p-12 bg-gray-50">
|
||||
<div class="w-full max-w-xs mx-auto">
|
||||
<div class="space-y-1">
|
||||
<Listbox
|
||||
value={active}
|
||||
on:updateValue={(event) => {
|
||||
active = event.detail.value;
|
||||
}}
|
||||
>
|
||||
<ListboxLabel class="block text-sm font-medium leading-5 text-gray-700">
|
||||
Assigned to
|
||||
</ListboxLabel>
|
||||
|
||||
<div class="relative">
|
||||
<span class="inline-block w-full rounded-md shadow-sm">
|
||||
<ListboxButton
|
||||
class="relative w-full py-2 pl-3 pr-10 text-left transition duration-150 ease-in-out bg-white border border-gray-300 rounded-md cursor-default focus:outline-none focus:shadow-outline-blue focus:border-blue-300 sm:text-sm sm:leading-5"
|
||||
>
|
||||
<span class="block truncate">{active}</span>
|
||||
<span
|
||||
class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 text-gray-400"
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
d="M7 7l3-3 3 3m0 6l-3 3-3-3"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</ListboxButton>
|
||||
</span>
|
||||
|
||||
<div class="absolute w-full mt-1 bg-white rounded-md shadow-lg">
|
||||
<ListboxOptions
|
||||
class="py-1 overflow-auto text-base leading-6 rounded-md shadow-xs max-h-60 focus:outline-none sm:text-sm sm:leading-5"
|
||||
>
|
||||
{#each people as name (name)}
|
||||
<ListboxOption
|
||||
key={name}
|
||||
value={name}
|
||||
class={({ active }) => {
|
||||
return classNames(
|
||||
"relative py-2 pl-3 cursor-default select-none pr-9 focus:outline-none",
|
||||
active ? "text-white bg-indigo-600" : "text-gray-900"
|
||||
);
|
||||
}}
|
||||
let:active
|
||||
let:selected
|
||||
>
|
||||
<span
|
||||
class={classNames(
|
||||
"block truncate",
|
||||
selected ? "font-semibold" : "font-normal"
|
||||
)}
|
||||
>
|
||||
{name}
|
||||
</span>
|
||||
{#if selected}
|
||||
<span
|
||||
class={classNames(
|
||||
"absolute inset-y-0 right-0 flex items-center pr-4",
|
||||
active ? "text-white" : "text-indigo-600"
|
||||
)}
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
{/if}
|
||||
</ListboxOption>
|
||||
{/each}
|
||||
</ListboxOptions>
|
||||
</div>
|
||||
</div>
|
||||
</Listbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
25
src/routes/listbox/multiple-elements.svelte
Normal file
25
src/routes/listbox/multiple-elements.svelte
Normal file
@@ -0,0 +1,25 @@
|
||||
<script lang="ts">
|
||||
import PeopleList from "./_PeopleList.svelte";
|
||||
</script>
|
||||
|
||||
<div class="flex justify-center w-screen h-full p-12 space-x-4 bg-gray-50">
|
||||
<PeopleList />
|
||||
|
||||
<div>
|
||||
<!-- svelte-ignore a11y-label-has-associated-control -->
|
||||
<label
|
||||
html-for="email"
|
||||
class="block text-sm font-medium leading-5 text-gray-700"
|
||||
>
|
||||
Email
|
||||
</label>
|
||||
<div class="relative mt-1 rounded-md shadow-sm">
|
||||
<input
|
||||
class="block w-full form-input sm:text-sm sm:leading-5"
|
||||
placeholder="you@example.com"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<PeopleList />
|
||||
</div>
|
||||
80
src/routes/menu/menu-with-transition.svelte
Normal file
80
src/routes/menu/menu-with-transition.svelte
Normal file
@@ -0,0 +1,80 @@
|
||||
<script lang="ts">
|
||||
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from "$lib";
|
||||
|
||||
function classNames(...classes) {
|
||||
return classes.filter(Boolean).join(" ");
|
||||
}
|
||||
function resolveClass({ active, disabled }) {
|
||||
return classNames(
|
||||
"flex justify-between w-full px-4 py-2 text-sm leading-5 text-left",
|
||||
active ? "bg-gray-100 text-gray-900" : "text-gray-700",
|
||||
disabled && "cursor-not-allowed opacity-50"
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex justify-center w-screen h-full p-12 bg-gray-50">
|
||||
<div class="relative inline-block text-left">
|
||||
<Menu>
|
||||
<span class="rounded-md shadow-sm">
|
||||
<MenuButton
|
||||
class="inline-flex justify-center w-full px-4 py-2 text-sm font-medium leading-5 text-gray-700 transition duration-150 ease-in-out bg-white border border-gray-300 rounded-md hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-50 active:text-gray-800"
|
||||
>
|
||||
<span>Options</span>
|
||||
<svg
|
||||
class="w-5 h-5 ml-2 -mr-1"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</MenuButton>
|
||||
</span>
|
||||
|
||||
<Transition
|
||||
enter="transition duration-1000 ease-out"
|
||||
enterFrom="transform scale-95 opacity-0"
|
||||
enterTo="transform scale-100 opacity-100"
|
||||
leave="transition duration-1000 ease-out"
|
||||
leaveFrom="transform scale-100 opacity-100"
|
||||
leaveTo="transform scale-95 opacity-0"
|
||||
>
|
||||
<MenuItems
|
||||
class="absolute right-0 w-56 mt-2 origin-top-right bg-white border border-gray-200 divide-y divide-gray-100 rounded-md shadow-lg outline-none"
|
||||
>
|
||||
<div class="px-4 py-3">
|
||||
<p class="text-sm leading-5">Signed in as</p>
|
||||
<p class="text-sm font-medium leading-5 text-gray-900 truncate">
|
||||
tom@example.com
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="py-1">
|
||||
<MenuItem as="a" href="#account-settings" class={resolveClass}>
|
||||
Account settings
|
||||
</MenuItem>
|
||||
<MenuItem as="a" href="#support" class={resolveClass}>
|
||||
Support
|
||||
</MenuItem>
|
||||
<MenuItem as="a" disabled href="#new-feature" class={resolveClass}>
|
||||
New feature (soon)
|
||||
</MenuItem>
|
||||
<MenuItem as="a" href="#license" class={resolveClass}>
|
||||
License
|
||||
</MenuItem>
|
||||
</div>
|
||||
|
||||
<div class="py-1">
|
||||
<MenuItem as="a" href="#sign-out" class={resolveClass}>
|
||||
Sign out
|
||||
</MenuItem>
|
||||
</div>
|
||||
</MenuItems>
|
||||
</Transition>
|
||||
</Menu>
|
||||
</div>
|
||||
</div>
|
||||
10
src/routes/popover/_Button.svelte
Normal file
10
src/routes/popover/_Button.svelte
Normal file
@@ -0,0 +1,10 @@
|
||||
<script>
|
||||
import { PopoverButton } from "$lib";
|
||||
</script>
|
||||
|
||||
<PopoverButton
|
||||
class="px-3 py-2 bg-gray-300 border-2 border-transparent focus:outline-none focus:border-blue-900"
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</PopoverButton>
|
||||
8
src/routes/popover/_Link.svelte
Normal file
8
src/routes/popover/_Link.svelte
Normal file
@@ -0,0 +1,8 @@
|
||||
<a
|
||||
href="/"
|
||||
class="px-3 py-2 border-2 border-transparent hover:bg-gray-200 focus:bg-gray-200 focus:outline-none focus:border-blue-900"
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</a>
|
||||
|
||||
109
src/routes/popover/popover.svelte
Normal file
109
src/routes/popover/popover.svelte
Normal file
@@ -0,0 +1,109 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
Popover,
|
||||
PopoverButton,
|
||||
PopoverGroup,
|
||||
PopoverOverlay,
|
||||
PopoverPanel,
|
||||
Transition,
|
||||
} from "$lib";
|
||||
import Portal from "$lib/components/portal/Portal.svelte";
|
||||
|
||||
import { createPopperActions } from "svelte-popperjs";
|
||||
import Button from "./_Button.svelte";
|
||||
import Link from "./_Link.svelte";
|
||||
|
||||
let options = {
|
||||
placement: "bottom-start",
|
||||
strategy: "fixed",
|
||||
modifiers: [],
|
||||
};
|
||||
|
||||
const [popperRef1, popperContent1] = createPopperActions();
|
||||
const [popperRef2, popperContent2] = createPopperActions();
|
||||
|
||||
let links = ["First", "Second", "Third", "Fourth"];
|
||||
</script>
|
||||
|
||||
<div class="flex justify-center items-center space-x-12 p-12">
|
||||
<button>Previous</button>
|
||||
|
||||
<PopoverGroup
|
||||
as="nav"
|
||||
aria-label="Mythical University"
|
||||
class="flex space-x-3"
|
||||
>
|
||||
<Popover as="div" class="relative">
|
||||
<Transition
|
||||
enter="ease-out duration-1000 fixed z-20"
|
||||
enterFrom="opacity-0"
|
||||
enterTo="opacity-100"
|
||||
leave="ease-in duration-300 fixed z-20"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<PopoverOverlay
|
||||
class="bg-opacity-75 bg-gray-500 fixed inset-0 z-20 transition-opacity transform"
|
||||
/>
|
||||
</Transition>
|
||||
|
||||
<PopoverButton
|
||||
class="px-3 py-2 bg-gray-300 border-2 border-transparent focus:outline-none focus:border-blue-900 relative z-30"
|
||||
>
|
||||
Normal
|
||||
</PopoverButton>
|
||||
<PopoverPanel
|
||||
class="absolute flex flex-col w-64 bg-gray-100 border-2 border-blue-900 z-30"
|
||||
>
|
||||
{#each links as link, i (link)}
|
||||
<Link key={link} hidden={i === 2 || undefined}>
|
||||
Normal - {link}
|
||||
</Link>
|
||||
{/each}
|
||||
</PopoverPanel>
|
||||
</Popover>
|
||||
|
||||
<Popover as="div" class="relative">
|
||||
<Button>Focus</Button>
|
||||
<PopoverPanel
|
||||
focus
|
||||
class="absolute flex flex-col w-64 bg-gray-100 border-2 border-blue-900"
|
||||
>
|
||||
{#each links as link (link)}
|
||||
<Link key={link}>Focus - {link}</Link>
|
||||
{/each}
|
||||
</PopoverPanel>
|
||||
</Popover>
|
||||
|
||||
<Popover as="div" class="relative">
|
||||
<Button use={[popperRef1]}>Portal</Button>
|
||||
<Portal>
|
||||
<PopoverPanel
|
||||
use={[[popperContent1, options]]}
|
||||
class="flex flex-col w-64 bg-gray-100 border-2 border-blue-900"
|
||||
>
|
||||
{#each links as link (link)}
|
||||
<Link key={link}>Portal - {link}</Link>
|
||||
{/each}
|
||||
</PopoverPanel>
|
||||
</Portal>
|
||||
</Popover>
|
||||
|
||||
<Popover as="div" class="relative">
|
||||
<Button use={[popperRef2]}>Focus in Portal</Button>
|
||||
<Portal>
|
||||
<PopoverPanel
|
||||
use={[[popperContent2, options]]}
|
||||
focus
|
||||
class="flex flex-col w-64 bg-gray-100 border-2 border-blue-900"
|
||||
>
|
||||
{#each links as link (link)}
|
||||
<Link key={link}>Focus in Portal - {link}</Link>
|
||||
{/each}
|
||||
</PopoverPanel>
|
||||
</Portal>
|
||||
</Popover>
|
||||
</PopoverGroup>
|
||||
|
||||
<button>Next</button>
|
||||
</div>
|
||||
Reference in New Issue
Block a user