@mithrl/design-system 0.3.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.
Files changed (35) hide show
  1. package/dist/components/approval-card/ApprovalCard.d.ts +61 -0
  2. package/dist/components/code-block/CodeBlock.d.ts +64 -0
  3. package/dist/components/command-search/CommandSearch.d.ts +121 -0
  4. package/dist/components/context-cards/ContextCards.d.ts +53 -0
  5. package/dist/components/disclosure/Disclosure.d.ts +38 -0
  6. package/dist/components/dot-field/DotField.d.ts +102 -0
  7. package/dist/components/field-message/FieldMessage.d.ts +12 -0
  8. package/dist/components/filter-table/FilterTable.d.ts +61 -0
  9. package/dist/components/flap-text/FlapText.d.ts +68 -0
  10. package/dist/components/flowchart/Flowchart.d.ts +250 -0
  11. package/dist/components/flowchart/graphLayout.d.ts +35 -0
  12. package/dist/components/global-app-bar/GlobalAppBar.d.ts +14 -4
  13. package/dist/components/icon-swap/IconSwap.d.ts +30 -0
  14. package/dist/components/insight-cards/InsightCards.d.ts +97 -0
  15. package/dist/components/number-flow/NumberFlow.d.ts +93 -0
  16. package/dist/components/pixel-loader/PixelLoader.d.ts +94 -0
  17. package/dist/components/progress-indicator/ProgressIndicator.d.ts +9 -1
  18. package/dist/components/prompt-bar/PromptBar.d.ts +103 -0
  19. package/dist/components/recommendation-card/RecommendationCard.d.ts +77 -0
  20. package/dist/components/records-table/RecordsTable.d.ts +87 -0
  21. package/dist/components/resizable-panels/ResizablePanels.d.ts +22 -0
  22. package/dist/components/selection-actions/SelectionActions.d.ts +72 -0
  23. package/dist/components/skeleton-reveal/SkeletonReveal.d.ts +33 -0
  24. package/dist/components/status-orb/StatusOrb.d.ts +51 -0
  25. package/dist/components/streaming-text/StreamingText.d.ts +85 -0
  26. package/dist/components/task-rows/TaskRows.d.ts +77 -0
  27. package/dist/components/text-reveal/TextReveal.d.ts +62 -0
  28. package/dist/components/upload-queue/UploadQueue.d.ts +10 -0
  29. package/dist/index.d.ts +49 -1
  30. package/dist/index.js +5959 -1863
  31. package/dist/internal/useStaggerBatch.d.ts +22 -0
  32. package/dist/patterns/notifications/Notifications.d.ts +159 -0
  33. package/dist/patterns/workspace-app-shell/WorkspaceAppShell.d.ts +50 -0
  34. package/dist/styles.css +1 -1
  35. package/package.json +4 -2
@@ -0,0 +1,61 @@
1
+ import { type FormHTMLAttributes } from "react";
2
+
3
+ export type ApprovalCardMode = "single" | "multi";
4
+ export type ApprovalCardOption = {
5
+ id: string;
6
+ title: string;
7
+ subtitle?: string;
8
+ disabled?: boolean;
9
+ };
10
+ export type ApprovalCardQuestion = {
11
+ id: string;
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>;
45
+ };
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>>;
61
+ export {};
@@ -0,0 +1,64 @@
1
+ import { type HTMLAttributes, type ReactNode } from "react";
2
+
3
+ export type CodeBlockVariant = "code" | "diff";
4
+ export type CodeLineKind = "context" | "added" | "removed";
5
+ export type CodeLine = {
6
+ /** Raw line text. Rendered verbatim in the mono column. */
7
+ content: string;
8
+ /** Diff classification. Ignored by the `code` variant. */
9
+ kind?: CodeLineKind;
10
+ };
11
+ export type CodeBlockRenderLineArgs = {
12
+ /** Raw line text. */
13
+ content: string;
14
+ /** Resolved diff classification. */
15
+ kind: CodeLineKind;
16
+ /** One-based line number as shown in the gutter. */
17
+ number: number;
18
+ /** Variant the line is being rendered for. */
19
+ variant: CodeBlockVariant;
20
+ };
21
+ export type CodeBlockLabels = {
22
+ copy: string;
23
+ copied: string;
24
+ copyFailed: string;
25
+ codeTab: string;
26
+ diffTab: string;
27
+ listing: string;
28
+ };
29
+ type CodeBlockOwnProps = {
30
+ /** Source text. Split on newlines into the listing. */
31
+ code?: string;
32
+ /** Pre-split lines, required for diff rendering. Wins over `code`. */
33
+ lines?: readonly CodeLine[];
34
+ /** Language label rendered as a Tag in the header. */
35
+ language?: string;
36
+ /** File path or name rendered as the header title. */
37
+ fileName?: string;
38
+ /** Listing mode. Ignored when `tabs` is enabled. */
39
+ variant?: CodeBlockVariant;
40
+ /** Renders a Code/Diff segmented control. Requires `code` and `lines`. */
41
+ tabs?: boolean;
42
+ /** Controlled tab value when `tabs` is enabled. */
43
+ activeTab?: CodeBlockVariant;
44
+ /** Called when the Code/Diff segmented control changes. */
45
+ onTabChange?: (variant: CodeBlockVariant) => void;
46
+ /** Hides the line-number column. */
47
+ hideLineNumbers?: boolean;
48
+ /** Called with the text placed on the clipboard. */
49
+ onCopy?: (text: string) => void;
50
+ /** Injects highlighted nodes for a line. Defaults to plain mono text. */
51
+ renderLine?: (line: CodeBlockRenderLineArgs) => ReactNode;
52
+ labels?: Partial<CodeBlockLabels>;
53
+ className?: string;
54
+ };
55
+ export type CodeBlockProps = Omit<HTMLAttributes<HTMLDivElement>, keyof CodeBlockOwnProps | "children"> & CodeBlockOwnProps;
56
+ /**
57
+ * A notebook-tier code surface: a titled header rail with an optional
58
+ * language Tag and copy action, and a line-numbered, horizontally scrolling
59
+ * listing. The `diff` variant renders unified diff lines with semantic
60
+ * tinting. CodeBlock ships no syntax highlighting engine — pass `renderLine`
61
+ * to inject already-highlighted nodes.
62
+ */
63
+ export declare const CodeBlock: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "children" | keyof CodeBlockOwnProps> & CodeBlockOwnProps & import("react").RefAttributes<HTMLDivElement>>;
64
+ export {};
@@ -0,0 +1,121 @@
1
+ import { type HTMLAttributes, type ReactNode } from "react";
2
+
3
+ export type CommandSearchItem = {
4
+ /** Stable identity used for keys and active-descendant wiring. */
5
+ id: string;
6
+ /** Visible command label; match highlighting applies to this text. */
7
+ label: string;
8
+ /** Optional group heading the item is filed under. */
9
+ group?: string;
10
+ /** Optional trailing hint such as a shortcut or destination. */
11
+ hint?: string;
12
+ /** Invoked on Enter or click. */
13
+ onSelect?: (item: CommandSearchItem) => void;
14
+ /** Removes the item from keyboard navigation and selection. */
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;
32
+ };
33
+ export type CommandSearchProps = Omit<HTMLAttributes<HTMLDivElement>, "children" | "onSelect"> & {
34
+ items: readonly CommandSearchItem[];
35
+ /** Required accessible name for the search field. */
36
+ label: string;
37
+ placeholder?: string;
38
+ /** Controlled query. Omit for uncontrolled use. */
39
+ query?: string;
40
+ defaultQuery?: string;
41
+ onQueryChange?: (query: string) => void;
42
+ /** Called after any item is chosen, in addition to the item's own handler. */
43
+ onSelect?: (item: CommandSearchItem) => void;
44
+ /** Called when Escape is pressed on a field that is already empty. */
45
+ onEscape?: () => void;
46
+ /** Renders group headings when items carry a `group`. */
47
+ grouped?: boolean;
48
+ /** Secondary line shown under the empty-state title. */
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;
71
+ };
72
+ /**
73
+ * A command palette search surface. CommandSearch renders inline as an
74
+ * embedded panel and can be composed inside a Dialog by the consumer; it owns
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.
82
+ */
83
+ export declare const CommandSearch: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "children" | "onSelect"> & {
84
+ items: readonly CommandSearchItem[];
85
+ /** Required accessible name for the search field. */
86
+ label: string;
87
+ placeholder?: string;
88
+ /** Controlled query. Omit for uncontrolled use. */
89
+ query?: string;
90
+ defaultQuery?: string;
91
+ onQueryChange?: (query: string) => void;
92
+ /** Called after any item is chosen, in addition to the item's own handler. */
93
+ onSelect?: (item: CommandSearchItem) => void;
94
+ /** Called when Escape is pressed on a field that is already empty. */
95
+ onEscape?: () => void;
96
+ /** Renders group headings when items carry a `group`. */
97
+ grouped?: boolean;
98
+ /** Secondary line shown under the empty-state title. */
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;
121
+ } & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,53 @@
1
+ import { type HTMLAttributes, type ReactNode } from "react";
2
+
3
+ /** File types a retrieved chunk can come from. */
4
+ export type ContextFileType = "PDF" | "CSV" | "XLSX" | "TXT";
5
+ export interface FileTypeChipProps {
6
+ /** The chunk's source file type. */
7
+ fileType: ContextFileType;
8
+ }
9
+ /**
10
+ * A tinted three-or-four letter file-type marker. Each type gets a distinct
11
+ * semantic tint so a mixed list is scannable at a glance without reading
12
+ * filenames.
13
+ */
14
+ export declare function FileTypeChip({ fileType }: FileTypeChipProps): import("react/jsx-runtime").JSX.Element;
15
+ export interface ContextCardProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
16
+ /** Chunk heading — usually the section or table it was taken from. */
17
+ title: ReactNode;
18
+ /** Retrieved text. Clamped to three lines and faded, never truncated mid-word with an ellipsis. */
19
+ excerpt: ReactNode;
20
+ /** Character count of the full chunk, shown as retrieval metadata. */
21
+ characterCount?: number;
22
+ /** File the chunk came from. */
23
+ fileName: string;
24
+ /** File type of `fileName`. */
25
+ fileType: ContextFileType;
26
+ /**
27
+ * Optional page or row provenance, e.g. `"p. 4"` or `"rows 120–184"`.
28
+ */
29
+ locator?: string;
30
+ }
31
+ /**
32
+ * One retrieved knowledge chunk. Presentational: the card is not a control, so
33
+ * it carries no role or tab stop. Wrap it in a button or link at the call site
34
+ * if opening the source is supported there.
35
+ */
36
+ export declare const ContextCard: import("react").ForwardRefExoticComponent<ContextCardProps & import("react").RefAttributes<HTMLElement>>;
37
+ export interface ContextCardListProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
38
+ /** Group heading. @default "All chunks" */
39
+ title?: ReactNode;
40
+ /**
41
+ * Number shown in the count Tag. Defaults to the number of rendered cards,
42
+ * so pass it explicitly only when the list is paged or virtualised.
43
+ */
44
+ count?: number;
45
+ /** `ContextCard` children. */
46
+ children: ReactNode;
47
+ }
48
+ /**
49
+ * A labelled group of retrieved chunks. Rendered as a `<section>` with its
50
+ * heading wired through `aria-labelledby`, and the cards themselves in a
51
+ * `<ul>` so assistive technology announces the group size.
52
+ */
53
+ export declare const ContextCardList: import("react").ForwardRefExoticComponent<ContextCardListProps & import("react").RefAttributes<HTMLElement>>;
@@ -0,0 +1,38 @@
1
+ import { type HTMLAttributes, type ReactNode } from "react";
2
+
3
+ export type DisclosureProps = Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
4
+ /** Whether the region is expanded. Disclosure is always controlled. */
5
+ open: boolean;
6
+ /** Region content. Padding belongs on the content, never on Disclosure. */
7
+ children?: ReactNode;
8
+ };
9
+ /**
10
+ * An animated, controlled disclosure region.
11
+ *
12
+ * Disclosure animates its own height between collapsed and expanded using the
13
+ * `grid-template-rows: 0fr -> 1fr` technique, so content of any size animates
14
+ * without JavaScript measurement. Open animates over
15
+ * `--motion-duration-moderate` on `--motion-easing-enter`; close animates over
16
+ * the shorter `--motion-duration-standard` on `--motion-easing-exit`, matching
17
+ * the foundations asymmetry rule and the Dialog precedent.
18
+ *
19
+ * Boundary — Disclosure is presentational and owns the region only. It does
20
+ * **not** own the trigger, the chevron, focus management, `aria-expanded`, or
21
+ * `aria-controls`; the caller already owns those and keeps them on its own
22
+ * trigger. Pass `id` here and reference it from the trigger's `aria-controls`.
23
+ *
24
+ * While closed the content is hidden from the accessibility tree and from the
25
+ * tab order twice over: `visibility: hidden` is deferred behind the collapse
26
+ * transition (the pattern already used by `secondary-panel.css` and
27
+ * `workspace-app-shell.css`), and `inert` is applied immediately so nothing
28
+ * inside can be focused during the closing transition.
29
+ *
30
+ * Under `prefers-reduced-motion: reduce` the height animation is dropped
31
+ * entirely and the region crossfades at `--motion-duration-fast`.
32
+ */
33
+ export declare const Disclosure: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
34
+ /** Whether the region is expanded. Disclosure is always controlled. */
35
+ open: boolean;
36
+ /** Region content. Padding belongs on the content, never on Disclosure. */
37
+ children?: ReactNode;
38
+ } & 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;
@@ -13,6 +13,18 @@ export type FieldMessageProps = Omit<HTMLAttributes<HTMLParagraphElement>, "chil
13
13
  /**
14
14
  * Supporting or validation text for one form control. The consumer owns the
15
15
  * ID, ARIA relationship, live-region policy, and validation behavior.
16
+ *
17
+ * The message reveals itself on mount rather than popping in: an outer grid
18
+ * wrapper animates `grid-template-rows: 0fr -> 1fr` from a CSS
19
+ * `@starting-style` rule, so surrounding layout eases open instead of jumping.
20
+ * The wrapper is purely presentational — every prop, the `className`, the
21
+ * forwarded ref, `role="alert"`, and the ARIA relationship stay on the same
22
+ * `<p>` element they were on before, so nothing about the announcement is
23
+ * delayed, duplicated, or moved. Browsers without `@starting-style` simply
24
+ * show the message immediately.
25
+ *
26
+ * Exit is owned by the consumer, because the consumer owns the unmount. Wrap
27
+ * FieldMessage in `Disclosure` and keep it mounted to animate it away.
16
28
  */
17
29
  export declare const FieldMessage: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLParagraphElement>, "children" | "className"> & VariantProps<(props?: ({
18
30
  tone?: "error" | "helper" | "warning" | null | undefined;
@@ -0,0 +1,61 @@
1
+ import { type HTMLAttributes } from "react";
2
+
3
+ export declare const filterTableStatuses: readonly ["to-do", "in-progress", "completed"];
4
+ export type FilterTableStatus = (typeof filterTableStatuses)[number];
5
+ export type FilterTableRow = {
6
+ /** Stable row identity. */
7
+ id: string;
8
+ /** Primary task name. */
9
+ name: string;
10
+ /** Preformatted date string; rendered with tabular figures. */
11
+ date: string;
12
+ status: FilterTableStatus;
13
+ /** Person or team accountable for the task. */
14
+ owner: string;
15
+ /** Optional secondary line under the task name. */
16
+ detail?: string;
17
+ };
18
+ export type FilterTableProps = Omit<HTMLAttributes<HTMLDivElement>, "children" | "onChange"> & {
19
+ rows: readonly FilterTableRow[];
20
+ /** Required accessible name for the table. */
21
+ caption: string;
22
+ /** Controlled filter. `null` shows every row. */
23
+ filter?: FilterTableStatus | null;
24
+ /** Initial filter for uncontrolled use. */
25
+ defaultFilter?: FilterTableStatus | null;
26
+ onFilterChange?: (filter: FilterTableStatus | null) => void;
27
+ /** Label used on the "show everything" chip. */
28
+ allLabel?: string;
29
+ /** Column headers, in render order. */
30
+ headers?: {
31
+ name: string;
32
+ date: string;
33
+ status: string;
34
+ owner: string;
35
+ };
36
+ };
37
+ /**
38
+ * A light task table whose status chips reorganize the visible rows in place.
39
+ * Row movement is animated with a FLIP pass that only touches `transform`.
40
+ */
41
+ export declare const FilterTable: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "children" | "onChange"> & {
42
+ rows: readonly FilterTableRow[];
43
+ /** Required accessible name for the table. */
44
+ caption: string;
45
+ /** Controlled filter. `null` shows every row. */
46
+ filter?: FilterTableStatus | null;
47
+ /** Initial filter for uncontrolled use. */
48
+ defaultFilter?: FilterTableStatus | null;
49
+ onFilterChange?: (filter: FilterTableStatus | null) => void;
50
+ /** Label used on the "show everything" chip. */
51
+ allLabel?: string;
52
+ /** Column headers, in render order. */
53
+ headers?: {
54
+ name: string;
55
+ date: string;
56
+ status: string;
57
+ owner: string;
58
+ };
59
+ } & import("react").RefAttributes<HTMLDivElement>>;
60
+ export type FilterTableStatusLabelMap = Record<FilterTableStatus, string>;
61
+ export declare const filterTableStatusLabels: FilterTableStatusLabelMap;
@@ -0,0 +1,68 @@
1
+ import { type CSSProperties } from "react";
2
+
3
+ /**
4
+ * Milliseconds one cell spends flipping. Mirrors `--motion-duration-moderate`;
5
+ * the CSS reads the token directly and only falls back to this number when the
6
+ * caller overrides `flapDuration`.
7
+ */
8
+ export declare const FLAP_TEXT_DEFAULT_DURATION_MS = 220;
9
+ /** Milliseconds each successive cell waits before it starts flipping. */
10
+ export declare const FLAP_TEXT_DEFAULT_STAGGER_MS = 18;
11
+ export type FlapTextElement = "span" | "div" | "p" | "strong" | "em";
12
+ export type FlapTextAlign = "start" | "center" | "end";
13
+ export interface FlapTextProps {
14
+ /** The string to display. Changing it flips the characters that differ. */
15
+ text: string;
16
+ /** Host element. @default "span" */
17
+ as?: FlapTextElement;
18
+ /** Per-character delay, in milliseconds. @default 18 */
19
+ stagger?: number;
20
+ /** Flip duration, in milliseconds. @default `--motion-duration-moderate` */
21
+ flapDuration?: number;
22
+ /** Horizontal alignment of the rendered line. @default "start" */
23
+ align?: FlapTextAlign;
24
+ className?: string;
25
+ style?: CSSProperties;
26
+ }
27
+ export type FlapCell = {
28
+ /** Glyph shown once the cell settles. */
29
+ char: string;
30
+ /** Glyph rotating out, or `null` when the cell is new or settled. */
31
+ previous: string | null;
32
+ /** Whether this cell is mid-flip. */
33
+ flap: boolean;
34
+ /** Trailing cell that disappears when the text got shorter. */
35
+ exiting: boolean;
36
+ };
37
+ /**
38
+ * A Solari board only moves the cells whose glyph actually changed. Identical
39
+ * characters at the same index stay perfectly still, which is both faithful and
40
+ * far calmer to read.
41
+ */
42
+ export declare function flapTextCells(previous: string, next: string): FlapCell[];
43
+ /**
44
+ * Split-flap text.
45
+ *
46
+ * Each character is its own cell. When `text` changes, only the cells whose
47
+ * glyph differs flip: the old glyph rotates away around the horizontal midline
48
+ * while the new one rotates in behind it, staggered left to right.
49
+ *
50
+ * Sharpness: cells are inline-block with `preserve-3d` and hidden backfaces,
51
+ * `will-change: transform` is present only while a cell is actually flipping,
52
+ * and settled cells carry `transform: none` exactly — never an identity matrix
53
+ * — so the browser re-rasterises the glyph at full fidelity. No scale is ever
54
+ * applied, and the component sets no font property, so text metrics are the
55
+ * caller's.
56
+ *
57
+ * Accessibility: cells are `aria-hidden`, the host carries `aria-label={text}`,
58
+ * and a visually hidden polite live region announces one clean string.
59
+ *
60
+ * Reduced motion: no 3D at all — a fast opacity crossfade swaps the glyph.
61
+ */
62
+ export declare function FlapText({ text, as, stagger, flapDuration, align, className, style, }: FlapTextProps): import("react").DetailedReactHTMLElement<{
63
+ className: string;
64
+ style: CSSProperties | undefined;
65
+ "aria-label": string;
66
+ "data-align": FlapTextAlign;
67
+ "data-flapping": string;
68
+ }, HTMLElement>;