@ternkit/tern 1.2.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/goscript/index.svelte.d.ts +32 -2
- package/dist/goscript/index.svelte.js +257 -31
- package/dist/goscript/patch.d.ts +6 -0
- package/dist/goscript/patch.js +25 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/runtime/validate.d.ts +31 -0
- package/dist/runtime/validate.js +168 -0
- package/dist/server/intl.js +55 -12
- package/dist/ui/Accordion.svelte +84 -0
- package/dist/ui/Accordion.svelte.d.ts +20 -0
- package/dist/ui/Alert.svelte +76 -0
- package/dist/ui/Alert.svelte.d.ts +12 -0
- package/dist/ui/AlertDialog.svelte +79 -0
- package/dist/ui/AlertDialog.svelte.d.ts +24 -0
- package/dist/ui/AreaChart.svelte +9 -0
- package/dist/ui/AreaChart.svelte.d.ts +26 -0
- package/dist/ui/AspectRatio.svelte +33 -0
- package/dist/ui/AspectRatio.svelte.d.ts +10 -0
- package/dist/ui/Avatar.svelte +48 -0
- package/dist/ui/Avatar.svelte.d.ts +10 -0
- package/dist/ui/Badge.svelte +54 -0
- package/dist/ui/Badge.svelte.d.ts +10 -0
- package/dist/ui/BarChart.svelte +170 -0
- package/dist/ui/BarChart.svelte.d.ts +40 -0
- package/dist/ui/Breadcrumb.svelte +92 -0
- package/dist/ui/Breadcrumb.svelte.d.ts +14 -0
- package/dist/ui/Button.svelte +136 -0
- package/dist/ui/Button.svelte.d.ts +18 -0
- package/dist/ui/ButtonGroup.svelte +61 -0
- package/dist/ui/ButtonGroup.svelte.d.ts +12 -0
- package/dist/ui/Calendar.svelte +265 -0
- package/dist/ui/Calendar.svelte.d.ts +28 -0
- package/dist/ui/Card.svelte +74 -0
- package/dist/ui/Card.svelte.d.ts +18 -0
- package/dist/ui/Carousel.svelte +169 -0
- package/dist/ui/Carousel.svelte.d.ts +36 -0
- package/dist/ui/ChartFrame.svelte +174 -0
- package/dist/ui/ChartFrame.svelte.d.ts +24 -0
- package/dist/ui/Checkbox.svelte +112 -0
- package/dist/ui/Checkbox.svelte.d.ts +14 -0
- package/dist/ui/Collapsible.svelte +59 -0
- package/dist/ui/Collapsible.svelte.d.ts +12 -0
- package/dist/ui/Combobox.svelte +350 -0
- package/dist/ui/Combobox.svelte.d.ts +24 -0
- package/dist/ui/Command.svelte +268 -0
- package/dist/ui/Command.svelte.d.ts +28 -0
- package/dist/ui/ConsentScreen.svelte +125 -0
- package/dist/ui/ConsentScreen.svelte.d.ts +21 -0
- package/dist/ui/ContextMenu.svelte +78 -0
- package/dist/ui/ContextMenu.svelte.d.ts +13 -0
- package/dist/ui/DataTable.svelte +277 -0
- package/dist/ui/DataTable.svelte.d.ts +53 -0
- package/dist/ui/DatePicker.svelte +138 -0
- package/dist/ui/DatePicker.svelte.d.ts +25 -0
- package/dist/ui/Dialog.svelte +301 -0
- package/dist/ui/Dialog.svelte.d.ts +30 -0
- package/dist/ui/DonutChart.svelte +115 -0
- package/dist/ui/DonutChart.svelte.d.ts +40 -0
- package/dist/ui/Drawer.svelte +19 -0
- package/dist/ui/Drawer.svelte.d.ts +14 -0
- package/dist/ui/Empty.svelte +62 -0
- package/dist/ui/Empty.svelte.d.ts +15 -0
- package/dist/ui/Field.svelte +97 -0
- package/dist/ui/Field.svelte.d.ts +19 -0
- package/dist/ui/Form.svelte +159 -0
- package/dist/ui/Form.svelte.d.ts +21 -0
- package/dist/ui/HoverCard.svelte +106 -0
- package/dist/ui/HoverCard.svelte.d.ts +26 -0
- package/dist/ui/Input.svelte +62 -0
- package/dist/ui/Input.svelte.d.ts +7 -0
- package/dist/ui/InputGroup.svelte +80 -0
- package/dist/ui/InputGroup.svelte.d.ts +13 -0
- package/dist/ui/InputOTP.svelte +140 -0
- package/dist/ui/InputOTP.svelte.d.ts +18 -0
- package/dist/ui/Item.svelte +86 -0
- package/dist/ui/Item.svelte.d.ts +17 -0
- package/dist/ui/Kbd.svelte +24 -0
- package/dist/ui/Kbd.svelte.d.ts +7 -0
- package/dist/ui/Label.svelte +29 -0
- package/dist/ui/Label.svelte.d.ts +10 -0
- package/dist/ui/LineChart.svelte +171 -0
- package/dist/ui/LineChart.svelte.d.ts +42 -0
- package/dist/ui/Menu.svelte +103 -0
- package/dist/ui/Menu.svelte.d.ts +15 -0
- package/dist/ui/MenuList.svelte +317 -0
- package/dist/ui/MenuList.svelte.d.ts +29 -0
- package/dist/ui/Menubar.svelte +133 -0
- package/dist/ui/Menubar.svelte.d.ts +14 -0
- package/dist/ui/NavigationMenu.svelte +208 -0
- package/dist/ui/NavigationMenu.svelte.d.ts +18 -0
- package/dist/ui/Pagination.svelte +114 -0
- package/dist/ui/Pagination.svelte.d.ts +16 -0
- package/dist/ui/PasswordInput.svelte +134 -0
- package/dist/ui/PasswordInput.svelte.d.ts +11 -0
- package/dist/ui/Popover.svelte +127 -0
- package/dist/ui/Popover.svelte.d.ts +29 -0
- package/dist/ui/Progress.svelte +73 -0
- package/dist/ui/Progress.svelte.d.ts +12 -0
- package/dist/ui/RadioGroup.svelte +105 -0
- package/dist/ui/RadioGroup.svelte.d.ts +21 -0
- package/dist/ui/Resizable.svelte +122 -0
- package/dist/ui/Resizable.svelte.d.ts +16 -0
- package/dist/ui/ScrollArea.svelte +43 -0
- package/dist/ui/ScrollArea.svelte.d.ts +13 -0
- package/dist/ui/Select.svelte +77 -0
- package/dist/ui/Select.svelte.d.ts +18 -0
- package/dist/ui/SelectMenu.svelte +301 -0
- package/dist/ui/SelectMenu.svelte.d.ts +18 -0
- package/dist/ui/Separator.svelte +19 -0
- package/dist/ui/Separator.svelte.d.ts +7 -0
- package/dist/ui/Sheet.svelte +21 -0
- package/dist/ui/Sheet.svelte.d.ts +16 -0
- package/dist/ui/Sidebar.svelte +263 -0
- package/dist/ui/Sidebar.svelte.d.ts +35 -0
- package/dist/ui/SignIn.svelte +182 -0
- package/dist/ui/SignIn.svelte.d.ts +38 -0
- package/dist/ui/SignUp.svelte +106 -0
- package/dist/ui/SignUp.svelte.d.ts +23 -0
- package/dist/ui/Skeleton.svelte +29 -0
- package/dist/ui/Skeleton.svelte.d.ts +9 -0
- package/dist/ui/Slider.svelte +196 -0
- package/dist/ui/Slider.svelte.d.ts +19 -0
- package/dist/ui/Sparkline.svelte +23 -0
- package/dist/ui/Sparkline.svelte.d.ts +11 -0
- package/dist/ui/Spinner.svelte +42 -0
- package/dist/ui/Spinner.svelte.d.ts +8 -0
- package/dist/ui/Stat.svelte +91 -0
- package/dist/ui/Stat.svelte.d.ts +18 -0
- package/dist/ui/Switch.svelte +90 -0
- package/dist/ui/Switch.svelte.d.ts +12 -0
- package/dist/ui/Table.svelte +70 -0
- package/dist/ui/Table.svelte.d.ts +36 -0
- package/dist/ui/Tabs.svelte +112 -0
- package/dist/ui/Tabs.svelte.d.ts +19 -0
- package/dist/ui/Textarea.svelte +52 -0
- package/dist/ui/Textarea.svelte.d.ts +7 -0
- package/dist/ui/Toaster.svelte +146 -0
- package/dist/ui/Toaster.svelte.d.ts +6 -0
- package/dist/ui/Toggle.svelte +82 -0
- package/dist/ui/Toggle.svelte.d.ts +17 -0
- package/dist/ui/ToggleGroup.svelte +143 -0
- package/dist/ui/ToggleGroup.svelte.d.ts +27 -0
- package/dist/ui/Tooltip.svelte +85 -0
- package/dist/ui/Tooltip.svelte.d.ts +16 -0
- package/dist/ui/chart.d.ts +26 -0
- package/dist/ui/chart.js +89 -0
- package/dist/ui/dates.d.ts +13 -0
- package/dist/ui/dates.js +64 -0
- package/dist/ui/field.d.ts +18 -0
- package/dist/ui/field.js +8 -0
- package/dist/ui/floating.d.ts +44 -0
- package/dist/ui/floating.js +97 -0
- package/dist/ui/form.d.ts +12 -0
- package/dist/ui/form.js +8 -0
- package/dist/ui/index.d.ts +78 -0
- package/dist/ui/index.js +70 -0
- package/dist/ui/menu.d.ts +25 -0
- package/dist/ui/menu.js +1 -0
- package/dist/ui/options.d.ts +17 -0
- package/dist/ui/options.js +22 -0
- package/dist/ui/table.d.ts +26 -0
- package/dist/ui/table.js +1 -0
- package/dist/ui/theme.css +176 -0
- package/dist/ui/toast.svelte.d.ts +19 -0
- package/dist/ui/toast.svelte.js +18 -0
- package/dist/vite/goscript.d.ts +14 -0
- package/dist/vite/goscript.js +45 -16
- package/dist/vite/index.js +15 -4
- package/package.json +7 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import { float, type Side } from './floating.js';
|
|
4
|
+
|
|
5
|
+
type Props = {
|
|
6
|
+
/** The tooltip's text. It describes the trigger; don't put anything interactive in it. */
|
|
7
|
+
text: string;
|
|
8
|
+
side?: Side;
|
|
9
|
+
/** How long to wait before showing, in milliseconds. */
|
|
10
|
+
delay?: number;
|
|
11
|
+
/** The trigger, which must be focusable, such as a Button. It receives aria-describedby through the snippet's props. */
|
|
12
|
+
children: Snippet<[{ 'aria-describedby': string }]>;
|
|
13
|
+
};
|
|
14
|
+
let { text, side = 'top', delay = 300, children }: Props = $props();
|
|
15
|
+
const uid = $props.id();
|
|
16
|
+
let open = $state(false);
|
|
17
|
+
let wrap = $state<HTMLSpanElement>();
|
|
18
|
+
let tip = $state<HTMLSpanElement>();
|
|
19
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
20
|
+
|
|
21
|
+
const show = (now = false) => {
|
|
22
|
+
clearTimeout(timer);
|
|
23
|
+
if (now) open = true;
|
|
24
|
+
else timer = setTimeout(() => (open = true), delay);
|
|
25
|
+
};
|
|
26
|
+
const hide = () => {
|
|
27
|
+
clearTimeout(timer);
|
|
28
|
+
open = false;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
$effect(() => {
|
|
32
|
+
if (!open || !tip || !wrap) return;
|
|
33
|
+
tip.showPopover?.();
|
|
34
|
+
const stop = float(tip, wrap.firstElementChild ?? wrap, { side, align: 'center', offset: 6 });
|
|
35
|
+
return () => {
|
|
36
|
+
stop();
|
|
37
|
+
tip?.hidePopover?.();
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
43
|
+
<span
|
|
44
|
+
bind:this={wrap}
|
|
45
|
+
class="tern-tooltip"
|
|
46
|
+
onpointerenter={() => show()}
|
|
47
|
+
onpointerleave={hide}
|
|
48
|
+
onfocusin={() => show(true)}
|
|
49
|
+
onfocusout={hide}
|
|
50
|
+
onkeydown={(e) => e.key === 'Escape' && hide()}
|
|
51
|
+
>
|
|
52
|
+
{@render children({ 'aria-describedby': `tern-tooltip-${uid}` })}
|
|
53
|
+
<span bind:this={tip} role="tooltip" id="tern-tooltip-{uid}" class="tip" class:open popover="manual">{text}</span>
|
|
54
|
+
</span>
|
|
55
|
+
|
|
56
|
+
<style>
|
|
57
|
+
.tern-tooltip {
|
|
58
|
+
display: inline-flex;
|
|
59
|
+
}
|
|
60
|
+
.tip {
|
|
61
|
+
width: max-content;
|
|
62
|
+
max-width: 16rem;
|
|
63
|
+
padding: 0.35rem 0.55rem;
|
|
64
|
+
border: 0;
|
|
65
|
+
border-radius: var(--tern-radius-sm);
|
|
66
|
+
background: var(--tern-fg);
|
|
67
|
+
color: var(--tern-bg);
|
|
68
|
+
font-size: 0.75rem;
|
|
69
|
+
line-height: 1.35;
|
|
70
|
+
pointer-events: none;
|
|
71
|
+
}
|
|
72
|
+
.tip.open {
|
|
73
|
+
animation: tern-tip-in var(--tern-duration) ease-out;
|
|
74
|
+
}
|
|
75
|
+
@keyframes tern-tip-in {
|
|
76
|
+
from {
|
|
77
|
+
opacity: 0;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
@media (prefers-reduced-motion: reduce) {
|
|
81
|
+
.tip.open {
|
|
82
|
+
animation: none;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
</style>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import { type Side } from './floating.js';
|
|
3
|
+
type Props = {
|
|
4
|
+
/** The tooltip's text. It describes the trigger; don't put anything interactive in it. */
|
|
5
|
+
text: string;
|
|
6
|
+
side?: Side;
|
|
7
|
+
/** How long to wait before showing, in milliseconds. */
|
|
8
|
+
delay?: number;
|
|
9
|
+
/** The trigger, which must be focusable, such as a Button. It receives aria-describedby through the snippet's props. */
|
|
10
|
+
children: Snippet<[{
|
|
11
|
+
'aria-describedby': string;
|
|
12
|
+
}]>;
|
|
13
|
+
};
|
|
14
|
+
declare const Tooltip: import("svelte").Component<Props, {}, "">;
|
|
15
|
+
type Tooltip = ReturnType<typeof Tooltip>;
|
|
16
|
+
export default Tooltip;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type XValue = number | string | Date;
|
|
2
|
+
export type Series<Row> = {
|
|
3
|
+
/** The field holding this series' numbers. */
|
|
4
|
+
key: keyof Row & string;
|
|
5
|
+
label: string;
|
|
6
|
+
};
|
|
7
|
+
/** The series colors, in their fixed order. A ninth series folds into "Other". */
|
|
8
|
+
export declare const seriesColor: (i: number) => string;
|
|
9
|
+
/** Turns x values into numbers for time and number axes, or null for categories. */
|
|
10
|
+
export declare function numericX(values: XValue[]): number[] | null;
|
|
11
|
+
export declare const isTime: (values: XValue[]) => boolean;
|
|
12
|
+
/** Round ticks covering [min, max], about count of them. */
|
|
13
|
+
export declare function niceTicks(min: number, max: number, count?: number): number[];
|
|
14
|
+
/** 1,284 in full under 10,000; 12K, 4.2M above. */
|
|
15
|
+
export declare function formatNumber(n: number, compact?: boolean): string;
|
|
16
|
+
/** Evenly spaced time ticks with a format that fits their spacing. */
|
|
17
|
+
export declare function timeTicks(min: number, max: number, count?: number): {
|
|
18
|
+
ticks: number[];
|
|
19
|
+
format: (t: number) => string;
|
|
20
|
+
};
|
|
21
|
+
/** A readable label for an x value in tooltips and tables. */
|
|
22
|
+
export declare function formatX(v: XValue, time: boolean): string;
|
|
23
|
+
/** An estimate of how wide a label is, for margins; the charts' text is 12px. */
|
|
24
|
+
export declare const textWidth: (s: string) => number;
|
|
25
|
+
/** Array.prototype.findLastIndex, for older targets. */
|
|
26
|
+
export declare function lastIndex<T>(a: T[], ok: (v: T) => boolean): number;
|
package/dist/ui/chart.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// Scales, ticks and formatting shared by the charts.
|
|
2
|
+
/** The series colors, in their fixed order. A ninth series folds into "Other". */
|
|
3
|
+
export const seriesColor = (i) => `var(--tern-chart-${(i % 8) + 1})`;
|
|
4
|
+
const isoDate = /^\d{4}-\d{2}-\d{2}([T ][\d:.]+(Z|[+-]\d{2}:?\d{2})?)?$/;
|
|
5
|
+
/** Turns x values into numbers for time and number axes, or null for categories. */
|
|
6
|
+
export function numericX(values) {
|
|
7
|
+
if (values.every((v) => typeof v === 'number'))
|
|
8
|
+
return values;
|
|
9
|
+
if (values.every((v) => v instanceof Date))
|
|
10
|
+
return values.map((d) => d.getTime());
|
|
11
|
+
if (values.every((v) => typeof v === 'string' && isoDate.test(v)))
|
|
12
|
+
return values.map((s) => Date.parse(s.length === 10 ? s + 'T00:00:00Z' : s));
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
export const isTime = (values) => values.length > 0 && !values.every((v) => typeof v === 'number') && numericX(values) !== null;
|
|
16
|
+
/** Round ticks covering [min, max], about count of them. */
|
|
17
|
+
export function niceTicks(min, max, count = 5) {
|
|
18
|
+
if (min === max) {
|
|
19
|
+
if (min === 0)
|
|
20
|
+
return [0, 1];
|
|
21
|
+
[min, max] = min > 0 ? [0, min] : [min, 0];
|
|
22
|
+
}
|
|
23
|
+
const span = max - min;
|
|
24
|
+
const raw = span / Math.max(1, count);
|
|
25
|
+
const mag = 10 ** Math.floor(Math.log10(raw));
|
|
26
|
+
const step = [1, 2, 2.5, 5, 10].map((m) => m * mag).find((s) => span / s <= count) ?? 10 * mag;
|
|
27
|
+
const start = Math.floor(min / step) * step;
|
|
28
|
+
const end = Math.ceil(max / step) * step;
|
|
29
|
+
const out = [];
|
|
30
|
+
for (let v = start; v <= end + step / 2; v += step)
|
|
31
|
+
out.push(Number(v.toFixed(10)));
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
/** 1,284 in full under 10,000; 12K, 4.2M above. */
|
|
35
|
+
export function formatNumber(n, compact = Math.abs(n) >= 10_000) {
|
|
36
|
+
return new Intl.NumberFormat(undefined, compact ? { notation: 'compact', maximumFractionDigits: 1 } : { maximumFractionDigits: 2 }).format(n);
|
|
37
|
+
}
|
|
38
|
+
const DAY = 86_400_000;
|
|
39
|
+
/** Evenly spaced time ticks with a format that fits their spacing. */
|
|
40
|
+
export function timeTicks(min, max, count = 6) {
|
|
41
|
+
const span = max - min;
|
|
42
|
+
const fmt = (o) => {
|
|
43
|
+
const f = new Intl.DateTimeFormat(undefined, { timeZone: 'UTC', ...o });
|
|
44
|
+
return (t) => f.format(new Date(t));
|
|
45
|
+
};
|
|
46
|
+
if (span <= 2 * DAY) {
|
|
47
|
+
const step = [1, 2, 3, 6, 12].map((h) => h * 3_600_000).find((s) => span / s <= count) ?? 24 * 3_600_000;
|
|
48
|
+
return { ticks: stepTicks(min, max, step), format: fmt({ hour: '2-digit', minute: '2-digit' }) };
|
|
49
|
+
}
|
|
50
|
+
if (span <= 120 * DAY) {
|
|
51
|
+
const step = [1, 2, 7, 14].map((d) => d * DAY).find((s) => span / s <= count) ?? 28 * DAY;
|
|
52
|
+
return { ticks: stepTicks(min, max, step), format: fmt({ month: 'short', day: 'numeric' }) };
|
|
53
|
+
}
|
|
54
|
+
const months = [];
|
|
55
|
+
const d = new Date(min);
|
|
56
|
+
d.setUTCDate(1);
|
|
57
|
+
d.setUTCHours(0, 0, 0, 0);
|
|
58
|
+
const every = Math.max(1, Math.ceil(span / (30 * DAY) / count));
|
|
59
|
+
while (d.getTime() <= max) {
|
|
60
|
+
if (d.getTime() >= min)
|
|
61
|
+
months.push(d.getTime());
|
|
62
|
+
d.setUTCMonth(d.getUTCMonth() + every);
|
|
63
|
+
}
|
|
64
|
+
return { ticks: months, format: fmt(span > 400 * DAY ? { month: 'short', year: 'numeric' } : { month: 'short' }) };
|
|
65
|
+
}
|
|
66
|
+
function stepTicks(min, max, step) {
|
|
67
|
+
const out = [];
|
|
68
|
+
for (let t = Math.ceil(min / step) * step; t <= max; t += step)
|
|
69
|
+
out.push(t);
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
/** A readable label for an x value in tooltips and tables. */
|
|
73
|
+
export function formatX(v, time) {
|
|
74
|
+
if (!time)
|
|
75
|
+
return v instanceof Date ? v.toISOString() : String(v);
|
|
76
|
+
const t = v instanceof Date ? v.getTime() : typeof v === 'number' ? v : Date.parse(v.length === 10 ? v + 'T00:00:00Z' : v);
|
|
77
|
+
const d = new Date(t);
|
|
78
|
+
const hasTime = d.getUTCHours() || d.getUTCMinutes();
|
|
79
|
+
return new Intl.DateTimeFormat(undefined, { timeZone: 'UTC', dateStyle: 'medium', ...(hasTime ? { timeStyle: 'short' } : {}) }).format(d);
|
|
80
|
+
}
|
|
81
|
+
/** An estimate of how wide a label is, for margins; the charts' text is 12px. */
|
|
82
|
+
export const textWidth = (s) => s.length * 6.6;
|
|
83
|
+
/** Array.prototype.findLastIndex, for older targets. */
|
|
84
|
+
export function lastIndex(a, ok) {
|
|
85
|
+
for (let i = a.length - 1; i >= 0; i--)
|
|
86
|
+
if (ok(a[i]))
|
|
87
|
+
return i;
|
|
88
|
+
return -1;
|
|
89
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type ISODate = string;
|
|
2
|
+
export declare function parse(iso: ISODate): Date;
|
|
3
|
+
export declare function iso(d: Date): ISODate;
|
|
4
|
+
export declare function today(): ISODate;
|
|
5
|
+
export declare function addDays(date: ISODate, n: number): ISODate;
|
|
6
|
+
/** Adds months, keeping the day where the month has it, else its last day. */
|
|
7
|
+
export declare function addMonths(date: ISODate, n: number): ISODate;
|
|
8
|
+
export declare function startOfMonth(date: ISODate): ISODate;
|
|
9
|
+
/** The weeks shown for date's month, each 7 ISO dates, starting on weekStart (0 = Sunday). */
|
|
10
|
+
export declare function monthGrid(date: ISODate, weekStart: number): ISODate[][];
|
|
11
|
+
/** The first day of the week for a locale, from Intl where the browser knows it. */
|
|
12
|
+
export declare function localeWeekStart(locale?: string): number;
|
|
13
|
+
export declare function format(date: ISODate, locale: string | undefined, options: Intl.DateTimeFormatOptions): string;
|
package/dist/ui/dates.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Calendar dates as ISO strings ("2026-11-10"), done in UTC so time zones
|
|
2
|
+
// and daylight saving never move a day.
|
|
3
|
+
export function parse(iso) {
|
|
4
|
+
const [y, m, d] = iso.split('-').map(Number);
|
|
5
|
+
return new Date(Date.UTC(y, (m ?? 1) - 1, d ?? 1));
|
|
6
|
+
}
|
|
7
|
+
export function iso(d) {
|
|
8
|
+
return d.toISOString().slice(0, 10);
|
|
9
|
+
}
|
|
10
|
+
export function today() {
|
|
11
|
+
const n = new Date();
|
|
12
|
+
return iso(new Date(Date.UTC(n.getFullYear(), n.getMonth(), n.getDate())));
|
|
13
|
+
}
|
|
14
|
+
export function addDays(date, n) {
|
|
15
|
+
const d = parse(date);
|
|
16
|
+
d.setUTCDate(d.getUTCDate() + n);
|
|
17
|
+
return iso(d);
|
|
18
|
+
}
|
|
19
|
+
/** Adds months, keeping the day where the month has it, else its last day. */
|
|
20
|
+
export function addMonths(date, n) {
|
|
21
|
+
const d = parse(date);
|
|
22
|
+
const day = d.getUTCDate();
|
|
23
|
+
d.setUTCDate(1);
|
|
24
|
+
d.setUTCMonth(d.getUTCMonth() + n);
|
|
25
|
+
const last = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + 1, 0)).getUTCDate();
|
|
26
|
+
d.setUTCDate(Math.min(day, last));
|
|
27
|
+
return iso(d);
|
|
28
|
+
}
|
|
29
|
+
export function startOfMonth(date) {
|
|
30
|
+
return date.slice(0, 8) + '01';
|
|
31
|
+
}
|
|
32
|
+
/** The weeks shown for date's month, each 7 ISO dates, starting on weekStart (0 = Sunday). */
|
|
33
|
+
export function monthGrid(date, weekStart) {
|
|
34
|
+
const first = parse(startOfMonth(date));
|
|
35
|
+
const lead = (first.getUTCDay() - weekStart + 7) % 7;
|
|
36
|
+
let day = addDays(iso(first), -lead);
|
|
37
|
+
const weeks = [];
|
|
38
|
+
const month = date.slice(0, 7);
|
|
39
|
+
do {
|
|
40
|
+
const week = [];
|
|
41
|
+
for (let i = 0; i < 7; i++) {
|
|
42
|
+
week.push(day);
|
|
43
|
+
day = addDays(day, 1);
|
|
44
|
+
}
|
|
45
|
+
weeks.push(week);
|
|
46
|
+
} while (day.slice(0, 7) === month);
|
|
47
|
+
return weeks;
|
|
48
|
+
}
|
|
49
|
+
/** The first day of the week for a locale, from Intl where the browser knows it. */
|
|
50
|
+
export function localeWeekStart(locale) {
|
|
51
|
+
try {
|
|
52
|
+
const loc = new Intl.Locale(locale ?? navigator.language);
|
|
53
|
+
const info = loc.getWeekInfo?.() ?? loc.weekInfo;
|
|
54
|
+
if (info)
|
|
55
|
+
return info.firstDay % 7;
|
|
56
|
+
return ['US', 'CA', 'JP', 'BR', 'IL', 'MX', 'PH', 'KR', 'TW', 'IN'].includes(loc.maximize().region ?? '') ? 0 : 1;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return 1;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export function format(date, locale, options) {
|
|
63
|
+
return new Intl.DateTimeFormat(locale, { timeZone: 'UTC', ...options }).format(parse(date));
|
|
64
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** What a Field tells the control inside it, so labels and messages are wired up. */
|
|
2
|
+
export interface FieldContext {
|
|
3
|
+
readonly id: string;
|
|
4
|
+
/** The label's id, for controls that aren't labelable elements and need aria-labelledby. */
|
|
5
|
+
readonly labelId: string;
|
|
6
|
+
readonly describedBy: string | undefined;
|
|
7
|
+
readonly invalid: boolean;
|
|
8
|
+
readonly required: boolean;
|
|
9
|
+
readonly disabled: boolean;
|
|
10
|
+
/** Custom controls call this: the label then focuses the element with the field's id instead of using for. */
|
|
11
|
+
custom(): void;
|
|
12
|
+
/** The name the control posts under, from the Field. */
|
|
13
|
+
readonly name: string | undefined;
|
|
14
|
+
/** What was posted before, to refill the control after a failed post. */
|
|
15
|
+
readonly value: string | undefined;
|
|
16
|
+
}
|
|
17
|
+
export declare function setField(ctx: FieldContext): void;
|
|
18
|
+
export declare function getField(): FieldContext | undefined;
|
package/dist/ui/field.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export type Side = 'top' | 'bottom' | 'left' | 'right';
|
|
2
|
+
export type Align = 'start' | 'center' | 'end';
|
|
3
|
+
export type FloatingOptions = {
|
|
4
|
+
side?: Side;
|
|
5
|
+
align?: Align;
|
|
6
|
+
/** The gap between the anchor and the floating element, in pixels. */
|
|
7
|
+
offset?: number;
|
|
8
|
+
/** The space kept free at the viewport's edges, in pixels. */
|
|
9
|
+
padding?: number;
|
|
10
|
+
/** Make the floating element at least as wide as the anchor. */
|
|
11
|
+
matchWidth?: boolean;
|
|
12
|
+
};
|
|
13
|
+
type Rect = {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
width: number;
|
|
17
|
+
height: number;
|
|
18
|
+
};
|
|
19
|
+
/** Computes where the floating element goes. Exported for tests. */
|
|
20
|
+
export declare function compute(anchor: Rect, size: {
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
}, viewport: {
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
}, o?: FloatingOptions): {
|
|
27
|
+
x: number;
|
|
28
|
+
y: number;
|
|
29
|
+
side: Side;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Keeps el next to anchor while it is shown: on scroll, resize and size
|
|
33
|
+
* changes. Returns a function that stops. el gets data-side with the side
|
|
34
|
+
* it ended up on, for styles.
|
|
35
|
+
*/
|
|
36
|
+
export declare function float(el: HTMLElement, anchor: Element | {
|
|
37
|
+
x: number;
|
|
38
|
+
y: number;
|
|
39
|
+
}, o?: FloatingOptions): () => void;
|
|
40
|
+
/** The elements inside root that can take focus, in order. */
|
|
41
|
+
export declare function focusables(root: Element): HTMLElement[];
|
|
42
|
+
/** Keeps Tab inside root, as modal dialogs need. Call it from keydown. */
|
|
43
|
+
export declare function trapTab(root: Element, e: KeyboardEvent): void;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// Positions a floating element (a popover, menu or tooltip) next to an
|
|
2
|
+
// anchor element or a point, flipping to the other side and shifting along
|
|
3
|
+
// it to stay in the viewport. The floating element is position: fixed,
|
|
4
|
+
// usually in the top layer through the Popover API.
|
|
5
|
+
const opposite = { top: 'bottom', bottom: 'top', left: 'right', right: 'left' };
|
|
6
|
+
/** Computes where the floating element goes. Exported for tests. */
|
|
7
|
+
export function compute(anchor, size, viewport, o = {}) {
|
|
8
|
+
const { side = 'bottom', align = 'start', offset = 6, padding = 8 } = o;
|
|
9
|
+
const place = (s) => {
|
|
10
|
+
const vertical = s === 'top' || s === 'bottom';
|
|
11
|
+
let x;
|
|
12
|
+
let y;
|
|
13
|
+
if (vertical) {
|
|
14
|
+
y = s === 'bottom' ? anchor.y + anchor.height + offset : anchor.y - size.height - offset;
|
|
15
|
+
x = align === 'start' ? anchor.x : align === 'end' ? anchor.x + anchor.width - size.width : anchor.x + (anchor.width - size.width) / 2;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
x = s === 'right' ? anchor.x + anchor.width + offset : anchor.x - size.width - offset;
|
|
19
|
+
y = align === 'start' ? anchor.y : align === 'end' ? anchor.y + anchor.height - size.height : anchor.y + (anchor.height - size.height) / 2;
|
|
20
|
+
}
|
|
21
|
+
return { x, y };
|
|
22
|
+
};
|
|
23
|
+
const fits = (s, p) => s === 'bottom' ? p.y + size.height <= viewport.height - padding : s === 'top' ? p.y >= padding : s === 'right' ? p.x + size.width <= viewport.width - padding : p.x >= padding;
|
|
24
|
+
let chosen = side;
|
|
25
|
+
let p = place(side);
|
|
26
|
+
if (!fits(side, p)) {
|
|
27
|
+
const q = place(opposite[side]);
|
|
28
|
+
if (fits(opposite[side], q)) {
|
|
29
|
+
chosen = opposite[side];
|
|
30
|
+
p = q;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Shift along the side to stay on screen.
|
|
34
|
+
const clamp = (v, min, max) => Math.max(min, Math.min(v, Math.max(min, max)));
|
|
35
|
+
p.x = clamp(p.x, padding, viewport.width - size.width - padding);
|
|
36
|
+
p.y = clamp(p.y, padding, viewport.height - size.height - padding);
|
|
37
|
+
return { x: Math.round(p.x), y: Math.round(p.y), side: chosen };
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Keeps el next to anchor while it is shown: on scroll, resize and size
|
|
41
|
+
* changes. Returns a function that stops. el gets data-side with the side
|
|
42
|
+
* it ended up on, for styles.
|
|
43
|
+
*/
|
|
44
|
+
export function float(el, anchor, o = {}) {
|
|
45
|
+
el.style.position = 'fixed';
|
|
46
|
+
el.style.margin = '0';
|
|
47
|
+
el.style.inset = 'auto';
|
|
48
|
+
const update = () => {
|
|
49
|
+
const r = anchor instanceof Element ? anchor.getBoundingClientRect() : { x: anchor.x, y: anchor.y, width: 0, height: 0 };
|
|
50
|
+
if (o.matchWidth)
|
|
51
|
+
el.style.minWidth = `${r.width}px`;
|
|
52
|
+
const pos = compute(r, { width: el.offsetWidth, height: el.offsetHeight }, { width: document.documentElement.clientWidth, height: window.innerHeight }, o);
|
|
53
|
+
el.style.left = `${pos.x}px`;
|
|
54
|
+
el.style.top = `${pos.y}px`;
|
|
55
|
+
el.dataset.side = pos.side;
|
|
56
|
+
};
|
|
57
|
+
update();
|
|
58
|
+
let frame = 0;
|
|
59
|
+
const schedule = () => {
|
|
60
|
+
cancelAnimationFrame(frame);
|
|
61
|
+
frame = requestAnimationFrame(update);
|
|
62
|
+
};
|
|
63
|
+
window.addEventListener('scroll', schedule, { capture: true, passive: true });
|
|
64
|
+
window.addEventListener('resize', schedule);
|
|
65
|
+
const ro = new ResizeObserver(schedule);
|
|
66
|
+
ro.observe(el);
|
|
67
|
+
if (anchor instanceof Element)
|
|
68
|
+
ro.observe(anchor);
|
|
69
|
+
return () => {
|
|
70
|
+
cancelAnimationFrame(frame);
|
|
71
|
+
window.removeEventListener('scroll', schedule, { capture: true });
|
|
72
|
+
window.removeEventListener('resize', schedule);
|
|
73
|
+
ro.disconnect();
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/** The elements inside root that can take focus, in order. */
|
|
77
|
+
export function focusables(root) {
|
|
78
|
+
return Array.from(root.querySelectorAll('a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter((el) => el.offsetParent !== null || el === document.activeElement);
|
|
79
|
+
}
|
|
80
|
+
/** Keeps Tab inside root, as modal dialogs need. Call it from keydown. */
|
|
81
|
+
export function trapTab(root, e) {
|
|
82
|
+
if (e.key !== 'Tab')
|
|
83
|
+
return;
|
|
84
|
+
const list = focusables(root);
|
|
85
|
+
if (list.length === 0)
|
|
86
|
+
return;
|
|
87
|
+
const first = list[0];
|
|
88
|
+
const last = list[list.length - 1];
|
|
89
|
+
if (e.shiftKey && document.activeElement === first) {
|
|
90
|
+
e.preventDefault();
|
|
91
|
+
last.focus();
|
|
92
|
+
}
|
|
93
|
+
else if (!e.shiftKey && document.activeElement === last) {
|
|
94
|
+
e.preventDefault();
|
|
95
|
+
first.focus();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FormField } from '../runtime/validate.js';
|
|
2
|
+
/** What a Form tells the Fields and controls inside it. */
|
|
3
|
+
export interface FormContext {
|
|
4
|
+
/** The message to show for a field, from the browser's checks or the server. */
|
|
5
|
+
error(name: string): string | undefined;
|
|
6
|
+
/** What was posted before, to refill a field after a failure without JavaScript. */
|
|
7
|
+
value(name: string): string | undefined;
|
|
8
|
+
/** A field's rules, such as whether it's required. */
|
|
9
|
+
field(name: string): FormField | undefined;
|
|
10
|
+
}
|
|
11
|
+
export declare function setForm(ctx: FormContext): void;
|
|
12
|
+
export declare function getForm(): FormContext | undefined;
|
package/dist/ui/form.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export { default as Accordion } from './Accordion.svelte';
|
|
2
|
+
export { default as Alert } from './Alert.svelte';
|
|
3
|
+
export { default as AlertDialog } from './AlertDialog.svelte';
|
|
4
|
+
export { default as AreaChart } from './AreaChart.svelte';
|
|
5
|
+
export { default as AspectRatio } from './AspectRatio.svelte';
|
|
6
|
+
export { default as Avatar } from './Avatar.svelte';
|
|
7
|
+
export { default as Badge } from './Badge.svelte';
|
|
8
|
+
export { default as BarChart } from './BarChart.svelte';
|
|
9
|
+
export { default as Breadcrumb } from './Breadcrumb.svelte';
|
|
10
|
+
export { default as Button } from './Button.svelte';
|
|
11
|
+
export { default as ButtonGroup } from './ButtonGroup.svelte';
|
|
12
|
+
export { default as Calendar } from './Calendar.svelte';
|
|
13
|
+
export { default as Card } from './Card.svelte';
|
|
14
|
+
export { default as Carousel } from './Carousel.svelte';
|
|
15
|
+
export { default as Checkbox } from './Checkbox.svelte';
|
|
16
|
+
export { default as Collapsible } from './Collapsible.svelte';
|
|
17
|
+
export { default as Combobox } from './Combobox.svelte';
|
|
18
|
+
export { default as Command } from './Command.svelte';
|
|
19
|
+
export { default as ConsentScreen } from './ConsentScreen.svelte';
|
|
20
|
+
export { default as ContextMenu } from './ContextMenu.svelte';
|
|
21
|
+
export { default as DataTable } from './DataTable.svelte';
|
|
22
|
+
export { default as DatePicker } from './DatePicker.svelte';
|
|
23
|
+
export { default as Dialog } from './Dialog.svelte';
|
|
24
|
+
export { default as DonutChart } from './DonutChart.svelte';
|
|
25
|
+
export { default as Drawer } from './Drawer.svelte';
|
|
26
|
+
export { default as Empty } from './Empty.svelte';
|
|
27
|
+
export { default as Field } from './Field.svelte';
|
|
28
|
+
export { default as Form } from './Form.svelte';
|
|
29
|
+
export { default as HoverCard } from './HoverCard.svelte';
|
|
30
|
+
export { default as Input } from './Input.svelte';
|
|
31
|
+
export { default as InputGroup } from './InputGroup.svelte';
|
|
32
|
+
export { default as InputOTP } from './InputOTP.svelte';
|
|
33
|
+
export { default as Item } from './Item.svelte';
|
|
34
|
+
export { default as Kbd } from './Kbd.svelte';
|
|
35
|
+
export { default as Label } from './Label.svelte';
|
|
36
|
+
export { default as LineChart } from './LineChart.svelte';
|
|
37
|
+
export { default as Menu } from './Menu.svelte';
|
|
38
|
+
export { default as Menubar } from './Menubar.svelte';
|
|
39
|
+
export { default as NavigationMenu } from './NavigationMenu.svelte';
|
|
40
|
+
export { default as Pagination } from './Pagination.svelte';
|
|
41
|
+
export { default as PasswordInput } from './PasswordInput.svelte';
|
|
42
|
+
export { default as Popover } from './Popover.svelte';
|
|
43
|
+
export { default as Progress } from './Progress.svelte';
|
|
44
|
+
export { default as RadioGroup } from './RadioGroup.svelte';
|
|
45
|
+
export { default as Resizable } from './Resizable.svelte';
|
|
46
|
+
export { default as ScrollArea } from './ScrollArea.svelte';
|
|
47
|
+
export { default as Select } from './Select.svelte';
|
|
48
|
+
export { default as SelectMenu } from './SelectMenu.svelte';
|
|
49
|
+
export { default as Separator } from './Separator.svelte';
|
|
50
|
+
export { default as Sheet } from './Sheet.svelte';
|
|
51
|
+
export { default as Sidebar } from './Sidebar.svelte';
|
|
52
|
+
export { default as SignIn } from './SignIn.svelte';
|
|
53
|
+
export { default as SignUp } from './SignUp.svelte';
|
|
54
|
+
export { default as Skeleton } from './Skeleton.svelte';
|
|
55
|
+
export { default as Slider } from './Slider.svelte';
|
|
56
|
+
export { default as Sparkline } from './Sparkline.svelte';
|
|
57
|
+
export { default as Spinner } from './Spinner.svelte';
|
|
58
|
+
export { default as Stat } from './Stat.svelte';
|
|
59
|
+
export { default as Switch } from './Switch.svelte';
|
|
60
|
+
export { default as Table } from './Table.svelte';
|
|
61
|
+
export { default as Tabs } from './Tabs.svelte';
|
|
62
|
+
export { default as Textarea } from './Textarea.svelte';
|
|
63
|
+
export { default as Toaster } from './Toaster.svelte';
|
|
64
|
+
export { default as Toggle } from './Toggle.svelte';
|
|
65
|
+
export { default as ToggleGroup } from './ToggleGroup.svelte';
|
|
66
|
+
export { default as Tooltip } from './Tooltip.svelte';
|
|
67
|
+
export { dismiss, toast, toasts, type Toast, type Tone } from './toast.svelte.js';
|
|
68
|
+
export type { MenuItem } from './menu.js';
|
|
69
|
+
export type { Align, Side } from './floating.js';
|
|
70
|
+
export type { Option } from './options.js';
|
|
71
|
+
export type { ISODate } from './dates.js';
|
|
72
|
+
export type { DateRange } from './Calendar.svelte';
|
|
73
|
+
export type { CommandItem } from './Command.svelte';
|
|
74
|
+
export type { PopoverTrigger } from './Popover.svelte';
|
|
75
|
+
export type { HoverCardTrigger } from './HoverCard.svelte';
|
|
76
|
+
export type { Column, DataQuery } from './table.js';
|
|
77
|
+
export type { SidebarGroup, SidebarLink } from './Sidebar.svelte';
|
|
78
|
+
export type { Series } from './chart.js';
|
package/dist/ui/index.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Tern UI: accessible Svelte 5 components with Tern's own look. Import the
|
|
2
|
+
// theme once (import '@ternkit/tern/ui/theme.css') and the components where
|
|
3
|
+
// you use them. See docs/ui.md.
|
|
4
|
+
export { default as Accordion } from './Accordion.svelte';
|
|
5
|
+
export { default as Alert } from './Alert.svelte';
|
|
6
|
+
export { default as AlertDialog } from './AlertDialog.svelte';
|
|
7
|
+
export { default as AreaChart } from './AreaChart.svelte';
|
|
8
|
+
export { default as AspectRatio } from './AspectRatio.svelte';
|
|
9
|
+
export { default as Avatar } from './Avatar.svelte';
|
|
10
|
+
export { default as Badge } from './Badge.svelte';
|
|
11
|
+
export { default as BarChart } from './BarChart.svelte';
|
|
12
|
+
export { default as Breadcrumb } from './Breadcrumb.svelte';
|
|
13
|
+
export { default as Button } from './Button.svelte';
|
|
14
|
+
export { default as ButtonGroup } from './ButtonGroup.svelte';
|
|
15
|
+
export { default as Calendar } from './Calendar.svelte';
|
|
16
|
+
export { default as Card } from './Card.svelte';
|
|
17
|
+
export { default as Carousel } from './Carousel.svelte';
|
|
18
|
+
export { default as Checkbox } from './Checkbox.svelte';
|
|
19
|
+
export { default as Collapsible } from './Collapsible.svelte';
|
|
20
|
+
export { default as Combobox } from './Combobox.svelte';
|
|
21
|
+
export { default as Command } from './Command.svelte';
|
|
22
|
+
export { default as ConsentScreen } from './ConsentScreen.svelte';
|
|
23
|
+
export { default as ContextMenu } from './ContextMenu.svelte';
|
|
24
|
+
export { default as DataTable } from './DataTable.svelte';
|
|
25
|
+
export { default as DatePicker } from './DatePicker.svelte';
|
|
26
|
+
export { default as Dialog } from './Dialog.svelte';
|
|
27
|
+
export { default as DonutChart } from './DonutChart.svelte';
|
|
28
|
+
export { default as Drawer } from './Drawer.svelte';
|
|
29
|
+
export { default as Empty } from './Empty.svelte';
|
|
30
|
+
export { default as Field } from './Field.svelte';
|
|
31
|
+
export { default as Form } from './Form.svelte';
|
|
32
|
+
export { default as HoverCard } from './HoverCard.svelte';
|
|
33
|
+
export { default as Input } from './Input.svelte';
|
|
34
|
+
export { default as InputGroup } from './InputGroup.svelte';
|
|
35
|
+
export { default as InputOTP } from './InputOTP.svelte';
|
|
36
|
+
export { default as Item } from './Item.svelte';
|
|
37
|
+
export { default as Kbd } from './Kbd.svelte';
|
|
38
|
+
export { default as Label } from './Label.svelte';
|
|
39
|
+
export { default as LineChart } from './LineChart.svelte';
|
|
40
|
+
export { default as Menu } from './Menu.svelte';
|
|
41
|
+
export { default as Menubar } from './Menubar.svelte';
|
|
42
|
+
export { default as NavigationMenu } from './NavigationMenu.svelte';
|
|
43
|
+
export { default as Pagination } from './Pagination.svelte';
|
|
44
|
+
export { default as PasswordInput } from './PasswordInput.svelte';
|
|
45
|
+
export { default as Popover } from './Popover.svelte';
|
|
46
|
+
export { default as Progress } from './Progress.svelte';
|
|
47
|
+
export { default as RadioGroup } from './RadioGroup.svelte';
|
|
48
|
+
export { default as Resizable } from './Resizable.svelte';
|
|
49
|
+
export { default as ScrollArea } from './ScrollArea.svelte';
|
|
50
|
+
export { default as Select } from './Select.svelte';
|
|
51
|
+
export { default as SelectMenu } from './SelectMenu.svelte';
|
|
52
|
+
export { default as Separator } from './Separator.svelte';
|
|
53
|
+
export { default as Sheet } from './Sheet.svelte';
|
|
54
|
+
export { default as Sidebar } from './Sidebar.svelte';
|
|
55
|
+
export { default as SignIn } from './SignIn.svelte';
|
|
56
|
+
export { default as SignUp } from './SignUp.svelte';
|
|
57
|
+
export { default as Skeleton } from './Skeleton.svelte';
|
|
58
|
+
export { default as Slider } from './Slider.svelte';
|
|
59
|
+
export { default as Sparkline } from './Sparkline.svelte';
|
|
60
|
+
export { default as Spinner } from './Spinner.svelte';
|
|
61
|
+
export { default as Stat } from './Stat.svelte';
|
|
62
|
+
export { default as Switch } from './Switch.svelte';
|
|
63
|
+
export { default as Table } from './Table.svelte';
|
|
64
|
+
export { default as Tabs } from './Tabs.svelte';
|
|
65
|
+
export { default as Textarea } from './Textarea.svelte';
|
|
66
|
+
export { default as Toaster } from './Toaster.svelte';
|
|
67
|
+
export { default as Toggle } from './Toggle.svelte';
|
|
68
|
+
export { default as ToggleGroup } from './ToggleGroup.svelte';
|
|
69
|
+
export { default as Tooltip } from './Tooltip.svelte';
|
|
70
|
+
export { dismiss, toast, toasts } from './toast.svelte.js';
|