@marianmeres/stuic 3.167.0 → 3.169.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/AGENTS.md +6 -6
- package/dist/README.md +1 -1
- package/dist/attachments/index.d.ts +1 -0
- package/dist/attachments/index.js +1 -0
- package/dist/attachments/long-press.d.ts +43 -0
- package/dist/attachments/long-press.js +107 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.svelte +198 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.svelte.d.ts +60 -0
- package/dist/components/Breadcrumbs/README.md +174 -0
- package/dist/components/Breadcrumbs/i18n-sk.d.ts +17 -0
- package/dist/components/Breadcrumbs/i18n-sk.js +19 -0
- package/dist/components/Breadcrumbs/i18n.d.ts +31 -0
- package/dist/components/Breadcrumbs/i18n.js +40 -0
- package/dist/components/Breadcrumbs/index.css +84 -0
- package/dist/components/Breadcrumbs/index.d.ts +4 -0
- package/dist/components/Breadcrumbs/index.js +4 -0
- package/dist/components/Breadcrumbs/json-ld.d.ts +58 -0
- package/dist/components/Breadcrumbs/json-ld.js +56 -0
- package/dist/components/Collapsible/Collapsible.svelte +84 -15
- package/dist/components/Collapsible/Collapsible.svelte.d.ts +29 -2
- package/dist/components/Collapsible/README.md +82 -23
- package/dist/components/Collapsible/index.css +38 -0
- package/dist/components/Collapsible/index.d.ts +1 -1
- package/dist/components/ContextMenu/ContextMenu.svelte +302 -0
- package/dist/components/ContextMenu/ContextMenu.svelte.d.ts +94 -0
- package/dist/components/ContextMenu/README.md +159 -0
- package/dist/components/ContextMenu/i18n-sk.d.ts +17 -0
- package/dist/components/ContextMenu/i18n-sk.js +18 -0
- package/dist/components/ContextMenu/i18n.d.ts +30 -0
- package/dist/components/ContextMenu/i18n.js +38 -0
- package/dist/components/ContextMenu/index.css +26 -0
- package/dist/components/ContextMenu/index.d.ts +3 -0
- package/dist/components/ContextMenu/index.js +3 -0
- package/dist/components/CopyButton/CopyButton.svelte +278 -0
- package/dist/components/CopyButton/CopyButton.svelte.d.ts +76 -0
- package/dist/components/CopyButton/README.md +241 -0
- package/dist/components/CopyButton/i18n-sk.d.ts +17 -0
- package/dist/components/CopyButton/i18n-sk.js +20 -0
- package/dist/components/CopyButton/i18n.d.ts +35 -0
- package/dist/components/CopyButton/i18n.js +43 -0
- package/dist/components/CopyButton/index.css +67 -0
- package/dist/components/CopyButton/index.d.ts +3 -0
- package/dist/components/CopyButton/index.js +3 -0
- package/dist/components/DataTable/DataTable.svelte +41 -34
- package/dist/components/DataTable/README.md +45 -0
- package/dist/components/DataTable/i18n-sk.js +1 -0
- package/dist/components/DataTable/i18n.d.ts +1 -0
- package/dist/components/DataTable/i18n.js +3 -0
- package/dist/components/DataTable/index.css +41 -3
- package/dist/components/EmptyState/EmptyState.svelte +121 -0
- package/dist/components/EmptyState/EmptyState.svelte.d.ts +40 -0
- package/dist/components/EmptyState/README.md +188 -0
- package/dist/components/EmptyState/index.css +154 -0
- package/dist/components/EmptyState/index.d.ts +1 -0
- package/dist/components/EmptyState/index.js +1 -0
- package/dist/components/Input/FieldOptions.svelte +92 -2
- package/dist/components/Input/FieldOptions.svelte.d.ts +13 -0
- package/dist/components/Input/README.md +66 -31
- package/dist/components/Input/_internal/FieldLikeChips.svelte +286 -0
- package/dist/components/Input/_internal/FieldLikeChips.svelte.d.ts +65 -0
- package/dist/components/Input/index.css +58 -0
- package/dist/components/Pagination/Pagination.svelte +250 -0
- package/dist/components/Pagination/Pagination.svelte.d.ts +69 -0
- package/dist/components/Pagination/README.md +152 -0
- package/dist/components/Pagination/i18n-sk.d.ts +17 -0
- package/dist/components/Pagination/i18n-sk.js +24 -0
- package/dist/components/Pagination/i18n.d.ts +41 -0
- package/dist/components/Pagination/i18n.js +49 -0
- package/dist/components/Pagination/index.css +50 -0
- package/dist/components/Pagination/index.d.ts +4 -0
- package/dist/components/Pagination/index.js +4 -0
- package/dist/components/Pagination/pagination-range.d.ts +21 -0
- package/dist/components/Pagination/pagination-range.js +41 -0
- package/dist/components/Pill/Pill.svelte +8 -2
- package/dist/components/Pill/Pill.svelte.d.ts +2 -0
- package/dist/components/Pill/README.md +35 -22
- package/dist/components/Pill/index.css +57 -18
- package/dist/components/Stat/README.md +157 -0
- package/dist/components/Stat/Stat.svelte +226 -0
- package/dist/components/Stat/Stat.svelte.d.ts +54 -0
- package/dist/components/Stat/index.css +217 -0
- package/dist/components/Stat/index.d.ts +1 -0
- package/dist/components/Stat/index.js +1 -0
- package/dist/components/Stepper/README.md +181 -0
- package/dist/components/Stepper/Stepper.svelte +240 -0
- package/dist/components/Stepper/Stepper.svelte.d.ts +86 -0
- package/dist/components/Stepper/i18n-sk.d.ts +17 -0
- package/dist/components/Stepper/i18n-sk.js +21 -0
- package/dist/components/Stepper/i18n.d.ts +35 -0
- package/dist/components/Stepper/i18n.js +43 -0
- package/dist/components/Stepper/index.css +302 -0
- package/dist/components/Stepper/index.d.ts +3 -0
- package/dist/components/Stepper/index.js +3 -0
- package/dist/components/TrendChart/README.md +123 -0
- package/dist/components/TrendChart/TrendChart.svelte +114 -0
- package/dist/components/TrendChart/TrendChart.svelte.d.ts +36 -0
- package/dist/components/TrendChart/index.css +51 -0
- package/dist/components/TrendChart/index.d.ts +1 -0
- package/dist/components/TrendChart/index.js +1 -0
- package/dist/icons/index.d.ts +4 -0
- package/dist/icons/index.js +4 -0
- package/dist/index.css +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +12 -0
- package/dist/utils/copy-to-clipboard.d.ts +43 -0
- package/dist/utils/copy-to-clipboard.js +102 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/docs/architecture.md +1 -1
- package/docs/domains/attachments.md +41 -4
- package/docs/domains/components.md +280 -13
- package/docs/domains/utils.md +8 -6
- package/docs/maybe-todo.md +132 -0
- package/docs/upgrading.md +6 -0
- package/package.json +11 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
import type { THC } from "../Thc/Thc.svelte";
|
|
4
|
+
import type { TranslateFn } from "../../types.js";
|
|
5
|
+
export type StepperOrientation = "horizontal" | "vertical";
|
|
6
|
+
export type StepperLabelPosition = "end" | "below";
|
|
7
|
+
export type StepperStepState = "completed" | "current" | "upcoming";
|
|
8
|
+
export type StepperClickable = "none" | "completed" | "all";
|
|
9
|
+
export interface StepperStep {
|
|
10
|
+
/** Step label */
|
|
11
|
+
label: THC;
|
|
12
|
+
/** Optional secondary line under the label */
|
|
13
|
+
description?: THC;
|
|
14
|
+
/**
|
|
15
|
+
* Raw svg/html string rendered inside the indicator instead of the step number
|
|
16
|
+
* (e.g. an `@marianmeres/icons-fns` render result). Completed/error markers
|
|
17
|
+
* still take precedence.
|
|
18
|
+
*/
|
|
19
|
+
icon?: string;
|
|
20
|
+
/** Marks the step as failed — destructive coloring + "×" indicator */
|
|
21
|
+
error?: boolean;
|
|
22
|
+
/** Never clickable, regardless of the `clickable` policy */
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface Props extends Omit<HTMLAttributes<HTMLElement>, "children"> {
|
|
26
|
+
/** The steps to render. Plain strings are shorthand for `{ label }`. */
|
|
27
|
+
steps: (StepperStep | string)[];
|
|
28
|
+
/**
|
|
29
|
+
* Zero-based index of the current step (default 0) — aligns with
|
|
30
|
+
* `@marianmeres/wizard`'s `step.index`. Steps before it render as completed,
|
|
31
|
+
* steps after it as upcoming. Pass `steps.length` to mark every step
|
|
32
|
+
* completed (wizard done). Out-of-range values are clamped.
|
|
33
|
+
*/
|
|
34
|
+
current?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Navigation callback. When provided (and `clickable` is not "none"), steps
|
|
37
|
+
* render as buttons and eligible ones fire this on click. The current step
|
|
38
|
+
* never fires.
|
|
39
|
+
*/
|
|
40
|
+
onSelect?: (index: number, step: StepperStep) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Which steps may be clicked when `onSelect` is present. `"completed"`
|
|
43
|
+
* (default): only completed steps — the "go back and revisit" wizard rule.
|
|
44
|
+
* `"all"`: any non-disabled step. `"none"`: display-only.
|
|
45
|
+
*/
|
|
46
|
+
clickable?: StepperClickable;
|
|
47
|
+
/** Layout direction (default "horizontal") */
|
|
48
|
+
orientation?: StepperOrientation;
|
|
49
|
+
/**
|
|
50
|
+
* Horizontal orientation only: labels to the right of the indicator
|
|
51
|
+
* (`"end"`, default) or centered below it (`"below"` — the classic
|
|
52
|
+
* checkout header).
|
|
53
|
+
*/
|
|
54
|
+
labelPosition?: StepperLabelPosition;
|
|
55
|
+
/** Disable all interaction (e.g. while a step is submitting) */
|
|
56
|
+
disabled?: boolean;
|
|
57
|
+
/** i18n translate function (see `createStepperT`) */
|
|
58
|
+
t?: TranslateFn;
|
|
59
|
+
/** Override the indicator bubble content */
|
|
60
|
+
renderIndicator?: Snippet<[
|
|
61
|
+
{
|
|
62
|
+
index: number;
|
|
63
|
+
step: StepperStep;
|
|
64
|
+
state: StepperStepState;
|
|
65
|
+
}
|
|
66
|
+
]>;
|
|
67
|
+
/** Skip all default styling */
|
|
68
|
+
unstyled?: boolean;
|
|
69
|
+
/** Additional CSS classes */
|
|
70
|
+
class?: string;
|
|
71
|
+
/** Class for every step item (`li`) */
|
|
72
|
+
classStep?: string;
|
|
73
|
+
/** Class for the indicator bubble */
|
|
74
|
+
classIndicator?: string;
|
|
75
|
+
/** Class for the label */
|
|
76
|
+
classLabel?: string;
|
|
77
|
+
/** Class for the description */
|
|
78
|
+
classDescription?: string;
|
|
79
|
+
/** Class for the connector line between steps */
|
|
80
|
+
classConnector?: string;
|
|
81
|
+
/** Bindable element reference */
|
|
82
|
+
el?: HTMLElement;
|
|
83
|
+
}
|
|
84
|
+
declare const Stepper: import("svelte").Component<Props, {}, "el">;
|
|
85
|
+
type Stepper = ReturnType<typeof Stepper>;
|
|
86
|
+
export default Stepper;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { StepperMessages } from "./i18n.js";
|
|
2
|
+
/**
|
|
3
|
+
* Slovak message catalog for `Stepper`. Opt-in — English stays the built-in default,
|
|
4
|
+
* and this module is only pulled into a bundle when it is actually imported (the
|
|
5
|
+
* component itself never references it).
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```svelte
|
|
9
|
+
* <script>
|
|
10
|
+
* import { Stepper, createStepperT, STEPPER_MESSAGES_SK } from "@marianmeres/stuic";
|
|
11
|
+
* const t = createStepperT(STEPPER_MESSAGES_SK);
|
|
12
|
+
* </script>
|
|
13
|
+
*
|
|
14
|
+
* <Stepper {steps} {current} {t} />
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare const STEPPER_MESSAGES_SK: StepperMessages;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slovak message catalog for `Stepper`. Opt-in — English stays the built-in default,
|
|
3
|
+
* and this module is only pulled into a bundle when it is actually imported (the
|
|
4
|
+
* component itself never references it).
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```svelte
|
|
8
|
+
* <script>
|
|
9
|
+
* import { Stepper, createStepperT, STEPPER_MESSAGES_SK } from "@marianmeres/stuic";
|
|
10
|
+
* const t = createStepperT(STEPPER_MESSAGES_SK);
|
|
11
|
+
* </script>
|
|
12
|
+
*
|
|
13
|
+
* <Stepper {steps} {current} {t} />
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export const STEPPER_MESSAGES_SK = {
|
|
17
|
+
stepper: "Priebeh",
|
|
18
|
+
step_x_of_y: "Krok {step} z {stepCount}",
|
|
19
|
+
completed: "Dokončený",
|
|
20
|
+
failed: "Zlyhal",
|
|
21
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { TranslateFn } from "../../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The built-in (English) message catalog of `Stepper`. Also the fallback of every
|
|
4
|
+
* other bundled locale, so a locale missing a key still renders text.
|
|
5
|
+
*
|
|
6
|
+
* Placeholders are single-brace (`{step}`, `{stepCount}`).
|
|
7
|
+
*/
|
|
8
|
+
export declare const STEPPER_MESSAGES_EN: {
|
|
9
|
+
stepper: string;
|
|
10
|
+
step_x_of_y: string;
|
|
11
|
+
completed: string;
|
|
12
|
+
failed: string;
|
|
13
|
+
};
|
|
14
|
+
/** Every message key `Stepper` may look up. */
|
|
15
|
+
export type StepperMessageKey = keyof typeof STEPPER_MESSAGES_EN;
|
|
16
|
+
/** A (possibly partial) catalog for one locale. */
|
|
17
|
+
export type StepperMessages = Record<StepperMessageKey, string>;
|
|
18
|
+
/**
|
|
19
|
+
* Builds the `t` prop of `Stepper` from a message catalog. Unknown or untranslated
|
|
20
|
+
* keys fall back to `fallbackMessages` (English by default), so a catalog may safely be
|
|
21
|
+
* partial and never renders a raw key.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```svelte
|
|
25
|
+
* <script>
|
|
26
|
+
* import { Stepper, createStepperT, STEPPER_MESSAGES_SK } from "@marianmeres/stuic";
|
|
27
|
+
* const t = createStepperT(STEPPER_MESSAGES_SK);
|
|
28
|
+
* </script>
|
|
29
|
+
*
|
|
30
|
+
* <Stepper {steps} {current} {t} />
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function createStepperT(messages: Partial<StepperMessages> | Record<string, string>, fallbackMessages?: Partial<StepperMessages> | Record<string, string>): TranslateFn;
|
|
34
|
+
/** The component's built-in English `t`. */
|
|
35
|
+
export declare const t_default: TranslateFn;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { isPlainObject } from "../../utils/is-plain-object.js";
|
|
2
|
+
import { replaceMap } from "../../utils/replace-map.js";
|
|
3
|
+
/**
|
|
4
|
+
* The built-in (English) message catalog of `Stepper`. Also the fallback of every
|
|
5
|
+
* other bundled locale, so a locale missing a key still renders text.
|
|
6
|
+
*
|
|
7
|
+
* Placeholders are single-brace (`{step}`, `{stepCount}`).
|
|
8
|
+
*/
|
|
9
|
+
export const STEPPER_MESSAGES_EN = {
|
|
10
|
+
stepper: "Progress",
|
|
11
|
+
step_x_of_y: "Step {step} of {stepCount}",
|
|
12
|
+
completed: "Completed",
|
|
13
|
+
failed: "Failed",
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Builds the `t` prop of `Stepper` from a message catalog. Unknown or untranslated
|
|
17
|
+
* keys fall back to `fallbackMessages` (English by default), so a catalog may safely be
|
|
18
|
+
* partial and never renders a raw key.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```svelte
|
|
22
|
+
* <script>
|
|
23
|
+
* import { Stepper, createStepperT, STEPPER_MESSAGES_SK } from "@marianmeres/stuic";
|
|
24
|
+
* const t = createStepperT(STEPPER_MESSAGES_SK);
|
|
25
|
+
* </script>
|
|
26
|
+
*
|
|
27
|
+
* <Stepper {steps} {current} {t} />
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export function createStepperT(messages, fallbackMessages = STEPPER_MESSAGES_EN) {
|
|
31
|
+
return (k, values = null, fallback = "") => {
|
|
32
|
+
const out = messages[k] ??
|
|
33
|
+
fallbackMessages[k] ??
|
|
34
|
+
(typeof fallback === "string" ? fallback : k);
|
|
35
|
+
return isPlainObject(values)
|
|
36
|
+
? replaceMap(out, values, {
|
|
37
|
+
preSearchKeyTransform: (k) => `{${k}}`,
|
|
38
|
+
})
|
|
39
|
+
: out;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** The component's built-in English `t`. */
|
|
43
|
+
export const t_default = createStepperT(STEPPER_MESSAGES_EN);
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/* ============================================================================
|
|
2
|
+
STEPPER COMPONENT TOKENS
|
|
3
|
+
Override globally: :root { --stuic-stepper-indicator-size: 2.5rem; }
|
|
4
|
+
Override locally: <Stepper style="--stuic-stepper-connector-thickness: 4px;">
|
|
5
|
+
============================================================================ */
|
|
6
|
+
|
|
7
|
+
/* prettier-ignore */
|
|
8
|
+
:root {
|
|
9
|
+
/* Layout */
|
|
10
|
+
--stuic-stepper-gap: 0.75rem; /* indicator↔label + step↔connector */
|
|
11
|
+
--stuic-stepper-gap-vertical: 1.75rem; /* vertical: distance between steps */
|
|
12
|
+
--stuic-stepper-connector-min-length: 1.5rem; /* horizontal: shortest connector */
|
|
13
|
+
|
|
14
|
+
/* Indicator bubble */
|
|
15
|
+
--stuic-stepper-indicator-size: 2rem;
|
|
16
|
+
--stuic-stepper-indicator-border-width: 2px;
|
|
17
|
+
--stuic-stepper-indicator-font-size: var(--text-sm);
|
|
18
|
+
--stuic-stepper-indicator-font-weight: var(--font-weight-medium);
|
|
19
|
+
--stuic-stepper-indicator-bg: transparent;
|
|
20
|
+
--stuic-stepper-indicator-text: var(--stuic-color-muted-foreground);
|
|
21
|
+
--stuic-stepper-indicator-border: var(--stuic-color-border);
|
|
22
|
+
--stuic-stepper-indicator-bg-current: transparent;
|
|
23
|
+
--stuic-stepper-indicator-text-current: var(--stuic-color-primary);
|
|
24
|
+
--stuic-stepper-indicator-border-current: var(--stuic-color-primary);
|
|
25
|
+
--stuic-stepper-indicator-bg-completed: var(--stuic-color-primary);
|
|
26
|
+
--stuic-stepper-indicator-text-completed: var(--stuic-color-primary-foreground);
|
|
27
|
+
--stuic-stepper-indicator-border-completed: var(--stuic-color-primary);
|
|
28
|
+
--stuic-stepper-indicator-bg-error: var(--stuic-color-destructive);
|
|
29
|
+
--stuic-stepper-indicator-text-error: var(--stuic-color-destructive-foreground);
|
|
30
|
+
--stuic-stepper-indicator-border-error: var(--stuic-color-destructive);
|
|
31
|
+
|
|
32
|
+
/* Label */
|
|
33
|
+
--stuic-stepper-label-font-size: var(--text-base);
|
|
34
|
+
--stuic-stepper-label-font-weight: var(--font-weight-medium);
|
|
35
|
+
--stuic-stepper-label-text: var(--stuic-color-muted-foreground);
|
|
36
|
+
--stuic-stepper-label-text-current: var(--stuic-color-foreground);
|
|
37
|
+
--stuic-stepper-label-text-completed: var(--stuic-color-foreground);
|
|
38
|
+
--stuic-stepper-label-text-error: var(--stuic-color-destructive);
|
|
39
|
+
|
|
40
|
+
/* Description */
|
|
41
|
+
--stuic-stepper-description-font-size: var(--text-sm);
|
|
42
|
+
--stuic-stepper-description-text: var(--stuic-color-muted-foreground);
|
|
43
|
+
|
|
44
|
+
/* Connector line */
|
|
45
|
+
--stuic-stepper-connector-thickness: 2px;
|
|
46
|
+
--stuic-stepper-connector-bg: var(--stuic-color-border);
|
|
47
|
+
--stuic-stepper-connector-bg-completed: var(--stuic-color-primary);
|
|
48
|
+
|
|
49
|
+
/* Focus ring */
|
|
50
|
+
--stuic-stepper-ring-width: 3px;
|
|
51
|
+
--stuic-stepper-ring-color: var(--stuic-color-ring);
|
|
52
|
+
|
|
53
|
+
/* Disabled */
|
|
54
|
+
--stuic-stepper-opacity-disabled: 0.5;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@layer components {
|
|
58
|
+
/* ============================================================================
|
|
59
|
+
BASE
|
|
60
|
+
============================================================================ */
|
|
61
|
+
|
|
62
|
+
.stuic-stepper[data-disabled] {
|
|
63
|
+
opacity: var(--stuic-stepper-opacity-disabled);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.stuic-stepper-list {
|
|
67
|
+
display: flex;
|
|
68
|
+
list-style: none;
|
|
69
|
+
margin: 0;
|
|
70
|
+
padding: 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.stuic-stepper-item[data-disabled] {
|
|
74
|
+
opacity: var(--stuic-stepper-opacity-disabled);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* ============================================================================
|
|
78
|
+
TRIGGER (the step content — <button> when interactive, <div> otherwise)
|
|
79
|
+
============================================================================ */
|
|
80
|
+
|
|
81
|
+
.stuic-stepper-trigger {
|
|
82
|
+
display: flex;
|
|
83
|
+
align-items: center;
|
|
84
|
+
gap: var(--stuic-stepper-gap);
|
|
85
|
+
text-align: start;
|
|
86
|
+
min-width: 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
button.stuic-stepper-trigger {
|
|
90
|
+
font: inherit;
|
|
91
|
+
color: inherit;
|
|
92
|
+
background: none;
|
|
93
|
+
border: 0;
|
|
94
|
+
padding: 0;
|
|
95
|
+
cursor: pointer;
|
|
96
|
+
-webkit-tap-highlight-color: transparent;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
button.stuic-stepper-trigger:disabled {
|
|
100
|
+
cursor: default;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
button.stuic-stepper-trigger:focus-visible {
|
|
104
|
+
outline: var(--stuic-stepper-ring-width) solid var(--stuic-stepper-ring-color);
|
|
105
|
+
outline-offset: 2px;
|
|
106
|
+
border-radius: var(--stuic-stepper-radius, var(--stuic-radius));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* clickable affordance: label picks up the emphasized color */
|
|
110
|
+
button.stuic-stepper-trigger:not(:disabled):hover .stuic-stepper-label {
|
|
111
|
+
color: var(--stuic-stepper-label-text-current);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/* ============================================================================
|
|
115
|
+
INDICATOR
|
|
116
|
+
============================================================================ */
|
|
117
|
+
|
|
118
|
+
.stuic-stepper-indicator {
|
|
119
|
+
display: inline-flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
justify-content: center;
|
|
122
|
+
flex-shrink: 0;
|
|
123
|
+
width: var(--stuic-stepper-indicator-size);
|
|
124
|
+
height: var(--stuic-stepper-indicator-size);
|
|
125
|
+
border-radius: var(--stuic-stepper-indicator-radius, calc(infinity * 1px));
|
|
126
|
+
border: var(--stuic-stepper-indicator-border-width) solid
|
|
127
|
+
var(--stuic-stepper-indicator-border);
|
|
128
|
+
background: var(--stuic-stepper-indicator-bg);
|
|
129
|
+
color: var(--stuic-stepper-indicator-text);
|
|
130
|
+
font-size: var(--stuic-stepper-indicator-font-size);
|
|
131
|
+
font-weight: var(--stuic-stepper-indicator-font-weight);
|
|
132
|
+
transition:
|
|
133
|
+
background var(--stuic-stepper-transition, var(--stuic-transition)),
|
|
134
|
+
border-color var(--stuic-stepper-transition, var(--stuic-transition)),
|
|
135
|
+
color var(--stuic-stepper-transition, var(--stuic-transition));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.stuic-stepper-indicator svg {
|
|
139
|
+
display: block;
|
|
140
|
+
width: 1.25em;
|
|
141
|
+
height: 1.25em;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.stuic-stepper-item[data-state="current"] .stuic-stepper-indicator {
|
|
145
|
+
background: var(--stuic-stepper-indicator-bg-current);
|
|
146
|
+
border-color: var(--stuic-stepper-indicator-border-current);
|
|
147
|
+
color: var(--stuic-stepper-indicator-text-current);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.stuic-stepper-item[data-state="completed"] .stuic-stepper-indicator {
|
|
151
|
+
background: var(--stuic-stepper-indicator-bg-completed);
|
|
152
|
+
border-color: var(--stuic-stepper-indicator-border-completed);
|
|
153
|
+
color: var(--stuic-stepper-indicator-text-completed);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* error wins over any state */
|
|
157
|
+
.stuic-stepper-item[data-error] .stuic-stepper-indicator {
|
|
158
|
+
background: var(--stuic-stepper-indicator-bg-error);
|
|
159
|
+
border-color: var(--stuic-stepper-indicator-border-error);
|
|
160
|
+
color: var(--stuic-stepper-indicator-text-error);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* ============================================================================
|
|
164
|
+
TEXT (label + description)
|
|
165
|
+
============================================================================ */
|
|
166
|
+
|
|
167
|
+
.stuic-stepper-text {
|
|
168
|
+
display: flex;
|
|
169
|
+
flex-direction: column;
|
|
170
|
+
gap: 0.125rem;
|
|
171
|
+
min-width: 0;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.stuic-stepper-label {
|
|
175
|
+
font-size: var(--stuic-stepper-label-font-size);
|
|
176
|
+
font-weight: var(--stuic-stepper-label-font-weight);
|
|
177
|
+
color: var(--stuic-stepper-label-text);
|
|
178
|
+
transition: color var(--stuic-stepper-transition, var(--stuic-transition));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.stuic-stepper-item[data-state="current"] .stuic-stepper-label {
|
|
182
|
+
color: var(--stuic-stepper-label-text-current);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.stuic-stepper-item[data-state="completed"] .stuic-stepper-label {
|
|
186
|
+
color: var(--stuic-stepper-label-text-completed);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.stuic-stepper-item[data-error] .stuic-stepper-label {
|
|
190
|
+
color: var(--stuic-stepper-label-text-error);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.stuic-stepper-description {
|
|
194
|
+
font-size: var(--stuic-stepper-description-font-size);
|
|
195
|
+
color: var(--stuic-stepper-description-text);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* ============================================================================
|
|
199
|
+
CONNECTOR
|
|
200
|
+
============================================================================ */
|
|
201
|
+
|
|
202
|
+
.stuic-stepper-connector {
|
|
203
|
+
background: var(--stuic-stepper-connector-bg);
|
|
204
|
+
transition: background var(--stuic-stepper-transition, var(--stuic-transition));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.stuic-stepper-connector[data-state="completed"] {
|
|
208
|
+
background: var(--stuic-stepper-connector-bg-completed);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* ============================================================================
|
|
212
|
+
HORIZONTAL (labels at the end — default)
|
|
213
|
+
============================================================================ */
|
|
214
|
+
|
|
215
|
+
.stuic-stepper[data-orientation="horizontal"] .stuic-stepper-list {
|
|
216
|
+
flex-direction: row;
|
|
217
|
+
align-items: center;
|
|
218
|
+
gap: var(--stuic-stepper-gap);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.stuic-stepper[data-orientation="horizontal"] .stuic-stepper-item {
|
|
222
|
+
display: flex;
|
|
223
|
+
align-items: center;
|
|
224
|
+
gap: var(--stuic-stepper-gap);
|
|
225
|
+
flex: 1;
|
|
226
|
+
min-width: 0;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/* the last step carries no connector — don't stretch it */
|
|
230
|
+
.stuic-stepper[data-orientation="horizontal"] .stuic-stepper-item:last-child {
|
|
231
|
+
flex: none;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.stuic-stepper[data-orientation="horizontal"] .stuic-stepper-connector {
|
|
235
|
+
flex: 1;
|
|
236
|
+
min-width: var(--stuic-stepper-connector-min-length);
|
|
237
|
+
height: var(--stuic-stepper-connector-thickness);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* ============================================================================
|
|
241
|
+
HORIZONTAL, LABELS BELOW (classic checkout header)
|
|
242
|
+
============================================================================ */
|
|
243
|
+
|
|
244
|
+
.stuic-stepper[data-label-position="below"] .stuic-stepper-item {
|
|
245
|
+
align-items: flex-start;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.stuic-stepper[data-label-position="below"] .stuic-stepper-trigger {
|
|
249
|
+
flex-direction: column;
|
|
250
|
+
align-items: center;
|
|
251
|
+
text-align: center;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.stuic-stepper[data-label-position="below"] .stuic-stepper-text {
|
|
255
|
+
align-items: center;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/* keep the connector on the indicator's horizontal axis */
|
|
259
|
+
.stuic-stepper[data-label-position="below"] .stuic-stepper-connector {
|
|
260
|
+
margin-top: calc(
|
|
261
|
+
(var(--stuic-stepper-indicator-size) - var(--stuic-stepper-connector-thickness)) / 2
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/* ============================================================================
|
|
266
|
+
VERTICAL
|
|
267
|
+
============================================================================ */
|
|
268
|
+
|
|
269
|
+
.stuic-stepper[data-orientation="vertical"] .stuic-stepper-list {
|
|
270
|
+
flex-direction: column;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.stuic-stepper[data-orientation="vertical"] .stuic-stepper-item {
|
|
274
|
+
position: relative;
|
|
275
|
+
padding-bottom: var(--stuic-stepper-gap-vertical);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.stuic-stepper[data-orientation="vertical"] .stuic-stepper-item:last-child {
|
|
279
|
+
padding-bottom: 0;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/* top-align so a multi-line description grows downward, not around the bubble */
|
|
283
|
+
.stuic-stepper[data-orientation="vertical"] .stuic-stepper-trigger {
|
|
284
|
+
align-items: flex-start;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/* ...while a single-line label still centers against the bubble */
|
|
288
|
+
.stuic-stepper[data-orientation="vertical"] .stuic-stepper-text {
|
|
289
|
+
min-height: var(--stuic-stepper-indicator-size);
|
|
290
|
+
justify-content: center;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.stuic-stepper[data-orientation="vertical"] .stuic-stepper-connector {
|
|
294
|
+
position: absolute;
|
|
295
|
+
inset-inline-start: calc(
|
|
296
|
+
(var(--stuic-stepper-indicator-size) - var(--stuic-stepper-connector-thickness)) / 2
|
|
297
|
+
);
|
|
298
|
+
top: calc(var(--stuic-stepper-indicator-size) + 0.25rem);
|
|
299
|
+
bottom: 0.25rem;
|
|
300
|
+
width: var(--stuic-stepper-connector-thickness);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { default as Stepper, type Props as StepperProps, type StepperStep, type StepperStepState, type StepperOrientation, type StepperLabelPosition, type StepperClickable, } from "./Stepper.svelte";
|
|
2
|
+
export { createStepperT, STEPPER_MESSAGES_EN, type StepperMessageKey, type StepperMessages, } from "./i18n.js";
|
|
3
|
+
export { STEPPER_MESSAGES_SK } from "./i18n-sk.js";
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# TrendChart
|
|
2
|
+
|
|
3
|
+
A thin Svelte wrapper around [`@marianmeres/trend-chart`](https://github.com/marianmeres/trend-chart)
|
|
4
|
+
(framework-agnostic, zero-dependency single-series SVG trend chart): reactive `data`
|
|
5
|
+
and `options` props, lifecycle management (create/update/destroy), a `sparkline`
|
|
6
|
+
preset, and automatic STUIC theming (dark mode included) by mapping the chart's
|
|
7
|
+
`--trend-chart-*` CSS hooks to STUIC tokens.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
This component ships as an **optional subpath export** — the
|
|
12
|
+
`@marianmeres/trend-chart` peer dependency is NOT bundled with stuic and is only
|
|
13
|
+
required if you actually use this component:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @marianmeres/trend-chart
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```svelte
|
|
20
|
+
<script>
|
|
21
|
+
import { TrendChart } from "@marianmeres/stuic/trend-chart";
|
|
22
|
+
</script>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
It is deliberately not exported from the main `@marianmeres/stuic` barrel, so
|
|
26
|
+
consumers who don't use it never pull the dependency into their module graph.
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
```svelte
|
|
31
|
+
<script>
|
|
32
|
+
import { TrendChart } from "@marianmeres/stuic/trend-chart";
|
|
33
|
+
|
|
34
|
+
let data = $state([3, 5, 4, 8, 6, 9, 7]);
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<!-- Full chart (axes, gridlines, pan/zoom) — themed via stuic tokens -->
|
|
38
|
+
<TrendChart {data} />
|
|
39
|
+
|
|
40
|
+
<!-- Sparkline (no axes/grid/interaction, compact height) -->
|
|
41
|
+
<TrendChart {data} sparkline />
|
|
42
|
+
|
|
43
|
+
<!-- Any @marianmeres/trend-chart option passes through -->
|
|
44
|
+
<TrendChart
|
|
45
|
+
{data}
|
|
46
|
+
options={{
|
|
47
|
+
smooth: true,
|
|
48
|
+
endDot: true,
|
|
49
|
+
formatX: (x) => new Date(x).toLocaleDateString(),
|
|
50
|
+
onPointClick: (e) => console.log(e.point),
|
|
51
|
+
}}
|
|
52
|
+
/>
|
|
53
|
+
|
|
54
|
+
<!-- Imperative API via the bindable chart instance -->
|
|
55
|
+
<TrendChart {data} bind:chart />
|
|
56
|
+
<button onclick={() => chart?.resetDomain()}>Reset zoom</button>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Updating `data` (reassignment or deep `$state` mutation) patches the chart in
|
|
60
|
+
place — pan/zoom state is preserved. Changing `options` merges them into the
|
|
61
|
+
running instance.
|
|
62
|
+
|
|
63
|
+
### With `Stat` (KPI card)
|
|
64
|
+
|
|
65
|
+
The first-class pairing — a sparkline in a `Stat` footer:
|
|
66
|
+
|
|
67
|
+
```svelte
|
|
68
|
+
<script>
|
|
69
|
+
import { Stat } from "@marianmeres/stuic";
|
|
70
|
+
import { TrendChart } from "@marianmeres/stuic/trend-chart";
|
|
71
|
+
</script>
|
|
72
|
+
|
|
73
|
+
<Stat label="Requests" value="1.2M" delta="+8.4%" trend="up" hint="last 7 days">
|
|
74
|
+
{#snippet renderFooter()}
|
|
75
|
+
<TrendChart data={[42, 51, 48, 63, 58, 71, 84]} sparkline />
|
|
76
|
+
{/snippet}
|
|
77
|
+
</Stat>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Props
|
|
81
|
+
|
|
82
|
+
| Prop | Type | Default | Description |
|
|
83
|
+
| ----------- | ------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
84
|
+
| `data` | `TrendData` | — | The series: `DataPoint[]` or plain `number[]` shorthand (index becomes x). Reactive. |
|
|
85
|
+
| `options` | `TrendChartOptions` | — | [`@marianmeres/trend-chart` options](https://github.com/marianmeres/trend-chart/blob/master/API.md), passed through. Reactive. Merged OVER the sparkline preset. |
|
|
86
|
+
| `sparkline` | `boolean` | `false` | Preset: no axes/grid/pan/zoom/points + compact default height |
|
|
87
|
+
| `chart` | `TrendChart` | — | Bindable underlying instance (`setDomainX`, `resetDomain`, ...). `undefined` during SSR/before mount. |
|
|
88
|
+
| `unstyled` | `boolean` | `false` | Skip all default styling — including the default height; size the container yourself |
|
|
89
|
+
| `class` | `string` | - | Additional CSS classes for the container |
|
|
90
|
+
| `el` | `HTMLElement` | - | Bindable element reference (the chart's container) |
|
|
91
|
+
|
|
92
|
+
## CSS Variables
|
|
93
|
+
|
|
94
|
+
| Variable | Default | Description |
|
|
95
|
+
| -------------------------------------- | ------------------------------------- | --------------------------------- |
|
|
96
|
+
| `--stuic-trend-chart-height` | `8rem` | Container height |
|
|
97
|
+
| `--stuic-trend-chart-height-sparkline` | `2.5rem` | Container height with `sparkline` |
|
|
98
|
+
| `--stuic-trend-chart-line` | `var(--stuic-color-primary)` | Line stroke |
|
|
99
|
+
| `--stuic-trend-chart-fill` | `var(--stuic-color-primary)` | Area fill base color |
|
|
100
|
+
| `--stuic-trend-chart-grid` | `var(--stuic-color-border)` | Gridline stroke |
|
|
101
|
+
| `--stuic-trend-chart-label` | `var(--stuic-color-muted-foreground)` | Axis label color |
|
|
102
|
+
| `--stuic-trend-chart-font` | `var(--font-sans)` | Label font family |
|
|
103
|
+
| `--stuic-trend-chart-end-dot-ring` | `var(--stuic-color-background)` | End-dot/hover-dot ring color |
|
|
104
|
+
| `--stuic-trend-chart-annotation` | `var(--stuic-color-warning)` | Annotation rule + label color |
|
|
105
|
+
| `--stuic-trend-chart-annotation-halo` | `var(--stuic-color-background)` | Halo behind annotation labels |
|
|
106
|
+
|
|
107
|
+
These map onto the chart's own `--trend-chart-*` hooks (active because the DOM
|
|
108
|
+
renderer's `cssVars` option defaults to `true`). Any `lineColor`/`fill`/... option
|
|
109
|
+
you pass still acts as the fallback inside the `var()` wrapper.
|
|
110
|
+
|
|
111
|
+
## Notes
|
|
112
|
+
|
|
113
|
+
- **Sizing**: the chart measures its container (via `ResizeObserver`), so the
|
|
114
|
+
container needs a real size. The default styles provide the height
|
|
115
|
+
(`--stuic-trend-chart-height`); with `unstyled` you must size it yourself, or
|
|
116
|
+
pass explicit `width`/`height` in `options`.
|
|
117
|
+
- **SSR**: the chart is created in an effect, so the server renders an empty
|
|
118
|
+
container. For static server-rendered charts use the library's
|
|
119
|
+
`renderToString` directly.
|
|
120
|
+
- Single-series by design (the underlying library's scope): one line/area — no
|
|
121
|
+
bars, pies, or multi-series.
|
|
122
|
+
- The chart instance is created once per container; `data`/`options` changes
|
|
123
|
+
patch it in place, so pan/zoom state survives updates.
|