@xtyle/astro 0.5.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/README.md +42 -0
- package/package.json +25 -0
- package/src/Accordion.astro +79 -0
- package/src/Alert.astro +57 -0
- package/src/AppShell.astro +97 -0
- package/src/Avatar.astro +71 -0
- package/src/AvatarGroup.astro +44 -0
- package/src/Badge.astro +73 -0
- package/src/Bar.astro +83 -0
- package/src/Breadcrumb.astro +54 -0
- package/src/Button.astro +91 -0
- package/src/Card.astro +44 -0
- package/src/CardLink.astro +60 -0
- package/src/Carousel.astro +39 -0
- package/src/Checkbox.astro +68 -0
- package/src/CheckboxGroup.astro +54 -0
- package/src/Cluster.astro +46 -0
- package/src/Code.astro +42 -0
- package/src/ColorPicker.astro +184 -0
- package/src/Dialog.astro +69 -0
- package/src/Dock.astro +79 -0
- package/src/DockZone.astro +17 -0
- package/src/Eyebrow.astro +30 -0
- package/src/Field.astro +117 -0
- package/src/FormGroup.astro +71 -0
- package/src/Grid.astro +57 -0
- package/src/Heading.astro +34 -0
- package/src/Heatmap.astro +116 -0
- package/src/Hero.astro +19 -0
- package/src/Icon.astro +53 -0
- package/src/Image.astro +56 -0
- package/src/Kbd.astro +27 -0
- package/src/Link.astro +56 -0
- package/src/Menu.astro +38 -0
- package/src/NumberInput.astro +86 -0
- package/src/Pagination.astro +53 -0
- package/src/Panel.astro +68 -0
- package/src/Parallax.astro +18 -0
- package/src/Pie.astro +65 -0
- package/src/Progress.astro +96 -0
- package/src/Radio.astro +71 -0
- package/src/RadioGroup.astro +44 -0
- package/src/Section.astro +61 -0
- package/src/Segment.astro +15 -0
- package/src/Segmented.astro +95 -0
- package/src/Select.astro +79 -0
- package/src/Separator.astro +36 -0
- package/src/Skeleton.astro +25 -0
- package/src/Slider.astro +93 -0
- package/src/Sparkline.astro +79 -0
- package/src/Spinner.astro +37 -0
- package/src/Splitter.astro +87 -0
- package/src/Stack.astro +42 -0
- package/src/Stat.astro +70 -0
- package/src/Statusbar.astro +56 -0
- package/src/Swatch.astro +69 -0
- package/src/Switch.astro +89 -0
- package/src/Table.astro +46 -0
- package/src/Tabs.astro +94 -0
- package/src/Text.astro +54 -0
- package/src/Textarea.astro +81 -0
- package/src/Toast.astro +62 -0
- package/src/ToastRegion.astro +39 -0
- package/src/Toc.astro +35 -0
- package/src/Toolbar.astro +68 -0
- package/src/Tooltip.astro +68 -0
- package/src/Tree.astro +78 -0
- package/src/internal/palette.ts +92 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { normalizeSegments } from "@xtyle/core/markup";
|
|
3
|
+
import { renderFragmentLight } from "@xtyle/core/elements/ssr";
|
|
4
|
+
|
|
5
|
+
import type { FullTone as Tone } from "@xtyle/core";
|
|
6
|
+
type Size = "sm" | "md" | "lg";
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
value?: string;
|
|
10
|
+
options?: string | ReadonlyArray<string | { value: string; label?: string; disabled?: boolean; badge?: string }>;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
size?: Size;
|
|
13
|
+
tone?: Tone;
|
|
14
|
+
label?: string;
|
|
15
|
+
labelledby?: string;
|
|
16
|
+
name?: string;
|
|
17
|
+
/** Render zero-JS: emit the resolved light-DOM markup but never load the runtime to hydrate it. */
|
|
18
|
+
static?: boolean;
|
|
19
|
+
class?: string;
|
|
20
|
+
/** Any other attribute (`id`, `title`, `data-*`, `aria-*`, …) passes through to the element. */
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const {
|
|
25
|
+
value,
|
|
26
|
+
options,
|
|
27
|
+
disabled = false,
|
|
28
|
+
size = "md",
|
|
29
|
+
tone = "accent",
|
|
30
|
+
label,
|
|
31
|
+
labelledby,
|
|
32
|
+
"aria-label": ariaLabel,
|
|
33
|
+
name,
|
|
34
|
+
static: isStatic = false,
|
|
35
|
+
class: extra,
|
|
36
|
+
...rest
|
|
37
|
+
} = Astro.props;
|
|
38
|
+
|
|
39
|
+
const elementId = `xtyle-segmented-${Math.random().toString(36).slice(2, 8)}`;
|
|
40
|
+
const segments = normalizeSegments(options);
|
|
41
|
+
const optionsAttr = typeof options === "string" ? options : options ? JSON.stringify(options) : undefined;
|
|
42
|
+
|
|
43
|
+
// Two authoring modes, mirroring Tabs. The `options` bar renders its whole chrome light from `bindings`
|
|
44
|
+
// and ships no children (the zero-JS SSR path). The rich-content mode pairs `<Segment>` children by
|
|
45
|
+
// order — live framework markup that can't be snapshotted — so it passes them through untouched and the
|
|
46
|
+
// element projects them on connect (shadow `<slot>`, client-hydrated).
|
|
47
|
+
const useSlotted = Astro.slots.has("default");
|
|
48
|
+
|
|
49
|
+
const bindings = {
|
|
50
|
+
segments,
|
|
51
|
+
value: value ?? null,
|
|
52
|
+
disabled,
|
|
53
|
+
size,
|
|
54
|
+
tone,
|
|
55
|
+
label: label ?? null,
|
|
56
|
+
labelledby: labelledby ?? null,
|
|
57
|
+
ariaLabel: ariaLabel ?? null,
|
|
58
|
+
elementId,
|
|
59
|
+
};
|
|
60
|
+
const light = useSlotted ? "" : await renderFragmentLight("segmented", bindings);
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
{useSlotted ? (
|
|
64
|
+
<xtyle-segmented
|
|
65
|
+
value={value}
|
|
66
|
+
disabled={disabled || undefined}
|
|
67
|
+
size={size}
|
|
68
|
+
tone={tone}
|
|
69
|
+
label={label}
|
|
70
|
+
labelledby={labelledby}
|
|
71
|
+
aria-label={ariaLabel}
|
|
72
|
+
name={name}
|
|
73
|
+
class={extra}
|
|
74
|
+
{...rest}
|
|
75
|
+
>
|
|
76
|
+
<slot />
|
|
77
|
+
</xtyle-segmented>
|
|
78
|
+
) : (
|
|
79
|
+
<xtyle-segmented
|
|
80
|
+
value={value}
|
|
81
|
+
options={optionsAttr}
|
|
82
|
+
disabled={disabled || undefined}
|
|
83
|
+
size={size}
|
|
84
|
+
tone={tone}
|
|
85
|
+
label={label}
|
|
86
|
+
labelledby={labelledby}
|
|
87
|
+
aria-label={ariaLabel}
|
|
88
|
+
name={name}
|
|
89
|
+
class={extra}
|
|
90
|
+
{...rest}
|
|
91
|
+
set:html={light}
|
|
92
|
+
/>
|
|
93
|
+
)}
|
|
94
|
+
|
|
95
|
+
{!isStatic && <script>import "@xtyle/core/elements";</script>}
|
package/src/Select.astro
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { renderFragmentLight } from "@xtyle/core/elements/ssr";
|
|
3
|
+
|
|
4
|
+
type Size = "sm" | "md" | "lg";
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
label?: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
value?: string;
|
|
10
|
+
size?: Size;
|
|
11
|
+
invalid?: boolean;
|
|
12
|
+
error?: string;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
required?: boolean;
|
|
15
|
+
ariaLabel?: string;
|
|
16
|
+
/** Render zero-JS: emit the resolved light-DOM markup but never load the runtime to hydrate it. */
|
|
17
|
+
static?: boolean;
|
|
18
|
+
class?: string;
|
|
19
|
+
/** Any other attribute (`id`, `title`, `data-*`, `aria-*`, …) passes through to the element. */
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const {
|
|
24
|
+
label,
|
|
25
|
+
name,
|
|
26
|
+
value,
|
|
27
|
+
size = "md",
|
|
28
|
+
invalid = false,
|
|
29
|
+
error,
|
|
30
|
+
disabled = false,
|
|
31
|
+
required = false,
|
|
32
|
+
ariaLabel,
|
|
33
|
+
static: isStatic = false,
|
|
34
|
+
class: extra,
|
|
35
|
+
...rest
|
|
36
|
+
} = Astro.props;
|
|
37
|
+
|
|
38
|
+
const fieldId = `xtyle-select-${Math.random().toString(36).slice(2, 9)}`;
|
|
39
|
+
const errorId = `${fieldId}-error`;
|
|
40
|
+
|
|
41
|
+
// The consumer's `<option>`/`<optgroup>` children populate the rendered `<select>` (via
|
|
42
|
+
// `bindings.optionsHtml`) AND ride along as hidden light-DOM children after the chrome, so the
|
|
43
|
+
// element can re-read them on a rebuild. `xtyle-select > option` is `display:none` (see
|
|
44
|
+
// `hostDisplayCss`), so the bare copies never show.
|
|
45
|
+
const optionsHtml = Astro.slots.has("default") ? await Astro.slots.render("default") : "";
|
|
46
|
+
|
|
47
|
+
const bindings = {
|
|
48
|
+
label: label ?? null,
|
|
49
|
+
value: value ?? null,
|
|
50
|
+
size,
|
|
51
|
+
disabled,
|
|
52
|
+
invalid,
|
|
53
|
+
required,
|
|
54
|
+
error: error ?? null,
|
|
55
|
+
name: name ?? null,
|
|
56
|
+
fieldId,
|
|
57
|
+
errorId,
|
|
58
|
+
optionsHtml,
|
|
59
|
+
};
|
|
60
|
+
const light = await renderFragmentLight("select", bindings);
|
|
61
|
+
const composed = light + optionsHtml;
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
<xtyle-select
|
|
65
|
+
label={label}
|
|
66
|
+
value={value}
|
|
67
|
+
size={size}
|
|
68
|
+
name={name}
|
|
69
|
+
disabled={disabled || undefined}
|
|
70
|
+
invalid={invalid || undefined}
|
|
71
|
+
required={required || undefined}
|
|
72
|
+
error={error}
|
|
73
|
+
aria-label={ariaLabel}
|
|
74
|
+
class={extra}
|
|
75
|
+
set:html={composed}
|
|
76
|
+
{...rest}
|
|
77
|
+
/>
|
|
78
|
+
|
|
79
|
+
{!isStatic && <script>import "@xtyle/core/elements";</script>}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { renderFragmentLight } from "@xtyle/core/elements/ssr";
|
|
3
|
+
|
|
4
|
+
type Orientation = "horizontal" | "vertical";
|
|
5
|
+
type SeparatorVariant = "default" | "with-label";
|
|
6
|
+
type SeparatorSize = "thin" | "normal";
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
orientation?: Orientation;
|
|
10
|
+
variant?: SeparatorVariant;
|
|
11
|
+
size?: SeparatorSize;
|
|
12
|
+
/** Render zero-JS: emit the resolved light-DOM markup but never load the runtime to hydrate it. */
|
|
13
|
+
static?: boolean;
|
|
14
|
+
class?: string;
|
|
15
|
+
/** Any other attribute (`id`, `title`, `data-*`, `aria-*`, …) passes through to the element. */
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
orientation = "horizontal",
|
|
21
|
+
variant = "default",
|
|
22
|
+
size = "normal",
|
|
23
|
+
static: isStatic = false,
|
|
24
|
+
class: extra,
|
|
25
|
+
...rest
|
|
26
|
+
} = Astro.props;
|
|
27
|
+
|
|
28
|
+
const bindings = { orientation, variant, size };
|
|
29
|
+
const chrome = await renderFragmentLight("separator", bindings);
|
|
30
|
+
const slotHtml = Astro.slots.has("default") ? await Astro.slots.render("default") : "";
|
|
31
|
+
const composed = chrome.replace("<slot></slot>", () => slotHtml);
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
<xtyle-separator orientation={orientation} variant={variant} size={size} class={extra} set:html={composed} {...rest} />
|
|
35
|
+
|
|
36
|
+
{!isStatic && <script>import "@xtyle/core/elements";</script>}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { renderFragmentLight } from "@xtyle/core/elements/ssr";
|
|
3
|
+
|
|
4
|
+
type SkeletonShape = "text" | "line" | "block" | "circle";
|
|
5
|
+
type Size = "sm" | "md" | "lg";
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
shape?: SkeletonShape;
|
|
9
|
+
size?: Size;
|
|
10
|
+
/** Render zero-JS: emit the resolved light-DOM markup but never load the runtime to hydrate it. */
|
|
11
|
+
static?: boolean;
|
|
12
|
+
class?: string;
|
|
13
|
+
/** Any other attribute (`id`, `title`, `data-*`, `aria-*`, …) passes through to the element. */
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const { shape = "text", size = "md", static: isStatic = false, class: extra, ...rest } = Astro.props;
|
|
18
|
+
|
|
19
|
+
const bindings = { shape, size };
|
|
20
|
+
const composed = await renderFragmentLight("skeleton", bindings);
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
<xtyle-skeleton shape={shape} size={size} class={extra} set:html={composed} {...rest} />
|
|
24
|
+
|
|
25
|
+
{!isStatic && <script>import "@xtyle/core/elements";</script>}
|
package/src/Slider.astro
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { renderFragmentLight } from "@xtyle/core/elements/ssr";
|
|
3
|
+
|
|
4
|
+
import type { FullTone as Tone } from "@xtyle/core";
|
|
5
|
+
type Size = "sm" | "md" | "lg";
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
value?: number;
|
|
9
|
+
min?: number;
|
|
10
|
+
max?: number;
|
|
11
|
+
step?: number;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
size?: Size;
|
|
14
|
+
tone?: Tone;
|
|
15
|
+
label?: string;
|
|
16
|
+
labelledby?: string;
|
|
17
|
+
name?: string;
|
|
18
|
+
showValue?: boolean;
|
|
19
|
+
hideLabel?: boolean;
|
|
20
|
+
/** Reset value for a double-click on the thumb. Defaults to the initial `value`. */
|
|
21
|
+
default?: number;
|
|
22
|
+
/** Disable click-to-edit on the shown value (it is on by default when `showValue` is set). */
|
|
23
|
+
staticValue?: boolean;
|
|
24
|
+
/** Render zero-JS: emit the resolved light-DOM markup but never load the runtime to hydrate it. */
|
|
25
|
+
static?: boolean;
|
|
26
|
+
class?: string;
|
|
27
|
+
/** Any other attribute (`id`, `title`, `data-*`, `aria-*`, …) passes through to the element. */
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const {
|
|
32
|
+
value = 0,
|
|
33
|
+
min = 0,
|
|
34
|
+
max = 100,
|
|
35
|
+
step = 1,
|
|
36
|
+
disabled = false,
|
|
37
|
+
size = "md",
|
|
38
|
+
tone = "accent",
|
|
39
|
+
label,
|
|
40
|
+
labelledby,
|
|
41
|
+
name,
|
|
42
|
+
showValue = false,
|
|
43
|
+
hideLabel = false,
|
|
44
|
+
default: defaultValue,
|
|
45
|
+
staticValue = false,
|
|
46
|
+
static: isStatic = false,
|
|
47
|
+
class: extra,
|
|
48
|
+
...rest
|
|
49
|
+
} = Astro.props;
|
|
50
|
+
|
|
51
|
+
const elementId = `xtyle-slider-${Math.random().toString(36).slice(2, 8)}`;
|
|
52
|
+
const editableValue = showValue && !staticValue;
|
|
53
|
+
|
|
54
|
+
const bindings = {
|
|
55
|
+
value,
|
|
56
|
+
min,
|
|
57
|
+
max,
|
|
58
|
+
step,
|
|
59
|
+
disabled,
|
|
60
|
+
size,
|
|
61
|
+
tone,
|
|
62
|
+
label: label ?? null,
|
|
63
|
+
labelledby: labelledby ?? null,
|
|
64
|
+
showValue,
|
|
65
|
+
hideLabel,
|
|
66
|
+
valueText: String(value),
|
|
67
|
+
elementId,
|
|
68
|
+
editableValue,
|
|
69
|
+
};
|
|
70
|
+
const light = await renderFragmentLight("slider", bindings);
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
<xtyle-slider
|
|
74
|
+
value={value}
|
|
75
|
+
min={min}
|
|
76
|
+
max={max}
|
|
77
|
+
step={step}
|
|
78
|
+
disabled={disabled || undefined}
|
|
79
|
+
size={size}
|
|
80
|
+
tone={tone}
|
|
81
|
+
label={label}
|
|
82
|
+
labelledby={labelledby}
|
|
83
|
+
name={name}
|
|
84
|
+
show-value={showValue || undefined}
|
|
85
|
+
hide-label={hideLabel || undefined}
|
|
86
|
+
default={defaultValue}
|
|
87
|
+
static-value={staticValue || undefined}
|
|
88
|
+
class={extra}
|
|
89
|
+
{...rest}
|
|
90
|
+
set:html={light}
|
|
91
|
+
/>
|
|
92
|
+
|
|
93
|
+
{!isStatic && <script>import "@xtyle/core/elements";</script>}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { renderFragmentLight } from "@xtyle/core/elements/ssr";
|
|
3
|
+
import { windowedPlot } from "@xtyle/core";
|
|
4
|
+
import type { SparklineVariant, SparklineTone, TimeSample } from "@xtyle/core";
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
values?: number[];
|
|
8
|
+
/** Time-windowed mode: timestamped points (`at` is epoch ms or a date string) placed on a real
|
|
9
|
+
* time axis instead of even spacing. Pass alongside `window` or `domain`. */
|
|
10
|
+
points?: TimeSample[];
|
|
11
|
+
/** The sliding window width in ms (default 5m), ending at now; ignored when `domain` is set. */
|
|
12
|
+
window?: number;
|
|
13
|
+
/** An explicit `[start, end]` x-axis span (epoch ms or date strings), instead of a sliding window. */
|
|
14
|
+
domain?: [number | string, number | string];
|
|
15
|
+
/** Render the line as a sample-and-hold step (for on/off or discrete series). */
|
|
16
|
+
step?: boolean;
|
|
17
|
+
variant?: SparklineVariant;
|
|
18
|
+
tone?: SparklineTone;
|
|
19
|
+
showEnd?: boolean;
|
|
20
|
+
min?: number;
|
|
21
|
+
max?: number;
|
|
22
|
+
label?: string;
|
|
23
|
+
/** Render zero-JS: emit the resolved light-DOM markup but never load the runtime to hydrate it. */
|
|
24
|
+
static?: boolean;
|
|
25
|
+
class?: string;
|
|
26
|
+
/** Any other attribute (`id`, `style`, `data-*`, `aria-*`, …) passes through to the element. */
|
|
27
|
+
[key: string]: unknown;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const {
|
|
31
|
+
values = [],
|
|
32
|
+
points,
|
|
33
|
+
window: windowMs,
|
|
34
|
+
domain,
|
|
35
|
+
step = false,
|
|
36
|
+
variant = "line",
|
|
37
|
+
tone = "accent",
|
|
38
|
+
showEnd = true,
|
|
39
|
+
min,
|
|
40
|
+
max,
|
|
41
|
+
label,
|
|
42
|
+
static: isStatic = false,
|
|
43
|
+
class: extra,
|
|
44
|
+
...rest
|
|
45
|
+
} = Astro.props;
|
|
46
|
+
|
|
47
|
+
const plot =
|
|
48
|
+
points && points.length > 0 ? windowedPlot(points, { window: windowMs, domain, now: Date.now() }) : null;
|
|
49
|
+
const bindings = {
|
|
50
|
+
...(plot ? { plot } : { values }),
|
|
51
|
+
variant,
|
|
52
|
+
tone,
|
|
53
|
+
showEnd,
|
|
54
|
+
step,
|
|
55
|
+
min,
|
|
56
|
+
max,
|
|
57
|
+
label: label ?? null,
|
|
58
|
+
};
|
|
59
|
+
const chrome = await renderFragmentLight("sparkline", bindings);
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
<xtyle-sparkline
|
|
63
|
+
values={JSON.stringify(values)}
|
|
64
|
+
points={points ? JSON.stringify(points) : undefined}
|
|
65
|
+
window={windowMs ?? undefined}
|
|
66
|
+
domain={domain ? JSON.stringify(domain) : undefined}
|
|
67
|
+
variant={variant}
|
|
68
|
+
tone={tone}
|
|
69
|
+
show-end={showEnd ? undefined : "false"}
|
|
70
|
+
step={step || undefined}
|
|
71
|
+
min={min ?? undefined}
|
|
72
|
+
max={max ?? undefined}
|
|
73
|
+
label={label}
|
|
74
|
+
class={extra}
|
|
75
|
+
set:html={chrome}
|
|
76
|
+
{...rest}
|
|
77
|
+
/>
|
|
78
|
+
|
|
79
|
+
{!isStatic && <script>import "@xtyle/core/elements";</script>}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { renderFragmentLight } from "@xtyle/core/elements/ssr";
|
|
3
|
+
|
|
4
|
+
import type { FullTone as Tone } from "@xtyle/core";
|
|
5
|
+
type Size = "sm" | "md" | "lg";
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
tone?: Tone;
|
|
9
|
+
size?: Size;
|
|
10
|
+
"aria-label"?: string;
|
|
11
|
+
/** Render zero-JS: emit the resolved light-DOM markup but never load the runtime to hydrate it. */
|
|
12
|
+
static?: boolean;
|
|
13
|
+
class?: string;
|
|
14
|
+
/** Any other attribute (`id`, `title`, `data-*`, `aria-*`, …) passes through to the element. */
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const {
|
|
19
|
+
tone = "accent",
|
|
20
|
+
size = "md",
|
|
21
|
+
"aria-label": ariaLabel = "Loading",
|
|
22
|
+
static: isStatic = false,
|
|
23
|
+
class: extra,
|
|
24
|
+
...rest
|
|
25
|
+
} = Astro.props;
|
|
26
|
+
|
|
27
|
+
const bindings = {
|
|
28
|
+
tone,
|
|
29
|
+
size,
|
|
30
|
+
label: ariaLabel,
|
|
31
|
+
};
|
|
32
|
+
const composed = await renderFragmentLight("spinner", bindings);
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
<xtyle-spinner tone={tone} size={size} aria-label={ariaLabel} class={extra} set:html={composed} {...rest} />
|
|
36
|
+
|
|
37
|
+
{!isStatic && <script>import "@xtyle/core/elements";</script>}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { renderFragmentLight } from "@xtyle/core/elements/ssr";
|
|
3
|
+
|
|
4
|
+
type SplitterOrientation = "vertical" | "horizontal";
|
|
5
|
+
type SplitterSize = "sm" | "md" | "lg";
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
orientation?: SplitterOrientation;
|
|
9
|
+
size?: SplitterSize;
|
|
10
|
+
line?: boolean;
|
|
11
|
+
min?: number;
|
|
12
|
+
max?: number;
|
|
13
|
+
step?: number;
|
|
14
|
+
value: number;
|
|
15
|
+
default?: number;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
reversed?: boolean;
|
|
18
|
+
/** The CSS custom property the splitter writes the pane size into. */
|
|
19
|
+
var?: string;
|
|
20
|
+
/** The id of the element the var is set on; defaults to the splitter's parent. */
|
|
21
|
+
for?: string;
|
|
22
|
+
label?: string;
|
|
23
|
+
labelledby?: string;
|
|
24
|
+
/** Render zero-JS: emit the resolved light-DOM markup but never load the runtime to hydrate it. */
|
|
25
|
+
static?: boolean;
|
|
26
|
+
class?: string;
|
|
27
|
+
/** Any other attribute (`id`, `title`, `data-*`, `aria-*`, …) passes through to the element. */
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const {
|
|
32
|
+
orientation = "vertical",
|
|
33
|
+
size = "md",
|
|
34
|
+
line = false,
|
|
35
|
+
min = 0,
|
|
36
|
+
max,
|
|
37
|
+
step = 1,
|
|
38
|
+
value,
|
|
39
|
+
default: defaultValue,
|
|
40
|
+
disabled = false,
|
|
41
|
+
reversed = false,
|
|
42
|
+
var: varName,
|
|
43
|
+
for: forId,
|
|
44
|
+
label,
|
|
45
|
+
labelledby,
|
|
46
|
+
static: isStatic = false,
|
|
47
|
+
class: extra,
|
|
48
|
+
...rest
|
|
49
|
+
} = Astro.props;
|
|
50
|
+
|
|
51
|
+
const ariaMax = max ?? value;
|
|
52
|
+
|
|
53
|
+
const bindings = {
|
|
54
|
+
orientation,
|
|
55
|
+
size,
|
|
56
|
+
line,
|
|
57
|
+
value,
|
|
58
|
+
min,
|
|
59
|
+
max: ariaMax,
|
|
60
|
+
disabled,
|
|
61
|
+
label: label ?? null,
|
|
62
|
+
labelledby: labelledby ?? null,
|
|
63
|
+
};
|
|
64
|
+
const light = await renderFragmentLight("splitter", bindings);
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
<xtyle-splitter
|
|
68
|
+
orientation={orientation}
|
|
69
|
+
size={size}
|
|
70
|
+
line={line || undefined}
|
|
71
|
+
min={min}
|
|
72
|
+
max={max ?? undefined}
|
|
73
|
+
step={step}
|
|
74
|
+
value={value}
|
|
75
|
+
default={defaultValue ?? undefined}
|
|
76
|
+
disabled={disabled || undefined}
|
|
77
|
+
reversed={reversed || undefined}
|
|
78
|
+
var={varName}
|
|
79
|
+
for={forId}
|
|
80
|
+
label={label}
|
|
81
|
+
labelledby={labelledby}
|
|
82
|
+
class={extra}
|
|
83
|
+
{...rest}
|
|
84
|
+
set:html={light}
|
|
85
|
+
/>
|
|
86
|
+
|
|
87
|
+
{!isStatic && <script>import "@xtyle/core/elements";</script>}
|
package/src/Stack.astro
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { renderFragmentLight } from "@xtyle/core/elements/ssr";
|
|
3
|
+
|
|
4
|
+
type StackAlign = "start" | "center" | "end" | "stretch" | "baseline";
|
|
5
|
+
type StackJustify = "start" | "center" | "end" | "between" | "around" | "evenly";
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
gap?: number;
|
|
9
|
+
align?: StackAlign;
|
|
10
|
+
justify?: StackJustify;
|
|
11
|
+
inline?: boolean;
|
|
12
|
+
/** Render zero-JS: emit the resolved light-DOM markup but never load the runtime to hydrate it. */
|
|
13
|
+
static?: boolean;
|
|
14
|
+
class?: string;
|
|
15
|
+
/** Any other attribute (`id`, `title`, `data-*`, `aria-*`, …) passes through to the element. */
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const { gap = 4, align, justify, inline = false, static: isStatic = false, class: extra, ...rest } = Astro.props;
|
|
20
|
+
|
|
21
|
+
const bindings = {
|
|
22
|
+
gap,
|
|
23
|
+
align: align ?? null,
|
|
24
|
+
justify: justify ?? null,
|
|
25
|
+
inline,
|
|
26
|
+
};
|
|
27
|
+
const chrome = await renderFragmentLight("stack", bindings);
|
|
28
|
+
const slotHtml = Astro.slots.has("default") ? await Astro.slots.render("default") : "";
|
|
29
|
+
const composed = chrome.replace("<slot></slot>", () => slotHtml);
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
<xtyle-stack
|
|
33
|
+
gap={gap}
|
|
34
|
+
align={align}
|
|
35
|
+
justify={justify}
|
|
36
|
+
inline={inline || undefined}
|
|
37
|
+
class={extra}
|
|
38
|
+
set:html={composed}
|
|
39
|
+
{...rest}
|
|
40
|
+
/>
|
|
41
|
+
|
|
42
|
+
{!isStatic && <script>import "@xtyle/core/elements";</script>}
|
package/src/Stat.astro
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { renderFragmentLight } from "@xtyle/core/elements/ssr";
|
|
3
|
+
|
|
4
|
+
type StatTrend = "up" | "down" | "flat";
|
|
5
|
+
type StatSentiment = "positive" | "negative" | "neutral";
|
|
6
|
+
type StatAlign = "start" | "center";
|
|
7
|
+
type Size = "sm" | "md" | "lg";
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
label?: string;
|
|
11
|
+
delta?: string;
|
|
12
|
+
trend?: StatTrend;
|
|
13
|
+
/** The delta's color reading. Omit to derive it from `trend` (up→positive, down→negative, flat→neutral). */
|
|
14
|
+
sentiment?: StatSentiment;
|
|
15
|
+
caption?: string;
|
|
16
|
+
size?: Size;
|
|
17
|
+
align?: StatAlign;
|
|
18
|
+
/** Lay the stat out horizontally: value, label, and trend delta on one line, like a ticker. */
|
|
19
|
+
inline?: boolean;
|
|
20
|
+
/** Render zero-JS: emit the resolved light-DOM markup but never load the runtime to hydrate it. */
|
|
21
|
+
static?: boolean;
|
|
22
|
+
class?: string;
|
|
23
|
+
/** Any other attribute (`id`, `title`, `data-*`, `aria-*`, …) passes through to the element. */
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const {
|
|
28
|
+
label,
|
|
29
|
+
delta,
|
|
30
|
+
trend = "flat",
|
|
31
|
+
sentiment,
|
|
32
|
+
caption,
|
|
33
|
+
size = "md",
|
|
34
|
+
align = "start",
|
|
35
|
+
inline = false,
|
|
36
|
+
static: isStatic = false,
|
|
37
|
+
class: extra,
|
|
38
|
+
...rest
|
|
39
|
+
} = Astro.props;
|
|
40
|
+
|
|
41
|
+
const bindings = {
|
|
42
|
+
label: label ?? null,
|
|
43
|
+
delta: delta ?? null,
|
|
44
|
+
trend,
|
|
45
|
+
sentiment,
|
|
46
|
+
caption: caption ?? null,
|
|
47
|
+
size,
|
|
48
|
+
align,
|
|
49
|
+
inline,
|
|
50
|
+
};
|
|
51
|
+
const chrome = await renderFragmentLight("stat", bindings);
|
|
52
|
+
const slotHtml = Astro.slots.has("default") ? await Astro.slots.render("default") : "";
|
|
53
|
+
const composed = chrome.replace("<slot></slot>", () => slotHtml);
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
<xtyle-stat
|
|
57
|
+
label={label}
|
|
58
|
+
delta={delta}
|
|
59
|
+
trend={trend}
|
|
60
|
+
sentiment={sentiment}
|
|
61
|
+
caption={caption}
|
|
62
|
+
size={size}
|
|
63
|
+
align={align}
|
|
64
|
+
inline={inline || undefined}
|
|
65
|
+
class={extra}
|
|
66
|
+
set:html={composed}
|
|
67
|
+
{...rest}
|
|
68
|
+
/>
|
|
69
|
+
|
|
70
|
+
{!isStatic && <script>import "@xtyle/core/elements";</script>}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { renderFragmentLight } from "@xtyle/core/elements/ssr";
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
live?: boolean;
|
|
6
|
+
label?: string;
|
|
7
|
+
overflow?: "clip" | "wrap" | "scroll" | "collapse";
|
|
8
|
+
manualOverflow?: boolean;
|
|
9
|
+
/** Draw a divider between adjacent items at the bar's own spacing — so items stay
|
|
10
|
+
* individual (and collapse counts them independently) instead of carrying their own separators. */
|
|
11
|
+
separated?: boolean;
|
|
12
|
+
/** Render zero-JS: emit the resolved light-DOM markup but never load the runtime to hydrate it. */
|
|
13
|
+
static?: boolean;
|
|
14
|
+
class?: string;
|
|
15
|
+
/** Any other attribute (`id`, `title`, `data-*`, `aria-*`, …) passes through to the element. */
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
live = false,
|
|
21
|
+
label,
|
|
22
|
+
overflow = "clip",
|
|
23
|
+
manualOverflow = false,
|
|
24
|
+
separated = false,
|
|
25
|
+
static: isStatic = false,
|
|
26
|
+
class: extra,
|
|
27
|
+
...rest
|
|
28
|
+
} = Astro.props;
|
|
29
|
+
|
|
30
|
+
const elementId = `xtyle-statusbar-${Math.random().toString(36).slice(2, 8)}`;
|
|
31
|
+
|
|
32
|
+
const bindings = {
|
|
33
|
+
live,
|
|
34
|
+
label: label ?? null,
|
|
35
|
+
overflow,
|
|
36
|
+
manualOverflow,
|
|
37
|
+
separated,
|
|
38
|
+
elementId,
|
|
39
|
+
};
|
|
40
|
+
const light = await renderFragmentLight("statusbar", bindings);
|
|
41
|
+
const slotHtml = Astro.slots.has("default") ? await Astro.slots.render("default") : "";
|
|
42
|
+
const composed = light.replace("<slot></slot>", () => slotHtml);
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
<xtyle-statusbar
|
|
46
|
+
live={live || undefined}
|
|
47
|
+
label={label}
|
|
48
|
+
overflow={overflow}
|
|
49
|
+
manual-overflow={manualOverflow || undefined}
|
|
50
|
+
separated={separated || undefined}
|
|
51
|
+
class={extra}
|
|
52
|
+
set:html={composed}
|
|
53
|
+
{...rest}
|
|
54
|
+
/>
|
|
55
|
+
|
|
56
|
+
{!isStatic && <script>import "@xtyle/core/elements";</script>}
|