@clicoh/orion-library 1.2.0-beta.11 → 1.2.0-beta.12

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.
Files changed (41) hide show
  1. package/dist/components/01-atoms/CodeBlock/CodeBlock.d.ts +56 -0
  2. package/dist/components/01-atoms/CodeBlock/CodeBlock.d.ts.map +1 -0
  3. package/dist/components/01-atoms/CodeBlock/CodeBlock.jsx +97 -0
  4. package/dist/components/01-atoms/CodeBlock/CodeBlock.jsx.map +1 -0
  5. package/dist/components/01-atoms/CodeBlock/index.d.ts +2 -0
  6. package/dist/components/01-atoms/CodeBlock/index.d.ts.map +1 -0
  7. package/dist/components/01-atoms/CodeBlock/index.js +2 -0
  8. package/dist/components/01-atoms/CodeBlock/index.js.map +1 -0
  9. package/dist/components/01-atoms/Stat/Stat.d.ts +44 -0
  10. package/dist/components/01-atoms/Stat/Stat.d.ts.map +1 -0
  11. package/dist/components/01-atoms/Stat/Stat.jsx +60 -0
  12. package/dist/components/01-atoms/Stat/Stat.jsx.map +1 -0
  13. package/dist/components/01-atoms/Stat/index.d.ts +2 -0
  14. package/dist/components/01-atoms/Stat/index.d.ts.map +1 -0
  15. package/dist/components/01-atoms/Stat/index.js +2 -0
  16. package/dist/components/01-atoms/Stat/index.js.map +1 -0
  17. package/dist/components/01-atoms/index.d.ts +2 -0
  18. package/dist/components/01-atoms/index.d.ts.map +1 -1
  19. package/dist/components/01-atoms/index.js +2 -0
  20. package/dist/components/01-atoms/index.js.map +1 -1
  21. package/dist/components/02-molecules/Stepper/Stepper.d.ts +70 -0
  22. package/dist/components/02-molecules/Stepper/Stepper.d.ts.map +1 -0
  23. package/dist/components/02-molecules/Stepper/Stepper.jsx +204 -0
  24. package/dist/components/02-molecules/Stepper/Stepper.jsx.map +1 -0
  25. package/dist/components/02-molecules/Stepper/index.d.ts +2 -0
  26. package/dist/components/02-molecules/Stepper/index.d.ts.map +1 -0
  27. package/dist/components/02-molecules/Stepper/index.js +2 -0
  28. package/dist/components/02-molecules/Stepper/index.js.map +1 -0
  29. package/dist/components/02-molecules/Timeline/Timeline.d.ts +47 -0
  30. package/dist/components/02-molecules/Timeline/Timeline.d.ts.map +1 -0
  31. package/dist/components/02-molecules/Timeline/Timeline.jsx +65 -0
  32. package/dist/components/02-molecules/Timeline/Timeline.jsx.map +1 -0
  33. package/dist/components/02-molecules/Timeline/index.d.ts +2 -0
  34. package/dist/components/02-molecules/Timeline/index.d.ts.map +1 -0
  35. package/dist/components/02-molecules/Timeline/index.js +2 -0
  36. package/dist/components/02-molecules/Timeline/index.js.map +1 -0
  37. package/dist/components/02-molecules/index.d.ts +2 -0
  38. package/dist/components/02-molecules/index.d.ts.map +1 -1
  39. package/dist/components/02-molecules/index.js +2 -0
  40. package/dist/components/02-molecules/index.js.map +1 -1
  41. package/package.json +1 -1
@@ -0,0 +1,56 @@
1
+ import { type HTMLAttributes, type ReactNode } from 'react';
2
+ /** Inclusive range of line numbers, counted from `startLine`. */
3
+ export type CodeBlockRange = [from: number, to: number];
4
+ export type CodeBlockProps = {
5
+ /** The source to show, as plain text. */
6
+ code: string;
7
+ /** Accessible name and tooltip of the copy button. */
8
+ copyLabel: string;
9
+ /** Replaces `copyLabel` for a moment after copying, and is announced. */
10
+ copiedLabel: string;
11
+ /** Shown in the header (`ts`, `sql`, `diff`). No syntax coloring is applied. */
12
+ language?: string;
13
+ /** Number of the first line. Line numbers are shown only when it is set. */
14
+ startLine?: number;
15
+ /** Lines to emphasize, as inclusive ranges in the same numbering. */
16
+ highlight?: CodeBlockRange[];
17
+ /** Called when the browser refuses to write to the clipboard. */
18
+ onCopyError?: (error: unknown) => void;
19
+ } & Omit<HTMLAttributes<HTMLDivElement>, 'children'>;
20
+ /**
21
+ * Read-only block of source code with a copy button. Shows an excerpt
22
+ * exactly as written: monospace, no wrapping, horizontal scroll when a line
23
+ * is longer than the block.
24
+ *
25
+ * Setting `startLine` numbers the lines, so an excerpt from the middle of a
26
+ * file keeps its real line numbers; `highlight` then marks ranges in that
27
+ * same numbering. There is no syntax coloring.
28
+ *
29
+ * Copying uses the Clipboard API, which browsers only expose on secure
30
+ * origins (`https` or `localhost`). When it fails the button stays as it was
31
+ * and `onCopyError` receives the reason.
32
+ *
33
+ * @component
34
+ * @example
35
+ * <CodeBlock
36
+ * code={excerpt}
37
+ * language="ts"
38
+ * startLine={940}
39
+ * highlight={[[943, 943]]}
40
+ * copyLabel="Copy code"
41
+ * copiedLabel="Copied"
42
+ * />
43
+ *
44
+ * @param {Object} props - The properties of the CodeBlock component.
45
+ * @param {string} props.code - The source to show, as plain text.
46
+ * @param {string} props.copyLabel - Accessible name and tooltip of the copy button.
47
+ * @param {string} props.copiedLabel - Shown and announced right after copying.
48
+ * @param {string} [props.language] - Label shown in the header.
49
+ * @param {number} [props.startLine] - Number of the first line; enables line numbers.
50
+ * @param {CodeBlockRange[]} [props.highlight=[]] - Inclusive line ranges to emphasize.
51
+ * @param {(error: unknown) => void} [props.onCopyError] - Called when the clipboard write fails.
52
+ *
53
+ * @returns {ReactNode} The rendered CodeBlock component.
54
+ */
55
+ export declare function CodeBlock({ code, copyLabel, copiedLabel, language, startLine, highlight, onCopyError, ...restProps }: CodeBlockProps): ReactNode;
56
+ //# sourceMappingURL=CodeBlock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeBlock.d.ts","sourceRoot":"","sources":["../../../../src/components/01-atoms/CodeBlock/CodeBlock.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AAKf,iEAAiE;AACjE,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;AAExD,MAAM,MAAM,cAAc,GAAG;IAC3B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,iEAAiE;IACjE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACxC,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,CAAC;AAQrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,SAAS,EACT,WAAW,EACX,QAAQ,EACR,SAAS,EACT,SAAc,EACd,WAAW,EACX,GAAG,SAAS,EACb,EAAE,cAAc,GAAG,SAAS,CAgG5B"}
@@ -0,0 +1,97 @@
1
+ 'use client';
2
+ import clsx from 'clsx';
3
+ import { useEffect, useRef, useState, } from 'react';
4
+ import { FiCheck, FiCopy } from 'react-icons/fi';
5
+ import { Each } from '../../00-base';
6
+ import { IconButton } from '../IconButton';
7
+ const COPIED_FEEDBACK_MS = 1600;
8
+ function isHighlighted(line, ranges) {
9
+ return ranges.some(([from, to]) => line >= from && line <= to);
10
+ }
11
+ /**
12
+ * Read-only block of source code with a copy button. Shows an excerpt
13
+ * exactly as written: monospace, no wrapping, horizontal scroll when a line
14
+ * is longer than the block.
15
+ *
16
+ * Setting `startLine` numbers the lines, so an excerpt from the middle of a
17
+ * file keeps its real line numbers; `highlight` then marks ranges in that
18
+ * same numbering. There is no syntax coloring.
19
+ *
20
+ * Copying uses the Clipboard API, which browsers only expose on secure
21
+ * origins (`https` or `localhost`). When it fails the button stays as it was
22
+ * and `onCopyError` receives the reason.
23
+ *
24
+ * @component
25
+ * @example
26
+ * <CodeBlock
27
+ * code={excerpt}
28
+ * language="ts"
29
+ * startLine={940}
30
+ * highlight={[[943, 943]]}
31
+ * copyLabel="Copy code"
32
+ * copiedLabel="Copied"
33
+ * />
34
+ *
35
+ * @param {Object} props - The properties of the CodeBlock component.
36
+ * @param {string} props.code - The source to show, as plain text.
37
+ * @param {string} props.copyLabel - Accessible name and tooltip of the copy button.
38
+ * @param {string} props.copiedLabel - Shown and announced right after copying.
39
+ * @param {string} [props.language] - Label shown in the header.
40
+ * @param {number} [props.startLine] - Number of the first line; enables line numbers.
41
+ * @param {CodeBlockRange[]} [props.highlight=[]] - Inclusive line ranges to emphasize.
42
+ * @param {(error: unknown) => void} [props.onCopyError] - Called when the clipboard write fails.
43
+ *
44
+ * @returns {ReactNode} The rendered CodeBlock component.
45
+ */
46
+ export function CodeBlock({ code, copyLabel, copiedLabel, language, startLine, highlight = [], onCopyError, ...restProps }) {
47
+ const [isCopied, setIsCopied] = useState(false);
48
+ const resetTimer = useRef(undefined);
49
+ useEffect(() => () => clearTimeout(resetTimer.current), []);
50
+ const lines = code.replace(/\n$/, '').split('\n');
51
+ const isNumbered = startLine !== undefined;
52
+ const firstLine = startLine ?? 1;
53
+ const gutterWidth = `${String(firstLine + lines.length - 1).length}ch`;
54
+ const copy = async () => {
55
+ try {
56
+ await navigator.clipboard.writeText(code);
57
+ }
58
+ catch (error) {
59
+ onCopyError?.(error);
60
+ return;
61
+ }
62
+ setIsCopied(true);
63
+ clearTimeout(resetTimer.current);
64
+ resetTimer.current = setTimeout(() => setIsCopied(false), COPIED_FEEDBACK_MS);
65
+ };
66
+ return (<div {...restProps} className={clsx('border-gray-5 bg-gray-7 dark:border-gray-1 dark:bg-black-1 min-w-0 overflow-hidden rounded-lg border', restProps.className)}>
67
+ <div className="border-gray-5 dark:border-gray-1 flex items-center justify-between gap-2 border-b py-1 pr-1 pl-3">
68
+ <span className="text-gray-1 dark:text-gray-2 truncate text-xs leading-4">
69
+ {language}
70
+ </span>
71
+ <IconButton icon={isCopied ? <FiCheck /> : <FiCopy />} label={isCopied ? copiedLabel : copyLabel} onClick={copy}/>
72
+ <span role="status" className="sr-only">
73
+ {isCopied ? copiedLabel : ''}
74
+ </span>
75
+ </div>
76
+ <pre tabIndex={0} className="focus-visible:ring-lavender dark:focus-visible:ring-lavender-dark m-0 overflow-x-auto py-2 font-mono text-xs leading-5 text-black focus-visible:ring-2 focus-visible:outline-none focus-visible:ring-inset dark:text-white">
77
+ <code className="block min-w-max">
78
+ <Each of={lines} render={(line, index) => {
79
+ const number = firstLine + index;
80
+ const isMarked = isHighlighted(number, highlight);
81
+ return (<span className={clsx('flex', isMarked && 'bg-lavender-2 dark:bg-lavender-dark-1')}>
82
+ {isNumbered && (<span aria-hidden="true" style={{ width: gutterWidth }} className={clsx('box-content shrink-0 px-3 text-right select-none', isMarked
83
+ ? 'text-lavender dark:text-lavender-dark font-semibold'
84
+ : 'text-gray-1 dark:text-gray-2')}>
85
+ {number}
86
+ </span>)}
87
+ <span className={clsx('pr-3 whitespace-pre', !isNumbered && 'pl-3')}>
88
+ {line || ' '}
89
+ </span>
90
+ {'\n'}
91
+ </span>);
92
+ }}/>
93
+ </code>
94
+ </pre>
95
+ </div>);
96
+ }
97
+ //# sourceMappingURL=CodeBlock.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeBlock.jsx","sourceRoot":"","sources":["../../../../src/components/01-atoms/CodeBlock/CodeBlock.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './CodeBlock';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/01-atoms/CodeBlock/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './CodeBlock';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/01-atoms/CodeBlock/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
@@ -0,0 +1,44 @@
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ export type StatTone = 'default' | 'success' | 'warning' | 'error';
3
+ export type StatProps = {
4
+ /** What the number measures. */
5
+ label: string;
6
+ /** The figure, already formatted. */
7
+ value: ReactNode;
8
+ /** Change against a previous period, already formatted (`+12 %`). */
9
+ delta?: string;
10
+ /** Short context under the value (`last 30 days`). */
11
+ hint?: string;
12
+ /** Dot next to the label that grades the value. `default` shows none. */
13
+ tone?: StatTone;
14
+ /** Holds the space with placeholders while the value loads. */
15
+ isLoading?: boolean;
16
+ } & Omit<HTMLAttributes<HTMLDivElement>, 'children'>;
17
+ /**
18
+ * Card with one key figure: a label, the value in large type and an optional
19
+ * line of context. Meant for summary rows above a list or a report, where
20
+ * several of them sit side by side in a grid.
21
+ *
22
+ * `tone` adds a dot next to the label to grade the value. Color is never the
23
+ * only signal: the label, the delta or the hint has to say it in words too.
24
+ *
25
+ * @component
26
+ * @example
27
+ * <Stat label="Resolved" value="84 %" delta="+6 pts" hint="last 30 days" tone="success" />
28
+ *
29
+ * @example
30
+ * // While loading
31
+ * <Stat label="Average cost" value="" isLoading />
32
+ *
33
+ * @param {Object} props - The properties of the Stat component.
34
+ * @param {string} props.label - What the number measures.
35
+ * @param {ReactNode} props.value - The figure, already formatted.
36
+ * @param {string} [props.delta] - Change against a previous period, already formatted.
37
+ * @param {string} [props.hint] - Short context shown after the delta.
38
+ * @param {'default' | 'success' | 'warning' | 'error'} [props.tone='default'] - Dot next to the label that grades the value.
39
+ * @param {boolean} [props.isLoading=false] - Shows placeholders instead of the value and the context line.
40
+ *
41
+ * @returns {ReactNode} The rendered Stat component.
42
+ */
43
+ export declare function Stat({ label, value, delta, hint, tone, isLoading, ...restProps }: StatProps): ReactNode;
44
+ //# sourceMappingURL=Stat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stat.d.ts","sourceRoot":"","sources":["../../../../src/components/01-atoms/Stat/Stat.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvD,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAEnE,MAAM,MAAM,SAAS,GAAG;IACtB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,KAAK,EAAE,SAAS,CAAC;IACjB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,CAAC;AAUrD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,KAAK,EACL,KAAK,EACL,IAAI,EACJ,IAAgB,EAChB,SAAiB,EACjB,GAAG,SAAS,EACb,EAAE,SAAS,GAAG,SAAS,CAuCvB"}
@@ -0,0 +1,60 @@
1
+ import clsx from 'clsx';
2
+ import { Show } from '../../00-base';
3
+ import { Skeleton } from '../Skeleton';
4
+ // `warning` uses the amber family, like `ProgressBar`: the yellow token sits
5
+ // below the 3:1 a graphic needs against the surface.
6
+ const toneMap = {
7
+ success: 'bg-success dark:bg-success-dark',
8
+ warning: 'bg-amber dark:bg-amber-dark',
9
+ error: 'bg-error dark:bg-error-dark',
10
+ };
11
+ /**
12
+ * Card with one key figure: a label, the value in large type and an optional
13
+ * line of context. Meant for summary rows above a list or a report, where
14
+ * several of them sit side by side in a grid.
15
+ *
16
+ * `tone` adds a dot next to the label to grade the value. Color is never the
17
+ * only signal: the label, the delta or the hint has to say it in words too.
18
+ *
19
+ * @component
20
+ * @example
21
+ * <Stat label="Resolved" value="84 %" delta="+6 pts" hint="last 30 days" tone="success" />
22
+ *
23
+ * @example
24
+ * // While loading
25
+ * <Stat label="Average cost" value="" isLoading />
26
+ *
27
+ * @param {Object} props - The properties of the Stat component.
28
+ * @param {string} props.label - What the number measures.
29
+ * @param {ReactNode} props.value - The figure, already formatted.
30
+ * @param {string} [props.delta] - Change against a previous period, already formatted.
31
+ * @param {string} [props.hint] - Short context shown after the delta.
32
+ * @param {'default' | 'success' | 'warning' | 'error'} [props.tone='default'] - Dot next to the label that grades the value.
33
+ * @param {boolean} [props.isLoading=false] - Shows placeholders instead of the value and the context line.
34
+ *
35
+ * @returns {ReactNode} The rendered Stat component.
36
+ */
37
+ export function Stat({ label, value, delta, hint, tone = 'default', isLoading = false, ...restProps }) {
38
+ const context = [delta, hint].filter(Boolean).join(' · ');
39
+ return (<div {...restProps} aria-busy={isLoading || undefined} className={clsx('border-gray-5 dark:border-gray-1 flex min-w-0 flex-col gap-1 rounded-lg border p-4', restProps.className)}>
40
+ <p className="text-gray-1 dark:text-gray-2 flex items-center gap-1.5 text-xs leading-4">
41
+ {tone !== 'default' && (<span aria-hidden="true" className={clsx('size-1.5 shrink-0 rounded-full', toneMap[tone])}/>)}
42
+ {label}
43
+ </p>
44
+ <Show>
45
+ <Show.When isTrue={isLoading}>
46
+ <Skeleton shape="rect" className="h-8 w-24"/>
47
+ <Skeleton className="mt-1.5 w-32"/>
48
+ </Show.When>
49
+ <Show.Else>
50
+ <div className="text-2xl leading-8 font-semibold whitespace-nowrap text-black dark:text-white">
51
+ {value}
52
+ </div>
53
+ {context && (<p className="text-gray-1 dark:text-gray-2 text-xs leading-4">
54
+ {context}
55
+ </p>)}
56
+ </Show.Else>
57
+ </Show>
58
+ </div>);
59
+ }
60
+ //# sourceMappingURL=Stat.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stat.jsx","sourceRoot":"","sources":["../../../../src/components/01-atoms/Stat/Stat.tsx"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAmBvC,6EAA6E;AAC7E,qDAAqD;AACrD,MAAM,OAAO,GAAiD;IAC5D,OAAO,EAAE,iCAAiC;IAC1C,OAAO,EAAE,6BAA6B;IACtC,KAAK,EAAE,6BAA6B;CACrC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,IAAI,CAAC,EACnB,KAAK,EACL,KAAK,EACL,KAAK,EACL,IAAI,EACJ,IAAI,GAAG,SAAS,EAChB,SAAS,GAAG,KAAK,EACjB,GAAG,SAAS,EACF;IACV,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAE1D,OAAO,CACL,CAAC,GAAG,CACF,IAAI,SAAS,CAAC,CACd,SAAS,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC,CAClC,SAAS,CAAC,CAAC,IAAI,CACb,oFAAoF,EACpF,SAAS,CAAC,SAAS,CACpB,CAAC,CAEF;MAAA,CAAC,CAAC,CAAC,SAAS,CAAC,0EAA0E,CACrF;QAAA,CAAC,IAAI,KAAK,SAAS,IAAI,CACrB,CAAC,IAAI,CACH,WAAW,CAAC,MAAM,CAClB,SAAS,CAAC,CAAC,IAAI,CAAC,gCAAgC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EACjE,CACH,CACD;QAAA,CAAC,KAAK,CACR;MAAA,EAAE,CAAC,CACH;MAAA,CAAC,IAAI,CACH;QAAA,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAC3B;UAAA,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,EAC3C;UAAA,CAAC,QAAQ,CAAC,SAAS,CAAC,aAAa,EACnC;QAAA,EAAE,IAAI,CAAC,IAAI,CACX;QAAA,CAAC,IAAI,CAAC,IAAI,CACR;UAAA,CAAC,GAAG,CAAC,SAAS,CAAC,+EAA+E,CAC5F;YAAA,CAAC,KAAK,CACR;UAAA,EAAE,GAAG,CACL;UAAA,CAAC,OAAO,IAAI,CACV,CAAC,CAAC,CAAC,SAAS,CAAC,gDAAgD,CAC3D;cAAA,CAAC,OAAO,CACV;YAAA,EAAE,CAAC,CAAC,CACL,CACH;QAAA,EAAE,IAAI,CAAC,IAAI,CACb;MAAA,EAAE,IAAI,CACR;IAAA,EAAE,GAAG,CAAC,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './Stat';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/01-atoms/Stat/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './Stat';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/01-atoms/Stat/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC"}
@@ -23,4 +23,6 @@ export * from './OtpInput';
23
23
  export * from './ThemeSwitch';
24
24
  export * from './SmallInput';
25
25
  export * from './CountryFlag';
26
+ export * from './Stat';
27
+ export * from './CodeBlock';
26
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/01-atoms/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/01-atoms/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC"}
@@ -23,4 +23,6 @@ export * from './OtpInput';
23
23
  export * from './ThemeSwitch';
24
24
  export * from './SmallInput';
25
25
  export * from './CountryFlag';
26
+ export * from './Stat';
27
+ export * from './CodeBlock';
26
28
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/01-atoms/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/01-atoms/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { type HTMLAttributes, type ReactNode } from 'react';
2
+ export type StepperStepState = 'done' | 'current' | 'pending' | 'skipped';
3
+ export type StepperStep = {
4
+ id: string;
5
+ label: string;
6
+ state: StepperStepState;
7
+ };
8
+ export type StepperOrientation = 'horizontal' | 'vertical';
9
+ export type StepperSize = 'md' | 'sm';
10
+ export type StepperProps = {
11
+ /** Steps in order. Their state is owned by the consumer. */
12
+ steps: StepperStep[];
13
+ /** Accessible name of the list. */
14
+ ariaLabel: string;
15
+ /**
16
+ * Words for each state, read by screen readers after every label.
17
+ * `skipped` is also shown under skipped steps.
18
+ */
19
+ stateLabels: Record<StepperStepState, string>;
20
+ orientation?: StepperOrientation;
21
+ size?: StepperSize;
22
+ /**
23
+ * Horizontal only. `true` shows dots with the label of the current step
24
+ * alone, the rest in tooltips. `'auto'` switches to that when the labels
25
+ * no longer fit.
26
+ */
27
+ compact?: boolean | 'auto';
28
+ /** Horizontal only. Minimum width of each step, in pixels. */
29
+ minStepWidth?: number;
30
+ } & Omit<HTMLAttributes<HTMLOListElement>, 'children' | 'aria-label'>;
31
+ /**
32
+ * Ordered list of the steps of a process, showing which are done, which one
33
+ * is current, which are still pending and which were skipped. It only
34
+ * displays progress: the consumer owns every state, and steps are not
35
+ * clickable.
36
+ *
37
+ * Horizontal by default; `vertical` stacks the steps for side panels and
38
+ * narrow screens, and lets long labels wrap. In horizontal mode labels never
39
+ * wrap: `compact` keeps the dots and leaves only the current label visible,
40
+ * the rest in tooltips, and `compact="auto"` switches to that by itself when
41
+ * the container is too narrow for the labels.
42
+ *
43
+ * Every label is followed, for screen readers, by the word for its state in
44
+ * `stateLabels`; the current step carries `aria-current="step"`.
45
+ *
46
+ * @component
47
+ * @example
48
+ * <Stepper
49
+ * ariaLabel="Progress"
50
+ * stateLabels={{ done: 'done', current: 'in progress', pending: 'pending', skipped: 'skipped' }}
51
+ * steps={[
52
+ * { id: 'read', label: 'Read', state: 'done' },
53
+ * { id: 'search', label: 'Search', state: 'current' },
54
+ * { id: 'answer', label: 'Answer', state: 'pending' },
55
+ * ]}
56
+ * />
57
+ *
58
+ * @param {Object} props - The properties of the Stepper component.
59
+ * @param {StepperStep[]} props.steps - Steps in order, each with `id`, `label` and `state`.
60
+ * @param {string} props.ariaLabel - Accessible name of the list.
61
+ * @param {Record<StepperStepState, string>} props.stateLabels - Words for each state; `skipped` is also shown.
62
+ * @param {'horizontal' | 'vertical'} [props.orientation='horizontal'] - Direction of the list.
63
+ * @param {'md' | 'sm'} [props.size='md'] - Size of the dots (20px or 16px).
64
+ * @param {boolean | 'auto'} [props.compact=false] - Horizontal only: dots with the current label alone.
65
+ * @param {number} [props.minStepWidth=80] - Horizontal only: minimum width of each step in pixels.
66
+ *
67
+ * @returns {ReactNode} The rendered Stepper component, or `null` without steps.
68
+ */
69
+ export declare function Stepper({ steps, ariaLabel, stateLabels, orientation, size, compact, minStepWidth, ...restProps }: StepperProps): ReactNode;
70
+ //# sourceMappingURL=Stepper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stepper.d.ts","sourceRoot":"","sources":["../../../../src/components/02-molecules/Stepper/Stepper.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AAKf,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAE1E,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,gBAAgB,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,UAAU,CAAC;AAE3D,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,CAAC;AAEtC,MAAM,MAAM,YAAY,GAAG;IACzB,4DAA4D;IAC5D,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAC9C,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC,CAAC;AA4ItE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,SAAS,EACT,WAAW,EACX,WAA0B,EAC1B,IAAW,EACX,OAAe,EACf,YAAiB,EACjB,GAAG,SAAS,EACb,EAAE,YAAY,GAAG,SAAS,CA0L1B"}
@@ -0,0 +1,204 @@
1
+ 'use client';
2
+ import clsx from 'clsx';
3
+ import { useEffect, useRef, useState, } from 'react';
4
+ import { FiCheck } from 'react-icons/fi';
5
+ import { Each, Show } from '../../00-base';
6
+ import { Tooltip } from '../../01-atoms';
7
+ const LABEL_GUTTER = 12;
8
+ const REACHED_STATES = new Set([
9
+ 'done',
10
+ 'current',
11
+ ]);
12
+ const dotMap = {
13
+ done: 'bg-black text-white dark:bg-white dark:text-black',
14
+ current: 'border-2 border-lavender bg-lavender-3 dark:border-lavender-dark dark:bg-lavender-dark-1',
15
+ skipped: 'border border-dashed border-gray-3 bg-white dark:border-gray-1 dark:bg-black',
16
+ pending: 'border border-gray-3 bg-white dark:border-gray-1 dark:bg-black',
17
+ };
18
+ const dotSizeMap = {
19
+ md: { dot: 'size-5', check: 'size-3', inner: 'size-2' },
20
+ sm: { dot: 'size-4', check: 'size-2.5', inner: 'size-1.5' },
21
+ };
22
+ const labelMap = {
23
+ done: 'font-medium text-black dark:text-white',
24
+ current: 'font-semibold text-lavender dark:text-lavender-dark',
25
+ skipped: 'text-gray-1 dark:text-gray-2',
26
+ pending: 'text-gray-1 dark:text-gray-2',
27
+ };
28
+ const connectorMap = {
29
+ horizontal: {
30
+ reached: 'border-t-2 border-black dark:border-white',
31
+ pending: 'border-t border-gray-5 dark:border-gray-1',
32
+ skipped: 'border-t border-dashed border-gray-3 dark:border-gray-1',
33
+ none: 'border-t border-transparent',
34
+ },
35
+ vertical: {
36
+ reached: 'border-l-2 border-black dark:border-white',
37
+ pending: 'border-l border-gray-5 dark:border-gray-1',
38
+ skipped: 'border-l border-dashed border-gray-3 dark:border-gray-1',
39
+ none: 'border-l border-transparent',
40
+ },
41
+ };
42
+ function connectorBetween(from, to) {
43
+ if (!from || !to)
44
+ return 'none';
45
+ if (from.state === 'skipped' || to.state === 'skipped')
46
+ return 'skipped';
47
+ return REACHED_STATES.has(to.state) ? 'reached' : 'pending';
48
+ }
49
+ function labelAlignment(index, count) {
50
+ if (index === 0)
51
+ return 'justify-start';
52
+ if (index === count - 1)
53
+ return 'justify-end';
54
+ return 'justify-center';
55
+ }
56
+ function StepDot({ state, size, }) {
57
+ const sizes = dotSizeMap[size];
58
+ return (<span aria-hidden="true" className={clsx('flex shrink-0 items-center justify-center rounded-full', sizes.dot, dotMap[state])}>
59
+ {state === 'done' && <FiCheck strokeWidth={3} className={sizes.check}/>}
60
+ {state === 'current' && (<span className={clsx('bg-lavender dark:bg-lavender-dark rounded-full', sizes.inner)}/>)}
61
+ </span>);
62
+ }
63
+ function useAutoCompact(isEnabled, minStepWidth, stepCount, labelsKey) {
64
+ const listRef = useRef(null);
65
+ const measureRef = useRef(null);
66
+ const [isTight, setIsTight] = useState(false);
67
+ useEffect(() => {
68
+ const list = listRef.current;
69
+ const measure = measureRef.current;
70
+ if (!isEnabled ||
71
+ !list ||
72
+ !measure ||
73
+ typeof ResizeObserver === 'undefined') {
74
+ return;
75
+ }
76
+ const update = () => {
77
+ const widest = Math.max(0, ...Array.from(measure.children, (label) => label.scrollWidth));
78
+ const needed = Math.max(minStepWidth, widest + LABEL_GUTTER);
79
+ setIsTight(list.clientWidth / Math.max(1, stepCount) < needed);
80
+ };
81
+ const observer = new ResizeObserver(update);
82
+ observer.observe(list);
83
+ update();
84
+ return () => observer.disconnect();
85
+ }, [isEnabled, minStepWidth, stepCount, labelsKey]);
86
+ return { listRef, measureRef, isTight: isEnabled && isTight };
87
+ }
88
+ /**
89
+ * Ordered list of the steps of a process, showing which are done, which one
90
+ * is current, which are still pending and which were skipped. It only
91
+ * displays progress: the consumer owns every state, and steps are not
92
+ * clickable.
93
+ *
94
+ * Horizontal by default; `vertical` stacks the steps for side panels and
95
+ * narrow screens, and lets long labels wrap. In horizontal mode labels never
96
+ * wrap: `compact` keeps the dots and leaves only the current label visible,
97
+ * the rest in tooltips, and `compact="auto"` switches to that by itself when
98
+ * the container is too narrow for the labels.
99
+ *
100
+ * Every label is followed, for screen readers, by the word for its state in
101
+ * `stateLabels`; the current step carries `aria-current="step"`.
102
+ *
103
+ * @component
104
+ * @example
105
+ * <Stepper
106
+ * ariaLabel="Progress"
107
+ * stateLabels={{ done: 'done', current: 'in progress', pending: 'pending', skipped: 'skipped' }}
108
+ * steps={[
109
+ * { id: 'read', label: 'Read', state: 'done' },
110
+ * { id: 'search', label: 'Search', state: 'current' },
111
+ * { id: 'answer', label: 'Answer', state: 'pending' },
112
+ * ]}
113
+ * />
114
+ *
115
+ * @param {Object} props - The properties of the Stepper component.
116
+ * @param {StepperStep[]} props.steps - Steps in order, each with `id`, `label` and `state`.
117
+ * @param {string} props.ariaLabel - Accessible name of the list.
118
+ * @param {Record<StepperStepState, string>} props.stateLabels - Words for each state; `skipped` is also shown.
119
+ * @param {'horizontal' | 'vertical'} [props.orientation='horizontal'] - Direction of the list.
120
+ * @param {'md' | 'sm'} [props.size='md'] - Size of the dots (20px or 16px).
121
+ * @param {boolean | 'auto'} [props.compact=false] - Horizontal only: dots with the current label alone.
122
+ * @param {number} [props.minStepWidth=80] - Horizontal only: minimum width of each step in pixels.
123
+ *
124
+ * @returns {ReactNode} The rendered Stepper component, or `null` without steps.
125
+ */
126
+ export function Stepper({ steps, ariaLabel, stateLabels, orientation = 'horizontal', size = 'md', compact = false, minStepWidth = 80, ...restProps }) {
127
+ const isHorizontal = orientation === 'horizontal';
128
+ const { listRef, measureRef, isTight } = useAutoCompact(isHorizontal && compact === 'auto', minStepWidth, steps.length, steps.map((step) => step.label).join('\u0000'));
129
+ if (steps.length === 0)
130
+ return null;
131
+ const isCompact = isHorizontal && (compact === true || isTight);
132
+ const dotSize = isCompact ? 'sm' : size;
133
+ const srState = (state) => (<span className="sr-only">, {stateLabels[state]}</span>);
134
+ const skippedCaption = (state) => state === 'skipped' && (<span aria-hidden="true" className="text-gray-1 dark:text-gray-2 text-xs leading-4">
135
+ {stateLabels.skipped}
136
+ </span>);
137
+ if (!isHorizontal) {
138
+ return (<ol {...restProps} aria-label={ariaLabel} className={clsx('flex flex-col', restProps.className)}>
139
+ <Each of={steps} render={(step, index) => {
140
+ const isLast = index === steps.length - 1;
141
+ return (<li key={step.id} aria-current={step.state === 'current' ? 'step' : undefined} className="flex gap-3">
142
+ <span aria-hidden="true" className="flex flex-col items-center">
143
+ <StepDot state={step.state} size={dotSize}/>
144
+ {!isLast && (<span className={clsx('min-h-4 flex-1', connectorMap.vertical[connectorBetween(step, steps[index + 1])])}/>)}
145
+ </span>
146
+ <span className={clsx('flex min-w-0 flex-col', dotSize === 'md' && 'pt-0.5', !isLast && 'pb-4')}>
147
+ <span className={clsx('text-xs leading-4 text-pretty', labelMap[step.state])}>
148
+ {step.label}
149
+ {srState(step.state)}
150
+ </span>
151
+ {skippedCaption(step.state)}
152
+ </span>
153
+ </li>);
154
+ }}/>
155
+ </ol>);
156
+ }
157
+ return (<>
158
+ <ol {...restProps} ref={listRef} aria-label={ariaLabel} className={clsx('flex w-full items-start', restProps.className)}>
159
+ <Each of={steps} render={(step, index) => {
160
+ const isCurrent = step.state === 'current';
161
+ const before = connectorBetween(steps[index - 1], step);
162
+ const after = connectorBetween(step, steps[index + 1]);
163
+ return (<li key={step.id} aria-current={isCurrent ? 'step' : undefined} style={compact === false ? { minWidth: minStepWidth } : undefined} className="flex min-w-0 flex-1 flex-col items-center gap-2">
164
+ <div className="flex w-full items-center">
165
+ <span aria-hidden="true" className={clsx('flex-1', connectorMap.horizontal[before])}/>
166
+ <Show>
167
+ <Show.When isTrue={isCompact && !isCurrent}>
168
+ <Tooltip message={step.label}>
169
+ <span tabIndex={0} className="focus-visible:ring-lavender dark:focus-visible:ring-lavender-dark flex rounded-full focus-visible:ring-2 focus-visible:outline-none">
170
+ <StepDot state={step.state} size={dotSize}/>
171
+ <span className="sr-only">
172
+ {step.label}, {stateLabels[step.state]}
173
+ </span>
174
+ </span>
175
+ </Tooltip>
176
+ </Show.When>
177
+ <Show.Else>
178
+ <StepDot state={step.state} size={dotSize}/>
179
+ </Show.Else>
180
+ </Show>
181
+ <span aria-hidden="true" className={clsx('flex-1', connectorMap.horizontal[after])}/>
182
+ </div>
183
+ {(!isCompact || isCurrent) && (<span className={clsx('flex w-full', isCompact
184
+ ? labelAlignment(index, steps.length)
185
+ : 'justify-center px-1')}>
186
+ <span className="flex flex-col items-center gap-0.5">
187
+ <span className={clsx('text-xs leading-4 whitespace-nowrap', labelMap[step.state])}>
188
+ {step.label}
189
+ {srState(step.state)}
190
+ </span>
191
+ {skippedCaption(step.state)}
192
+ </span>
193
+ </span>)}
194
+ </li>);
195
+ }}/>
196
+ </ol>
197
+ {compact === 'auto' && (<div ref={measureRef} aria-hidden="true" className="pointer-events-none invisible absolute top-0 left-0 flex h-0 flex-col overflow-hidden">
198
+ <Each of={steps} render={(step) => (<span key={step.id} className="text-xs leading-4 font-semibold whitespace-nowrap">
199
+ {step.label}
200
+ </span>)}/>
201
+ </div>)}
202
+ </>);
203
+ }
204
+ //# sourceMappingURL=Stepper.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stepper.jsx","sourceRoot":"","sources":["../../../../src/components/02-molecules/Stepper/Stepper.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './Stepper';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/02-molecules/Stepper/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './Stepper';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/02-molecules/Stepper/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC"}
@@ -0,0 +1,47 @@
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ export type TimelineTone = 'neutral' | 'success' | 'warning' | 'error' | 'progress';
3
+ export type TimelineItem = {
4
+ id: string;
5
+ /** When it happened, already formatted for display. */
6
+ at: string;
7
+ /** Machine-readable date for `<time dateTime>` (ISO 8601). */
8
+ dateTime?: string;
9
+ /** Who did it. */
10
+ actor?: string;
11
+ /** What happened. */
12
+ text: ReactNode;
13
+ /** Color of the dot. */
14
+ tone?: TimelineTone;
15
+ };
16
+ export type TimelineProps = {
17
+ /** Events in the order they should read, usually oldest first. */
18
+ items: TimelineItem[];
19
+ /** Accessible name of the list. */
20
+ ariaLabel: string;
21
+ } & Omit<HTMLAttributes<HTMLOListElement>, 'children' | 'aria-label'>;
22
+ /**
23
+ * Vertical list of dated events: a dot and a rule on the left, and for each
24
+ * event a line with its time and author over the description. For activity
25
+ * logs and change histories, read top to bottom in the order given.
26
+ *
27
+ * `tone` colors the dot. Color is never the only signal: the text has to say
28
+ * what happened in words too.
29
+ *
30
+ * @component
31
+ * @example
32
+ * <Timeline
33
+ * ariaLabel="Activity"
34
+ * items={[
35
+ * { id: '1', at: '09:12', dateTime: '2026-10-10T09:12', actor: 'Ana', text: 'Opened the request' },
36
+ * { id: '2', at: '09:40', text: 'Answer sent', tone: 'success' },
37
+ * ]}
38
+ * />
39
+ *
40
+ * @param {Object} props - The properties of the Timeline component.
41
+ * @param {TimelineItem[]} props.items - Events with `id`, `at`, `text` and optional `dateTime`, `actor`, `tone`.
42
+ * @param {string} props.ariaLabel - Accessible name of the list.
43
+ *
44
+ * @returns {ReactNode} The rendered Timeline component, or `null` without items.
45
+ */
46
+ export declare function Timeline({ items, ariaLabel, ...restProps }: TimelineProps): ReactNode;
47
+ //# sourceMappingURL=Timeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Timeline.d.ts","sourceRoot":"","sources":["../../../../src/components/02-molecules/Timeline/Timeline.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvD,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,SAAS,GACT,SAAS,GACT,OAAO,GACP,UAAU,CAAC;AAEf,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,uDAAuD;IACvD,EAAE,EAAE,MAAM,CAAC;IACX,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,IAAI,EAAE,SAAS,CAAC;IAChB,wBAAwB;IACxB,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,kEAAkE;IAClE,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC,CAAC;AAYtE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,SAAS,EACT,GAAG,SAAS,EACb,EAAE,aAAa,GAAG,SAAS,CAyD3B"}
@@ -0,0 +1,65 @@
1
+ import clsx from 'clsx';
2
+ import { Each } from '../../00-base';
3
+ // `warning` uses the amber family, like `ProgressBar`: the yellow token sits
4
+ // below the 3:1 a graphic needs against the surface.
5
+ const toneMap = {
6
+ neutral: 'bg-gray-3 dark:bg-gray-1',
7
+ success: 'bg-success dark:bg-success-dark',
8
+ warning: 'bg-amber dark:bg-amber-dark',
9
+ error: 'bg-error dark:bg-error-dark',
10
+ progress: 'bg-lavender dark:bg-lavender-dark',
11
+ };
12
+ /**
13
+ * Vertical list of dated events: a dot and a rule on the left, and for each
14
+ * event a line with its time and author over the description. For activity
15
+ * logs and change histories, read top to bottom in the order given.
16
+ *
17
+ * `tone` colors the dot. Color is never the only signal: the text has to say
18
+ * what happened in words too.
19
+ *
20
+ * @component
21
+ * @example
22
+ * <Timeline
23
+ * ariaLabel="Activity"
24
+ * items={[
25
+ * { id: '1', at: '09:12', dateTime: '2026-10-10T09:12', actor: 'Ana', text: 'Opened the request' },
26
+ * { id: '2', at: '09:40', text: 'Answer sent', tone: 'success' },
27
+ * ]}
28
+ * />
29
+ *
30
+ * @param {Object} props - The properties of the Timeline component.
31
+ * @param {TimelineItem[]} props.items - Events with `id`, `at`, `text` and optional `dateTime`, `actor`, `tone`.
32
+ * @param {string} props.ariaLabel - Accessible name of the list.
33
+ *
34
+ * @returns {ReactNode} The rendered Timeline component, or `null` without items.
35
+ */
36
+ export function Timeline({ items, ariaLabel, ...restProps }) {
37
+ if (items.length === 0)
38
+ return null;
39
+ return (<ol {...restProps} aria-label={ariaLabel} className={clsx('flex flex-col', restProps.className)}>
40
+ <Each of={items} render={(item, index) => {
41
+ const isLast = index === items.length - 1;
42
+ return (<li key={item.id} className="flex gap-3">
43
+ <span aria-hidden="true" className="flex w-2.5 shrink-0 flex-col items-center">
44
+ <span className={clsx('mt-[3px] size-2.5 shrink-0 rounded-full', toneMap[item.tone ?? 'neutral'])}/>
45
+ {!isLast && (<span className="bg-gray-5 dark:bg-gray-1 mt-1 w-px flex-1"/>)}
46
+ </span>
47
+ <div className={clsx('flex min-w-0 flex-col gap-0.5', !isLast && 'pb-4')}>
48
+ <p className="text-gray-1 dark:text-gray-2 text-xs leading-4">
49
+ <time dateTime={item.dateTime}>{item.at}</time>
50
+ {item.actor && (<>
51
+ {' · '}
52
+ <span className="font-semibold text-black dark:text-white">
53
+ {item.actor}
54
+ </span>
55
+ </>)}
56
+ </p>
57
+ <div className="text-xs leading-[18px] text-pretty text-black dark:text-white">
58
+ {item.text}
59
+ </div>
60
+ </div>
61
+ </li>);
62
+ }}/>
63
+ </ol>);
64
+ }
65
+ //# sourceMappingURL=Timeline.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Timeline.jsx","sourceRoot":"","sources":["../../../../src/components/02-molecules/Timeline/Timeline.tsx"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AA8BrC,6EAA6E;AAC7E,qDAAqD;AACrD,MAAM,OAAO,GAAiC;IAC5C,OAAO,EAAE,0BAA0B;IACnC,OAAO,EAAE,iCAAiC;IAC1C,OAAO,EAAE,6BAA6B;IACtC,KAAK,EAAE,6BAA6B;IACpC,QAAQ,EAAE,mCAAmC;CAC9C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,QAAQ,CAAC,EACvB,KAAK,EACL,SAAS,EACT,GAAG,SAAS,EACE;IACd,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,OAAO,CACL,CAAC,EAAE,CACD,IAAI,SAAS,CAAC,CACd,UAAU,CAAC,CAAC,SAAS,CAAC,CACtB,SAAS,CAAC,CAAC,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,CAEtD;MAAA,CAAC,IAAI,CACH,EAAE,CAAC,CAAC,KAAK,CAAC,CACV,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACtB,MAAM,MAAM,GAAG,KAAK,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YAE1C,OAAO,CACL,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,YAAY,CACtC;cAAA,CAAC,IAAI,CACH,WAAW,CAAC,MAAM,CAClB,SAAS,CAAC,2CAA2C,CAErD;gBAAA,CAAC,IAAI,CACH,SAAS,CAAC,CAAC,IAAI,CACb,yCAAyC,EACzC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC,CAChC,CAAC,EAEJ;gBAAA,CAAC,CAAC,MAAM,IAAI,CACV,CAAC,IAAI,CAAC,SAAS,CAAC,2CAA2C,EAAG,CAC/D,CACH;cAAA,EAAE,IAAI,CACN;cAAA,CAAC,GAAG,CACF,SAAS,CAAC,CAAC,IAAI,CACb,+BAA+B,EAC/B,CAAC,MAAM,IAAI,MAAM,CAClB,CAAC,CAEF;gBAAA,CAAC,CAAC,CAAC,SAAS,CAAC,gDAAgD,CAC3D;kBAAA,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAC9C;kBAAA,CAAC,IAAI,CAAC,KAAK,IAAI,CACb,EACE;sBAAA,CAAC,KAAK,CACN;sBAAA,CAAC,IAAI,CAAC,SAAS,CAAC,0CAA0C,CACxD;wBAAA,CAAC,IAAI,CAAC,KAAK,CACb;sBAAA,EAAE,IAAI,CACR;oBAAA,GAAG,CACJ,CACH;gBAAA,EAAE,CAAC,CACH;gBAAA,CAAC,GAAG,CAAC,SAAS,CAAC,+DAA+D,CAC5E;kBAAA,CAAC,IAAI,CAAC,IAAI,CACZ;gBAAA,EAAE,GAAG,CACP;cAAA,EAAE,GAAG,CACP;YAAA,EAAE,EAAE,CAAC,CACN,CAAC;QACJ,CAAC,CAAC,EAEN;IAAA,EAAE,EAAE,CAAC,CACN,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './Timeline';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/02-molecules/Timeline/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './Timeline';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/02-molecules/Timeline/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
@@ -19,4 +19,6 @@ export * from './TimePicker';
19
19
  export * from './BellNotifications';
20
20
  export * from './DatePicker';
21
21
  export * from './InlineMessage';
22
+ export * from './Stepper';
23
+ export * from './Timeline';
22
24
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/02-molecules/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/02-molecules/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC"}
@@ -19,4 +19,6 @@ export * from './TimePicker';
19
19
  export * from './BellNotifications';
20
20
  export * from './DatePicker';
21
21
  export * from './InlineMessage';
22
+ export * from './Stepper';
23
+ export * from './Timeline';
22
24
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/02-molecules/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/02-molecules/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clicoh/orion-library",
3
- "version": "1.2.0-beta.11",
3
+ "version": "1.2.0-beta.12",
4
4
  "main": "index.js",
5
5
  "dependencies": {
6
6
  "@floating-ui/react": "0.26.19",