@mithrl/design-system 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/approval-card/ApprovalCard.d.ts +56 -65
- package/dist/components/command-search/CommandSearch.d.ts +64 -0
- package/dist/components/dot-field/DotField.d.ts +102 -0
- package/dist/components/flowchart/Flowchart.d.ts +110 -0
- package/dist/components/flowchart/graphLayout.d.ts +35 -0
- package/dist/components/pixel-loader/PixelLoader.d.ts +94 -0
- package/dist/components/text-reveal/TextReveal.d.ts +62 -0
- package/dist/index.d.ts +13 -5
- package/dist/index.js +3402 -2502
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -1,70 +1,61 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type FormHTMLAttributes } from "react";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
export
|
|
3
|
+
export type ApprovalCardMode = "single" | "multi";
|
|
4
|
+
export type ApprovalCardOption = {
|
|
5
5
|
id: string;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface ApprovalQuestion {
|
|
6
|
+
title: string;
|
|
7
|
+
subtitle?: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
};
|
|
10
|
+
export type ApprovalCardQuestion = {
|
|
12
11
|
id: string;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export type
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
12
|
+
title: string;
|
|
13
|
+
mode: ApprovalCardMode;
|
|
14
|
+
options: readonly ApprovalCardOption[];
|
|
15
|
+
};
|
|
16
|
+
export type ApprovalCardAnswer = {
|
|
17
|
+
selectedOptionIds: readonly string[];
|
|
18
|
+
customValue: string;
|
|
19
|
+
};
|
|
20
|
+
export type ApprovalCardNavigationReason = "previous" | "next" | "continue" | "auto";
|
|
21
|
+
export type ApprovalCardLabels = {
|
|
22
|
+
customAnswer: string;
|
|
23
|
+
previousQuestion: string;
|
|
24
|
+
nextQuestion: string;
|
|
25
|
+
skip: string;
|
|
26
|
+
continue: string;
|
|
27
|
+
submit: string;
|
|
28
|
+
submitting: string;
|
|
29
|
+
};
|
|
30
|
+
type NativeApprovalCardProps = Omit<FormHTMLAttributes<HTMLFormElement>, "children" | "onSubmit">;
|
|
31
|
+
export type ApprovalCardProps = NativeApprovalCardProps & {
|
|
32
|
+
questions: readonly ApprovalCardQuestion[];
|
|
33
|
+
activeQuestionId: string;
|
|
34
|
+
answers: Readonly<Record<string, ApprovalCardAnswer | undefined>>;
|
|
35
|
+
onAnswerChange: (questionId: string, answer: ApprovalCardAnswer) => void;
|
|
36
|
+
onActiveQuestionChange: (questionId: string, reason: ApprovalCardNavigationReason) => void;
|
|
37
|
+
onSubmit: (answers: Readonly<Record<string, ApprovalCardAnswer | undefined>>) => void;
|
|
38
|
+
onSkip?: (questionId: string) => void;
|
|
39
|
+
error?: string;
|
|
40
|
+
submitting?: boolean;
|
|
41
|
+
disabled?: boolean;
|
|
42
|
+
showSkip?: boolean;
|
|
43
|
+
autoAdvanceSingle?: boolean;
|
|
44
|
+
labels?: Partial<ApprovalCardLabels>;
|
|
44
45
|
};
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
onComplete?: (answers: ApprovalAnswers) => void;
|
|
61
|
-
/** Fired when the scientist declines to answer and lets the agent decide. */
|
|
62
|
-
onSkip?: (answers: ApprovalAnswers) => void;
|
|
63
|
-
skipLabel?: string;
|
|
64
|
-
continueLabel?: string;
|
|
65
|
-
/** Label for the final page's primary action. */
|
|
66
|
-
completeLabel?: string;
|
|
67
|
-
/** Require a selection before the primary action enables. @default true */
|
|
68
|
-
requireAnswer?: boolean;
|
|
69
|
-
} & import("react").RefAttributes<HTMLElement>>;
|
|
46
|
+
export declare const ApprovalCard: import("react").ForwardRefExoticComponent<NativeApprovalCardProps & {
|
|
47
|
+
questions: readonly ApprovalCardQuestion[];
|
|
48
|
+
activeQuestionId: string;
|
|
49
|
+
answers: Readonly<Record<string, ApprovalCardAnswer | undefined>>;
|
|
50
|
+
onAnswerChange: (questionId: string, answer: ApprovalCardAnswer) => void;
|
|
51
|
+
onActiveQuestionChange: (questionId: string, reason: ApprovalCardNavigationReason) => void;
|
|
52
|
+
onSubmit: (answers: Readonly<Record<string, ApprovalCardAnswer | undefined>>) => void;
|
|
53
|
+
onSkip?: (questionId: string) => void;
|
|
54
|
+
error?: string;
|
|
55
|
+
submitting?: boolean;
|
|
56
|
+
disabled?: boolean;
|
|
57
|
+
showSkip?: boolean;
|
|
58
|
+
autoAdvanceSingle?: boolean;
|
|
59
|
+
labels?: Partial<ApprovalCardLabels>;
|
|
60
|
+
} & import("react").RefAttributes<HTMLFormElement>>;
|
|
70
61
|
export {};
|
|
@@ -13,6 +13,22 @@ export type CommandSearchItem = {
|
|
|
13
13
|
onSelect?: (item: CommandSearchItem) => void;
|
|
14
14
|
/** Removes the item from keyboard navigation and selection. */
|
|
15
15
|
disabled?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Opaque consumer payload, carried untouched through selection and
|
|
18
|
+
* `renderItem`. CommandSearch never reads it — it exists so a caller does not
|
|
19
|
+
* have to keep a parallel id-to-record map just to draw an icon or route a
|
|
20
|
+
* command.
|
|
21
|
+
*/
|
|
22
|
+
data?: unknown;
|
|
23
|
+
};
|
|
24
|
+
/** State handed to `renderItem` for one row. */
|
|
25
|
+
export type CommandSearchItemState = {
|
|
26
|
+
/** This row currently carries the roving highlight. */
|
|
27
|
+
active: boolean;
|
|
28
|
+
/** This row is not selectable and is skipped by keyboard navigation. */
|
|
29
|
+
disabled: boolean;
|
|
30
|
+
/** The live query, for a consumer highlighting its own text. */
|
|
31
|
+
query: string;
|
|
16
32
|
};
|
|
17
33
|
export type CommandSearchProps = Omit<HTMLAttributes<HTMLDivElement>, "children" | "onSelect"> & {
|
|
18
34
|
items: readonly CommandSearchItem[];
|
|
@@ -31,11 +47,38 @@ export type CommandSearchProps = Omit<HTMLAttributes<HTMLDivElement>, "children"
|
|
|
31
47
|
grouped?: boolean;
|
|
32
48
|
/** Secondary line shown under the empty-state title. */
|
|
33
49
|
emptyHint?: ReactNode;
|
|
50
|
+
/**
|
|
51
|
+
* Run the built-in label/group/hint substring filter. @default true
|
|
52
|
+
*
|
|
53
|
+
* Set `false` when the caller already filtered — an alias-aware catalog or a
|
|
54
|
+
* server content search, say. Every item then renders exactly as supplied
|
|
55
|
+
* and nothing is hidden, so a result that matched on something CommandSearch
|
|
56
|
+
* cannot see (an alias, a synonym, document body text) still appears. Match
|
|
57
|
+
* highlighting is unaffected: a label that happens to contain the query is
|
|
58
|
+
* still marked, and one that does not simply renders plain.
|
|
59
|
+
*/
|
|
60
|
+
filter?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Replaces the content of a row — icon, label, status, shortcut, whatever the
|
|
63
|
+
* surface needs. CommandSearch keeps ownership of the listbox and option
|
|
64
|
+
* semantics around it: ids, `role`, `aria-selected`, active handling, pointer
|
|
65
|
+
* and click wiring, and disabled skipping are all unchanged, so a custom row
|
|
66
|
+
* cannot break keyboard navigation.
|
|
67
|
+
*
|
|
68
|
+
* Default row content (marked label plus hint) is used when this is omitted.
|
|
69
|
+
*/
|
|
70
|
+
renderItem?: (item: CommandSearchItem, state: CommandSearchItemState) => ReactNode;
|
|
34
71
|
};
|
|
35
72
|
/**
|
|
36
73
|
* A command palette search surface. CommandSearch renders inline as an
|
|
37
74
|
* embedded panel and can be composed inside a Dialog by the consumer; it owns
|
|
38
75
|
* filtering, match highlighting, and roving keyboard selection only.
|
|
76
|
+
*
|
|
77
|
+
* Both halves of that are optional. A surface whose catalog already knows about
|
|
78
|
+
* aliases, or whose results come back from a server search, passes
|
|
79
|
+
* `filter={false}` and keeps the listbox semantics without the second,
|
|
80
|
+
* narrower filter running behind it. A surface needing richer rows than
|
|
81
|
+
* label-plus-hint passes `renderItem` and keeps the keyboard model.
|
|
39
82
|
*/
|
|
40
83
|
export declare const CommandSearch: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "children" | "onSelect"> & {
|
|
41
84
|
items: readonly CommandSearchItem[];
|
|
@@ -54,4 +97,25 @@ export declare const CommandSearch: import("react").ForwardRefExoticComponent<Om
|
|
|
54
97
|
grouped?: boolean;
|
|
55
98
|
/** Secondary line shown under the empty-state title. */
|
|
56
99
|
emptyHint?: ReactNode;
|
|
100
|
+
/**
|
|
101
|
+
* Run the built-in label/group/hint substring filter. @default true
|
|
102
|
+
*
|
|
103
|
+
* Set `false` when the caller already filtered — an alias-aware catalog or a
|
|
104
|
+
* server content search, say. Every item then renders exactly as supplied
|
|
105
|
+
* and nothing is hidden, so a result that matched on something CommandSearch
|
|
106
|
+
* cannot see (an alias, a synonym, document body text) still appears. Match
|
|
107
|
+
* highlighting is unaffected: a label that happens to contain the query is
|
|
108
|
+
* still marked, and one that does not simply renders plain.
|
|
109
|
+
*/
|
|
110
|
+
filter?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Replaces the content of a row — icon, label, status, shortcut, whatever the
|
|
113
|
+
* surface needs. CommandSearch keeps ownership of the listbox and option
|
|
114
|
+
* semantics around it: ids, `role`, `aria-selected`, active handling, pointer
|
|
115
|
+
* and click wiring, and disabled skipping are all unchanged, so a custom row
|
|
116
|
+
* cannot break keyboard navigation.
|
|
117
|
+
*
|
|
118
|
+
* Default row content (marked label plus hint) is used when this is omitted.
|
|
119
|
+
*/
|
|
120
|
+
renderItem?: (item: CommandSearchItem, state: CommandSearchItemState) => ReactNode;
|
|
57
121
|
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { type CSSProperties, type RefObject } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A plain rectangle in the field's own coordinate space — CSS pixels measured
|
|
5
|
+
* from the top-left of the canvas, not from the viewport. Stored as a plain
|
|
6
|
+
* object rather than a `DOMRect` so the exclusion maths can be tested without
|
|
7
|
+
* a DOM.
|
|
8
|
+
*/
|
|
9
|
+
export interface DotFieldRect {
|
|
10
|
+
left: number;
|
|
11
|
+
top: number;
|
|
12
|
+
right: number;
|
|
13
|
+
bottom: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Spotlight falloff at `distance` from the pointer, in `[0, 1]`.
|
|
17
|
+
*
|
|
18
|
+
* Quadratic rather than linear: the brightened region reads as a soft pool of
|
|
19
|
+
* light with no visible rim, because the derivative goes to zero at the edge.
|
|
20
|
+
* `0` at and beyond `radius`, `1` exactly under the pointer.
|
|
21
|
+
*
|
|
22
|
+
* A non-positive radius disables the spotlight entirely rather than dividing
|
|
23
|
+
* by zero.
|
|
24
|
+
*/
|
|
25
|
+
export declare function dotFieldFalloff(distance: number, radius: number): number;
|
|
26
|
+
/** Grow a rectangle equally on all sides. */
|
|
27
|
+
export declare function dotFieldInflateRect(rect: DotFieldRect, padding: number): DotFieldRect;
|
|
28
|
+
/**
|
|
29
|
+
* Shortest distance from a point to a rectangle. Zero when the point is inside
|
|
30
|
+
* or on the boundary.
|
|
31
|
+
*/
|
|
32
|
+
export declare function dotFieldDistanceToRect(x: number, y: number, rect: DotFieldRect): number;
|
|
33
|
+
/**
|
|
34
|
+
* How much of a dot survives the exclusion halo, in `[0, 1]`.
|
|
35
|
+
*
|
|
36
|
+
* `0` anywhere inside an already-inflated rect — no dot is drawn at all — then
|
|
37
|
+
* a linear ramp back to `1` over `feather` pixels outside it, so the halo has
|
|
38
|
+
* no hard cut. With several rects the smallest value wins, which is what makes
|
|
39
|
+
* overlapping halos merge into one hole instead of cancelling each other out.
|
|
40
|
+
*
|
|
41
|
+
* Rects are expected pre-inflated; `dotFieldInflateRect` does that separately
|
|
42
|
+
* so the padding is applied once per layout rather than once per dot.
|
|
43
|
+
*/
|
|
44
|
+
export declare function dotFieldExclusionAlpha(x: number, y: number, rects: readonly DotFieldRect[], feather: number): number;
|
|
45
|
+
export interface DotFieldProps {
|
|
46
|
+
/** Lattice pitch in CSS pixels. @default 24 */
|
|
47
|
+
spacing?: number;
|
|
48
|
+
/** Radius of a resting dot in CSS pixels. @default 0.5 */
|
|
49
|
+
dotRadius?: number;
|
|
50
|
+
/** Opacity of the resting lattice. @default 0.14 */
|
|
51
|
+
baseAlpha?: number;
|
|
52
|
+
/** Opacity directly under the pointer. @default 0.75 */
|
|
53
|
+
peakAlpha?: number;
|
|
54
|
+
/** Spotlight reach in CSS pixels. @default 180 */
|
|
55
|
+
radius?: number;
|
|
56
|
+
/** Dot scale directly under the pointer. @default 2.6 */
|
|
57
|
+
peakScale?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Element whose pointer movement drives the field. Defaults to the host's
|
|
60
|
+
* own parent, which is the common case: the field is the background layer of
|
|
61
|
+
* the section it reacts to.
|
|
62
|
+
*/
|
|
63
|
+
containerRef?: RefObject<HTMLElement | null>;
|
|
64
|
+
/**
|
|
65
|
+
* Element the lattice makes room for. Its bounding box, inflated by
|
|
66
|
+
* `exclusionPadding` and feathered, renders no dots. One element means one
|
|
67
|
+
* collective halo, however many children it wraps.
|
|
68
|
+
*/
|
|
69
|
+
exclusionRef?: RefObject<HTMLElement | null>;
|
|
70
|
+
/**
|
|
71
|
+
* Static exclusion rects in the field's own coordinate space, as an
|
|
72
|
+
* alternative to `exclusionRef`. Combined with it when both are given.
|
|
73
|
+
*/
|
|
74
|
+
exclusionRects?: readonly DotFieldRect[];
|
|
75
|
+
/** Inflation applied to every exclusion rect. @default 24 */
|
|
76
|
+
exclusionPadding?: number;
|
|
77
|
+
/** Alpha ramp width at the exclusion edge. @default 40 */
|
|
78
|
+
exclusionFeather?: number;
|
|
79
|
+
className?: string;
|
|
80
|
+
style?: CSSProperties;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Cursor-reactive dot lattice, as a full-bleed background layer.
|
|
84
|
+
*
|
|
85
|
+
* At rest it is a dim monotone grid of dots. Under the pointer a soft pool of
|
|
86
|
+
* light brightens and enlarges the dots it covers, trailing the cursor by a
|
|
87
|
+
* frame or two so the surface feels physical rather than pinned. An optional
|
|
88
|
+
* exclusion element punches a feathered hole in the lattice, so content
|
|
89
|
+
* floating above the field keeps a clean field of its own.
|
|
90
|
+
*
|
|
91
|
+
* Performance: the resting lattice is rasterised once to an offscreen canvas
|
|
92
|
+
* and blitted each frame, so per-frame work is bounded by the spotlight's
|
|
93
|
+
* footprint (a few hundred dots) rather than the page's (several thousand).
|
|
94
|
+
* The rAF loop runs only while the pointer is inside and until the eased
|
|
95
|
+
* pointer settles; an untouched field costs nothing.
|
|
96
|
+
*
|
|
97
|
+
* Colour is resolved from `--color-foreground` at draw time and re-resolved
|
|
98
|
+
* when `data-theme` changes, so the field is monotone and correct in both
|
|
99
|
+
* themes without a theme prop. It is decorative: `aria-hidden` and inert to
|
|
100
|
+
* pointer events.
|
|
101
|
+
*/
|
|
102
|
+
export declare function DotField({ spacing, dotRadius, baseAlpha, peakAlpha, radius, peakScale, containerRef, exclusionRef, exclusionRects, exclusionPadding, exclusionFeather, className, style, }: DotFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type HTMLAttributes, type ReactNode } from "react";
|
|
2
2
|
import { type IconGlyphComponent } from "../icon/Icon";
|
|
3
|
+
import { type FlowchartGraphEdge, type FlowchartGraphNodeKind } from "./graphLayout";
|
|
3
4
|
|
|
4
5
|
export type FlowchartCanvasProps = HTMLAttributes<HTMLDivElement> & {
|
|
5
6
|
/** Flow nodes and connectors, composed top to bottom. */
|
|
@@ -54,6 +55,11 @@ export type FlowchartTriggerProps = Omit<HTMLAttributes<HTMLDivElement>, "title"
|
|
|
54
55
|
eyebrow?: string;
|
|
55
56
|
/** Optional metadata slot, typically a `Tag`. */
|
|
56
57
|
trailing?: ReactNode;
|
|
58
|
+
/**
|
|
59
|
+
* Drag grip rendered at the card's leading edge. It repositions the card on
|
|
60
|
+
* the canvas; it does not reorder the flow, which stays owned by the edges.
|
|
61
|
+
*/
|
|
62
|
+
handle?: ReactNode;
|
|
57
63
|
};
|
|
58
64
|
/** The entry node of a flow. Carries an accent left treatment. */
|
|
59
65
|
export declare const FlowchartTrigger: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "children" | "title"> & {
|
|
@@ -67,6 +73,11 @@ export declare const FlowchartTrigger: import("react").ForwardRefExoticComponent
|
|
|
67
73
|
eyebrow?: string;
|
|
68
74
|
/** Optional metadata slot, typically a `Tag`. */
|
|
69
75
|
trailing?: ReactNode;
|
|
76
|
+
/**
|
|
77
|
+
* Drag grip rendered at the card's leading edge. It repositions the card on
|
|
78
|
+
* the canvas; it does not reorder the flow, which stays owned by the edges.
|
|
79
|
+
*/
|
|
80
|
+
handle?: ReactNode;
|
|
70
81
|
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
71
82
|
export type FlowchartActionProps = Omit<HTMLAttributes<HTMLDivElement>, "title"> & {
|
|
72
83
|
icon?: IconGlyphComponent;
|
|
@@ -79,6 +90,11 @@ export type FlowchartActionProps = Omit<HTMLAttributes<HTMLDivElement>, "title">
|
|
|
79
90
|
trailing?: ReactNode;
|
|
80
91
|
/** Extra detail rendered beneath the header. */
|
|
81
92
|
children?: ReactNode;
|
|
93
|
+
/**
|
|
94
|
+
* Drag grip rendered at the card's leading edge. It repositions the card on
|
|
95
|
+
* the canvas; it does not reorder the flow, which stays owned by the edges.
|
|
96
|
+
*/
|
|
97
|
+
handle?: ReactNode;
|
|
82
98
|
};
|
|
83
99
|
/** A generic executed step in the flow. */
|
|
84
100
|
export declare const FlowchartAction: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "title"> & {
|
|
@@ -92,6 +108,11 @@ export declare const FlowchartAction: import("react").ForwardRefExoticComponent<
|
|
|
92
108
|
trailing?: ReactNode;
|
|
93
109
|
/** Extra detail rendered beneath the header. */
|
|
94
110
|
children?: ReactNode;
|
|
111
|
+
/**
|
|
112
|
+
* Drag grip rendered at the card's leading edge. It repositions the card on
|
|
113
|
+
* the canvas; it does not reorder the flow, which stays owned by the edges.
|
|
114
|
+
*/
|
|
115
|
+
handle?: ReactNode;
|
|
95
116
|
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
96
117
|
export type FlowchartClauseJoin = "and" | "or";
|
|
97
118
|
export type FlowchartConditionClause = {
|
|
@@ -121,6 +142,11 @@ export type FlowchartConditionProps = Omit<HTMLAttributes<HTMLDivElement>, "titl
|
|
|
121
142
|
elseLabel?: string;
|
|
122
143
|
/** Optional metadata slot, typically a `Tag`. */
|
|
123
144
|
trailing?: ReactNode;
|
|
145
|
+
/**
|
|
146
|
+
* Drag grip rendered at the card's leading edge. It repositions the card on
|
|
147
|
+
* the canvas; it does not reorder the flow, which stays owned by the edges.
|
|
148
|
+
*/
|
|
149
|
+
handle?: ReactNode;
|
|
124
150
|
};
|
|
125
151
|
/** A branching If/Else node whose clauses read as inline chips. */
|
|
126
152
|
export declare const FlowchartCondition: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "title"> & {
|
|
@@ -137,4 +163,88 @@ export declare const FlowchartCondition: import("react").ForwardRefExoticCompone
|
|
|
137
163
|
elseLabel?: string;
|
|
138
164
|
/** Optional metadata slot, typically a `Tag`. */
|
|
139
165
|
trailing?: ReactNode;
|
|
166
|
+
/**
|
|
167
|
+
* Drag grip rendered at the card's leading edge. It repositions the card on
|
|
168
|
+
* the canvas; it does not reorder the flow, which stays owned by the edges.
|
|
169
|
+
*/
|
|
170
|
+
handle?: ReactNode;
|
|
171
|
+
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
172
|
+
type FlowchartGraphNodeBase = {
|
|
173
|
+
id: string;
|
|
174
|
+
title: ReactNode;
|
|
175
|
+
description?: ReactNode;
|
|
176
|
+
eyebrow?: string;
|
|
177
|
+
icon?: IconGlyphComponent;
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
* A node in a graph-laid-out flowchart.
|
|
181
|
+
*
|
|
182
|
+
* Discriminated on `kind` so that `clauses` is *required* for a condition and
|
|
183
|
+
* unavailable on the other kinds. `FlowchartCondition` throws without at least
|
|
184
|
+
* one clause, so a condition that omits them has no valid rendering — this
|
|
185
|
+
* turns that into a compile error instead of silently drawing the branch as an
|
|
186
|
+
* ordinary action step.
|
|
187
|
+
*/
|
|
188
|
+
export type FlowchartGraphNode = (FlowchartGraphNodeBase & {
|
|
189
|
+
kind: Exclude<FlowchartGraphNodeKind, "condition">;
|
|
190
|
+
clauses?: never;
|
|
191
|
+
}) | (FlowchartGraphNodeBase & {
|
|
192
|
+
kind: "condition";
|
|
193
|
+
clauses: readonly FlowchartConditionClause[];
|
|
194
|
+
});
|
|
195
|
+
export type FlowchartGraphProps = Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
|
|
196
|
+
nodes: readonly FlowchartGraphNode[];
|
|
197
|
+
edges: readonly FlowchartGraphEdge[];
|
|
198
|
+
/** Hides the dotted grid when the flow sits inside an already-textured surface. */
|
|
199
|
+
grid?: boolean;
|
|
200
|
+
/** Widest layer the layout will accept. @default 3 */
|
|
201
|
+
maxLanes?: number;
|
|
202
|
+
/** Largest graph the layout will accept. @default 12 */
|
|
203
|
+
maxNodes?: number;
|
|
204
|
+
/** Rendered when the graph is outside the supported layout bound. */
|
|
205
|
+
fallback?: ReactNode;
|
|
206
|
+
/**
|
|
207
|
+
* Gives every card the reorder grip and lets a reader move it around the
|
|
208
|
+
* canvas. The grip is a real button, so pointer drag has a full keyboard
|
|
209
|
+
* equivalent: arrow keys nudge by 8px, `Shift` + arrow by 32px, and `Escape`
|
|
210
|
+
* returns the card to its laid-out position — cancelling an in-flight pointer
|
|
211
|
+
* drag as well as undoing keyboard nudges. Positions are ephemeral: they live
|
|
212
|
+
* for the life of the mount and are never persisted, because the graph itself
|
|
213
|
+
* is still the source of truth.
|
|
214
|
+
*/
|
|
215
|
+
interactive?: boolean;
|
|
216
|
+
};
|
|
217
|
+
/**
|
|
218
|
+
* A bounded directed-acyclic flow: parallel branches sit side by side as lanes
|
|
219
|
+
* in the same layer, and lanes rejoin wherever a node has more than one
|
|
220
|
+
* incoming edge. Layout is automatic and presentation-only — the graph is
|
|
221
|
+
* already decided, `FlowchartGraph` only draws it.
|
|
222
|
+
*
|
|
223
|
+
* Supports at most `FLOWCHART_GRAPH_MAX_NODES` (12) nodes and
|
|
224
|
+
* `FLOWCHART_GRAPH_MAX_LANES` (3) parallel lanes per layer. Outside that
|
|
225
|
+
* bound it renders `fallback` (or nothing), so a consumer can present the flow
|
|
226
|
+
* some other way rather than show an unreadable tangle.
|
|
227
|
+
*/
|
|
228
|
+
export declare const FlowchartGraph: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
|
|
229
|
+
nodes: readonly FlowchartGraphNode[];
|
|
230
|
+
edges: readonly FlowchartGraphEdge[];
|
|
231
|
+
/** Hides the dotted grid when the flow sits inside an already-textured surface. */
|
|
232
|
+
grid?: boolean;
|
|
233
|
+
/** Widest layer the layout will accept. @default 3 */
|
|
234
|
+
maxLanes?: number;
|
|
235
|
+
/** Largest graph the layout will accept. @default 12 */
|
|
236
|
+
maxNodes?: number;
|
|
237
|
+
/** Rendered when the graph is outside the supported layout bound. */
|
|
238
|
+
fallback?: ReactNode;
|
|
239
|
+
/**
|
|
240
|
+
* Gives every card the reorder grip and lets a reader move it around the
|
|
241
|
+
* canvas. The grip is a real button, so pointer drag has a full keyboard
|
|
242
|
+
* equivalent: arrow keys nudge by 8px, `Shift` + arrow by 32px, and `Escape`
|
|
243
|
+
* returns the card to its laid-out position — cancelling an in-flight pointer
|
|
244
|
+
* drag as well as undoing keyboard nudges. Positions are ephemeral: they live
|
|
245
|
+
* for the life of the mount and are never persisted, because the graph itself
|
|
246
|
+
* is still the source of truth.
|
|
247
|
+
*/
|
|
248
|
+
interactive?: boolean;
|
|
140
249
|
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
250
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layered layout for the small directed acyclic graphs `FlowchartGraph`
|
|
3
|
+
* renders. The layout is deliberately bounded: past these limits a readable
|
|
4
|
+
* automatic layout stops being possible in a reading surface, and consumers
|
|
5
|
+
* are expected to fall back to their own presentation.
|
|
6
|
+
*/
|
|
7
|
+
export declare const FLOWCHART_GRAPH_MAX_NODES = 12;
|
|
8
|
+
export declare const FLOWCHART_GRAPH_MAX_LANES = 3;
|
|
9
|
+
export type FlowchartGraphNodeKind = "trigger" | "action" | "condition";
|
|
10
|
+
export type FlowchartGraphEdge = {
|
|
11
|
+
from: string;
|
|
12
|
+
to: string;
|
|
13
|
+
/** Short caption drawn on the run, e.g. `Yes` or `on failure`. */
|
|
14
|
+
label?: string;
|
|
15
|
+
/** Draws the run dashed to signal a conditional or indirect path. */
|
|
16
|
+
dashed?: boolean;
|
|
17
|
+
};
|
|
18
|
+
export type FlowchartGraphLayout = {
|
|
19
|
+
/** Node ids grouped into layers, first layer first. */
|
|
20
|
+
layers: readonly (readonly string[])[];
|
|
21
|
+
};
|
|
22
|
+
type LayoutInput = {
|
|
23
|
+
ids: readonly string[];
|
|
24
|
+
edges: readonly FlowchartGraphEdge[];
|
|
25
|
+
maxNodes?: number;
|
|
26
|
+
maxLanes?: number;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Assigns every node to a layer using longest-path layering, so an edge always
|
|
30
|
+
* runs from a lower layer to a higher one and merges land on a shared layer.
|
|
31
|
+
* Returns `null` when the graph is outside the supported bound: unknown edge
|
|
32
|
+
* endpoints, a cycle, too many nodes, or a layer wider than the lane limit.
|
|
33
|
+
*/
|
|
34
|
+
export declare function layoutFlowchartGraph({ ids, edges, maxNodes, maxLanes, }: LayoutInput): FlowchartGraphLayout | null;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The pixel grid is always square. Five columns is the smallest grid that still
|
|
5
|
+
* reads as a *pattern* rather than a row of dots at 16px, and stays crisp at 50.
|
|
6
|
+
*/
|
|
7
|
+
export declare const PIXEL_LOADER_GRID = 5;
|
|
8
|
+
/**
|
|
9
|
+
* Motion patterns. Each is a distinct reading of the same grid, not a speed
|
|
10
|
+
* variation of one loop:
|
|
11
|
+
*
|
|
12
|
+
* - `dots` — cells pulse in a scattered, non-repeating rhythm.
|
|
13
|
+
* - `orbit` — a lit cluster travels around the perimeter; the core stays dim.
|
|
14
|
+
* - `drive` — a column sweeps left to right, like a plate reader head.
|
|
15
|
+
* - `surfer` — a diagonal wavefront crosses the grid corner to corner.
|
|
16
|
+
*/
|
|
17
|
+
export declare const pixelLoaderVariants: readonly ["dots", "orbit", "drive", "surfer"];
|
|
18
|
+
export type PixelLoaderVariant = (typeof pixelLoaderVariants)[number];
|
|
19
|
+
/**
|
|
20
|
+
* DS size scale, deliberately identical to `StatusOrbSize` so a running-state
|
|
21
|
+
* indicator can be swapped between the two without touching layout.
|
|
22
|
+
*/
|
|
23
|
+
export type PixelLoaderSize = "small" | "default" | "medium" | "large";
|
|
24
|
+
/**
|
|
25
|
+
* Where one cell sits in the loop, as a fraction of the cycle in `[0, 1)`.
|
|
26
|
+
* `null` means the cell never lights for this variant and stays at rest — the
|
|
27
|
+
* dim core of `orbit`, for instance.
|
|
28
|
+
*
|
|
29
|
+
* Exported so the phase table can be asserted directly rather than inferred
|
|
30
|
+
* from rendered CSS.
|
|
31
|
+
*/
|
|
32
|
+
export declare function pixelLoaderCellPhase(variant: PixelLoaderVariant, x: number, y: number, grid?: number): number | null;
|
|
33
|
+
/**
|
|
34
|
+
* Accessible name used when the caller supplies none, or supplies one that is
|
|
35
|
+
* blank once trimmed. `role="img"` must always resolve to a name.
|
|
36
|
+
*/
|
|
37
|
+
export declare const PIXEL_LOADER_DEFAULT_LABEL = "Loading";
|
|
38
|
+
/**
|
|
39
|
+
* A cell's `animation-delay`, as a multiple of the cycle. Mirrors the `calc()`
|
|
40
|
+
* in `pixel-loader.css` exactly, and is asserted against that stylesheet in the
|
|
41
|
+
* tests so the two cannot drift.
|
|
42
|
+
*
|
|
43
|
+
* Always negative, so the loop is in flight on the first painted frame. The
|
|
44
|
+
* shape is `phase - 1`, not `-phase`: a negative delay advances the playhead by
|
|
45
|
+
* its own magnitude, so `-phase` would light the *highest* phase first and run
|
|
46
|
+
* every pattern backwards.
|
|
47
|
+
*/
|
|
48
|
+
export declare function pixelLoaderCellDelay(phase: number): number;
|
|
49
|
+
/**
|
|
50
|
+
* Which cells are at peak brightness at wall-clock time `t`, expressed as a
|
|
51
|
+
* fraction of one cycle.
|
|
52
|
+
*
|
|
53
|
+
* This resolves the same delay/duration arithmetic the browser does — playhead
|
|
54
|
+
* `= t - delay`, brightest when the playhead sits on the keyframe's peak — so
|
|
55
|
+
* the *rendered travel direction* can be asserted directly rather than inferred
|
|
56
|
+
* from the phase table. Returned in row-major cell-index order.
|
|
57
|
+
*/
|
|
58
|
+
export declare function pixelLoaderLitCellsAt(variant: PixelLoaderVariant, t: number, grid?: number): number[];
|
|
59
|
+
export interface PixelLoaderProps {
|
|
60
|
+
/** Which pattern the grid animates. @default "dots" */
|
|
61
|
+
variant?: PixelLoaderVariant;
|
|
62
|
+
/** DS size scale. @default "medium" (30px) */
|
|
63
|
+
size?: PixelLoaderSize;
|
|
64
|
+
/** One full pass of the pattern, in milliseconds. @default `--motion-duration-ambient` */
|
|
65
|
+
cycle?: number;
|
|
66
|
+
/** Sweep a soft highlight across the grid on top of the pattern. @default false */
|
|
67
|
+
shimmer?: boolean;
|
|
68
|
+
/** Freeze the pattern on its resting frame. @default false */
|
|
69
|
+
paused?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Accessible name. Trimmed; a blank or whitespace-only value falls back to
|
|
72
|
+
* the default rather than leaving `role="img"` unnamed. @default "Loading"
|
|
73
|
+
*/
|
|
74
|
+
"aria-label"?: string;
|
|
75
|
+
className?: string;
|
|
76
|
+
style?: CSSProperties;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Pixel-grid loading indicator.
|
|
80
|
+
*
|
|
81
|
+
* A 5×5 grid of cells lights in a variant-specific rhythm. Every cell carries a
|
|
82
|
+
* phase offset computed once at render; the animation itself is a single CSS
|
|
83
|
+
* keyframe on the compositor (opacity and transform only), so a page full of
|
|
84
|
+
* these costs no JavaScript per frame.
|
|
85
|
+
*
|
|
86
|
+
* Colour comes entirely from the brand ramp, mixed against `transparent`, so
|
|
87
|
+
* both themes are correct without a theme prop.
|
|
88
|
+
*
|
|
89
|
+
* Reduced motion: no travel. Cells settle into a static readout of their phase
|
|
90
|
+
* and the whole grid breathes on a slow, low-amplitude opacity pulse.
|
|
91
|
+
*
|
|
92
|
+
* This component never displays elapsed time.
|
|
93
|
+
*/
|
|
94
|
+
export declare function PixelLoader({ variant, size, cycle, shimmer, paused, "aria-label": ariaLabel, className, style, }: PixelLoaderProps): import("react/jsx-runtime").JSX.Element;
|