feat: docker compose maybe

This commit is contained in:
2023-11-13 16:10:04 -05:00
parent 180b261e40
commit b625ccd8d6
8031 changed files with 2182966 additions and 0 deletions

21
node_modules/@skeletonlabs/skeleton/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Skeleton Labs, LLC
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

38
node_modules/@skeletonlabs/skeleton/README.md generated vendored Normal file
View File

@ -0,0 +1,38 @@
[![Skeleton](https://user-images.githubusercontent.com/1509726/199282306-7454adcb-b765-4618-8438-67655a7dee47.png)](https://www.skeleton.dev/)
[![npm version](https://img.shields.io/npm/v/@skeletonlabs/skeleton?logo=npm&color=cb3837)](https://www.npmjs.com/package/@skeletonlabs/skeleton)
[![Chat](https://img.shields.io/discord/1003691521280856084?label=chat&logo=discord&color=7289da)](https://discord.gg/EXqV7W8MtY)
[![license](https://img.shields.io/badge/license-MIT-%23bada55)](https://github.com/skeletonlabs/skeleton/blob/master/LICENSE)
# 💀 Skeleton
Skeleton is an open source UI toolkit built with Svelte + Tailwind that allows you to create reactive web interfaces using [Svelte](https://svelte.dev/) + [Tailwind CSS](https://tailwindcss.com/).
## 🔗 Useful Links
- [Documentation](https://skeleton.dev/)
- [Contribution Guide](https://skeleton.dev/docs/contributing)
<!-- - [Project Roadmap](https://github.com/skeletonlabs/skeleton/wiki/%F0%9F%9B%A3%EF%B8%8F-The-Skeleton-Roadmap) -->
## 👋 Community
- [Join the Discord](https://discord.gg/EXqV7W8MtY)
- [Follow on Twitter](https://twitter.com/SkeletonUI)
## 👍 Sponsor the Project
- [Ko-Fi](https://ko-fi.com/skeletonlabs)
- [GitHub Sponsors](https://github.com/sponsors/skeletonlabs)
- [Patreon](https://patreon.com/user?u=83786276)
## 🐞 Report an Issue
- [File a Ticket](https://github.com/skeletonlabs/skeleton/issues/new/choose)
## 🛠️ Contributions
We've provided a detailed [contribution guide](https://www.skeleton.dev/docs/contributing) to help you get started. [Find an open issue](https://github.com/skeletonlabs/skeleton/issues), discuss the requirements with other contributors, then send a PR!
## Maintainers
Skeleton was created by [Chris Simmons](https://github.com/endigo9740) (@endigo9740) and is currently maintained by [Skeleton Labs](https://www.skeletonlabs.co/) and the open source community.

View File

@ -0,0 +1,5 @@
declare namespace svelteHTML {
interface HTMLAttributes {
'on:copyComplete'?: () => void;
}
}

View File

@ -0,0 +1,10 @@
type ClipboardArgs = string | {
element: string;
} | {
input: string;
};
export declare function clipboard(node: HTMLElement, args: ClipboardArgs): {
update(newArgs: ClipboardArgs): void;
destroy(): void;
} | undefined;
export {};

View File

@ -0,0 +1,64 @@
export function clipboard(node, args) {
if (!window.isSecureContext) {
console.error('Clipboard action failed: app not running in secure context, see: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard');
return;
}
const fireCopyCompleteEvent = () => {
node.dispatchEvent(new CustomEvent('copyComplete'));
};
const onClick = () => {
// Handle `data-clipboard` target based on object key
if (typeof args === 'object') {
// Element Inner HTML
if ('element' in args) {
const element = document.querySelector(`[data-clipboard="${args.element}"]`);
if (!element)
throw new Error(`Missing HTMLElement with an attribute of [data-clipboard="${args.element}"]`);
copyToClipboard(element.innerHTML, 'text/html').then(fireCopyCompleteEvent);
return;
}
// Form Input Value
if ('input' in args) {
const input = document.querySelector(`[data-clipboard="${args.input}"]`);
if (!input)
throw new Error(`Missing HTMLInputElement with an attribute of [data-clipboard="${args.input}"]`);
copyToClipboard(input.value).then(fireCopyCompleteEvent);
return;
}
}
// Handle everything else.
copyToClipboard(args).then(fireCopyCompleteEvent);
};
// Event Listener
node.addEventListener('click', onClick);
// Lifecycle
return {
update(newArgs) {
args = newArgs;
},
destroy() {
node.removeEventListener('click', onClick);
}
};
}
// Shared copy method
async function copyToClipboard(data, mimeType = 'text/plain') {
if (navigator.clipboard.write) {
await navigator.clipboard.write([
new ClipboardItem({
[mimeType]: new Blob([data], {
type: mimeType
}),
['text/plain']: new Blob([data], {
type: 'text/plain'
})
})
]);
}
else {
// fallback since .writeText has wider browser support
await new Promise((resolve) => {
resolve(navigator.clipboard.writeText(String(data)));
});
}
}

View File

@ -0,0 +1,6 @@
type Filters = ['Apollo', 'BlueNight', 'Emerald', 'GreenFall', 'Noir', 'NoirLight', 'Rustic', 'Summer84', 'XPro'];
type FilterName = `#${Filters[number]}` | (string & {});
export declare function filter(node: HTMLElement, filterName: FilterName): {
update(newArgs: FilterName): void;
} | undefined;
export {};

View File

@ -0,0 +1,16 @@
// Action: Filter
export function filter(node, filterName) {
// Return if no filterName provided
if (filterName === undefined)
return;
const applyFilter = () => {
node.setAttribute('style', `filter: url("${filterName}")`);
};
applyFilter();
return {
update(newArgs) {
filterName = newArgs;
applyFilter();
}
};
}

View File

@ -0,0 +1,13 @@
<!-- Apollo: `filter: url(#Apollo)` -->
<svg id="svg-filter-apollo" class="filter absolute -left-full w-0 h-0">
<filter id="Apollo" filterUnits="objectBoundingBox" primitiveUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feColorMatrix
values="0.8 0.6 -0.4 0.1 0,
0 1.2 0.05 0 0,
0 -1 3 0.02 0,
0 0 0 50 0"
result="final"
in="SourceGraphic"
/>
</filter>
</svg>

After

Width:  |  Height:  |  Size: 402 B

View File

@ -0,0 +1,23 @@
/** @typedef {typeof __propDef.props} ApolloProps */
/** @typedef {typeof __propDef.events} ApolloEvents */
/** @typedef {typeof __propDef.slots} ApolloSlots */
export default class Apollo extends SvelteComponentTyped<{
[x: string]: never;
}, {
[evt: string]: CustomEvent<any>;
}, {}> {
}
export type ApolloProps = typeof __propDef.props;
export type ApolloEvents = typeof __propDef.events;
export type ApolloSlots = typeof __propDef.slots;
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: never;
};
events: {
[evt: string]: CustomEvent<any>;
};
slots: {};
};
export {};

View File

@ -0,0 +1,12 @@
<!-- BlueNight: `filter: url(#BlueNight)` -->
<svg id="svg-filter-bluenight" class="filter absolute -left-full w-0 h-0">
<filter id="BlueNight" filterUnits="objectBoundingBox" primitiveUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feColorMatrix
type="matrix"
values="1.000 0.000 0.000 0.000 0.000
0.000 1.000 0.000 0.000 0.05
0.000 0.000 1.000 0.000 0.400
0.000 0.000 0.000 1.000 0.000"
/>
</filter>
</svg>

After

Width:  |  Height:  |  Size: 496 B

View File

@ -0,0 +1,23 @@
/** @typedef {typeof __propDef.props} BlueNightProps */
/** @typedef {typeof __propDef.events} BlueNightEvents */
/** @typedef {typeof __propDef.slots} BlueNightSlots */
export default class BlueNight extends SvelteComponentTyped<{
[x: string]: never;
}, {
[evt: string]: CustomEvent<any>;
}, {}> {
}
export type BlueNightProps = typeof __propDef.props;
export type BlueNightEvents = typeof __propDef.events;
export type BlueNightSlots = typeof __propDef.slots;
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: never;
};
events: {
[evt: string]: CustomEvent<any>;
};
slots: {};
};
export {};

View File

@ -0,0 +1,23 @@
<!-- Emerald: `filter: url(#Emerald)` -->
<svg id="svg-filter-emerald" class="filter absolute -left-full w-0 h-0">
<filter id="Emerald" filterUnits="objectBoundingBox" primitiveUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<!-- RGB, RGB, RGB, Opacity -->
<feColorMatrix
type="matrix"
in="SourceGraphic"
result="colormatrix"
values="
.16 .185 .129 0 0
.16 .185 .129 0 0
.16 .185 .129 0 0
0 0 0 0.33 0"
/>
<feComponentTransfer in="colormatrix" result="componentTransfer">
<feFuncR type="table" tableValues="0.03 0.9" />
<feFuncG type="table" tableValues="0.57 1" />
<feFuncB type="table" tableValues="0.49 0.53" />
<feFuncA type="table" tableValues="0 1" />
</feComponentTransfer>
<feBlend mode="normal" in="componentTransfer" in2="SourceGraphic" result="blend" />
</filter>
</svg>

After

Width:  |  Height:  |  Size: 879 B

View File

@ -0,0 +1,23 @@
/** @typedef {typeof __propDef.props} EmeraldProps */
/** @typedef {typeof __propDef.events} EmeraldEvents */
/** @typedef {typeof __propDef.slots} EmeraldSlots */
export default class Emerald extends SvelteComponentTyped<{
[x: string]: never;
}, {
[evt: string]: CustomEvent<any>;
}, {}> {
}
export type EmeraldProps = typeof __propDef.props;
export type EmeraldEvents = typeof __propDef.events;
export type EmeraldSlots = typeof __propDef.slots;
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: never;
};
events: {
[evt: string]: CustomEvent<any>;
};
slots: {};
};
export {};

View File

@ -0,0 +1,27 @@
<!-- GreenFall: `filter: url(#GreenFall)` -->
<svg id="svg-filter-greenfall" class="filter absolute -left-full w-0 h-0">
<filter
id="GreenFall"
x="-20%"
y="-20%"
width="140%"
height="140%"
filterUnits="objectBoundingBox"
primitiveUnits="userSpaceOnUse"
color-interpolation-filters="linearRGB"
>
<feColorMatrix
type="matrix"
values="0.5 -0.4 0.3332 0 0
0 0.4 0.3 0 0
0 0 0.5 0 0
0 0 0 500 -20"
x="0%"
y="0%"
width="100%"
height="100%"
in="SourceGraphic"
result="colormatrix"
/>
</filter>
</svg>

After

Width:  |  Height:  |  Size: 556 B

View File

@ -0,0 +1,23 @@
/** @typedef {typeof __propDef.props} GreenFallProps */
/** @typedef {typeof __propDef.events} GreenFallEvents */
/** @typedef {typeof __propDef.slots} GreenFallSlots */
export default class GreenFall extends SvelteComponentTyped<{
[x: string]: never;
}, {
[evt: string]: CustomEvent<any>;
}, {}> {
}
export type GreenFallProps = typeof __propDef.props;
export type GreenFallEvents = typeof __propDef.events;
export type GreenFallSlots = typeof __propDef.slots;
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: never;
};
events: {
[evt: string]: CustomEvent<any>;
};
slots: {};
};
export {};

View File

@ -0,0 +1,17 @@
<!-- Noir: `filter: url(#Noir)` -->
<svg id="svg-filter-noir" class="filter absolute -left-full w-0 h-0">
<filter
id="Noir"
x="-20%"
y="-20%"
width="140%"
height="140%"
filterUnits="objectBoundingBox"
primitiveUnits="userSpaceOnUse"
color-interpolation-filters="linearRGB"
>
<feColorMatrix type="saturate" values="0" x="0%" y="0%" width="100%" height="100%" in="SourceGraphic" result="colormatrix1" />
<feBlend mode="lighten" x="0%" y="0%" width="100%" height="100%" in="colormatrix1" in2="colormatrix1" result="blend" />
<feBlend mode="multiply" x="0%" y="0%" width="100%" height="100%" in="colormatrix1" in2="diffuseLighting" result="blend1" />
</filter>
</svg>

After

Width:  |  Height:  |  Size: 689 B

View File

@ -0,0 +1,23 @@
/** @typedef {typeof __propDef.props} NoirProps */
/** @typedef {typeof __propDef.events} NoirEvents */
/** @typedef {typeof __propDef.slots} NoirSlots */
export default class Noir extends SvelteComponentTyped<{
[x: string]: never;
}, {
[evt: string]: CustomEvent<any>;
}, {}> {
}
export type NoirProps = typeof __propDef.props;
export type NoirEvents = typeof __propDef.events;
export type NoirSlots = typeof __propDef.slots;
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: never;
};
events: {
[evt: string]: CustomEvent<any>;
};
slots: {};
};
export {};

View File

@ -0,0 +1,19 @@
<!-- NoirLight: `filter: url(#NoirLight)` -->
<svg id="svg-filter-noirlight" class="filter absolute -left-full w-0 h-0">
<filter
id="NoirLight"
x="-20%"
y="-20%"
width="140%"
height="140%"
filterUnits="objectBoundingBox"
primitiveUnits="userSpaceOnUse"
color-interpolation-filters="linearRGB"
>
<feColorMatrix type="saturate" values="0" x="0%" y="0%" width="100%" height="100%" in="SourceGraphic" result="colormatrix2" />
<feBlend mode="saturation" x="0%" y="0%" width="100%" height="100%" in="SourceGraphic" in2="colormatrix2" result="blend2" />
<feBlend mode="screen" x="0%" y="0%" width="100%" height="100%" in="colormatrix2" in2="blend2" result="blend3" />
<feColorMatrix type="luminanceToAlpha" x="0%" y="0%" width="100%" height="100%" in="blend3" result="colormatrix3" />
<feBlend mode="exclusion" x="0%" y="0%" width="100%" height="100%" in="blend3" in2="colormatrix3" result="blend5" />
</filter>
</svg>

After

Width:  |  Height:  |  Size: 941 B

View File

@ -0,0 +1,23 @@
/** @typedef {typeof __propDef.props} NoirLightProps */
/** @typedef {typeof __propDef.events} NoirLightEvents */
/** @typedef {typeof __propDef.slots} NoirLightSlots */
export default class NoirLight extends SvelteComponentTyped<{
[x: string]: never;
}, {
[evt: string]: CustomEvent<any>;
}, {}> {
}
export type NoirLightProps = typeof __propDef.props;
export type NoirLightEvents = typeof __propDef.events;
export type NoirLightSlots = typeof __propDef.slots;
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: never;
};
events: {
[evt: string]: CustomEvent<any>;
};
slots: {};
};
export {};

View File

@ -0,0 +1,14 @@
<!-- Rustic: `filter: url(#Rustic)` -->
<svg id="svg-filter-rustic" class="filter absolute -left-full w-0 h-0">
<filter id="Rustic" filterUnits="objectBoundingBox" primitiveUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feColorMatrix
type="matrix"
in="SourceGraphic"
result="colormatrix"
values="0.39215686274509803 0.39215686274509803 0.39215686274509803 0 0
0.3333333333333333 0.3333333333333333 0.3333333333333333 0 0
0.30980392156862746 0.30980392156862746 0.30980392156862746 0 0
0 0 0 1 0"
/>
</filter>
</svg>

After

Width:  |  Height:  |  Size: 569 B

View File

@ -0,0 +1,23 @@
/** @typedef {typeof __propDef.props} RusticProps */
/** @typedef {typeof __propDef.events} RusticEvents */
/** @typedef {typeof __propDef.slots} RusticSlots */
export default class Rustic extends SvelteComponentTyped<{
[x: string]: never;
}, {
[evt: string]: CustomEvent<any>;
}, {}> {
}
export type RusticProps = typeof __propDef.props;
export type RusticEvents = typeof __propDef.events;
export type RusticSlots = typeof __propDef.slots;
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: never;
};
events: {
[evt: string]: CustomEvent<any>;
};
slots: {};
};
export {};

View File

@ -0,0 +1,12 @@
<!-- Summer84: `filter: url(#Summer84)` -->
<svg id="svg-filter-summer84" class="filter absolute -left-full w-0 h-0">
<filter id="Summer84" filterUnits="objectBoundingBox" primitiveUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feColorMatrix
type="matrix"
values="1.300 0.200 0.000 0.000 0.000
0.300 0.600 0.200 0.000 0.000
0.200 1.000 0.200 0.000 0.000
0.000 0.000 0.000 1.000 0.000"
/>
</filter>
</svg>

After

Width:  |  Height:  |  Size: 448 B

View File

@ -0,0 +1,23 @@
/** @typedef {typeof __propDef.props} Summer84Props */
/** @typedef {typeof __propDef.events} Summer84Events */
/** @typedef {typeof __propDef.slots} Summer84Slots */
export default class Summer84 extends SvelteComponentTyped<{
[x: string]: never;
}, {
[evt: string]: CustomEvent<any>;
}, {}> {
}
export type Summer84Props = typeof __propDef.props;
export type Summer84Events = typeof __propDef.events;
export type Summer84Slots = typeof __propDef.slots;
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: never;
};
events: {
[evt: string]: CustomEvent<any>;
};
slots: {};
};
export {};

View File

@ -0,0 +1,12 @@
<!-- XPro: `filter: url(#XPro)` -->
<svg id="svg-filter-xpro" class="filter absolute -left-full w-0 h-0">
<filter id="XPro" filterUnits="objectBoundingBox" primitiveUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feColorMatrix
type="matrix"
values="1.70 -0.20 0.00 0.00 0.00
0.10 0.800 0.30 0.00 0.00
0.20 0.300 0.50 0.00 0.00
0.00 0.00 0.00 1.00 0.00"
/>
</filter>
</svg>

After

Width:  |  Height:  |  Size: 460 B

View File

@ -0,0 +1,23 @@
/** @typedef {typeof __propDef.props} XProProps */
/** @typedef {typeof __propDef.events} XProEvents */
/** @typedef {typeof __propDef.slots} XProSlots */
export default class XPro extends SvelteComponentTyped<{
[x: string]: never;
}, {
[evt: string]: CustomEvent<any>;
}, {}> {
}
export type XProProps = typeof __propDef.props;
export type XProEvents = typeof __propDef.events;
export type XProSlots = typeof __propDef.slots;
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: never;
};
events: {
[evt: string]: CustomEvent<any>;
};
slots: {};
};
export {};

View File

@ -0,0 +1,4 @@
export declare function focusTrap(node: HTMLElement, enabled: boolean): {
update(newArgs: boolean): void;
destroy(): void;
};

View File

@ -0,0 +1,65 @@
// Action: Focus Trap
export function focusTrap(node, enabled) {
const elemWhitelist = 'a[href]:not([tabindex="-1"]), button:not([tabindex="-1"]), input:not([tabindex="-1"]), textarea:not([tabindex="-1"]), select:not([tabindex="-1"]), details:not([tabindex="-1"]), [tabindex]:not([tabindex="-1"])';
let elemFirst;
let elemLast;
// When the first element is selected, shift+tab pressed, jump to the last selectable item.
function onFirstElemKeydown(e) {
if (e.shiftKey && e.code === 'Tab') {
e.preventDefault();
elemLast.focus();
}
}
// When the last item selected, tab pressed, jump to the first selectable item.
function onLastElemKeydown(e) {
if (!e.shiftKey && e.code === 'Tab') {
e.preventDefault();
elemFirst.focus();
}
}
const onScanElements = (fromObserver) => {
if (enabled === false)
return;
// Gather all focusable elements
const focusableElems = Array.from(node.querySelectorAll(elemWhitelist));
if (focusableElems.length) {
// Set first/last focusable elements
elemFirst = focusableElems[0];
elemLast = focusableElems[focusableElems.length - 1];
// Auto-focus first focusable element only when not called from observer
if (!fromObserver)
elemFirst.focus();
// Listen for keydown on first & last element
elemFirst.addEventListener('keydown', onFirstElemKeydown);
elemLast.addEventListener('keydown', onLastElemKeydown);
}
};
onScanElements(false);
function onCleanUp() {
if (elemFirst)
elemFirst.removeEventListener('keydown', onFirstElemKeydown);
if (elemLast)
elemLast.removeEventListener('keydown', onLastElemKeydown);
}
// When children of node are changed (added or removed)
const onObservationChange = (mutationRecords, observer) => {
if (mutationRecords.length) {
onCleanUp();
onScanElements(true);
}
return observer;
};
const observer = new MutationObserver(onObservationChange);
observer.observe(node, { childList: true, subtree: true });
// Lifecycle
return {
update(newArgs) {
enabled = newArgs;
newArgs ? onScanElements(false) : onCleanUp();
},
destroy() {
onCleanUp();
observer.disconnect();
}
};
}

View File

@ -0,0 +1,49 @@
<script context="module">import { slide } from "svelte/transition";
import { prefersReducedMotionStore } from "../../index.js";
</script>
<script generics="TransitionIn extends Transition = SlideTransition, TransitionOut extends Transition = SlideTransition">import { writable } from "svelte/store";
import { setContext } from "svelte";
export let autocollapse = false;
export let width = "w-full";
export let spacing = "space-y-1";
export let disabled = false;
export let padding = "py-2 px-4";
export let hover = "hover:bg-primary-hover-token";
export let rounded = "rounded-container-token";
export let caretOpen = "rotate-180";
export let caretClosed = "";
export let regionControl = "";
export let regionPanel = "space-y-4";
export let regionCaret = "";
export let transitions = !$prefersReducedMotionStore;
export let transitionIn = slide;
export let transitionInParams = { duration: 200 };
export let transitionOut = slide;
export let transitionOutParams = { duration: 200 };
const active = writable(null);
setContext("active", active);
setContext("autocollapse", autocollapse);
setContext("disabled", disabled);
setContext("padding", padding);
setContext("hover", hover);
setContext("rounded", rounded);
setContext("caretOpen", caretOpen);
setContext("caretClosed", caretClosed);
setContext("regionControl", regionControl);
setContext("regionPanel", regionPanel);
setContext("regionCaret", regionCaret);
setContext("transitions", transitions);
setContext("transitionIn", transitionIn);
setContext("transitionInParams", transitionInParams);
setContext("transitionOut", transitionOut);
setContext("transitionOutParams", transitionOutParams);
$:
classesBase = `${width} ${spacing} ${$$props.class ?? ""}`;
</script>
<!-- @component The Accordion parent element. -->
<div class="accordion {classesBase}" data-testid="accordion">
<slot />
</div>

View File

@ -0,0 +1,56 @@
import { SvelteComponentTyped } from "svelte";
import { slide } from 'svelte/transition';
import { type Transition, type TransitionParams } from '../../index.js';
type SlideTransition = typeof slide;
declare class __sveltets_Render<TransitionIn extends Transition = SlideTransition, TransitionOut extends Transition = SlideTransition> {
props(): {
[x: string]: any;
/** Set the auto-collapse mode.*/
autocollapse?: boolean | undefined;
/** Provide classes to set the accordion width.*/
width?: string | undefined;
/** Provide classes to set the vertical spacing between items.*/
spacing?: string | undefined;
/** Set the accordion disabled state for all items.*/
disabled?: boolean | undefined;
/** Provide classes to set the accordion item padding styles.*/
padding?: string | undefined;
/** Provide classes to set the accordion item hover styles.*/
hover?: string | undefined;
/** Provide classes to set the accordion item rounded styles.*/
rounded?: string | undefined;
/** Set the rotation of the item caret in the open state.*/
caretOpen?: string | undefined;
/** Set the rotation of the item caret in the closed state.*/
caretClosed?: string | undefined;
/** Provide arbitrary classes to the trigger button region.*/
regionControl?: string | undefined;
/** Provide arbitrary classes to the content panel region.*/
regionPanel?: string | undefined;
/** Provide arbitrary classes to the caret icon region.*/
regionCaret?: string | undefined;
/** Enable/Disable transitions*/
transitions?: boolean | undefined;
/** Provide the transition to used on entry.*/
transitionIn?: TransitionIn | undefined;
/** Transition params provided to `transitionIn`.*/
transitionInParams?: TransitionParams<TransitionIn> | undefined;
/** Provide the transition to used on exit.*/
transitionOut?: TransitionOut | undefined;
/** Transition params provided to `transitionOut`.*/
transitionOutParams?: TransitionParams<TransitionOut> | undefined;
};
events(): {} & {
[evt: string]: CustomEvent<any>;
};
slots(): {
default: {};
};
}
export type AccordionProps<TransitionIn extends Transition = SlideTransition, TransitionOut extends Transition = SlideTransition> = ReturnType<__sveltets_Render<TransitionIn, TransitionOut>['props']>;
export type AccordionEvents<TransitionIn extends Transition = SlideTransition, TransitionOut extends Transition = SlideTransition> = ReturnType<__sveltets_Render<TransitionIn, TransitionOut>['events']>;
export type AccordionSlots<TransitionIn extends Transition = SlideTransition, TransitionOut extends Transition = SlideTransition> = ReturnType<__sveltets_Render<TransitionIn, TransitionOut>['slots']>;
/** The Accordion parent element. */
export default class Accordion<TransitionIn extends Transition = SlideTransition, TransitionOut extends Transition = SlideTransition> extends SvelteComponentTyped<AccordionProps<TransitionIn, TransitionOut>, AccordionEvents<TransitionIn, TransitionOut>, AccordionSlots<TransitionIn, TransitionOut>> {
}
export {};

View File

@ -0,0 +1,109 @@
<script>import { getContext } from "svelte";
import { createEventDispatcher } from "svelte";
import { dynamicTransition } from "../../internal/transitions.js";
const dispatch = createEventDispatcher();
export let open = false;
export let id = String(Math.random());
const cBase = "";
const cControl = "text-start w-full flex items-center space-x-4";
const cControlCaret = "fill-current w-3 transition-transform duration-[200ms]";
const cPanel = "";
export let autocollapse = getContext("autocollapse");
export let active = getContext("active");
export let disabled = getContext("disabled");
export let padding = getContext("padding");
export let hover = getContext("hover");
export let rounded = getContext("rounded");
export let caretOpen = getContext("caretOpen");
export let caretClosed = getContext("caretClosed");
export let regionControl = getContext("regionControl");
export let regionPanel = getContext("regionPanel");
export let regionCaret = getContext("regionCaret");
export let transitions = getContext("transitions");
export let transitionIn = getContext("transitionIn");
export let transitionInParams = getContext("transitionInParams");
export let transitionOut = getContext("transitionOut");
export let transitionOutParams = getContext("transitionOutParams");
function setActive(event) {
if (autocollapse === true) {
active.set(id);
} else {
open = !open;
}
onToggle(event);
}
function onToggle(event) {
const currentOpenState = autocollapse ? $active === id : open;
dispatch("toggle", { event, id: `accordion-control-${id}`, open: currentOpenState, autocollapse });
}
if (autocollapse && open)
setActive();
$:
if (open && autocollapse)
setActive();
$:
openState = autocollapse ? $active === id : open;
$:
classesBase = `${cBase} ${$$props.class ?? ""}`;
$:
classesControl = `${cControl} ${padding} ${hover} ${rounded} ${regionControl}`;
$:
classesCaretState = openState ? caretOpen : caretClosed;
$:
classesControlCaret = `${cControlCaret} ${regionCaret} ${classesCaretState}`;
$:
classesPanel = `${cPanel} ${padding} ${rounded} ${regionPanel}`;
</script>
<!-- @component The Accordion child element. -->
<div class="accordion-item {classesBase}" data-testid="accordion-item">
<!-- Control -->
<button
type="button"
class="accordion-control {classesControl}"
id="accordion-control-{id}"
on:click={setActive}
on:click
on:keydown
on:keyup
on:keypress
aria-expanded={openState}
aria-controls="accordion-panel-{id}"
{disabled}
>
<!-- Lead -->
{#if $$slots.lead}
<div class="accordion-lead">
<slot name="lead" />
</div>
{/if}
<!-- Summary -->
<div class="accordion-summary flex-1">
<slot name="summary">(summary)</slot>
</div>
<!-- Caret -->
<div class="accordion-summary-caret {classesControlCaret}">
<!-- SVG Caret -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path
d="M201.4 374.6c12.5 12.5 32.8 12.5 45.3 0l160-160c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L224 306.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160z"
/>
</svg>
</div>
</button>
<!-- Panel -->
{#if openState}
<div
class="accordion-panel {classesPanel}"
id="accordion-panel-{id}"
in:dynamicTransition|local={{ transition: transitionIn, params: transitionInParams, enabled: transitions }}
out:dynamicTransition|local={{ transition: transitionOut, params: transitionOutParams, enabled: transitions }}
role="region"
aria-hidden={!openState}
aria-labelledby="accordion-control-{id}"
>
<slot name="content">(content)</slot>
</div>
{/if}
</div>

View File

@ -0,0 +1,70 @@
import { SvelteComponentTyped } from "svelte";
import type { Writable } from 'svelte/store';
import type { Transition, TransitionParams } from '../../index.js';
declare class __sveltets_Render<TransitionIn extends Transition, TransitionOut extends Transition> {
props(): {
[x: string]: any;
/** Set open by default on load.*/
open?: boolean | undefined;
/** Provide a unique input id. Auto-generated by default*/
id?: string | undefined;
/** Set the auto-collapse mode.*/
autocollapse?: boolean | undefined;
/** The writable store that houses the auto-collapse active item UUID.*/
active?: Writable<string | null> | undefined;
/** Set the disabled state for this item.*/
disabled?: boolean | undefined;
/** Provide classes to set the accordion item padding styles.*/
padding?: string | undefined;
/** Provide classes to set the accordion item hover styles.*/
hover?: string | undefined;
/** Provide classes to set the accordion item rounded styles.*/
rounded?: string | undefined;
/** Provide arbitrary classes to the trigger button region.*/
caretOpen?: string | undefined;
/** Provide arbitrary classes to content panel region.*/
caretClosed?: string | undefined;
/** Provide arbitrary classes to the trigger button region.*/
regionControl?: string | undefined;
/** Provide arbitrary classes to content panel region.*/
regionPanel?: string | undefined;
/** Provide arbitrary classes caret icon region.*/
regionCaret?: string | undefined;
/** Enable/Disable transitions*/
transitions?: boolean | undefined;
/** Provide the transition to used on entry.*/
transitionIn?: TransitionIn | undefined;
/** Transition params provided to `transitionIn`.*/
transitionInParams?: TransitionParams<TransitionIn> | undefined;
/** Provide the transition to used on exit.*/
transitionOut?: TransitionOut | undefined;
/** Transition params provided to `transitionOut`.*/
transitionOutParams?: TransitionParams<TransitionOut> | undefined;
};
events(): {
click: MouseEvent;
keydown: KeyboardEvent;
keyup: KeyboardEvent;
keypress: KeyboardEvent;
toggle: CustomEvent<{
event?: Event | undefined;
id: string;
open: boolean;
autocollapse: boolean;
}>;
} & {
[evt: string]: CustomEvent<any>;
};
slots(): {
lead: {};
summary: {};
content: {};
};
}
export type AccordionItemProps<TransitionIn extends Transition, TransitionOut extends Transition> = ReturnType<__sveltets_Render<TransitionIn, TransitionOut>['props']>;
export type AccordionItemEvents<TransitionIn extends Transition, TransitionOut extends Transition> = ReturnType<__sveltets_Render<TransitionIn, TransitionOut>['events']>;
export type AccordionItemSlots<TransitionIn extends Transition, TransitionOut extends Transition> = ReturnType<__sveltets_Render<TransitionIn, TransitionOut>['slots']>;
/** The Accordion child element. */
export default class AccordionItem<TransitionIn extends Transition, TransitionOut extends Transition> extends SvelteComponentTyped<AccordionItemProps<TransitionIn, TransitionOut>, AccordionItemEvents<TransitionIn, TransitionOut>, AccordionItemSlots<TransitionIn, TransitionOut>> {
}
export {};

View File

@ -0,0 +1,53 @@
<script>export let background = "bg-surface-100-800-token";
export let border = "";
export let padding = "p-4";
export let shadow = "";
export let spacing = "space-y-4";
export let gridColumns = "grid-cols-[auto_1fr_auto]";
export let gap = "gap-4";
export let regionRowMain = "";
export let regionRowHeadline = "";
export let slotLead = "";
export let slotDefault = "";
export let slotTrail = "";
export let label = "";
export let labelledby = "";
const cBase = "flex flex-col";
const cRowMain = "grid items-center";
const cRowHeadline = "";
const cSlotLead = "flex-none flex justify-between items-center";
const cSlotDefault = "flex-auto";
const cSlotTrail = "flex-none flex items-center space-x-4";
$:
classesBase = `${cBase} ${background} ${border} ${spacing} ${padding} ${shadow} ${$$props.class ?? ""}`;
$:
classesRowMain = `${cRowMain} ${gridColumns} ${gap} ${regionRowMain}`;
$:
classesRowHeadline = `${cRowHeadline} ${regionRowHeadline}`;
$:
classesSlotLead = `${cSlotLead} ${slotLead}`;
$:
classesSlotDefault = `${cSlotDefault} ${slotDefault}`;
$:
classesSlotTrail = `${cSlotTrail} ${slotTrail}`;
</script>
<div class="app-bar {classesBase}" data-testid="app-bar" role="toolbar" aria-label={label} aria-labelledby={labelledby}>
<!-- Row: Main -->
<div class="app-bar-row-main {classesRowMain}">
<!-- Slot: lead -->
{#if $$slots.lead}
<div class="app-bar-slot-lead {classesSlotLead}"><slot name="lead" /></div>
{/if}
<!-- Slot: default -->
<div class="app-bar-slot-default {classesSlotDefault}"><slot /></div>
<!-- Slot: trail -->
{#if $$slots.trail}
<div class="app-bar-slot-trail {classesSlotTrail}"><slot name="trail" /></div>
{/if}
</div>
<!-- Row: Headline -->
{#if $$slots.headline}
<div class="app-bar-row-headline {classesRowHeadline}"><slot name="headline" /></div>
{/if}
</div>

View File

@ -0,0 +1,49 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Provide classes to set background color.*/
background?: string | undefined;
/** Provide classes to set border styles.*/
border?: string | undefined;
/** Provide classes to set padding.*/
padding?: string | undefined;
/** Provide classes to define a box shadow.*/
shadow?: string | undefined;
/** Provide classes to set the vertical spacing between rows.*/
spacing?: string | undefined;
/** Provide classes to set grid columns for the main row.*/
gridColumns?: string | undefined;
/** Provide classes to set gap spacing for the main row.*/
gap?: string | undefined;
/** Provide arbitrary classes to style the top (main) row.*/
regionRowMain?: string | undefined;
/** Provide arbitrary classes to style the bottom (headline) row.*/
regionRowHeadline?: string | undefined;
/** Classes to apply to the lead slot container element*/
slotLead?: string | undefined;
/** Classes to apply to the default slot container element*/
slotDefault?: string | undefined;
/** Classes to apply to the trail slot container element*/
slotTrail?: string | undefined;
/** Provide a semantic ID for the ARIA label.*/
label?: string | undefined;
/** Provide the ID of the element that labels the toolbar.*/
labelledby?: string | undefined;
};
events: {
[evt: string]: CustomEvent<any>;
};
slots: {
lead: {};
default: {};
trail: {};
headline: {};
};
};
export type AppBarProps = typeof __propDef.props;
export type AppBarEvents = typeof __propDef.events;
export type AppBarSlots = typeof __propDef.slots;
export default class AppBar extends SvelteComponentTyped<AppBarProps, AppBarEvents, AppBarSlots> {
}
export {};

View File

@ -0,0 +1,41 @@
<script>import { setContext } from "svelte";
export let background = "bg-surface-100-800-token";
export let border = "";
export let width = "w-20";
export let height = "h-full";
export let gap = "gap-0";
export let regionLead = "";
export let regionDefault = "";
export let regionTrail = "";
export let hover = "bg-primary-hover-token";
export let active = "bg-primary-active-token";
export let spacing = "space-y-1";
export let aspectRatio = "aspect-square";
setContext("active", active);
setContext("hover", hover);
setContext("spacing", spacing);
setContext("aspectRatio", aspectRatio);
const cBase = "grid grid-rows-[auto_1fr_auto] overflow-y-auto";
const cRegionLead = "box-border";
const cRegionDefault = "box-border";
const cRegionTrail = "box-border";
$:
classesBase = `${cBase} ${background} ${border} ${width} ${height} ${gap} ${$$props.class || ""}`;
$:
classesRegionLead = `${cRegionLead} ${regionLead}`;
$:
classesRegionDefault = `${cRegionDefault} ${regionDefault}`;
$:
classesRegionTrail = `${cRegionTrail} ${regionTrail}`;
</script>
<!-- @component A vertical navigation rail component. -->
<div class="app-rail {classesBase}" data-testid="app-rail">
<!-- Slot: lead -->
<div class="app-bar-lead {classesRegionLead}"><slot name="lead" /></div>
<!-- Slot: Default -->
<div class="app-bar-default {classesRegionDefault}"><slot /></div>
<!-- Slot: lead -->
<div class="app-bar-trail {classesRegionTrail}"><slot name="trail" /></div>
</div>

View File

@ -0,0 +1,45 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Rail: Provide classes to set the background color.*/
background?: string | undefined;
/** Rail: Provide classes to set the background color.*/
border?: string | undefined;
/** Rail: Provide classes to set the width.*/
width?: string | undefined;
/** Rail: Provide classes to set the height.*/
height?: string | undefined;
/** Rail: Provide a class to set the grid gap.*/
gap?: string | undefined;
/** Rail: Provide arbitrary classes to the lead region.*/
regionLead?: string | undefined;
/** Rail: Provide arbitrary classes to the default region.*/
regionDefault?: string | undefined;
/** Rail: Provide arbitrary classes to the trail region.*/
regionTrail?: string | undefined;
/** Provide classes to set the tile/anchor hover background color.*/
hover?: string | undefined;
/** Provide classes to set the tile/anchor active tile background.*/
active?: string | undefined;
/** Provide classes to set the tile/anchor vertical spacing.*/
spacing?: string | undefined;
/** Provide classes to set the tile/anchor aspect ratio.*/
aspectRatio?: string | undefined;
};
events: {
[evt: string]: CustomEvent<any>;
};
slots: {
lead: {};
default: {};
trail: {};
};
};
export type AppRailProps = typeof __propDef.props;
export type AppRailEvents = typeof __propDef.events;
export type AppRailSlots = typeof __propDef.slots;
/** A vertical navigation rail component. */
export default class AppRail extends SvelteComponentTyped<AppRailProps, AppRailEvents, AppRailSlots> {
}
export {};

View File

@ -0,0 +1,46 @@
<script>import { getContext } from "svelte";
export let selected = false;
export let regionLead = "flex justify-center items-center";
export let regionLabel = "";
export let hover = getContext("hover");
export let active = getContext("active");
export let spacing = getContext("spacing");
export let aspectRatio = getContext("aspectRatio");
const cBase = "unstyled";
const cWrapper = "w-full flex flex-col justify-center items-stretch text-center space-y-1";
const cLabel = "font-bold text-xs";
$:
classActive = selected ? active : "";
$:
classesBase = `${cBase} ${$$props.class || ""}`;
$:
classesWrapper = `${cWrapper} ${aspectRatio} ${hover} ${spacing} ${classActive}`;
$:
classesLead = `${regionLead}`;
$:
classesLabel = `${cLabel} ${regionLabel}`;
function prunedRestProps() {
delete $$restProps.class;
return $$restProps;
}
</script>
<a
class="app-rail-anchor {classesBase}"
href={$$props.href}
{...prunedRestProps()}
on:click
on:keydown
on:keyup
on:keypress
on:mouseover
on:mouseleave
on:focus
on:blur
data-testid="app-rail-anchor"
>
<div class="app-rail-wrapper {classesWrapper}">
{#if $$slots.lead}<div class="app-rail-lead {classesLead}"><slot name="lead" /></div>{/if}
<div class="app-rail-label {classesLabel}"><slot /></div>
</div>
</a>

View File

@ -0,0 +1,38 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Enables the active state styles when set true.*/
selected?: boolean | undefined;
/** Provide arbitrary classes to style the lead region.*/
regionLead?: string | undefined;
/** Provide arbitrary classes to style the label region.*/
regionLabel?: string | undefined;
hover?: string | undefined;
active?: string | undefined;
spacing?: string | undefined;
aspectRatio?: string | undefined;
};
events: {
click: MouseEvent;
keydown: KeyboardEvent;
keyup: KeyboardEvent;
keypress: KeyboardEvent;
mouseover: MouseEvent;
mouseleave: MouseEvent;
focus: FocusEvent;
blur: FocusEvent;
} & {
[evt: string]: CustomEvent<any>;
};
slots: {
lead: {};
default: {};
};
};
export type AppRailAnchorProps = typeof __propDef.props;
export type AppRailAnchorEvents = typeof __propDef.events;
export type AppRailAnchorSlots = typeof __propDef.slots;
export default class AppRailAnchor extends SvelteComponentTyped<AppRailAnchorProps, AppRailAnchorEvents, AppRailAnchorSlots> {
}
export {};

View File

@ -0,0 +1,51 @@
<script>import { getContext } from "svelte";
export let group;
export let name;
export let value;
export let title = "";
export let regionLead = "";
export let regionLabel = "";
export let hover = getContext("hover");
export let active = getContext("active");
export let spacing = getContext("spacing");
export let width = getContext("width");
export let aspectRatio = getContext("aspectRatio");
const cBase = "cursor-pointer";
const cWrapper = "flex flex-col justify-center items-stretch";
const cInterface = "text-center";
const cLabel = "font-bold text-xs";
let elemInput;
$:
classActive = group === value ? active : "";
$:
classesBase = `${cBase} ${$$props.class || ""}`;
$:
classesWrapper = `${cWrapper} ${aspectRatio} ${width} ${hover} ${classActive}`;
$:
classesInterface = `${cInterface} ${spacing}`;
$:
classesLead = `${regionLead}`;
$:
classesLabel = `${cLabel} ${regionLabel}`;
function prunedRestProps() {
delete $$restProps.class;
return $$restProps;
}
</script>
<label class="app-rail-tile {classesBase}" data-testid="app-rail-tile" {title} on:mouseover on:mouseleave on:focus on:blur>
<!-- A11y attributes are not allowed on <label> -->
<!-- FIXME: resolve a11y warnings -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div class="app-rail-wrapper {classesWrapper}" on:keydown on:keyup on:keypress>
<!-- NOTE: Don't use `hidden` as it prevents `required` from operating -->
<div class="h-0 w-0 overflow-hidden">
<input bind:this={elemInput} type="radio" bind:group {name} {value} {...prunedRestProps()} tabindex="-1" on:click on:change />
</div>
<!-- Interface -->
<div class="app-rail-interface {classesInterface}">
{#if $$slots.lead}<div class="app-rail-lead {classesLead}"><slot name="lead" /></div>{/if}
<div class="app-rail-label {classesLabel}"><slot /></div>
</div>
</div>
</label>

View File

@ -0,0 +1,46 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Set the radio group binding value.*/
group: any;
/** Set a unique name value for the input.*/
name: string;
/** Set the input's value.*/
value: any;
/** Provide a hoverable title attribute for the tile.*/
title?: string | undefined;
/** Provide arbitrary classes to style the lead region.*/
regionLead?: string | undefined;
/** Provide arbitrary classes to style the label region.*/
regionLabel?: string | undefined;
hover?: string | undefined;
active?: string | undefined;
spacing?: string | undefined;
width?: string | undefined;
aspectRatio?: string | undefined;
};
events: {
mouseover: MouseEvent;
mouseleave: MouseEvent;
focus: FocusEvent;
blur: FocusEvent;
keydown: KeyboardEvent;
keyup: KeyboardEvent;
keypress: KeyboardEvent;
click: MouseEvent;
change: Event;
} & {
[evt: string]: CustomEvent<any>;
};
slots: {
lead: {};
default: {};
};
};
export type AppRailTileProps = typeof __propDef.props;
export type AppRailTileEvents = typeof __propDef.events;
export type AppRailTileSlots = typeof __propDef.slots;
export default class AppRailTile extends SvelteComponentTyped<AppRailTileProps, AppRailTileEvents, AppRailTileSlots> {
}
export {};

View File

@ -0,0 +1,72 @@
<script>export let scrollbarGutter = "auto";
export let regionPage = "";
export let slotHeader = "z-10";
export let slotSidebarLeft = "w-auto";
export let slotSidebarRight = "w-auto";
export let slotPageHeader = "";
export let slotPageContent = "";
export let slotPageFooter = "";
export let slotFooter = "";
const cBaseAppShell = "w-full h-full flex flex-col overflow-hidden";
const cContentArea = "w-full h-full flex overflow-hidden";
const cPage = "flex-1 overflow-x-hidden flex flex-col";
const cSidebarLeft = "flex-none overflow-x-hidden overflow-y-auto";
const cSidebarRight = "flex-none overflow-x-hidden overflow-y-auto";
$:
classesBase = `${cBaseAppShell} ${$$props.class ?? ""}`;
$:
classesHeader = `${slotHeader}`;
$:
classesSidebarLeft = `${cSidebarLeft} ${slotSidebarLeft}`;
$:
classesSidebarRight = `${cSidebarRight} ${slotSidebarRight}`;
$:
classesPageHeader = `${slotPageHeader}`;
$:
classesPageContent = `${slotPageContent}`;
$:
classesPageFooter = `${slotPageFooter}`;
$:
classesFooter = `${slotFooter}`;
</script>
<div id="appShell" class={classesBase} data-testid="app-shell">
<!-- Slot: Header -->
{#if $$slots.header}
<header id="shell-header" class="flex-none {classesHeader}"><slot name="header" /></header>
{/if}
<!-- Content Area -->
<div class="flex-auto {cContentArea}">
<!-- Slot: Sidebar (left) -->
{#if $$slots.sidebarLeft}
<aside id="sidebar-left" class={classesSidebarLeft}><slot name="sidebarLeft" /></aside>
{/if}
<!-- Page -->
<div id="page" class="{regionPage} {cPage}" style:scrollbar-gutter={scrollbarGutter} on:scroll>
<!-- Slot: Page Header -->
{#if $$slots.pageHeader}
<header id="page-header" class="flex-none {classesPageHeader}"><slot name="pageHeader">(slot:header)</slot></header>
{/if}
<!-- Slot: Page Content (default) -->
<main id="page-content" class="flex-auto {classesPageContent}"><slot /></main>
<!-- Slot: Page Footer -->
{#if $$slots.pageFooter}
<footer id="page-footer" class="flex-none {classesPageFooter}"><slot name="pageFooter">(slot:footer)</slot></footer>
{/if}
</div>
<!-- Slot: Sidebar (right) -->
{#if $$slots.sidebarRight}
<aside id="sidebar-right" class={classesSidebarRight}><slot name="sidebarRight" /></aside>
{/if}
</div>
<!-- Slot: footer -->
{#if $$slots.footer}
<footer id="shell-footer" class="flex-none {classesFooter}"><slot name="footer" /></footer>
{/if}
</div>

View File

@ -0,0 +1,50 @@
import { SvelteComponentTyped } from "svelte";
/** @slot header - Insert fixed header content, such as Skeleton's App Bar component.
* @slot sidebarLeft - Hidden when empty. Allows you to set fixed left sidebar content.
* @slot sidebarRight - Hidden when empty. Allows you to set fixed right sidebar content.
* @slot pageHeader - Insert content that resides above your page content. Great for global alerts.
* @slot pageFooter - Insert content that resides below your page content. Recommended for most layouts.
* @slot footer - Insert fixed footer content. Not recommended for most layouts.
*/
import type { SvelteEvent } from '../../index.js';
declare const __propDef: {
props: {
[x: string]: any;
/** Set `scrollbar-gutter` style.*/
scrollbarGutter?: string | undefined;
/** Apply arbitrary classes to the entire `#page` region.*/
regionPage?: string | undefined;
/** Apply arbitrary classes to the `header` slot container element*/
slotHeader?: string | undefined;
/** Apply arbitrary classes to the `sidebarLeft` slot container element*/
slotSidebarLeft?: string | undefined;
/** Apply arbitrary classes to the `sidebarRight` slot container element*/
slotSidebarRight?: string | undefined;
/** Apply arbitrary classes to the `pageHeader` slot container element*/
slotPageHeader?: string | undefined;
/** Apply arbitrary classes to the `pageContent` slot container element*/
slotPageContent?: string | undefined;
/** Apply arbitrary classes to the `pageFooter` slot container element*/
slotPageFooter?: string | undefined;
/** Apply arbitrary classes to the `footer` slot container element*/
slotFooter?: string | undefined;
};
events: {
scroll: SvelteEvent<UIEvent, HTMLDivElement>;
};
slots: {
header: {};
sidebarLeft: {};
pageHeader: {};
default: {};
pageFooter: {};
sidebarRight: {};
footer: {};
};
};
export type AppShellProps = typeof __propDef.props;
export type AppShellEvents = typeof __propDef.events;
export type AppShellSlots = typeof __propDef.slots;
export default class AppShell extends SvelteComponentTyped<AppShellProps, AppShellEvents, AppShellSlots> {
}
export {};

View File

@ -0,0 +1,97 @@
<script context="module">import { slide } from "svelte/transition";
import { prefersReducedMotionStore } from "../../index.js";
import { dynamicTransition } from "../../internal/transitions.js";
</script>
<script
generics="Value = unknown, Meta = unknown,
TransitionIn extends Transition = SlideTransition, TransitionOut extends Transition = SlideTransition"
>import { createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher();
export let input = void 0;
export let options = [];
export let limit = void 0;
export let allowlist = [];
export let denylist = [];
export let emptyState = "No Results Found.";
export let regionNav = "";
export let regionList = "list-nav";
export let regionItem = "";
export let regionButton = "w-full";
export let regionEmpty = "text-center";
export let transitions = !$prefersReducedMotionStore;
export let transitionIn = slide;
export let transitionInParams = { duration: 200 };
export let transitionOut = slide;
export let transitionOutParams = { duration: 200 };
$:
listedOptions = options;
function filterByAllowDeny(allowlist2, denylist2) {
let _options = [...options];
if (allowlist2.length) {
_options = _options.filter((option) => allowlist2.includes(option.value));
}
if (denylist2.length) {
_options = _options.filter((option) => !denylist2.includes(option.value));
}
if (!allowlist2.length && !denylist2.length) {
_options = options;
}
listedOptions = _options;
}
function filterOptions() {
let _options = [...listedOptions];
_options = _options.filter((option) => {
const inputFormatted = String(input).toLowerCase().trim();
let optionFormatted = JSON.stringify([option.label, option.value, option.keywords]).toLowerCase();
if (optionFormatted.includes(inputFormatted))
return option;
});
return _options;
}
function onSelection(option) {
dispatch("selection", option);
}
$:
filterByAllowDeny(allowlist, denylist);
$:
optionsFiltered = input ? filterOptions() : listedOptions;
$:
sliceLimit = limit ?? optionsFiltered.length;
$:
classesBase = `${$$props.class ?? ""}`;
$:
classesNav = `${regionNav}`;
$:
classesList = `${regionList}`;
$:
classesItem = `${regionItem}`;
$:
classesButton = `${regionButton}`;
$:
classesEmpty = `${regionEmpty}`;
</script>
<!-- animate:flip={{ duration }} -->
<div class="autocomplete {classesBase}" data-testid="autocomplete">
{#if optionsFiltered.length > 0}
<nav class="autocomplete-nav {classesNav}">
<ul class="autocomplete-list {classesList}">
{#each optionsFiltered.slice(0, sliceLimit) as option (option)}
<li
class="autocomplete-item {classesItem}"
in:dynamicTransition|local={{ transition: transitionIn, params: transitionInParams, enabled: transitions }}
out:dynamicTransition|local={{ transition: transitionOut, params: transitionOutParams, enabled: transitions }}
>
<button class="autocomplete-button {classesButton}" type="button" on:click={() => onSelection(option)} on:click on:keypress>
{@html option.label}
</button>
</li>
{/each}
</ul>
</nav>
{:else}
<div class="autocomplete-empty {classesEmpty}">{emptyState}</div>
{/if}
</div>

View File

@ -0,0 +1,56 @@
import { SvelteComponentTyped } from "svelte";
import { slide } from 'svelte/transition';
import { type Transition, type TransitionParams } from '../../index.js';
type SlideTransition = typeof slide;
import type { AutocompleteOption } from './types.js';
declare class __sveltets_Render<Value = unknown, Meta = unknown, TransitionIn extends Transition = SlideTransition, TransitionOut extends Transition = SlideTransition> {
props(): {
[x: string]: any;
/** Bind the input value.*/
input?: Value | undefined;
/** Define values for the list.*/
options?: AutocompleteOption<Value, Meta>[] | undefined;
/** Limit the total number of suggestions.*/
limit?: number | undefined;
/** Provide allowlist values.*/
allowlist?: Value[] | undefined;
/** Provide denylist values.*/
denylist?: Value[] | undefined;
/** Provide a HTML markup to display when no match is found.*/
emptyState?: string | undefined;
/** Provide arbitrary classes to nav element.*/
regionNav?: string | undefined;
/** Provide arbitrary classes to each list.*/
regionList?: string | undefined;
/** Provide arbitrary classes to each list item.*/
regionItem?: string | undefined;
/** Provide arbitrary classes to each button.*/
regionButton?: string | undefined;
/** Provide arbitrary classes to empty message.*/
regionEmpty?: string | undefined;
/** Enable/Disable transitions*/
transitions?: boolean | undefined;
/** Provide the transition used on entry.*/
transitionIn?: TransitionIn | undefined;
/** Transition params provided to `transitionIn`.*/
transitionInParams?: TransitionParams<TransitionIn> | undefined;
/** Provide the transition used on exit.*/
transitionOut?: TransitionOut | undefined;
/** Transition params provided to `transitionOut`.*/
transitionOutParams?: TransitionParams<TransitionOut> | undefined;
};
events(): {
click: MouseEvent;
keypress: KeyboardEvent;
selection: CustomEvent<AutocompleteOption<Value, Meta>>;
} & {
[evt: string]: CustomEvent<any>;
};
slots(): {};
}
export type AutocompleteProps<Value = unknown, Meta = unknown, TransitionIn extends Transition = SlideTransition, TransitionOut extends Transition = SlideTransition> = ReturnType<__sveltets_Render<Value, Meta, TransitionIn, TransitionOut>['props']>;
export type AutocompleteEvents<Value = unknown, Meta = unknown, TransitionIn extends Transition = SlideTransition, TransitionOut extends Transition = SlideTransition> = ReturnType<__sveltets_Render<Value, Meta, TransitionIn, TransitionOut>['events']>;
export type AutocompleteSlots<Value = unknown, Meta = unknown, TransitionIn extends Transition = SlideTransition, TransitionOut extends Transition = SlideTransition> = ReturnType<__sveltets_Render<Value, Meta, TransitionIn, TransitionOut>['slots']>;
export default class Autocomplete<Value = unknown, Meta = unknown, TransitionIn extends Transition = SlideTransition, TransitionOut extends Transition = SlideTransition> extends SvelteComponentTyped<AutocompleteProps<Value, Meta, TransitionIn, TransitionOut>, AutocompleteEvents<Value, Meta, TransitionIn, TransitionOut>, AutocompleteSlots<Value, Meta, TransitionIn, TransitionOut>> {
}
export {};

View File

@ -0,0 +1,10 @@
export interface AutocompleteOption<Value = unknown, Meta = unknown> {
/** Provide a unique display label per option. Supports HTML. */
label: string;
/** Provide a unique option value. */
value: Value;
/** Provide a comma separated list of keywords. */
keywords?: string;
/** Pass arbitrary data per option. */
meta?: Meta;
}

View File

@ -0,0 +1,2 @@
// Autocomplete Types
export {};

View File

@ -0,0 +1,44 @@
<script>export let initials = "AB";
export let fill = "fill-token";
export let src = "";
export let fallback = "";
export let action = () => {
};
export let actionParams = "";
export let background = "bg-surface-400-500-token";
export let width = "w-16";
export let border = "";
export let rounded = "rounded-full";
export let shadow = "";
export let cursor = "";
let cBase = "flex aspect-square text-surface-50 font-semibold justify-center items-center overflow-hidden isolate";
let cImage = "w-full h-full object-cover";
$:
classesBase = `${cBase} ${background} ${width} ${border} ${rounded} ${shadow} ${cursor} ${$$props.class ?? ""}`;
function prunedRestProps() {
delete $$restProps.class;
return $$restProps;
}
</script>
<!-- FIXME: resolve a11y warnings -->
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<figure class="avatar {classesBase}" data-testid="avatar" on:click on:keydown on:keyup on:keypress>
{#if src}
<img
class="avatar-image {cImage}"
style={$$props.style ?? ''}
{src}
alt={$$props.alt || ''}
use:action={actionParams}
on:error={() => (src = fallback)}
{...prunedRestProps()}
/>
{:else}
<svg class="avatar-initials w-full h-full" viewBox="0 0 512 512">
<text x="50%" y="50%" dominant-baseline="central" text-anchor="middle" font-weight="bold" font-size={150} class="avatar-text {fill}">
{String(initials).substring(0, 2).toUpperCase()}
</text>
</svg>
{/if}
</figure>

View File

@ -0,0 +1,46 @@
import { SvelteComponentTyped } from "svelte";
import type { Action } from 'svelte/action';
declare const __propDef: {
props: {
[x: string]: any;
/** Initials only - Provide up to two text characters.*/
initials?: string | undefined;
/** Initials only - Provide classes to set the SVG text fill color.*/
fill?: string | undefined;
/** Provide the avatar image element source.*/
src?: string | undefined;
/** Provide the fallback image element source.*/
fallback?: string | undefined;
/** Image only. Provide a Svelte action reference, such as `filter`.*/
action?: Action<HTMLElement, string, Record<never, any>> | undefined;
/** Image only. Provide Svelte action params, such as Apollo.*/
actionParams?: string | undefined;
/** Provide classes to set background styles.*/
background?: string | undefined;
/** Provide classes to set avatar width.*/
width?: string | undefined;
/** Provide classes to set border styles.*/
border?: string | undefined;
/** Provide classes to set rounded style.*/
rounded?: string | undefined;
/** Provide classes to set shadow styles.*/
shadow?: string | undefined;
/** Provide classes to set cursor styles.*/
cursor?: string | undefined;
};
events: {
click: MouseEvent;
keydown: KeyboardEvent;
keyup: KeyboardEvent;
keypress: KeyboardEvent;
} & {
[evt: string]: CustomEvent<any>;
};
slots: {};
};
export type AvatarProps = typeof __propDef.props;
export type AvatarEvents = typeof __propDef.events;
export type AvatarSlots = typeof __propDef.slots;
export default class Avatar extends SvelteComponentTyped<AvatarProps, AvatarEvents, AvatarSlots> {
}
export {};

View File

@ -0,0 +1,77 @@
<script>import { afterUpdate } from "svelte";
import { tailwindDefaultColors } from "./settings.js";
export let stops = [{ color: ["neutral", 500], start: 0, end: 100 }];
export let legend = false;
export let spin = false;
export let width = "w-24";
export let hover = "bg-primary-hover-token";
export let digits = 0;
export let regionCaption = "";
export let regionCone = "";
export let regionLegend = "";
let cone;
let generatedLegendList;
const cBase = "flex flex-col items-center space-y-4 w-";
const cCaption = "text-center";
const cCone = "block aspect-square rounded-full";
const cLegend = "text-sm w-full";
const cSwatch = "block aspect-square bg-black w-5 rounded-full mr-2";
function setColorValue(color) {
if (typeof color === "string")
return color;
const colorSet = tailwindDefaultColors.find((c) => c.label === color[0]);
return colorSet?.shades[color[1]].hex;
}
function genConicGradient() {
let d = stops.map((v) => `${setColorValue(v.color)} ${v.start}% ${v.end}%`);
cone = `conic-gradient(${d.join(", ")})`;
}
function genLegend() {
if (!legend)
return;
generatedLegendList = stops.map((v) => {
return {
label: v.label,
color: setColorValue(v.color),
value: (v.end - v.start).toFixed(digits)
};
});
}
afterUpdate(() => {
genConicGradient();
genLegend();
});
$:
classesBase = `${cBase} ${$$props.class ?? ""}`;
$:
classesCaption = `${cCaption} ${regionCaption}`;
$:
classesCone = `${cCone} ${width} ${regionCone}`;
$:
classesLegend = `${cLegend} ${regionLegend}`;
</script>
<figure class="conic-gradient {classesBase}" data-testid="conic-gradient">
<!-- Label -->
{#if $$slots.default}
<figcaption class="conic-caption {classesCaption}"><slot /></figcaption>
{/if}
<!-- Conic Gradient -->
{#if cone}
<div class="conic-cone {classesCone}" class:animate-spin={spin} style:background={cone} />
{/if}
<!-- Legend -->
{#if legend && generatedLegendList}
<ul class="conic-list list {classesLegend}">
{#each generatedLegendList as { color, label, value }}
<!-- FIXME: resolve a11y warnings -->
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<li class="conic-item {hover}" on:click on:keydown on:keyup on:keypress>
<span class="conic-swatch {cSwatch}" style:background={color} />
<span class="conic-label flex-auto">{label}</span>
<strong class="conic-value">{value}%</strong>
</li>
{/each}
</ul>
{/if}
</figure>

View File

@ -0,0 +1,42 @@
import { SvelteComponentTyped } from "svelte";
import type { ConicStop } from './types.js';
declare const __propDef: {
props: {
[x: string]: any;
/** Provide a data set of color stops and labels.*/
stops?: ConicStop[] | undefined;
/** Enable a contextual legend.*/
legend?: boolean | undefined;
/** When enabled, the conic gradient will spin.*/
spin?: boolean | undefined;
/** Style the conic gradient width.*/
width?: string | undefined;
/** Style the legend hover effect.*/
hover?: string | undefined;
/** Set the number of digits on the legend values.*/
digits?: number | undefined;
/** Style the caption region above the gradient.*/
regionCaption?: string | undefined;
/** Style the conic gradient region.*/
regionCone?: string | undefined;
/** Style the legend region below the gradient.*/
regionLegend?: string | undefined;
};
events: {
click: MouseEvent;
keydown: KeyboardEvent;
keyup: KeyboardEvent;
keypress: KeyboardEvent;
} & {
[evt: string]: CustomEvent<any>;
};
slots: {
default: {};
};
};
export type ConicGradientProps = typeof __propDef.props;
export type ConicGradientEvents = typeof __propDef.events;
export type ConicGradientSlots = typeof __propDef.slots;
export default class ConicGradient extends SvelteComponentTyped<ConicGradientProps, ConicGradientEvents, ConicGradientSlots> {
}
export {};

View File

@ -0,0 +1,9 @@
export type HexRgb = {
hex: string;
rgb: string;
};
export type TailwindColorObject = {
label: string;
shades: Record<string, HexRgb>;
};
export declare const tailwindDefaultColors: TailwindColorObject[];

View File

@ -0,0 +1,334 @@
// Provides the full set of Tailwind colors via Javascript
// https://tailwindcss.com/docs/customizing-colors#default-color-palette
export const tailwindDefaultColors = [
{
label: 'slate',
shades: {
'50': { hex: '#f8fafc', rgb: '248 250 252' },
'100': { hex: '#f1f5f9', rgb: '241 245 249' },
'200': { hex: '#e2e8f0', rgb: '226 232 240' },
'300': { hex: '#cbd5e1', rgb: '203 213 225' },
'400': { hex: '#94a3b8', rgb: '148 163 184' },
'500': { hex: '#64748b', rgb: '100 116 139' },
'600': { hex: '#475569', rgb: '71 85 105' },
'700': { hex: '#334155', rgb: '51 65 85' },
'800': { hex: '#1e293b', rgb: '30 41 59' },
'900': { hex: '#0f172a', rgb: '15 23 42' }
}
},
{
label: 'gray',
shades: {
'50': { hex: '#f9fafb', rgb: '249 250 251' },
'100': { hex: '#f3f4f6', rgb: '243 244 246' },
'200': { hex: '#e5e7eb', rgb: '229 231 235' },
'300': { hex: '#d1d5db', rgb: '209 213 219' },
'400': { hex: '#9ca3af', rgb: '156 163 175' },
'500': { hex: '#6b7280', rgb: '107 114 128' },
'600': { hex: '#4b5563', rgb: '75 85 99' },
'700': { hex: '#374151', rgb: '55 65 81' },
'800': { hex: '#1f2937', rgb: '31 41 55' },
'900': { hex: '#111827', rgb: '17 24 39' }
}
},
{
label: 'zinc',
shades: {
'50': { hex: '#fafafa', rgb: '250 250 250' },
'100': { hex: '#f4f4f5', rgb: '244 244 245' },
'200': { hex: '#e4e4e7', rgb: '228 228 231' },
'300': { hex: '#d4d4d8', rgb: '212 212 216' },
'400': { hex: '#a1a1aa', rgb: '161 161 170' },
'500': { hex: '#71717a', rgb: '113 113 122' },
'600': { hex: '#52525b', rgb: '82 82 91' },
'700': { hex: '#3f3f46', rgb: '63 63 70' },
'800': { hex: '#27272a', rgb: '39 39 42' },
'900': { hex: '#18181b', rgb: '24 24 27' }
}
},
{
label: 'neutral',
shades: {
'50': { hex: '#fafafa', rgb: '250 250 250' },
'100': { hex: '#f5f5f5', rgb: '245 245 245' },
'200': { hex: '#e5e5e5', rgb: '229 229 229' },
'300': { hex: '#d4d4d4', rgb: '212 212 212' },
'400': { hex: '#a3a3a3', rgb: '163 163 163' },
'500': { hex: '#737373', rgb: '115 115 115' },
'600': { hex: '#525252', rgb: '82 82 82' },
'700': { hex: '#404040', rgb: '64 64 64' },
'800': { hex: '#262626', rgb: '38 38 38' },
'900': { hex: '#171717', rgb: '23 23 23' }
}
},
{
label: 'stone',
shades: {
'50': { hex: '#fafaf9', rgb: '250 250 249' },
'100': { hex: '#f5f5f4', rgb: '245 245 244' },
'200': { hex: '#e7e5e4', rgb: '231 229 228' },
'300': { hex: '#d6d3d1', rgb: '214 211 209' },
'400': { hex: '#a8a29e', rgb: '168 162 158' },
'500': { hex: '#78716c', rgb: '120 113 108' },
'600': { hex: '#57534e', rgb: '87 83 78' },
'700': { hex: '#44403c', rgb: '68 64 60' },
'800': { hex: '#292524', rgb: '41 37 36' },
'900': { hex: '#1c1917', rgb: '28 25 23' }
}
},
{
label: 'red',
shades: {
'50': { hex: '#fef2f2', rgb: '254 242 242' },
'100': { hex: '#fee2e2', rgb: '254 226 226' },
'200': { hex: '#fecaca', rgb: '254 202 202' },
'300': { hex: '#fca5a5', rgb: '252 165 165' },
'400': { hex: '#f87171', rgb: '248 113 113' },
'500': { hex: '#ef4444', rgb: '239 68 68' },
'600': { hex: '#dc2626', rgb: '220 38 38' },
'700': { hex: '#b91c1c', rgb: '185 28 28' },
'800': { hex: '#991b1b', rgb: '153 27 27' },
'900': { hex: '#7f1d1d', rgb: '127 29 29' }
}
},
{
label: 'orange',
shades: {
'50': { hex: '#fff7ed', rgb: '255 247 237' },
'100': { hex: '#ffedd5', rgb: '255 237 213' },
'200': { hex: '#fed7aa', rgb: '254 215 170' },
'300': { hex: '#fdba74', rgb: '253 186 116' },
'400': { hex: '#fb923c', rgb: '251 146 60' },
'500': { hex: '#f97316', rgb: '249 115 22' },
'600': { hex: '#ea580c', rgb: '234 88 12' },
'700': { hex: '#c2410c', rgb: '194 65 12' },
'800': { hex: '#9a3412', rgb: '154 52 18' },
'900': { hex: '#7c2d12', rgb: '124 45 18' }
}
},
{
label: 'amber',
shades: {
'50': { hex: '#fffbeb', rgb: '255 251 235' },
'100': { hex: '#fef3c7', rgb: '254 243 199' },
'200': { hex: '#fde68a', rgb: '253 230 138' },
'300': { hex: '#fcd34d', rgb: '252 211 77' },
'400': { hex: '#fbbf24', rgb: '251 191 36' },
'500': { hex: '#f59e0b', rgb: '245 158 11' },
'600': { hex: '#d97706', rgb: '217 119 6' },
'700': { hex: '#b45309', rgb: '180 83 9' },
'800': { hex: '#92400e', rgb: '146 64 14' },
'900': { hex: '#78350f', rgb: '120 53 15' }
}
},
{
label: 'yellow',
shades: {
'50': { hex: '#fefce8', rgb: '254 252 232' },
'100': { hex: '#fef9c3', rgb: '254 249 195' },
'200': { hex: '#fef08a', rgb: '254 240 138' },
'300': { hex: '#fde047', rgb: '253 224 71' },
'400': { hex: '#facc15', rgb: '250 204 21' },
'500': { hex: '#eab308', rgb: '234 179 8' },
'600': { hex: '#ca8a04', rgb: '202 138 4' },
'700': { hex: '#a16207', rgb: '161 98 7' },
'800': { hex: '#854d0e', rgb: '133 77 14' },
'900': { hex: '#713f12', rgb: '113 63 18' }
}
},
{
label: 'lime',
shades: {
'50': { hex: '#f7fee7', rgb: '247 254 231' },
'100': { hex: '#ecfccb', rgb: '236 252 203' },
'200': { hex: '#d9f99d', rgb: '217 249 157' },
'300': { hex: '#bef264', rgb: '190 242 100' },
'400': { hex: '#a3e635', rgb: '163 230 53' },
'500': { hex: '#84cc16', rgb: '132 204 22' },
'600': { hex: '#65a30d', rgb: '101 163 13' },
'700': { hex: '#4d7c0f', rgb: '77 124 15' },
'800': { hex: '#3f6212', rgb: '63 98 18' },
'900': { hex: '#365314', rgb: '54 83 20' }
}
},
{
label: 'green',
shades: {
'50': { hex: '#f0fdf4', rgb: '240 253 244' },
'100': { hex: '#dcfce7', rgb: '220 252 231' },
'200': { hex: '#bbf7d0', rgb: '187 247 208' },
'300': { hex: '#86efac', rgb: '134 239 172' },
'400': { hex: '#4ade80', rgb: '74 222 128' },
'500': { hex: '#22c55e', rgb: '34 197 94' },
'600': { hex: '#16a34a', rgb: '22 163 74' },
'700': { hex: '#15803d', rgb: '21 128 61' },
'800': { hex: '#166534', rgb: '22 101 52' },
'900': { hex: '#14532d', rgb: '20 83 45' }
}
},
{
label: 'emerald',
shades: {
'50': { hex: '#ecfdf5', rgb: '236 253 245' },
'100': { hex: '#d1fae5', rgb: '209 250 229' },
'200': { hex: '#a7f3d0', rgb: '167 243 208' },
'300': { hex: '#6ee7b7', rgb: '110 231 183' },
'400': { hex: '#34d399', rgb: '52 211 153' },
'500': { hex: '#10b981', rgb: '16 185 129' },
'600': { hex: '#059669', rgb: '5 150 105' },
'700': { hex: '#047857', rgb: '4 120 87' },
'800': { hex: '#065f46', rgb: '6 95 70' },
'900': { hex: '#064e3b', rgb: '6 78 59' }
}
},
{
label: 'teal',
shades: {
'50': { hex: '#f0fdfa', rgb: '240 253 250' },
'100': { hex: '#ccfbf1', rgb: '204 251 241' },
'200': { hex: '#99f6e4', rgb: '153 246 228' },
'300': { hex: '#5eead4', rgb: '94 234 212' },
'400': { hex: '#2dd4bf', rgb: '45 212 191' },
'500': { hex: '#14b8a6', rgb: '20 184 166' },
'600': { hex: '#0d9488', rgb: '13 148 136' },
'700': { hex: '#0f766e', rgb: '15 118 110' },
'800': { hex: '#115e59', rgb: '17 94 89' },
'900': { hex: '#134e4a', rgb: '19 78 74' }
}
},
{
label: 'cyan',
shades: {
'50': { hex: '#ecfeff', rgb: '236 254 255' },
'100': { hex: '#cffafe', rgb: '207 250 254' },
'200': { hex: '#a5f3fc', rgb: '165 243 252' },
'300': { hex: '#67e8f9', rgb: '103 232 249' },
'400': { hex: '#22d3ee', rgb: '34 211 238' },
'500': { hex: '#06b6d4', rgb: '6 182 212' },
'600': { hex: '#0891b2', rgb: '8 145 178' },
'700': { hex: '#0e7490', rgb: '14 116 144' },
'800': { hex: '#155e75', rgb: '21 94 117' },
'900': { hex: '#164e63', rgb: '22 78 99' }
}
},
{
label: 'sky',
shades: {
'50': { hex: '#f0f9ff', rgb: '240 249 255' },
'100': { hex: '#e0f2fe', rgb: '224 242 254' },
'200': { hex: '#bae6fd', rgb: '186 230 253' },
'300': { hex: '#7dd3fc', rgb: '125 211 252' },
'400': { hex: '#38bdf8', rgb: '56 189 248' },
'500': { hex: '#0ea5e9', rgb: '14 165 233' },
'600': { hex: '#0284c7', rgb: '2 132 199' },
'700': { hex: '#0369a1', rgb: '3 105 161' },
'800': { hex: '#075985', rgb: '7 89 133' },
'900': { hex: '#0c4a6e', rgb: '12 74 110' }
}
},
{
label: 'blue',
shades: {
'50': { hex: '#eff6ff', rgb: '239 246 255' },
'100': { hex: '#dbeafe', rgb: '219 234 254' },
'200': { hex: '#bfdbfe', rgb: '191 219 254' },
'300': { hex: '#93c5fd', rgb: '147 197 253' },
'400': { hex: '#60a5fa', rgb: '96 165 250' },
'500': { hex: '#3b82f6', rgb: '59 130 246' },
'600': { hex: '#2563eb', rgb: '37 99 235' },
'700': { hex: '#1d4ed8', rgb: '29 78 216' },
'800': { hex: '#1e40af', rgb: '30 64 175' },
'900': { hex: '#1e3a8a', rgb: '30 58 138' }
}
},
{
label: 'indigo',
shades: {
'50': { hex: '#eef2ff', rgb: '238 242 255' },
'100': { hex: '#e0e7ff', rgb: '224 231 255' },
'200': { hex: '#c7d2fe', rgb: '199 210 254' },
'300': { hex: '#a5b4fc', rgb: '165 180 252' },
'400': { hex: '#818cf8', rgb: '129 140 248' },
'500': { hex: '#6366f1', rgb: '99 102 241' },
'600': { hex: '#4f46e5', rgb: '79 70 229' },
'700': { hex: '#4338ca', rgb: '67 56 202' },
'800': { hex: '#3730a3', rgb: '55 48 163' },
'900': { hex: '#312e81', rgb: '49 46 129' }
}
},
{
label: 'violet',
shades: {
'50': { hex: '#f5f3ff', rgb: '245 243 255' },
'100': { hex: '#ede9fe', rgb: '237 233 254' },
'200': { hex: '#ddd6fe', rgb: '221 214 254' },
'300': { hex: '#c4b5fd', rgb: '196 181 253' },
'400': { hex: '#a78bfa', rgb: '167 139 250' },
'500': { hex: '#8b5cf6', rgb: '139 92 246' },
'600': { hex: '#7c3aed', rgb: '124 58 237' },
'700': { hex: '#6d28d9', rgb: '109 40 217' },
'800': { hex: '#5b21b6', rgb: '91 33 182' },
'900': { hex: '#4c1d95', rgb: '76 29 149' }
}
},
{
label: 'purple',
shades: {
'50': { hex: '#faf5ff', rgb: '250 245 255' },
'100': { hex: '#f3e8ff', rgb: '243 232 255' },
'200': { hex: '#e9d5ff', rgb: '233 213 255' },
'300': { hex: '#d8b4fe', rgb: '216 180 254' },
'400': { hex: '#c084fc', rgb: '192 132 252' },
'500': { hex: '#a855f7', rgb: '168 85 247' },
'600': { hex: '#9333ea', rgb: '147 51 234' },
'700': { hex: '#7e22ce', rgb: '126 34 206' },
'800': { hex: '#6b21a8', rgb: '107 33 168' },
'900': { hex: '#581c87', rgb: '88 28 135' }
}
},
{
label: 'fuchsia',
shades: {
'50': { hex: '#fdf4ff', rgb: '253 244 255' },
'100': { hex: '#fae8ff', rgb: '250 232 255' },
'200': { hex: '#f5d0fe', rgb: '245 208 254' },
'300': { hex: '#f0abfc', rgb: '240 171 252' },
'400': { hex: '#e879f9', rgb: '232 121 249' },
'500': { hex: '#d946ef', rgb: '217 70 239' },
'600': { hex: '#c026d3', rgb: '192 38 211' },
'700': { hex: '#a21caf', rgb: '162 28 175' },
'800': { hex: '#86198f', rgb: '134 25 143' },
'900': { hex: '#701a75', rgb: '112 26 117' }
}
},
{
label: 'pink',
shades: {
'50': { hex: '#fdf2f8', rgb: '253 242 248' },
'100': { hex: '#fce7f3', rgb: '252 231 243' },
'200': { hex: '#fbcfe8', rgb: '251 207 232' },
'300': { hex: '#f9a8d4', rgb: '249 168 212' },
'400': { hex: '#f472b6', rgb: '244 114 182' },
'500': { hex: '#ec4899', rgb: '236 72 153' },
'600': { hex: '#db2777', rgb: '219 39 119' },
'700': { hex: '#be185d', rgb: '190 24 93' },
'800': { hex: '#9d174d', rgb: '157 23 77' },
'900': { hex: '#831843', rgb: '131 24 67' }
}
},
{
label: 'rose',
shades: {
'50': { hex: '#fff1f2', rgb: '255 241 242' },
'100': { hex: '#ffe4e6', rgb: '255 228 230' },
'200': { hex: '#fecdd3', rgb: '254 205 211' },
'300': { hex: '#fda4af', rgb: '253 164 175' },
'400': { hex: '#fb7185', rgb: '251 113 133' },
'500': { hex: '#f43f5e', rgb: '244 63 94' },
'600': { hex: '#e11d48', rgb: '225 29 72' },
'700': { hex: '#be123c', rgb: '190 18 60' },
'800': { hex: '#9f1239', rgb: '159 18 57' },
'900': { hex: '#881337', rgb: '136 19 55' }
}
}
];

View File

@ -0,0 +1,10 @@
export interface ConicStop {
/** The legend label value. */
label?: string;
/** The desired color value. */
color: string | object;
/** Starting stop value (0-100) */
start: number;
/** Ending stop value (0-100) */
end: number;
}

View File

@ -0,0 +1,2 @@
// Conic Gradient Types
export {};

View File

@ -0,0 +1,37 @@
<script>export let files = void 0;
export let fileInput = void 0;
export let name;
export let width = "";
export let button = "btn variant-filled";
function onButtonClick() {
if (fileInput)
fileInput.click();
}
function prunedRestProps() {
delete $$restProps.class;
return $$restProps;
}
$:
classesBase = `${$$props.class ?? ""}`;
$:
classesButton = `${button} ${width}`;
</script>
<div class="file-button {classesBase}" data-testid="file-button">
<!-- NOTE: Don't use `hidden` as it prevents `required` from operating -->
<div class="w-0 h-0 overflow-hidden">
<input type="file" bind:this={fileInput} bind:files {name} {...prunedRestProps()} on:change />
</div>
<!-- Button -->
<button
type="button"
class="file-button-btn {classesButton}"
disabled={$$restProps.disabled}
on:click={onButtonClick}
on:keydown
on:keyup
on:keypress
>
<slot>Select a File</slot>
</button>
</div>

View File

@ -0,0 +1,33 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Bind FileList to the file input.*/
files?: FileList | undefined;
/** File input reference.*/
fileInput?: HTMLInputElement | undefined;
/** Required. Set a unique name for the file input.*/
name: string;
/** Provide classes to set the width.*/
width?: string | undefined;
/** Provide a button variant or other class styles.*/
button?: string | undefined;
};
events: {
change: Event;
keydown: KeyboardEvent;
keyup: KeyboardEvent;
keypress: KeyboardEvent;
} & {
[evt: string]: CustomEvent<any>;
};
slots: {
default: {};
};
};
export type FileButtonProps = typeof __propDef.props;
export type FileButtonEvents = typeof __propDef.events;
export type FileButtonSlots = typeof __propDef.slots;
export default class FileButton extends SvelteComponentTyped<FileButtonProps, FileButtonEvents, FileButtonSlots> {
}
export {};

View File

@ -0,0 +1,63 @@
<script>export let files = void 0;
export let fileInput = void 0;
export let name;
export let border = "border-2 border-dashed";
export let padding = "p-4 py-8";
export let rounded = "rounded-container-token";
export let regionInterface = "";
export let regionInterfaceText = "";
export let slotLead = "mb-4";
export let slotMessage = "";
export let slotMeta = "opacity-75";
const cBase = "textarea relative flex justify-center items-center";
const cInput = "w-full absolute top-0 left-0 right-0 bottom-0 z-[1] opacity-0 disabled:!opacity-0 cursor-pointer";
const cInterface = "flex justify-center items-center text-center";
$:
classesBase = `${cBase} ${border} ${padding} ${rounded} ${$$props.class ?? ""}`;
$:
classesInput = `${cInput}`;
$:
classesInterface = `${cInterface}`;
function prunedRestProps() {
delete $$restProps.class;
return $$restProps;
}
</script>
<div class="dropzone {classesBase}" class:opacity-50={$$restProps.disabled} data-testid="file-dropzone">
<!-- Input: File (hidden) -->
<!-- NOTE: keep `bind:files` here, unlike FileButton -->
<input
bind:files
bind:this={fileInput}
type="file"
{name}
class="dropzone-input {classesInput}"
{...prunedRestProps()}
on:change
on:dragenter
on:dragover
on:dragleave
on:drop
on:click
on:keydown
on:keyup
on:keypress
on:focus
on:focusin
on:focusout
/>
<!-- Interface -->
<div class="dropzone-interface {classesInterface} {regionInterface}">
<div class="dropzone-interface-text {regionInterfaceText}">
<!-- Lead -->
{#if $$slots.lead}<div class="dropzone-lead {slotLead}"><slot name="lead" /></div>{/if}
<!-- Message -->
<div class="dropzone-message {slotMessage}">
<slot name="message"><strong>Upload a file</strong> or drag and drop</slot>
</div>
<!-- Meta Text -->
{#if $$slots.meta}<small class="dropzone-meta {slotMeta}"><slot name="meta" /></small>{/if}
</div>
</div>
</div>

View File

@ -0,0 +1,55 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Bind FileList to the file input.*/
files?: FileList | undefined;
/** File input reference.*/
fileInput?: HTMLInputElement | undefined;
/** Required. Set a unique name for the file input.*/
name: string;
/** Provide classes to set the border styles.*/
border?: string | undefined;
/** Provide classes to set the padding styles.*/
padding?: string | undefined;
/** Provide classes to set the box radius styles.*/
rounded?: string | undefined;
/** Provide arbitrary styles for the UI region.*/
regionInterface?: string | undefined;
/** Provide arbitrary styles for the UI text region.*/
regionInterfaceText?: string | undefined;
/** Provide arbitrary styles for lead slot container.*/
slotLead?: string | undefined;
/** Provide arbitrary styles for message slot container.*/
slotMessage?: string | undefined;
/** Provide arbitrary styles for meta text slot container.*/
slotMeta?: string | undefined;
};
events: {
change: Event;
dragenter: DragEvent;
dragover: DragEvent;
dragleave: DragEvent;
drop: DragEvent;
click: MouseEvent;
keydown: KeyboardEvent;
keyup: KeyboardEvent;
keypress: KeyboardEvent;
focus: FocusEvent;
focusin: FocusEvent;
focusout: FocusEvent;
} & {
[evt: string]: CustomEvent<any>;
};
slots: {
lead: {};
message: {};
meta: {};
};
};
export type FileDropzoneProps = typeof __propDef.props;
export type FileDropzoneEvents = typeof __propDef.events;
export type FileDropzoneSlots = typeof __propDef.slots;
export default class FileDropzone extends SvelteComponentTyped<FileDropzoneProps, FileDropzoneEvents, FileDropzoneSlots> {
}
export {};

View File

@ -0,0 +1,179 @@
<script context="module">import { fly, scale } from "svelte/transition";
import { prefersReducedMotionStore } from "../../index.js";
import { dynamicTransition } from "../../internal/transitions.js";
</script>
<script
generics="ListTransitionIn extends Transition = FlyTransition, ListTransitionOut extends Transition = FlyTransition, ChipTransitionIn extends Transition = ScaleTransition, ChipTransitionOut extends Transition = ScaleTransition"
>import { createEventDispatcher, onMount } from "svelte";
import { flip } from "svelte/animate";
const dispatch = createEventDispatcher();
export let input = "";
export let name;
export let value = [];
export let whitelist = [];
export let max = -1;
export let minlength = -1;
export let maxlength = -1;
export let allowUpperCase = false;
export let allowDuplicates = false;
export let validation = () => true;
export let duration = 150;
export let required = false;
export let chips = "variant-filled";
export let invalid = "input-error";
export let padding = "p-2";
export let rounded = "rounded-container-token";
export let regionChipWrapper = "";
export let regionChipList = "";
export let regionInput = "";
export let transitions = !$prefersReducedMotionStore;
export let listTransitionIn = fly;
export let listTransitionInParams = { duration: 150, opacity: 0, y: -20 };
export let listTransitionOut = fly;
export let listTransitionOutParams = { duration: 150, opacity: 0, y: -20 };
export let chipTransitionIn = scale;
export let chipTransitionInParams = { duration: 150, opacity: 0 };
export let chipTransitionOut = scale;
export let chipTransitionOutParams = { duration: 150, opacity: 0 };
const cBase = "textarea cursor-pointer";
const cChipWrapper = "space-y-4";
const cChipList = "flex flex-wrap gap-2";
const cInputField = "unstyled bg-transparent border-0 !ring-0 p-0 w-full";
let inputValid = true;
let chipValues = value?.map((val) => {
return { val, id: Math.random() };
}) || [];
function resetFormHandler() {
value = [];
}
let selectElement;
onMount(() => {
if (!selectElement.form)
return;
const externalForm = selectElement.form;
externalForm.addEventListener("reset", resetFormHandler);
return () => {
externalForm.removeEventListener("reset", resetFormHandler);
};
});
function onInputHandler() {
inputValid = true;
}
function validate() {
if (!input)
return false;
input = input.trim();
if (validation !== void 0 && !validation(input))
return false;
if (max !== -1 && value.length >= max)
return false;
if (minlength !== -1 && input.length < minlength)
return false;
if (maxlength !== -1 && input.length > maxlength)
return false;
if (whitelist.length > 0 && !whitelist.includes(input))
return false;
if (allowDuplicates === false && value.includes(input))
return false;
return true;
}
function addChip(event) {
event.preventDefault();
inputValid = validate();
if (inputValid === false) {
dispatch("invalid", { event, input });
return;
}
input = allowUpperCase ? input : input.toLowerCase();
value.push(input);
value = value;
chipValues.push({ val: input, id: Math.random() });
chipValues = chipValues;
dispatch("add", { event, chipIndex: value.length - 1, chipValue: input });
input = "";
}
function removeChip(event, chipIndex, chipValue) {
if ($$restProps.disabled)
return;
value.splice(chipIndex, 1);
value = value;
chipValues.splice(chipIndex, 1);
chipValues = chipValues;
dispatch("remove", { event, chipIndex, chipValue });
}
$:
classesInvalid = inputValid === false ? invalid : "";
$:
classesBase = `${cBase} ${padding} ${rounded} ${$$props.class ?? ""} ${classesInvalid}`;
$:
classesChipWrapper = `${cChipWrapper} ${regionChipWrapper}`;
$:
classesChipList = `${cChipList} ${regionChipList}`;
$:
classesInput = `${cInputField} ${regionInput}`;
$:
chipValues = value?.map((val, i) => {
if (chipValues[i]?.val === val)
return chipValues[i];
return { id: Math.random(), val };
}) || [];
</script>
<div class="input-chip {classesBase}" class:opacity-50={$$restProps.disabled}>
<!-- NOTE: Don't use `hidden` as it prevents `required` from operating -->
<div class="h-0 overflow-hidden">
<select bind:this={selectElement} bind:value {name} multiple {required} tabindex="-1">
<!-- NOTE: options are required! -->
{#each value as option}<option value={option}>{option}</option>{/each}
</select>
</div>
<!-- Chip Wrapper -->
<div class="input-chip-wrapper {classesChipWrapper}">
<!-- Input Field -->
<form on:submit={addChip}>
<input
type="text"
bind:value={input}
placeholder={$$restProps.placeholder ?? 'Enter values...'}
class="input-chip-field {classesInput}"
on:input={onInputHandler}
on:input
on:focus
on:blur
disabled={$$restProps.disabled}
/>
</form>
<!-- Chip List -->
{#if chipValues.length}
<div
class="input-chip-list {classesChipList}"
in:dynamicTransition|local={{ transition: listTransitionIn, params: listTransitionInParams, enabled: transitions }}
out:dynamicTransition|local={{ transition: listTransitionOut, params: listTransitionOutParams, enabled: transitions }}
>
{#each chipValues as { id, val }, i (id)}
<!-- Wrapping div required for FLIP animation -->
<div animate:flip={{ duration }}>
<button
type="button"
class="chip {chips}"
on:click={(e) => {
removeChip(e, i, val);
}}
on:click
on:keypress
on:keydown
on:keyup
in:dynamicTransition|local={{ transition: chipTransitionIn, params: chipTransitionInParams, enabled: transitions }}
out:dynamicTransition|local={{ transition: chipTransitionOut, params: chipTransitionOutParams, enabled: transitions }}
>
<span>{val}</span>
<span></span>
</button>
</div>
{/each}
</div>
{/if}
</div>
</div>

View File

@ -0,0 +1,98 @@
import { SvelteComponentTyped } from "svelte";
import { fly, scale } from 'svelte/transition';
import { type Transition, type TransitionParams } from '../../index.js';
type FlyTransition = typeof fly;
type ScaleTransition = typeof scale;
declare class __sveltets_Render<ListTransitionIn extends Transition = FlyTransition, ListTransitionOut extends Transition = FlyTransition, ChipTransitionIn extends Transition = ScaleTransition, ChipTransitionOut extends Transition = ScaleTransition> {
props(): {
[x: string]: any;
/** Bind the input value.*/
input?: string | undefined;
/** Set a unique select input name.*/
name: string;
/** An array of values.*/
value?: any[] | undefined;
/** Provide a whitelist of accepted values.*/
whitelist?: string[] | undefined;
/** Maximum number of chips. Set -1 to disable.*/
max?: number | undefined;
/** Set the minimum character length.*/
minlength?: number | undefined;
/** Set the maximum character length.*/
maxlength?: number | undefined;
/** When enabled, allows for uppercase values.*/
allowUpperCase?: boolean | undefined;
/** When enabled, allows for duplicate values.*/
allowDuplicates?: boolean | undefined;
/** Provide a custom validator function.*/
validation?: ((...args: any[]) => boolean) | undefined;
/** The duration of the flip (first, last, invert, play) animation.*/
duration?: number | undefined;
/** Set the required state for this input field.*/
required?: boolean | undefined;
/** Provide classes or a variant to style the chips.*/
chips?: string | undefined;
/** {{ event: Event, input: any }} invalid - Fires when the input value is invalid.*/
invalid?: string | undefined;
/** Provide classes to set padding styles.*/
padding?: string | undefined;
/** Provide classes to set border radius styles.*/
rounded?: string | undefined;
/** Provide arbitrary classes to style the chip wrapper region.*/
regionChipWrapper?: string | undefined;
/** Provide arbitrary classes to style the chip list region.*/
regionChipList?: string | undefined;
/** Provide arbitrary classes to style the input field region.*/
regionInput?: string | undefined;
/** Enable/Disable transitions*/
transitions?: boolean | undefined;
/** Provide the transition used in list on entry.*/
listTransitionIn?: ListTransitionIn | undefined;
/** Transition params provided to `ListTransitionIn`.*/
listTransitionInParams?: TransitionParams<ListTransitionIn> | undefined;
/** Provide the transition used in list on exit.*/
listTransitionOut?: ListTransitionOut | undefined;
/** Transition params provided to `ListTransitionOut`.*/
listTransitionOutParams?: TransitionParams<ListTransitionOut> | undefined;
/** Provide the transition used in chip on entry.*/
chipTransitionIn?: ChipTransitionIn | undefined;
/** Transition params provided to `ChipTransitionIn`.*/
chipTransitionInParams?: TransitionParams<ChipTransitionIn> | undefined;
/** Provide the transition used in chip on exit.*/
chipTransitionOut?: ChipTransitionOut | undefined;
/** Transition params provided to `ChipTransitionOut`.*/
chipTransitionOutParams?: TransitionParams<ChipTransitionOut> | undefined;
};
events(): {
input: Event;
focus: FocusEvent;
blur: FocusEvent;
click: MouseEvent;
keypress: KeyboardEvent;
keydown: KeyboardEvent;
keyup: KeyboardEvent;
add: CustomEvent<{
event: SubmitEvent;
chipIndex: number;
chipValue: string;
}>;
remove: CustomEvent<{
event: MouseEvent;
chipIndex: number;
chipValue: string;
}>;
invalid: CustomEvent<{
event: SubmitEvent;
input: string;
}>;
} & {
[evt: string]: CustomEvent<any>;
};
slots(): {};
}
export type InputChipProps<ListTransitionIn extends Transition = FlyTransition, ListTransitionOut extends Transition = FlyTransition, ChipTransitionIn extends Transition = ScaleTransition, ChipTransitionOut extends Transition = ScaleTransition> = ReturnType<__sveltets_Render<ListTransitionIn, ListTransitionOut, ChipTransitionIn, ChipTransitionOut>['props']>;
export type InputChipEvents<ListTransitionIn extends Transition = FlyTransition, ListTransitionOut extends Transition = FlyTransition, ChipTransitionIn extends Transition = ScaleTransition, ChipTransitionOut extends Transition = ScaleTransition> = ReturnType<__sveltets_Render<ListTransitionIn, ListTransitionOut, ChipTransitionIn, ChipTransitionOut>['events']>;
export type InputChipSlots<ListTransitionIn extends Transition = FlyTransition, ListTransitionOut extends Transition = FlyTransition, ChipTransitionIn extends Transition = ScaleTransition, ChipTransitionOut extends Transition = ScaleTransition> = ReturnType<__sveltets_Render<ListTransitionIn, ListTransitionOut, ChipTransitionIn, ChipTransitionOut>['slots']>;
export default class InputChip<ListTransitionIn extends Transition = FlyTransition, ListTransitionOut extends Transition = FlyTransition, ChipTransitionIn extends Transition = ScaleTransition, ChipTransitionOut extends Transition = ScaleTransition> extends SvelteComponentTyped<InputChipProps<ListTransitionIn, ListTransitionOut, ChipTransitionIn, ChipTransitionOut>, InputChipEvents<ListTransitionIn, ListTransitionOut, ChipTransitionIn, ChipTransitionOut>, InputChipSlots<ListTransitionIn, ListTransitionOut, ChipTransitionIn, ChipTransitionOut>> {
}
export {};

View File

@ -0,0 +1,27 @@
<script>import { setContext } from "svelte";
export let multiple = false;
export let spacing = "space-y-1";
export let rounded = "rounded-token";
export let active = "variant-filled";
export let hover = "hover:variant-soft";
export let padding = "px-4 py-2";
export let regionLead = "";
export let regionDefault = "";
export let regionTrail = "";
export let labelledby = "";
setContext("multiple", multiple);
setContext("rounded", rounded);
setContext("active", active);
setContext("hover", hover);
setContext("padding", padding);
setContext("regionLead", regionLead);
setContext("regionDefault", regionDefault);
setContext("regionTrail", regionTrail);
const cBase = "";
$:
classesBase = `${cBase} ${spacing} ${rounded} ${$$props.class ?? ""}`;
</script>
<div class="listbox {classesBase}" role="listbox" aria-labelledby={labelledby} data-testid="listbox">
<slot />
</div>

View File

@ -0,0 +1,38 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Enable selection of multiple items.*/
multiple?: boolean | undefined;
/** Provide class to set the vertical spacing style.*/
spacing?: string | undefined;
/** Provide classes to set the listbox box radius styles.*/
rounded?: string | undefined;
/** Provide classes to set the listbox item active background styles.*/
active?: string | undefined;
/** Provide classes to set the listbox item hover background styles.*/
hover?: string | undefined;
/** Provide classes to set the listbox item padding styles.*/
padding?: string | undefined;
/** Provide arbitrary classes to style the lead region.*/
regionLead?: string | undefined;
/** Provide arbitrary classes to the default region.*/
regionDefault?: string | undefined;
/** Provide arbitrary classes to the trail region.*/
regionTrail?: string | undefined;
/** Provide the ARIA labelledby value.*/
labelledby?: string | undefined;
};
events: {
[evt: string]: CustomEvent<any>;
};
slots: {
default: {};
};
};
export type ListBoxProps = typeof __propDef.props;
export type ListBoxEvents = typeof __propDef.events;
export type ListBoxSlots = typeof __propDef.slots;
export default class ListBox extends SvelteComponentTyped<ListBoxProps, ListBoxEvents, ListBoxSlots> {
}
export {};

View File

@ -0,0 +1,113 @@
<script>import { getContext } from "svelte";
export let group;
export let name;
export let value;
export let multiple = getContext("multiple");
export let rounded = getContext("rounded");
export let active = getContext("active");
export let hover = getContext("hover");
export let padding = getContext("padding");
export let regionLead = getContext("regionLead");
export let regionDefault = getContext("regionDefault");
export let regionTrail = getContext("regionTrail");
const cBase = "cursor-pointer -outline-offset-[3px]";
const cLabel = "flex items-center space-x-4";
let checked;
let elemInput;
function areDeeplyEqual(param1, param2) {
if (param1 === param2)
return true;
if (!(param1 instanceof Object) || !(param2 instanceof Object))
return false;
const keys1 = Object.keys(param1);
const keys2 = Object.keys(param2);
if (keys1.length !== keys2.length)
return false;
for (const key of keys1) {
const value1 = param1[key];
const value2 = param2[key];
if (!areDeeplyEqual(value1, value2))
return false;
}
return true;
}
$:
if (multiple)
updateCheckbox(group);
$:
if (multiple)
updateGroup(checked);
function updateCheckbox(group2) {
checked = group2.indexOf(value) >= 0;
}
function updateGroup(checked2) {
const index = group.indexOf(value);
if (checked2) {
if (index < 0) {
group.push(value);
group = group;
}
} else {
if (index >= 0) {
group.splice(index, 1);
group = group;
}
}
}
function onKeyDown(event) {
if (["Enter", "Space"].includes(event.code)) {
event.preventDefault();
elemInput.click();
}
}
const cRegionLead = "";
const cRegionDefault = "flex-1";
const cRegionTrail = "";
$:
selected = multiple ? group.some((groupVal) => areDeeplyEqual(value, groupVal)) : areDeeplyEqual(group, value);
$:
classesActive = selected ? active : hover;
$:
classesBase = `${cBase} ${rounded} ${padding} ${classesActive} ${$$props.class ?? ""}`;
$:
classesLabel = `${cLabel}`;
$:
classesRegionLead = `${cRegionLead} ${regionLead}`;
$:
classesRegionDefault = `${cRegionDefault} ${regionDefault}`;
$:
classesRegionTrail = `${cRegionTrail} ${regionTrail}`;
</script>
<label>
<!-- A11y attributes are not allowed on <label> -->
<div
class="listbox-item {classesBase}"
data-testid="listbox-item"
role="option"
aria-selected={selected}
tabindex="0"
on:keydown={onKeyDown}
on:keydown
on:keyup
on:keypress
>
<!-- NOTE: Don't use `hidden` as it prevents `required` from operating -->
<div class="h-0 w-0 overflow-hidden">
{#if multiple}
<input bind:this={elemInput} type="checkbox" {name} {value} bind:checked tabindex="-1" on:click on:change />
{:else}
<input bind:this={elemInput} type="radio" bind:group {name} {value} tabindex="-1" on:click on:change />
{/if}
</div>
<!-- <slot /> -->
<div class="listbox-label {classesLabel}">
<!-- Slot: Lead -->
{#if $$slots.lead}<div class="listbox-label-lead {classesRegionLead}"><slot name="lead" /></div>{/if}
<!-- Slot: Default -->
<div class="listbox-label-content {classesRegionDefault}"><slot /></div>
<!-- Slot: Trail -->
{#if $$slots.trail}<div class="listbox-label-trail {classesRegionTrail}"><slot name="trail" /></div>{/if}
</div>
</div>
</label>

View File

@ -0,0 +1,40 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Set the radio group binding value.*/
group: any;
/** Set a unique name value for the input.*/
name: string;
/** Set the input's value.*/
value: any;
multiple?: string | undefined;
rounded?: string | undefined;
active?: string | undefined;
hover?: string | undefined;
padding?: string | undefined;
regionLead?: string | undefined;
regionDefault?: string | undefined;
regionTrail?: string | undefined;
};
events: {
keydown: KeyboardEvent;
keyup: KeyboardEvent;
keypress: KeyboardEvent;
click: MouseEvent;
change: Event;
} & {
[evt: string]: CustomEvent<any>;
};
slots: {
lead: {};
default: {};
trail: {};
};
};
export type ListBoxItemProps = typeof __propDef.props;
export type ListBoxItemEvents = typeof __propDef.events;
export type ListBoxItemSlots = typeof __propDef.slots;
export default class ListBoxItem extends SvelteComponentTyped<ListBoxItemProps, ListBoxItemEvents, ListBoxItemSlots> {
}
export {};

View File

@ -0,0 +1,190 @@
<script>import { createEventDispatcher } from "svelte";
import { leftAngles, leftArrow, rightAngles, rightArrow } from "./icons.js";
const dispatch = createEventDispatcher();
export let settings = { page: 0, limit: 5, size: 0, amounts: [1, 2, 5, 10] };
export let disabled = false;
export let showPreviousNextButtons = true;
export let showFirstLastButtons = false;
export let showNumerals = false;
export let maxNumerals = 1;
export let justify = "justify-between";
export let select = "select min-w-[150px]";
export let amountText = "Items";
export let regionControl = "btn-group";
export let controlVariant = "variant-filled";
export let controlSeparator = "";
export let active = "variant-filled-primary";
export let buttonClasses = "!px-3 !py-1.5 fill-current";
export let buttonTextPrevious = leftArrow;
export let buttonTextNext = rightArrow;
export let buttonTextFirst = leftAngles;
export let buttonTextLast = rightAngles;
export let separatorText = "of";
export let labelFirst = "First page";
export let labelPrevious = "Previous page";
export let labelNext = "Next page";
export let labelLast = "Last page";
const cBase = "flex flex-col md:flex-row items-center space-y-4 md:space-y-0 md:space-x-4";
const cLabel = "w-full md:w-auto";
let lastPage = Math.max(0, Math.ceil(settings.size / settings.limit - 1));
let controlPages = getNumerals();
function onChangeLength() {
dispatch("amount", settings.limit);
lastPage = Math.max(0, Math.ceil(settings.size / settings.limit - 1));
if (settings.page > lastPage) {
settings.page = lastPage;
}
controlPages = getNumerals();
}
function gotoPage(page) {
if (page < 0)
return;
settings.page = page;
dispatch("page", settings.page);
controlPages = getNumerals();
}
function getFullNumerals() {
const pages = [];
for (let index = 0; index <= lastPage; index++) {
pages.push(index);
}
return pages;
}
function getNumerals() {
const pages = [];
const isWithinLeftSection = settings.page < maxNumerals + 2;
const isWithinRightSection = settings.page > lastPage - (maxNumerals + 2);
if (lastPage <= maxNumerals * 2 + 1)
return getFullNumerals();
pages.push(0);
if (!isWithinLeftSection)
pages.push(-1);
if (isWithinLeftSection || isWithinRightSection) {
const sectionStart = isWithinLeftSection ? 1 : lastPage - (maxNumerals + 2);
const sectionEnd = isWithinRightSection ? lastPage - 1 : maxNumerals + 2;
for (let i = sectionStart; i <= sectionEnd; i++) {
pages.push(i);
}
} else {
for (let i = settings.page - maxNumerals; i <= settings.page + maxNumerals; i++) {
pages.push(i);
}
}
if (!isWithinRightSection)
pages.push(-1);
pages.push(lastPage);
return pages;
}
function updateSize(size) {
lastPage = Math.max(0, Math.ceil(size / settings.limit - 1));
controlPages = getNumerals();
}
$:
classesButtonActive = (page) => {
return page === settings.page ? `${active} pointer-events-none` : "";
};
$:
maxNumerals, onChangeLength();
$:
updateSize(settings.size);
$:
classesBase = `${cBase} ${justify} ${$$props.class ?? ""}`;
$:
classesLabel = `${cLabel}`;
$:
classesSelect = `${select}`;
$:
classesControls = `${regionControl} ${controlVariant} ${controlSeparator}`;
</script>
<div class="paginator {classesBase}" data-testid="paginator">
<!-- Select Amount -->
{#if settings.amounts.length}
<label class="paginator-label {classesLabel}">
<select
bind:value={settings.limit}
on:change={onChangeLength}
class="paginator-select {classesSelect}"
{disabled}
aria-label="Select Amount"
>
{#each settings.amounts as amount}<option value={amount}>{amount} {amountText}</option>{/each}
</select>
</label>
{/if}
<!-- Controls -->
<div class="paginator-controls {classesControls}">
<!-- Button: First -->
{#if showFirstLastButtons}
<button
type="button"
aria-label={labelFirst}
class={buttonClasses}
on:click={() => {
gotoPage(0);
}}
disabled={disabled || settings.page === 0}
>
{@html buttonTextFirst}
</button>
{/if}
<!-- Button: Back -->
{#if showPreviousNextButtons}
<button
type="button"
aria-label={labelPrevious}
class={buttonClasses}
on:click={() => {
gotoPage(settings.page - 1);
}}
disabled={disabled || settings.page === 0}
>
{@html buttonTextPrevious}
</button>
{/if}
<!-- Center -->
{#if showNumerals === false}
<!-- Details -->
<button type="button" class="{buttonClasses} pointer-events-none !text-sm">
{settings.page * settings.limit + 1}-{Math.min(settings.page * settings.limit + settings.limit, settings.size)}&nbsp;<span
class="opacity-50">{separatorText} {settings.size}</span
>
</button>
{:else}
<!-- Numeric Row -->
{#each controlPages as page}
<button type="button" class="{buttonClasses} {classesButtonActive(page)}" on:click={() => gotoPage(page)}>
{page >= 0 ? page + 1 : '...'}
</button>
{/each}
{/if}
<!-- Button: Next -->
{#if showPreviousNextButtons}
<button
type="button"
aria-label={labelNext}
class={buttonClasses}
on:click={() => {
gotoPage(settings.page + 1);
}}
disabled={disabled || (settings.page + 1) * settings.limit >= settings.size}
>
{@html buttonTextNext}
</button>
{/if}
<!-- Button: last -->
{#if showFirstLastButtons}
<button
type="button"
aria-label={labelLast}
class={buttonClasses}
on:click={() => {
gotoPage(lastPage);
}}
disabled={disabled || (settings.page + 1) * settings.limit >= settings.size}
>
{@html buttonTextLast}
</button>
{/if}
</div>
</div>

View File

@ -0,0 +1,68 @@
import { SvelteComponentTyped } from "svelte";
import type { PaginationSettings } from './types.js';
declare const __propDef: {
props: {
[x: string]: any;
/** Pass the page setting object.*/
settings?: PaginationSettings | undefined;
/** Sets selection and buttons to disabled state on-demand.*/
disabled?: boolean | undefined;
/** Show Previous and Next buttons.*/
showPreviousNextButtons?: boolean | undefined;
/** Show First and Last buttons.*/
showFirstLastButtons?: boolean | undefined;
/** Displays a numeric row of page buttons.*/
showNumerals?: boolean | undefined;
/** Maximum number of active page siblings in the numeric row.*/
maxNumerals?: number | undefined;
/** Provide classes to set flexbox justification.*/
justify?: string | undefined;
/** Provide classes to style the select input.*/
select?: string | undefined;
/** Set the text for the amount selection input.*/
amountText?: string | undefined;
/** Set the base classes for the control element.*/
regionControl?: string | undefined;
/** Provide variant style for the control button group.*/
controlVariant?: string | undefined;
/** Provide separator style for the control button group.*/
controlSeparator?: string | undefined;
/** Provide arbitrary classes to the active page buttons.*/
active?: string | undefined;
/** * Set the base button classes.*/
buttonClasses?: string | undefined;
/** Set the label for the Previous button.*/
buttonTextPrevious?: string | undefined;
/** Set the label for the Next button.*/
buttonTextNext?: string | undefined;
/** Set the label for the First button.*/
buttonTextFirst?: string | undefined;
/** Set the label for the Last button.*/
buttonTextLast?: string | undefined;
/** Set the label for the pages separator.*/
separatorText?: string | undefined;
/** Provide the ARIA label for the First page button.*/
labelFirst?: string | undefined;
/** Provide the ARIA label for the Previous page button.*/
labelPrevious?: string | undefined;
/** Provide the ARIA label for the Next page button.*/
labelNext?: string | undefined;
/** Provide the ARIA label for the Last page button.*/
labelLast?: string | undefined;
};
events: {
/** {{ length: number }} amount - Fires when the amount selection input changes.*/
amount: CustomEvent<number>;
/** {{ page: number }} page Fires when the next/back buttons are pressed.*/
page: CustomEvent<number>;
} & {
[evt: string]: CustomEvent<any>;
};
slots: {};
};
export type PaginatorProps = typeof __propDef.props;
export type PaginatorEvents = typeof __propDef.events;
export type PaginatorSlots = typeof __propDef.slots;
export default class Paginator extends SvelteComponentTyped<PaginatorProps, PaginatorEvents, PaginatorSlots> {
}
export {};

View File

@ -0,0 +1,4 @@
export declare const leftArrow = "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 448 512\"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d=\"M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.2 288 416 288c17.7 0 32-14.3 32-32s-14.3-32-32-32l-306.7 0L214.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z\"/></svg>";
export declare const rightArrow = "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 448 512\"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d=\"M438.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L338.8 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l306.7 0L233.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l160-160z\"/></svg>";
export declare const leftAngles = "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d=\"M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 246.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160zm352-160l-160 160c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L301.3 256 438.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0z\"/></svg>";
export declare const rightAngles = "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"1em\" viewBox=\"0 0 512 512\"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d=\"M470.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L402.7 256 265.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l160-160zm-352 160l160-160c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L210.7 256 73.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0z\"/></svg>";

View File

@ -0,0 +1,4 @@
export const leftArrow = `<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.2 288 416 288c17.7 0 32-14.3 32-32s-14.3-32-32-32l-306.7 0L214.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z"/></svg>`;
export const rightArrow = `<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M438.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L338.8 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l306.7 0L233.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l160-160z"/></svg>`;
export const leftAngles = `<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 246.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160zm352-160l-160 160c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L301.3 256 438.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0z"/></svg>`;
export const rightAngles = `<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M470.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L402.7 256 265.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l160-160zm-352 160l160-160c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L210.7 256 73.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0z"/></svg>`;

View File

@ -0,0 +1,10 @@
export interface PaginationSettings {
/** Index of the current page to display. */
page: number;
/** Current number of items to display. */
limit: number;
/** The total size (length) of your source content. */
size: number;
/** List of amounts available to the select input */
amounts: number[];
}

View File

@ -0,0 +1,2 @@
// Pagination Types
export {};

View File

@ -0,0 +1,48 @@
<script>export let value = void 0;
export let min = 0;
export let max = 100;
export let height = "h-2";
export let rounded = "rounded-token";
export let meter = "bg-surface-900-50-token";
export let track = "bg-surface-200-700-token";
export let labelledby = "";
const cTrack = "w-full overflow-hidden";
const cMeter = "h-full";
$:
fillPercent = value ? 100 * (value - min) / (max - min) : 0;
$:
indeterminate = value === void 0 || value < 0;
$:
classesIndeterminate = indeterminate ? "animIndeterminate" : "";
$:
classesTrack = `${cTrack} ${height} ${rounded} ${track} ${$$props.class ?? ""}`;
$:
classesMeter = `${cMeter} ${rounded} ${classesIndeterminate} ${meter}`;
</script>
<!-- Track -->
<div
class="progress-bar {classesTrack}"
data-testid="progress-bar"
role="progressbar"
aria-labelledby={labelledby}
aria-valuenow={value}
aria-valuemin={min}
aria-valuemax={max - min}
>
<!-- Meter -->
<div class="progress-bar-meter {classesMeter} {classesMeter}" style:width="{indeterminate ? 100 : fillPercent}%" />
</div>
<style>
.animIndeterminate {
transform-origin: 0% 50%;
animation: animIndeterminate 2s infinite linear;
}
/* prettier-ignore */
@keyframes animIndeterminate {
0% { transform: translateX(0) scaleX(0); }
40% { transform: translateX(0) scaleX(0.4); }
100% { transform: translateX(100%) scaleX(0.5); }
}
</style>

View File

@ -0,0 +1,32 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Specifies the amount completed. Indeterminate when `undefined`.*/
value?: number | undefined;
/** Minimum amount the bar represents.*/
min?: number | undefined;
/** Maximum amount the bar represents.*/
max?: number | undefined;
/** Provide classes to set track height.*/
height?: string | undefined;
/** Provide classes to set rounded styles.*/
rounded?: string | undefined;
/** Provide arbitrary classes to style the meter element.*/
meter?: string | undefined;
/** Provide arbitrary classes to style the track element.*/
track?: string | undefined;
/** Provide the ARIA labelledby value.*/
labelledby?: string | undefined;
};
events: {
[evt: string]: CustomEvent<any>;
};
slots: {};
};
export type ProgressBarProps = typeof __propDef.props;
export type ProgressBarEvents = typeof __propDef.events;
export type ProgressBarSlots = typeof __propDef.slots;
export default class ProgressBar extends SvelteComponentTyped<ProgressBarProps, ProgressBarEvents, ProgressBarSlots> {
}
export {};

View File

@ -0,0 +1,72 @@
<!-- Reference: https://css-tricks.com/building-progress-ring-quickly/ -->
<script>import { afterUpdate } from "svelte";
export let value = void 0;
export let stroke = 40;
export let font = 56;
export let strokeLinecap = "butt";
export let width = "w-36";
export let meter = "stroke-surface-900 dark:stroke-surface-50";
export let track = "stroke-surface-500/30";
export let fill = "fill-token";
export let labelledby = "";
const cBase = "progress-radial relative overflow-hidden";
const cBaseTrack = "fill-transparent";
const cBaseMeter = "fill-transparent transition-[stroke-dashoffset] duration-200 -rotate-90 origin-[50%_50%]";
const baseSize = 512;
const radius = baseSize / 2 - stroke / 2;
let circumference = radius;
let dashoffset;
function setProgress(percent) {
circumference = radius * 2 * Math.PI;
dashoffset = circumference - percent / 100 * circumference;
}
setProgress(0);
afterUpdate(() => {
setProgress(value === void 0 ? 25 : value);
});
$:
classesBase = `${cBase} ${width} ${$$props.class ?? ""}`;
</script>
<figure
class="progress-radial {classesBase}"
data-testid="progress-radial"
role="meter"
aria-labelledby={labelledby}
aria-valuenow={value || 0}
aria-valuetext={value ? `${value}%` : 'Indeterminate Spinner'}
aria-valuemin={0}
aria-valuemax={100}
>
<!-- Draw SVG -->
<svg viewBox="0 0 {baseSize} {baseSize}" class="rounded-full" class:animate-spin={value === undefined}>
<!-- Track -->
<circle class="progress-radial-track {cBaseTrack} {track}" stroke-width={stroke} r={radius} cx="50%" cy="50%" />
<!-- Meter -->
<circle
class="progress-radial-meter {cBaseMeter} {meter}"
stroke-width={stroke}
r={radius}
cx="50%"
cy="50%"
style:stroke-dasharray="{circumference}
{circumference}"
style:stroke-dashoffset={dashoffset}
stroke-linecap={strokeLinecap}
/>
<!-- Center Text -->
{#if value != undefined && value >= 0 && $$slots.default}
<text
x="50%"
y="50%"
text-anchor="middle"
dominant-baseline="middle"
font-weight="bold"
font-size={font}
class="progress-radial-text {fill}"><slot /></text
>
{/if}
</svg>
</figure>

View File

@ -0,0 +1,36 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Set the meter fill amount. Shows as indeterminate when set `undefined`.*/
value?: number | undefined;
/** Sets the base stroke width. Scales responsively.*/
stroke?: number | undefined;
/** Sets the base font size. Scales responsively.*/
font?: number | undefined;
/** Sets the stoke-linecap value*/
strokeLinecap?: "butt" | "round" | "square" | undefined;
/** Provide classes to set the width.*/
width?: string | undefined;
/** Provide classes to set meter color.*/
meter?: string | undefined;
/** Provide classes to set track color.*/
track?: string | undefined;
/** Provide classes to set the SVG text fill color.*/
fill?: string | undefined;
/** Provide the ARIA labelledby value.*/
labelledby?: string | undefined;
};
events: {
[evt: string]: CustomEvent<any>;
};
slots: {
default: {};
};
};
export type ProgressRadialProps = typeof __propDef.props;
export type ProgressRadialEvents = typeof __propDef.events;
export type ProgressRadialSlots = typeof __propDef.slots;
export default class ProgressRadial extends SvelteComponentTyped<ProgressRadialProps, ProgressRadialEvents, ProgressRadialSlots> {
}
export {};

View File

@ -0,0 +1,30 @@
<script>import { setContext } from "svelte";
export let display = "inline-flex";
export let background = "bg-surface-200-700-token";
export let border = "border-token border-surface-400-500-token";
export let spacing = "";
export let rounded = "rounded-token";
export let padding = "px-4 py-1";
export let active = "variant-filled";
export let hover = "hover:variant-soft";
export let color = "";
export let fill = "";
export let regionLabel = "";
export let labelledby = "";
setContext("rounded", rounded);
setContext("padding", padding);
setContext("active", active);
setContext("hover", hover);
setContext("color", color);
setContext("fill", fill);
setContext("regionLabel", regionLabel);
const cBase = "p-1";
$:
spacing = `${display.includes("flex-col") ? "" : "space-x-1"}`;
$:
classesBase = `${cBase} ${display} ${background} ${border} ${spacing} ${rounded} ${$$props.class ?? ""}`;
</script>
<div class="radio-group {classesBase}" data-testid="radio-group" role="radiogroup" aria-labelledby={labelledby}>
<slot />
</div>

View File

@ -0,0 +1,42 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Provide display classes. Set `flex` to stretch full width.*/
display?: string | undefined;
/** Provide classes to set the base background color.*/
background?: string | undefined;
/** Provide classes to set the border styles.*/
border?: string | undefined;
/** Provide classes horizontal spacing between items.*/
spacing?: string | undefined;
/** Provide classes to set the border radius.*/
rounded?: string | undefined;
/** Provide classes to set the RadioItem padding.*/
padding?: string | undefined;
/** Provide classes to set the active item color.*/
active?: string | undefined;
/** Provide classes to set the hover style.*/
hover?: string | undefined;
/** Provide classes to set the highlighted text color.*/
color?: string | undefined;
/** Provide classes to set the highlighted SVG fill color.*/
fill?: string | undefined;
/** Provide classes for the label region.*/
regionLabel?: string | undefined;
/** Provide the ARIA labelledby value.*/
labelledby?: string | undefined;
};
events: {
[evt: string]: CustomEvent<any>;
};
slots: {
default: {};
};
};
export type RadioGroupProps = typeof __propDef.props;
export type RadioGroupEvents = typeof __propDef.events;
export type RadioGroupSlots = typeof __propDef.slots;
export default class RadioGroup extends SvelteComponentTyped<RadioGroupProps, RadioGroupEvents, RadioGroupSlots> {
}
export {};

View File

@ -0,0 +1,61 @@
<script>import { getContext } from "svelte";
export let group;
export let name;
export let value;
export let title = "";
export let label = "";
export let rounded = getContext("rounded");
export let padding = getContext("padding");
export let active = getContext("active");
export let hover = getContext("hover");
export let color = getContext("color");
export let fill = getContext("fill");
export let regionLabel = getContext("regionLabel");
const cBase = "flex-auto";
const cWrapper = "text-base text-center cursor-pointer";
const cDisabled = "opacity-50 cursor-not-allowed";
let elemInput;
function onKeyDown(event) {
if (["Enter", "Space"].includes(event.code)) {
event.preventDefault();
elemInput.click();
}
}
$:
checked = value === group;
$:
classesActive = checked ? `${active} ${color} ${fill}` : hover;
$:
classesDisabled = $$props.disabled ? cDisabled : "";
$:
classsBase = `${cBase}`;
$:
classesWrapper = `${cWrapper} ${padding} ${rounded} ${classesActive} ${classesDisabled} ${$$props.class ?? ""}`;
function prunedRestProps() {
delete $$restProps.class;
return $$restProps;
}
</script>
<label class="radio-label {classsBase} {regionLabel}">
<!-- A11y attributes are not allowed on <label> -->
<div
class="radio-item {classesWrapper}"
data-testid="radio-item"
role="radio"
aria-checked={checked}
aria-label={label}
tabindex="0"
{title}
on:keydown={onKeyDown}
on:keydown
on:keyup
on:keypress
>
<!-- NOTE: Don't use `hidden` as it prevents `required` from operating -->
<div class="h-0 w-0 overflow-hidden">
<input bind:this={elemInput} type="radio" bind:group {name} {value} {...prunedRestProps()} tabindex="-1" on:click on:change />
</div>
<slot />
</div>
</label>

View File

@ -0,0 +1,41 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Set the radio group binding value.*/
group: any;
/** Set a unique name value for the input.*/
name: string;
/** Set the input's value.*/
value: any;
/** Set the hover title.*/
title?: string | undefined;
/** Defines a semantic ARIA label.*/
label?: string | undefined;
rounded?: string | undefined;
padding?: string | undefined;
active?: string | undefined;
hover?: string | undefined;
color?: string | undefined;
fill?: string | undefined;
regionLabel?: string | undefined;
};
events: {
keydown: KeyboardEvent;
keyup: KeyboardEvent;
keypress: KeyboardEvent;
click: MouseEvent;
change: Event;
} & {
[evt: string]: CustomEvent<any>;
};
slots: {
default: {};
};
};
export type RadioItemProps = typeof __propDef.props;
export type RadioItemEvents = typeof __propDef.events;
export type RadioItemSlots = typeof __propDef.slots;
export default class RadioItem extends SvelteComponentTyped<RadioItemProps, RadioItemEvents, RadioItemSlots> {
}
export {};

View File

@ -0,0 +1,72 @@
<script>import { afterUpdate } from "svelte";
export let name;
export let id = String(Math.random());
export let value = 0;
export let min = 0;
export let max = 100;
export let step = 1;
export let ticked = false;
export let accent = "accent-surface-900 dark:accent-surface-50";
export let label = "";
const cBase = "space-y-2";
const cBaseLabel = "";
const cBaseContent = "flex justify-center py-2";
const cBaseInput = "w-full h-2";
let tickmarks;
function setTicks() {
if (ticked == false)
return;
tickmarks = Array.from({ length: max - min + 1 }, (_, i) => i + min);
}
if (ticked)
setTicks();
afterUpdate(() => {
setTicks();
});
$:
classesBase = `${cBase} ${$$props.class ?? ""}`;
$:
classesInput = `${cBaseInput} ${accent}`;
function prunedRestProps() {
delete $$restProps.class;
return $$restProps;
}
</script>
<div class="range-slider {classesBase}" data-testid="range-slider">
<!-- Slot: Default -->
{#if $$slots.default}<label class="range-slider-label {cBaseLabel}" for={id}><slot /></label>{/if}
<!-- Content -->
<div class="range-content {cBaseContent}">
<!-- Input -->
<input
type="range"
{id}
{name}
class="range-slider-input {classesInput}"
list="tickmarks-{id}"
aria-label={label}
{min}
{max}
{step}
bind:value
on:click
on:change
on:blur
{...prunedRestProps()}
/>
<!-- Tickmarks -->
{#if ticked && tickmarks && tickmarks.length}
<datalist id="tickmarks-{id}" class="range-slider-ticks">
{#each tickmarks as tm}
<option value={tm} label={tm} />
{/each}
</datalist>
{/if}
</div>
<!-- Slot: Trail -->
{#if $$slots.trail}<div class="range-slider-trail"><slot name="trail" /></div>{/if}
</div>

View File

@ -0,0 +1,41 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Required. Set a unique name for the input.*/
name: string;
/** Provide a unique input id. Auto-generated by default*/
id?: string | undefined;
/** Set the input value.*/
value?: number | undefined;
/** Set the input minimum range.*/
min?: number | undefined;
/** Set the input maximum range.*/
max?: number | undefined;
/** Set the input step offset.*/
step?: number | undefined;
/** Enables tick marks. See browser support below.*/
ticked?: boolean | undefined;
/** Provide classes to set the input accent color.*/
accent?: string | undefined;
/** A semantic ARIA label.*/
label?: string | undefined;
};
events: {
click: MouseEvent;
change: Event;
blur: FocusEvent;
} & {
[evt: string]: CustomEvent<any>;
};
slots: {
default: {};
trail: {};
};
};
export type RangeSliderProps = typeof __propDef.props;
export type RangeSliderEvents = typeof __propDef.events;
export type RangeSliderSlots = typeof __propDef.slots;
export default class RangeSlider extends SvelteComponentTyped<RangeSliderProps, RangeSliderEvents, RangeSliderSlots> {
}
export {};

View File

@ -0,0 +1,52 @@
<script>import { createEventDispatcher } from "svelte";
export let value = 0;
export let max = 5;
export let interactive = false;
export let text = "text-token";
export let fill = "fill-token";
export let justify = "justify-center";
export let spacing = "space-x-2";
export let regionIcon = "";
const dispatch = createEventDispatcher();
function iconClick(index) {
dispatch("icon", {
index: index + 1
});
}
function isFull(value2, index) {
return Math.floor(value2) >= index + 1;
}
function isHalf(value2, index) {
return value2 === index + 0.5;
}
const cBase = "w-full flex";
$:
classesBase = `${cBase} ${text} ${fill} ${justify} ${spacing} ${$$props.class ?? ""}`;
</script>
<div class="ratings {classesBase}" data-testid="rating-bar">
<!-- eslint-disable-next-line @typescript-eslint/no-unused-vars -->
{#each { length: max } as _, i}
{#if interactive}
<button class="rating-icon {regionIcon}" type="button" on:click={() => iconClick(i)}>
{#if isFull(value, i)}
<slot name="full" />
{:else if isHalf(value, i)}
<slot name="half" />
{:else}
<slot name="empty" />
{/if}
</button>
{:else}
<span class="rating-icon {regionIcon}">
{#if isFull(value, i)}
<slot name="full" />
{:else if isHalf(value, i)}
<slot name="half" />
{:else}
<slot name="empty" />
{/if}
</span>
{/if}
{/each}
</div>

View File

@ -0,0 +1,41 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Current rating value.*/
value?: number | undefined;
/** Maximum rating value.*/
max?: number | undefined;
/** Enables interactive mode for each rating icon.*/
interactive?: boolean | undefined;
/** Provide classes to set the text color.*/
text?: string | undefined;
/** Provide classes to set the SVG fill color.*/
fill?: string | undefined;
/** Provide classes to set the flexbox justification.*/
justify?: string | undefined;
/** Provide classes to set the horizontal spacing style.*/
spacing?: string | undefined;
/** Provide arbitrary classes to the icon region.*/
regionIcon?: string | undefined;
};
events: {
/** {{ index: number }} icon - Fires when an icons is clicked*/
icon: CustomEvent<{
index: number;
}>;
} & {
[evt: string]: CustomEvent<any>;
};
slots: {
full: {};
half: {};
empty: {};
};
};
export type RatingsProps = typeof __propDef.props;
export type RatingsEvents = typeof __propDef.events;
export type RatingsSlots = typeof __propDef.slots;
export default class Ratings extends SvelteComponentTyped<RatingsProps, RatingsEvents, RatingsSlots> {
}
export {};

View File

@ -0,0 +1,91 @@
<script>import { createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher();
export let name;
export let checked = false;
export let size = "md";
export let background = "bg-surface-400 dark:bg-surface-700";
export let active = "bg-surface-900 dark:bg-surface-300";
export let border = "";
export let rounded = "rounded-full";
export let label = "";
const cBase = "inline-block";
const cLabel = "unstyled flex items-center";
const cTrack = "flex transition-all duration-[200ms] cursor-pointer";
const cThumb = "w-[50%] h-full scale-[0.8] transition-all duration-[200ms] shadow";
let trackSize;
switch (size) {
case "sm":
trackSize = "w-12 h-6";
break;
case "lg":
trackSize = "w-20 h-10";
break;
default:
trackSize = "w-16 h-8";
}
function onKeyDown(event) {
if (["Enter", "Space"].includes(event.code)) {
event.preventDefault();
dispatch("keyup", event);
const inputElem = event.currentTarget.firstChild;
inputElem.click();
}
}
$:
cTrackActive = checked ? active : `${background} cursor-pointer`;
$:
cThumbBackground = checked ? "bg-white/75" : "bg-white";
$:
cThumbPos = checked ? "translate-x-full" : "";
$:
classesDisabled = $$props.disabled === true ? "opacity-50" : "hover:brightness-[105%] dark:hover:brightness-110 cursor-pointer";
$:
classesBase = `${cBase} ${rounded} ${classesDisabled} ${$$props.class ?? ""}`;
$:
classesLabel = `${cLabel}`;
$:
classesTrack = `${cTrack} ${border} ${rounded} ${trackSize} ${cTrackActive}`;
$:
classesThumb = `${cThumb} ${rounded} ${cThumbBackground} ${cThumbPos}`;
function prunedRestProps() {
delete $$restProps.class;
return $$restProps;
}
</script>
<div
id={label}
class="slide-toggle {classesBase}"
data-testid="slide-toggle"
on:keydown={onKeyDown}
role="switch"
aria-label={label}
aria-checked={checked}
tabindex="0"
>
<label class="slide-toggle-label {classesLabel}">
<!-- Hidden Input -->
<input
type="checkbox"
class="slide-toggle-input hidden"
bind:checked
{name}
on:click
on:keydown
on:keyup
on:keypress
on:mouseover
on:change
on:focus
on:blur
{...prunedRestProps()}
disabled={$$props.disabled}
/>
<!-- Slider Track/Thumb -->
<div class="slide-toggle-track {classesTrack}" class:cursor-not-allowed={$$props.disabled}>
<div class="slide-toggle-thumb {classesThumb}" class:cursor-not-allowed={$$props.disabled} />
</div>
<!-- Label -->
{#if $$slots.default}<div class="slide-toggle-text ml-3"><slot /></div>{/if}
</label>
</div>

View File

@ -0,0 +1,44 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Required. Set a unique name for the input.*/
name: string;
/** The checked state of the input element.*/
checked?: boolean | undefined;
/** Sets the size of the component.*/
size?: string | undefined;
/** Provide classes to set the inactive state background color.*/
background?: string | undefined;
/** Provide classes to set the active state background color.*/
active?: string | undefined;
/** Provide classes to set the border styles.*/
border?: string | undefined;
/** Provide classes to set border radius styles.*/
rounded?: string | undefined;
/** Provide a semantic label.*/
label?: string | undefined;
};
events: {
click: MouseEvent;
keydown: KeyboardEvent;
/** {{ event }} keyup Fires when the component is focused and key is pressed.*/
keyup: KeyboardEvent;
keypress: KeyboardEvent;
mouseover: MouseEvent;
change: Event;
focus: FocusEvent;
blur: FocusEvent;
} & {
[evt: string]: CustomEvent<any>;
};
slots: {
default: {};
};
};
export type SlideToggleProps = typeof __propDef.props;
export type SlideToggleEvents = typeof __propDef.events;
export type SlideToggleSlots = typeof __propDef.slots;
export default class SlideToggle extends SvelteComponentTyped<SlideToggleProps, SlideToggleEvents, SlideToggleSlots> {
}
export {};

View File

@ -0,0 +1,111 @@
<!-- Reference: https://dribbble.com/shots/16221169-Figma-Material-Ui-components-Steppers-and-sliders -->
<script>import { getContext, onDestroy } from "svelte";
import { dynamicTransition } from "../../internal/transitions.js";
export let locked = false;
export let regionHeader = "";
export let regionContent = "";
export let regionNavigation = "";
export let state = getContext("state");
export let dispatchParent = getContext("dispatchParent");
export let stepTerm = getContext("stepTerm");
export let gap = getContext("gap");
export let justify = getContext("justify");
export let buttonBack = getContext("buttonBack");
export let buttonBackType = getContext("buttonBackType");
export let buttonBackLabel = getContext("buttonBackLabel");
export let buttonNext = getContext("buttonNext");
export let buttonNextType = getContext("buttonNextType");
export let buttonNextLabel = getContext("buttonNextLabel");
export let buttonComplete = getContext("buttonComplete");
export let buttonCompleteType = getContext("buttonCompleteType");
export let buttonCompleteLabel = getContext("buttonCompleteLabel");
export let transitions = getContext("transitions");
export let transitionIn = getContext("transitionIn");
export let transitionInParams = getContext("transitionInParams");
export let transitionOut = getContext("transitionOut");
export let transitionOutParams = getContext("transitionOutParams");
const stepIndex = $state.total;
$state.total++;
const cBase = "space-y-4";
const cHeader = "text-2xl font-bold";
const cContent = "space-y-4";
const cNavigation = "flex";
async function onNext() {
await new Promise((resolve) => setTimeout(resolve));
if (locked)
return;
$state.current++;
dispatchParent("next", { step: stepIndex, state: $state });
dispatchParent("step", { step: stepIndex, state: $state });
}
function onBack() {
$state.current--;
dispatchParent("back", { step: stepIndex, state: $state });
dispatchParent("step", { step: stepIndex, state: $state });
}
function onComplete() {
dispatchParent("complete", { step: stepIndex, state: $state });
}
$:
classesBase = `${cBase} ${$$props.class ?? ""}`;
$:
classesHeader = `${cHeader} ${regionHeader}`;
$:
classesContent = `${cContent} ${regionContent}`;
$:
classesNavigation = `${cNavigation} ${justify} ${gap} ${regionNavigation}`;
onDestroy(() => {
$state.total--;
});
</script>
{#if stepIndex === $state.current}
<div class="step {classesBase}" data-testid="step">
<!-- Slot: Header -->
<header class="step-header {classesHeader}">
<slot name="header">{stepTerm} {stepIndex + 1}</slot>
</header>
<!-- Slot: Default -->
<div class="step-content {classesContent}">
<slot>({stepTerm} {stepIndex + 1} Content)</slot>
</div>
<!-- Navigation -->
{#if $state.total > 1}
<div
class="step-navigation {classesNavigation}"
in:dynamicTransition|local={{ transition: transitionIn, params: transitionInParams, enabled: transitions }}
out:dynamicTransition|local={{ transition: transitionOut, params: transitionOutParams, enabled: transitions }}
>
{#if stepIndex === 0 && $$slots.navigation}
<!-- Slot: Navigation -->
<div class="step-navigation-slot">
<slot name="navigation" />
</div>
{:else}
<!-- Button: Back -->
<button type={buttonBackType} class="btn {buttonBack}" on:click={onBack} disabled={$state.current === 0}>
{@html buttonBackLabel}
</button>
{/if}
{#if stepIndex < $state.total - 1}
<!-- Button: Next -->
<button type={buttonNextType} class="btn {buttonNext}" on:click={onNext} disabled={locked}>
{#if locked}
<svg class="w-3 aspect-square fill-current" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path
d="M144 144v48H304V144c0-44.2-35.8-80-80-80s-80 35.8-80 80zM80 192V144C80 64.5 144.5 0 224 0s144 64.5 144 144v48h16c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V256c0-35.3 28.7-64 64-64H80z"
/>
</svg>
{/if}
<span>{@html buttonNextLabel}</span>
</button>
{:else}
<!-- Button: Complete -->
<button type={buttonCompleteType} class="btn {buttonComplete}" on:click={onComplete} disabled={locked}>
{@html buttonCompleteLabel}
</button>
{/if}
</div>
{/if}
</div>
{/if}

View File

@ -0,0 +1,54 @@
import { SvelteComponentTyped } from "svelte";
import type { Writable } from 'svelte/store';
import type { StepperEventDispatcher, StepperState } from './types.js';
import type { Transition, TransitionParams } from '../../index.js';
declare class __sveltets_Render<TransitionIn extends Transition, TransitionOut extends Transition> {
props(): {
[x: string]: any;
locked?: boolean | undefined;
/** Provide arbitrary classes to the step header region.*/
regionHeader?: string | undefined;
/** Provide arbitrary classes to the step content region.*/
regionContent?: string | undefined;
/** Provide arbitrary classes to the step navigation region.*/
regionNavigation?: string | undefined;
state?: Writable<StepperState> | undefined;
dispatchParent?: StepperEventDispatcher | undefined;
stepTerm?: string | undefined;
gap?: string | undefined;
justify?: string | undefined;
buttonBack?: string | undefined;
buttonBackType?: "button" | "reset" | "submit" | undefined;
buttonBackLabel?: string | undefined;
buttonNext?: string | undefined;
buttonNextType?: "button" | "reset" | "submit" | undefined;
buttonNextLabel?: string | undefined;
buttonComplete?: string | undefined;
buttonCompleteType?: "button" | "reset" | "submit" | undefined;
buttonCompleteLabel?: string | undefined;
/** Enable/Disable transitions*/
transitions?: boolean | undefined;
/** Provide the transition to used on entry.*/
transitionIn?: TransitionIn | undefined;
/** Transition params provided to `transitionIn`.*/
transitionInParams?: TransitionParams<TransitionIn> | undefined;
/** Provide the transition to used on exit.*/
transitionOut?: TransitionOut | undefined;
/** Transition params provided to `transitionOut`.*/
transitionOutParams?: TransitionParams<TransitionOut> | undefined;
};
events(): {} & {
[evt: string]: CustomEvent<any>;
};
slots(): {
header: {};
default: {};
navigation: {};
};
}
export type StepProps<TransitionIn extends Transition, TransitionOut extends Transition> = ReturnType<__sveltets_Render<TransitionIn, TransitionOut>['props']>;
export type StepEvents<TransitionIn extends Transition, TransitionOut extends Transition> = ReturnType<__sveltets_Render<TransitionIn, TransitionOut>['events']>;
export type StepSlots<TransitionIn extends Transition, TransitionOut extends Transition> = ReturnType<__sveltets_Render<TransitionIn, TransitionOut>['slots']>;
export default class Step<TransitionIn extends Transition, TransitionOut extends Transition> extends SvelteComponentTyped<StepProps<TransitionIn, TransitionOut>, StepEvents<TransitionIn, TransitionOut>, StepSlots<TransitionIn, TransitionOut>> {
}
export {};

View File

@ -0,0 +1,89 @@
<script context="module">import { fade } from "svelte/transition";
import { prefersReducedMotionStore } from "../../index.js";
</script>
<script generics="TransitionIn extends Transition = FadeTransition, TransitionOut extends Transition = FadeTransition">import { createEventDispatcher, setContext } from "svelte";
import { writable } from "svelte/store";
import { dynamicTransition } from "../../internal/transitions.js";
const dispatch = createEventDispatcher();
export let gap = "gap-4";
export let stepTerm = "Step";
export let badge = "variant-filled-surface";
export let active = "variant-filled";
export let border = "border-surface-400-500-token";
export let start = 0;
export let justify = "justify-between";
export let buttonBack = "variant-ghost";
export let buttonBackType = "button";
export let buttonBackLabel = "&larr; Back";
export let buttonNext = "variant-filled";
export let buttonNextType = "button";
export let buttonNextLabel = "Next &rarr;";
export let buttonComplete = "variant-filled-primary";
export let buttonCompleteType = "button";
export let buttonCompleteLabel = "Complete";
export let regionHeader = "";
export let regionContent = "";
export let transitions = !$prefersReducedMotionStore;
export let transitionIn = fade;
export let transitionInParams = { duration: 100 };
export let transitionOut = fade;
export let transitionOutParams = { duration: 100 };
let state = writable({ current: start, total: 0 });
setContext("state", state);
setContext("dispatchParent", dispatch);
setContext("stepTerm", stepTerm);
setContext("gap", gap);
setContext("justify", justify);
setContext("buttonBack", buttonBack);
setContext("buttonBackType", buttonBackType);
setContext("buttonBackLabel", buttonBackLabel);
setContext("buttonNext", buttonNext);
setContext("buttonNextType", buttonNextType);
setContext("buttonNextLabel", buttonNextLabel);
setContext("buttonComplete", buttonComplete);
setContext("buttonCompleteType", buttonCompleteType);
setContext("buttonCompleteLabel", buttonCompleteLabel);
setContext("transitions", transitions);
setContext("transitionIn", transitionIn);
setContext("transitionInParams", transitionInParams);
setContext("transitionOut", transitionOut);
setContext("transitionOutParams", transitionOutParams);
const cBase = "space-y-4";
const cHeader = "flex items-center border-t mt-[15px]";
const cHeaderStep = "-mt-[15px] transition-all duration-300";
const cContent = "";
$:
isActive = (step) => step === $state.current;
$:
classesBase = `${cBase} ${$$props.class ?? ""}`;
$:
classesHeader = `${cHeader} ${border} ${gap} ${regionHeader}`;
$:
classesHeaderStep = `${cHeaderStep}`;
$:
classesBadge = (step) => isActive(step) ? active : badge;
$:
classesContent = `${cContent} ${regionContent}`;
</script>
<div class="stepper {classesBase}" data-testid="stepper">
<!-- Header -->
{#if $state.total}
<header
class="stepper-header {classesHeader}"
in:dynamicTransition|local={{ transition: transitionIn, params: transitionInParams, enabled: transitions }}
out:dynamicTransition|local={{ transition: transitionOut, params: transitionOutParams, enabled: transitions }}
>
{#each Array.from(Array($state.total).keys()) as step}
<div class="stepper-header-step {classesHeaderStep}" class:flex-1={isActive(step)}>
<span class="badge {classesBadge(step)}">{isActive(step) ? `${stepTerm} ${step + 1}` : step + 1}</span>
</div>
{/each}
</header>
{/if}
<!-- Content -->
<div class="stepper-content {classesContent}">
<slot />
</div>
</div>

View File

@ -0,0 +1,85 @@
import { SvelteComponentTyped } from "svelte";
import { fade } from 'svelte/transition';
import { type Transition, type TransitionParams } from '../../index.js';
type FadeTransition = typeof fade;
import type { StepperButton, StepperState } from './types.js';
declare class __sveltets_Render<TransitionIn extends Transition = FadeTransition, TransitionOut extends Transition = FadeTransition> {
props(): {
[x: string]: any;
/** Provide classes to style the stepper header gap.*/
gap?: string | undefined;
/** Provide the verbiage that represents "Step".*/
stepTerm?: string | undefined;
/** Provide classes to style the stepper header badges.*/
badge?: string | undefined;
/** Provide classes to style the stepper header active step badge.*/
active?: string | undefined;
/** Provide classes to style the stepper header border.*/
border?: string | undefined;
/** Provide the initially selected step*/
start?: number | undefined;
/** Set the justification for the step navigation buttons.*/
justify?: string | undefined;
/** Provide arbitrary classes to style the back button.*/
buttonBack?: string | undefined;
/** Set the type of the back button.*/
buttonBackType?: StepperButton | undefined;
/** Provide the HTML label content for the back button.*/
buttonBackLabel?: string | undefined;
/** Provide arbitrary classes to style the next button.*/
buttonNext?: string | undefined;
/** Set the type of the next button.*/
buttonNextType?: StepperButton | undefined;
/** Provide the HTML label content for the next button.*/
buttonNextLabel?: string | undefined;
/** Provide arbitrary classes to style the complete button.*/
buttonComplete?: string | undefined;
/** Set the type of the complete button.*/
buttonCompleteType?: StepperButton | undefined;
/** Provide the HTML label content for the complete button.*/
buttonCompleteLabel?: string | undefined;
/** Provide arbitrary classes to the stepper header region.*/
regionHeader?: string | undefined;
/** Provide arbitrary classes to the stepper content region.*/
regionContent?: string | undefined;
/** Enable/Disable transitions*/
transitions?: boolean | undefined;
/** Provide the transition to used on entry.*/
transitionIn?: TransitionIn | undefined;
/** Transition params provided to `transitionIn`.*/
transitionInParams?: TransitionParams<TransitionIn> | undefined;
/** Provide the transition to used on exit.*/
transitionOut?: TransitionOut | undefined;
/** Transition params provided to `transitionOut`.*/
transitionOutParams?: TransitionParams<TransitionOut> | undefined;
};
events(): {
next: CustomEvent<{
step: number;
state: StepperState;
}>;
step: CustomEvent<{
step: number;
state: StepperState;
}>;
back: CustomEvent<{
step: number;
state: StepperState;
}>;
complete: CustomEvent<{
step: number;
state: StepperState;
}>;
} & {
[evt: string]: CustomEvent<any>;
};
slots(): {
default: {};
};
}
export type StepperProps<TransitionIn extends Transition = FadeTransition, TransitionOut extends Transition = FadeTransition> = ReturnType<__sveltets_Render<TransitionIn, TransitionOut>['props']>;
export type StepperEvents<TransitionIn extends Transition = FadeTransition, TransitionOut extends Transition = FadeTransition> = ReturnType<__sveltets_Render<TransitionIn, TransitionOut>['events']>;
export type StepperSlots<TransitionIn extends Transition = FadeTransition, TransitionOut extends Transition = FadeTransition> = ReturnType<__sveltets_Render<TransitionIn, TransitionOut>['slots']>;
export default class Stepper<TransitionIn extends Transition = FadeTransition, TransitionOut extends Transition = FadeTransition> extends SvelteComponentTyped<StepperProps<TransitionIn, TransitionOut>, StepperEvents<TransitionIn, TransitionOut>, StepperSlots<TransitionIn, TransitionOut>> {
}
export {};

View File

@ -0,0 +1,25 @@
import type { EventDispatcher } from 'svelte';
export interface StepperState {
current: number;
total: number;
}
export type StepperButton = 'submit' | 'reset' | 'button';
export type StepperEvent = {
next: {
step: number;
state: StepperState;
};
step: {
step: number;
state: StepperState;
};
back: {
step: number;
state: StepperState;
};
complete: {
step: number;
state: StepperState;
};
};
export type StepperEventDispatcher = EventDispatcher<StepperEvent>;

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,95 @@
<script>import { getContext } from "svelte";
export let group;
export let name;
export let value;
export let title = "";
export let controls = "";
export let regionTab = "";
export let active = getContext("active");
export let hover = getContext("hover");
export let flex = getContext("flex");
export let padding = getContext("padding");
export let rounded = getContext("rounded");
export let spacing = getContext("spacing");
const cBase = "text-center cursor-pointer transition-colors duration-100";
const cInterface = "";
let elemInput;
function onKeyDown(event) {
if (["Enter", "Space"].includes(event.code)) {
event.preventDefault();
elemInput.click();
} else if (event.code === "ArrowRight") {
const tabList = elemInput.closest(".tab-list");
if (!tabList)
return;
const tabs = Array.from(tabList.querySelectorAll(".tab"));
const currTab = elemInput.closest(".tab");
if (!currTab)
return;
const currIndex = tabs.indexOf(currTab);
const nextIndex = currIndex + 1 >= tabs.length ? 0 : currIndex + 1;
const nextTab = tabs[nextIndex];
const nextTabInput = nextTab?.querySelector("input");
if (nextTab && nextTabInput) {
nextTabInput.click();
nextTab.focus();
}
} else if (event.code === "ArrowLeft") {
const tabList = elemInput.closest(".tab-list");
if (!tabList)
return;
const tabs = Array.from(tabList.querySelectorAll(".tab"));
const currTab = elemInput.closest(".tab");
if (!currTab)
return;
const currIndex = tabs.indexOf(currTab);
const nextIndex = currIndex - 1 < 0 ? tabs.length - 1 : currIndex - 1;
const nextTab = tabs[nextIndex];
const nextTabInput = nextTab?.querySelector("input");
if (nextTab && nextTabInput) {
nextTabInput.click();
nextTab.focus();
}
}
}
$:
selected = value === group;
$:
classesActive = selected ? active : hover;
$:
classesBase = `${cBase} ${flex} ${padding} ${rounded} ${classesActive} ${$$props.class ?? ""}`;
$:
classesInterface = `${cInterface} ${spacing}`;
$:
classesTab = `${regionTab}`;
function prunedRestProps() {
delete $$restProps.class;
return $$restProps;
}
</script>
<label class={classesBase} {title}>
<!-- A11y attributes are not allowed on <label> -->
<div
class="tab {classesTab}"
data-testid="tab"
role="tab"
aria-controls={controls}
aria-selected={selected}
tabindex={selected ? 0 : -1}
on:keydown={onKeyDown}
on:keydown
on:keyup
on:keypress
>
<!-- NOTE: Don't use `hidden` as it prevents `required` from operating -->
<div class="h-0 w-0 overflow-hidden">
<input bind:this={elemInput} type="radio" bind:group {name} {value} {...prunedRestProps()} tabindex="-1" on:click on:change />
</div>
<!-- Interface -->
<div class="tab-interface {classesInterface}">
{#if $$slots.lead}<div class="tab-lead"><slot name="lead" /></div>{/if}
<div class="tab-label"><slot /></div>
</div>
</div>
</label>

View File

@ -0,0 +1,49 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Set the radio group binding value.*/
group: any;
/** Set a unique name value for the input.*/
name: string;
/** Set the input's value.*/
value: any;
/** Provide a hoverable title attribute for the tab.*/
title?: string | undefined;
/** Set the ARIA controls value to define which panel this tab controls.*/
controls?: string | undefined;
/** Provide arbitrary classes to style the tab region.*/
regionTab?: string | undefined;
/** Provide classes to style each tab's active styles.*/
active?: string | undefined;
/** Provide classes to style each tab's hover styles.*/
hover?: string | undefined;
/** Provide classes to style each tab's flex styles.*/
flex?: string | undefined;
/** Provide classes to style each tab's padding styles.*/
padding?: string | undefined;
/** Provide classes to style each tab's box radius styles.*/
rounded?: string | undefined;
/** Provide classes to set the vertical spacing between items.*/
spacing?: string | undefined;
};
events: {
keydown: KeyboardEvent;
keyup: KeyboardEvent;
keypress: KeyboardEvent;
click: MouseEvent;
change: Event;
} & {
[evt: string]: CustomEvent<any>;
};
slots: {
lead: {};
default: {};
};
};
export type TabProps = typeof __propDef.props;
export type TabEvents = typeof __propDef.events;
export type TabSlots = typeof __propDef.slots;
export default class Tab extends SvelteComponentTyped<TabProps, TabEvents, TabSlots> {
}
export {};

View File

@ -0,0 +1,44 @@
<script>import { getContext } from "svelte";
export let selected = false;
export let controls = "";
export let active = getContext("active");
export let hover = getContext("hover");
export let flex = getContext("flex");
export let padding = getContext("padding");
export let rounded = getContext("rounded");
export let spacing = getContext("spacing");
const cBase = "text-center cursor-pointer transition-colors duration-100";
const cInterface = "";
$:
classesActive = selected ? active : hover;
$:
classesBase = `${cBase} ${flex} ${padding} ${rounded} ${classesActive} ${$$props.class ?? ""}`;
$:
classesInterface = `${cInterface} ${spacing}`;
function prunedRestProps() {
delete $$restProps.class;
return $$restProps;
}
</script>
<a
class="tab-anchor {classesBase}"
href={$$props.href}
{...prunedRestProps()}
aria-controls={controls}
on:click
on:keydown
on:keyup
on:keypress
on:mouseover
on:mouseleave
on:focus
on:blur
data-testid="tab-anchor"
>
<!-- Interface -->
<div class="tab-interface {classesInterface}">
{#if $$slots.lead}<div class="tab-lead"><slot name="lead" /></div>{/if}
<div class="tab-label"><slot /></div>
</div>
</a>

View File

@ -0,0 +1,44 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Enables the active state styles when set true.*/
selected?: boolean | undefined;
/** Set the ARIA controls value to define which panel this tab controls.*/
controls?: string | undefined;
/** Provide classes to style each tab's active styles.*/
active?: string | undefined;
/** Provide classes to style each tab's hover styles.*/
hover?: string | undefined;
/** Provide classes to style each tab's flex styles.*/
flex?: string | undefined;
/** Provide classes to style each tab's padding styles.*/
padding?: string | undefined;
/** Provide classes to style each tab's box radius styles.*/
rounded?: string | undefined;
/** Provide classes to set the vertical spacing between items.*/
spacing?: string | undefined;
};
events: {
click: MouseEvent;
keydown: KeyboardEvent;
keyup: KeyboardEvent;
keypress: KeyboardEvent;
mouseover: MouseEvent;
mouseleave: MouseEvent;
focus: FocusEvent;
blur: FocusEvent;
} & {
[evt: string]: CustomEvent<any>;
};
slots: {
lead: {};
default: {};
};
};
export type TabAnchorProps = typeof __propDef.props;
export type TabAnchorEvents = typeof __propDef.events;
export type TabAnchorSlots = typeof __propDef.slots;
export default class TabAnchor extends SvelteComponentTyped<TabAnchorProps, TabAnchorEvents, TabAnchorSlots> {
}
export {};

View File

@ -0,0 +1,44 @@
<script>import { setContext } from "svelte";
export let justify = "justify-start";
export let border = "border-b border-surface-400-500-token";
export let active = "border-b-2 border-surface-900-50-token";
export let hover = "hover:variant-soft";
export let flex = "flex-none";
export let padding = "px-4 py-2";
export let rounded = "rounded-tl-container-token rounded-tr-container-token";
export let spacing = "space-y-1";
export let regionList = "";
export let regionPanel = "";
export let labelledby = "";
export let panel = "";
setContext("active", active);
setContext("hover", hover);
setContext("flex", flex);
setContext("padding", padding);
setContext("rounded", rounded);
setContext("spacing", spacing);
const cBase = "space-y-4";
const cList = "flex overflow-x-auto hide-scrollbar";
const cPanel = "";
$:
classesBase = `${cBase} ${$$props.class ?? ""}`;
$:
classesList = `${cList} ${justify} ${border} ${regionList}`;
$:
classesPanel = `${cPanel} ${regionPanel}`;
</script>
<!-- FIXME: resolve a11y warnings -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div class="tab-group {classesBase}" data-testid="tab-group" on:click on:keypress on:keydown on:keyup>
<!-- Tab List -->
<div class="tab-list {classesList}" role="tablist" aria-labelledby={labelledby}>
<slot />
</div>
<!-- Tab Panel -->
{#if $$slots.panel}
<div class="tab-panel {classesPanel}" role="tabpanel" aria-labelledby={panel} tabindex="0">
<slot name="panel" />
</div>
{/if}
</div>

View File

@ -0,0 +1,48 @@
import { SvelteComponentTyped } from "svelte";
declare const __propDef: {
props: {
[x: string]: any;
/** Provide classes to set the tab list flex justification.*/
justify?: string | undefined;
/** Provide classes to set the tab group border styles.*/
border?: string | undefined;
/** Provide classes to style each tab's active styles.*/
active?: string | undefined;
/** Provide classes to style each tab's hover styles.*/
hover?: string | undefined;
/** Provide classes to style each tab's flex styles.*/
flex?: string | undefined;
/** Provide classes to style each tab's padding styles.*/
padding?: string | undefined;
/** Provide classes to style each tab's box radius styles.*/
rounded?: string | undefined;
/** Provide classes to set the vertical spacing between items.*/
spacing?: string | undefined;
/** Provide arbitrary classes to style the tab list region.*/
regionList?: string | undefined;
/** Provide arbitrary classes to style the tab panel region.*/
regionPanel?: string | undefined;
/** Provide the ID of the element that labels the tab list.*/
labelledby?: string | undefined;
/** Matches the tab aria-control value, pairs with the panel.*/
panel?: string | undefined;
};
events: {
click: MouseEvent;
keypress: KeyboardEvent;
keydown: KeyboardEvent;
keyup: KeyboardEvent;
} & {
[evt: string]: CustomEvent<any>;
};
slots: {
default: {};
panel: {};
};
};
export type TabGroupProps = typeof __propDef.props;
export type TabGroupEvents = typeof __propDef.events;
export type TabGroupSlots = typeof __propDef.slots;
export default class TabGroup extends SvelteComponentTyped<TabGroupProps, TabGroupEvents, TabGroupSlots> {
}
export {};

View File

@ -0,0 +1,87 @@
<script>import { createEventDispatcher } from "svelte";
import { tableA11y } from "./actions.js";
const dispatch = createEventDispatcher();
export let source;
export let interactive = false;
export let element = "table";
export let text = "";
export let color = "";
export let regionHead = "";
export let regionHeadCell = "";
export let regionBody = "";
export let regionCell = "";
export let regionFoot = "";
export let regionFootCell = "";
function onRowClick(event, rowIndex) {
if (!interactive)
return;
event.preventDefault();
event.stopPropagation();
const rowMetaData = source.meta ? source.meta[rowIndex] : source.body[rowIndex];
dispatch("selected", rowMetaData);
}
function onRowKeydown(event, rowIndex) {
if (["Enter", "Space"].includes(event.code))
onRowClick(event, rowIndex);
}
$:
classesBase = `${$$props.class || ""}`;
$:
classesTable = `${element} ${text} ${color}`;
</script>
<div class="table-container {classesBase}">
<!-- Table -->
<!-- prettier-ignore -->
<table
class="{classesTable}"
class:table-interactive={interactive}
role="grid"
use:tableA11y
>
<!-- on:keydown={(e) => onTableKeydown(elemTable, e)} -->
<!-- Head -->
<thead class="table-head {regionHead}">
<tr>
{#each source.head as heading }
<th class="{regionHeadCell}">{@html heading}</th>
{/each}
</tr>
</thead>
<!-- Body -->
<tbody class="table-body {regionBody}">
{#each source.body as row, rowIndex}
<!-- Row -->
<!-- prettier-ignore -->
<tr
on:click={(e) => { onRowClick(e, rowIndex); }}
on:keydown={(e) => { onRowKeydown(e, rowIndex); }}
aria-rowindex={rowIndex + 1}
>
{#each row as cell, cellIndex}
<!-- Cell -->
<!-- prettier-ignore -->
<td
class="{regionCell}"
role="gridcell"
aria-colindex={cellIndex + 1}
tabindex={cellIndex === 0 ? 0 : -1}
>
{@html Number(cell) === 0 ? cell : (cell ? cell : '-')}
</td>
{/each}
</tr>
{/each}
</tbody>
<!-- Foot -->
{#if source.foot}
<tfoot class="table-foot {regionFoot}">
<tr>
{#each source.foot as cell }
<td class="{regionFootCell}">{@html cell}</td>
{/each}
</tr>
</tfoot>
{/if}
</table>
</div>

View File

@ -0,0 +1,42 @@
import { SvelteComponentTyped } from "svelte";
import type { TableSource } from '../../index.js';
declare const __propDef: {
props: {
[x: string]: any;
/** Provide the full set of table source data.*/
source: TableSource;
/** Enables row hover style and `on:selected` event when rows are clicked.*/
interactive?: boolean | undefined;
/** Override the Tailwind Element class. Replace this for a headless UI.*/
element?: string | undefined;
/** Provide classes to set the table text size.*/
text?: string | undefined;
/** Provide classes to set the table text color.*/
color?: string | undefined;
/** Provide arbitrary classes for the table head.*/
regionHead?: string | undefined;
/** Provide arbitrary classes for the table head cells.*/
regionHeadCell?: string | undefined;
/** Provide arbitrary classes for the table body.*/
regionBody?: string | undefined;
/** Provide arbitrary classes for the table cells.*/
regionCell?: string | undefined;
/** Provide arbitrary classes for the table foot.*/
regionFoot?: string | undefined;
/** Provide arbitrary classes for the table foot cells.*/
regionFootCell?: string | undefined;
};
events: {
/** {rowMetaData} selected - Fires when a table row is clicked.*/
selected: CustomEvent<string[]>;
} & {
[evt: string]: CustomEvent<any>;
};
slots: {};
};
export type TableProps = typeof __propDef.props;
export type TableEvents = typeof __propDef.events;
export type TableSlots = typeof __propDef.slots;
export default class Table extends SvelteComponentTyped<TableProps, TableEvents, TableSlots> {
}
export {};

View File

@ -0,0 +1,8 @@
/** Svelte Action for applying sort asc/dsc classes. */
export declare function tableInteraction(node: HTMLElement): {
destroy(): void;
};
/** Svelte Action for handling table a11y keyboard interactions. */
export declare function tableA11y(node: HTMLElement): {
destroy(): void;
};

View File

@ -0,0 +1,114 @@
// Shared Data/Table Actions
// Data Table (only) ---
/** Svelte Action for applying sort asc/dsc classes. */
export function tableInteraction(node) {
const classAsc = 'table-sort-asc';
const classDsc = 'table-sort-dsc';
// Click Handler
const onClick = (e) => {
if (!(e.target instanceof Element))
return;
const sortTarget = e.target;
// Get target state before modification
const targetAscSorted = sortTarget.classList.contains(classAsc);
const sortTargetKey = sortTarget.getAttribute('data-sort');
// Clear asc class
const elemAsc = node.querySelector(`.${classAsc}`);
if (elemAsc)
elemAsc.classList.remove(classAsc);
// Clear dsc class
const elemDsc = node.querySelector(`.${classDsc}`);
if (elemDsc)
elemDsc.classList.remove(classDsc);
// Set new sort class
if (sortTargetKey) {
const classToApply = targetAscSorted ? classDsc : classAsc;
e.target.classList.add(classToApply);
}
};
// Events
node.addEventListener('click', onClick);
// Lifecycle
return {
destroy() {
node.removeEventListener('click', onClick);
}
};
}
// Shared ---
/** Svelte Action for handling table a11y keyboard interactions. */
export function tableA11y(node) {
const keyWhitelist = ['ArrowRight', 'ArrowUp', 'ArrowLeft', 'ArrowDown', 'Home', 'End'];
// on:keydown
const onKeyDown = (event) => {
// console.log('keydown triggered');
if (keyWhitelist.includes(event.code)) {
event.preventDefault();
// prettier-ignore
switch (event.code) {
case 'ArrowUp':
a11ySetActiveCell(node, 0, -1);
break;
case 'ArrowDown':
a11ySetActiveCell(node, 0, 1);
break;
case 'ArrowLeft':
a11ySetActiveCell(node, -1, 0);
break;
case 'ArrowRight':
a11ySetActiveCell(node, 1, 0);
break;
case 'Home':
a11yJumpToOuterColumn(node, 'first');
break;
case 'End':
a11yJumpToOuterColumn(node, 'last');
break;
default: break;
}
}
};
// Event Listener
node.addEventListener('keydown', onKeyDown);
// Lifecycle
return {
destroy() {
node.removeEventListener('keydown', onKeyDown);
}
};
}
function a11ySetActiveCell(node, x, y) {
// Focused Element
const focusedElem = document.activeElement;
if (!focusedElem || !focusedElem.parentElement || !focusedElem.parentElement.ariaRowIndex || !focusedElem.ariaColIndex)
return;
const focusedElemRowIndex = parseInt(focusedElem.parentElement.ariaRowIndex);
const focusedElemColIndex = parseInt(focusedElem.ariaColIndex);
// Target Element
const targetRowElement = node.querySelector(`[aria-rowindex="${focusedElemRowIndex + y}"]`);
if (targetRowElement !== null) {
const targetColElement = targetRowElement.querySelector(`[aria-colindex="${focusedElemColIndex + x}"]`);
if (targetColElement !== null)
targetColElement.focus();
}
}
function a11yGetTargetElem(node) {
// Focused Element
const focusedElem = document.activeElement;
if (!focusedElem || !focusedElem.parentElement || !focusedElem.parentElement.ariaRowIndex)
return null;
const focusedElemRowIndex = parseInt(focusedElem.parentElement.ariaRowIndex);
// Return Target Element
return node.querySelector(`[aria-rowindex="${focusedElemRowIndex}"]`);
}
function a11yJumpToOuterColumn(node, type = 'first') {
const targetRowElement = a11yGetTargetElem(node);
if (targetRowElement === null)
return;
const lastIndex = targetRowElement.children.length;
const selected = type === 'first' ? 1 : lastIndex;
const targetColElement = targetRowElement.querySelector(`[aria-colindex="${selected}"]`);
if (targetColElement === null)
return;
targetColElement.focus();
}

View File

@ -0,0 +1,10 @@
export interface TableSource {
/** The formatted table heading values. */
head: string[];
/** The formatted table body values. */
body: string[][];
/** The data returned when an interactive row is clicked. */
meta?: string[][];
/** The formatted table footer values. */
foot?: string[];
}

Some files were not shown because too many files have changed in this diff Show More