altitude-design 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -6
- package/dist/adapters/codemirror.cjs +88 -0
- package/dist/adapters/codemirror.cjs.map +7 -0
- package/dist/adapters/codemirror.js +67 -0
- package/dist/adapters/codemirror.js.map +7 -0
- package/dist/adapters/react-flow.css +102 -0
- package/dist/adapters/tiptap.css +71 -0
- package/dist/altitude.css +3121 -244
- package/dist/altitude.iife.js +33 -5
- package/dist/altitude.no-fonts.css +3121 -244
- package/dist/chart-themes.cjs +195 -0
- package/dist/chart-themes.cjs.map +7 -0
- package/dist/chart-themes.js +165 -0
- package/dist/chart-themes.js.map +7 -0
- package/dist/cli/altitude.mjs +134 -0
- package/dist/guidance/README.md +32 -0
- package/dist/guidance/agent-setup.md +22 -0
- package/dist/guidance/app-skeleton.md +17 -0
- package/dist/guidance/evidence.json +95 -0
- package/dist/guidance/index.json +493 -0
- package/dist/guidance/llms.txt +20 -0
- package/dist/guidance/manifest.json +92 -0
- package/dist/guidance/pattern.schema.json +181 -0
- package/dist/guidance/patterns/agent-action.json +77 -0
- package/dist/guidance/patterns/agent-action.md +39 -0
- package/dist/guidance/patterns/assistant-conversation.json +77 -0
- package/dist/guidance/patterns/assistant-conversation.md +50 -0
- package/dist/guidance/patterns/async-collection.json +71 -0
- package/dist/guidance/patterns/async-collection.md +29 -0
- package/dist/guidance/patterns/audit-log.json +75 -0
- package/dist/guidance/patterns/audit-log.md +27 -0
- package/dist/guidance/patterns/auth.json +86 -0
- package/dist/guidance/patterns/auth.md +29 -0
- package/dist/guidance/patterns/billing.json +80 -0
- package/dist/guidance/patterns/billing.md +29 -0
- package/dist/guidance/patterns/consequential-action.json +76 -0
- package/dist/guidance/patterns/consequential-action.md +27 -0
- package/dist/guidance/patterns/developer-settings.json +79 -0
- package/dist/guidance/patterns/developer-settings.md +29 -0
- package/dist/guidance/patterns/edit-record.json +74 -0
- package/dist/guidance/patterns/edit-record.md +51 -0
- package/dist/guidance/patterns/import.json +77 -0
- package/dist/guidance/patterns/import.md +31 -0
- package/dist/guidance/patterns/members.json +77 -0
- package/dist/guidance/patterns/members.md +27 -0
- package/dist/guidance/patterns/onboarding.json +78 -0
- package/dist/guidance/patterns/onboarding.md +31 -0
- package/dist/guidance/patterns/review-submit.json +72 -0
- package/dist/guidance/patterns/review-submit.md +27 -0
- package/dist/guidance/patterns/screen-layout.json +79 -0
- package/dist/guidance/patterns/screen-layout.md +40 -0
- package/dist/guidance/patterns/settings.json +78 -0
- package/dist/guidance/patterns/settings.md +32 -0
- package/dist/guidance/patterns/sync.json +77 -0
- package/dist/guidance/patterns/sync.md +31 -0
- package/dist/guidance/principles.md +23 -0
- package/dist/guidance/references/build/checks/agent-action-pattern.mjs +57 -0
- package/dist/guidance/references/build/checks/agent-setup.mjs +78 -0
- package/dist/guidance/references/build/checks/assistant-conversation-pattern.mjs +49 -0
- package/dist/guidance/references/build/checks/audit-log-pattern.mjs +63 -0
- package/dist/guidance/references/build/checks/auth-pattern.mjs +67 -0
- package/dist/guidance/references/build/checks/billing-pattern.mjs +63 -0
- package/dist/guidance/references/build/checks/developer-settings-pattern.mjs +76 -0
- package/dist/guidance/references/build/checks/guidance.mjs +71 -0
- package/dist/guidance/references/build/checks/import-pattern.mjs +69 -0
- package/dist/guidance/references/build/checks/members-pattern.mjs +71 -0
- package/dist/guidance/references/build/checks/onboarding-pattern.mjs +54 -0
- package/dist/guidance/references/build/checks/pattern-types.mjs +13 -0
- package/dist/guidance/references/build/checks/pattern-workflows.mjs +226 -0
- package/dist/guidance/references/build/checks/primary-scope.mjs +49 -0
- package/dist/guidance/references/build/checks/render-tells.mjs +72 -0
- package/dist/guidance/references/build/checks/screen-layout-pattern.mjs +111 -0
- package/dist/guidance/references/build/checks/semantics.mjs +72 -0
- package/dist/guidance/references/build/checks/settings-pattern.mjs +73 -0
- package/dist/guidance/references/build/checks/sync-pattern.mjs +62 -0
- package/dist/guidance/references/build/checks/tells-lint.mjs +164 -0
- package/dist/guidance/references/build/fixtures/pattern-workflows.tsx +83 -0
- package/dist/guidance/references/build/fixtures/patterns/agent-action.jsx +60 -0
- package/dist/guidance/references/build/fixtures/patterns/app-skeleton.jsx +94 -0
- package/dist/guidance/references/build/fixtures/patterns/assistant-conversation.jsx +79 -0
- package/dist/guidance/references/build/fixtures/patterns/audit-log.jsx +81 -0
- package/dist/guidance/references/build/fixtures/patterns/auth.jsx +150 -0
- package/dist/guidance/references/build/fixtures/patterns/billing.jsx +96 -0
- package/dist/guidance/references/build/fixtures/patterns/developer-settings.jsx +95 -0
- package/dist/guidance/references/build/fixtures/patterns/import.jsx +102 -0
- package/dist/guidance/references/build/fixtures/patterns/members.jsx +106 -0
- package/dist/guidance/references/build/fixtures/patterns/onboarding.jsx +70 -0
- package/dist/guidance/references/build/fixtures/patterns/screen-layout-decision.jsx +74 -0
- package/dist/guidance/references/build/fixtures/patterns/screen-layout-editor.jsx +56 -0
- package/dist/guidance/references/build/fixtures/patterns/screen-layout-report.jsx +42 -0
- package/dist/guidance/references/build/fixtures/patterns/settings.jsx +73 -0
- package/dist/guidance/references/build/fixtures/patterns/sync.jsx +78 -0
- package/dist/guidance/references/project/components/src/pattern-async-collection.tsx +57 -0
- package/dist/guidance/references/project/components/src/pattern-consequential-action.tsx +77 -0
- package/dist/guidance/references/project/components/src/pattern-edit-record.tsx +127 -0
- package/dist/guidance/references/project/components/src/pattern-review-submit.tsx +47 -0
- package/dist/guidance/references/project/components/src/settings.tsx +79 -0
- package/dist/guidance/references/scripts/build-framework-fixture.mjs +20 -0
- package/dist/guidance/rules.json +653 -0
- package/dist/guidance/visual/Elevation.md +194 -0
- package/dist/guidance/visual/Fundamentals.md +83 -0
- package/dist/guidance/visual/Research.md +1620 -0
- package/dist/index.cjs +18792 -1925
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +18792 -1925
- package/dist/index.js.map +4 -4
- package/dist/tokens.css +84 -84
- package/dist/tokens.json +301 -128
- package/dist/types/adapter-codemirror.d.ts +13 -0
- package/dist/types/agent-fleet.d.ts +166 -0
- package/dist/types/ai-label.d.ts +30 -0
- package/dist/types/app-shell.d.ts +83 -0
- package/dist/types/area-chart.d.ts +80 -0
- package/dist/types/artifact.d.ts +65 -0
- package/dist/types/bar-chart.d.ts +83 -0
- package/dist/types/bar-list.d.ts +35 -0
- package/dist/types/breadcrumb.d.ts +62 -0
- package/dist/types/chart-brush.d.ts +35 -0
- package/dist/types/chart-themes.d.ts +229 -0
- package/dist/types/chart.d.ts +570 -0
- package/dist/types/checklist.d.ts +71 -0
- package/dist/types/code-block.d.ts +32 -0
- package/dist/types/collections.d.ts +111 -4
- package/dist/types/color-picker.d.ts +38 -0
- package/dist/types/command.d.ts +6 -3
- package/dist/types/comment-thread.d.ts +48 -0
- package/dist/types/confirmation.d.ts +60 -0
- package/dist/types/context-menu.d.ts +17 -0
- package/dist/types/controls.d.ts +100 -17
- package/dist/types/conversation.d.ts +130 -0
- package/dist/types/copy-button.d.ts +19 -0
- package/dist/types/core.d.ts +139 -10
- package/dist/types/data-grid.d.ts +76 -0
- package/dist/types/date-picker.d.ts +96 -0
- package/dist/types/diff-view.d.ts +54 -0
- package/dist/types/dot-plot.d.ts +54 -0
- package/dist/types/edit-region.d.ts +121 -0
- package/dist/types/feature-gate.d.ts +22 -0
- package/dist/types/filter-bar.d.ts +65 -0
- package/dist/types/formatted-number.d.ts +38 -0
- package/dist/types/heatmap.d.ts +64 -0
- package/dist/types/in-place.d.ts +24 -0
- package/dist/types/index.d.ts +158 -15
- package/dist/types/inline-citation.d.ts +35 -0
- package/dist/types/inline-edit.d.ts +71 -0
- package/dist/types/input-otp.d.ts +37 -0
- package/dist/types/item-group.d.ts +104 -0
- package/dist/types/line-chart.d.ts +116 -0
- package/dist/types/link.d.ts +11 -0
- package/dist/types/markdown.d.ts +88 -0
- package/dist/types/meter.d.ts +43 -0
- package/dist/types/modal-state.d.ts +62 -0
- package/dist/types/nav.d.ts +8 -1
- package/dist/types/notifications.d.ts +42 -0
- package/dist/types/number-input.d.ts +30 -0
- package/dist/types/overlays.d.ts +51 -17
- package/dist/types/page-header.d.ts +27 -0
- package/dist/types/pagination.d.ts +29 -0
- package/dist/types/palette.d.ts +64 -0
- package/dist/types/password-input.d.ts +22 -0
- package/dist/types/pattern-assistant-conversation.d.ts +55 -0
- package/dist/types/pattern-async-collection.d.ts +34 -0
- package/dist/types/pattern-consequential-action.d.ts +53 -0
- package/dist/types/pattern-edit-record.d.ts +72 -0
- package/dist/types/pattern-review-submit.d.ts +43 -0
- package/dist/types/permission-matrix.d.ts +34 -0
- package/dist/types/plan-picker.d.ts +40 -0
- package/dist/types/prompt-input.d.ts +106 -0
- package/dist/types/property-list.d.ts +67 -0
- package/dist/types/question.d.ts +64 -0
- package/dist/types/relative-time.d.ts +21 -0
- package/dist/types/removal-receipt.d.ts +1180 -0
- package/dist/types/resizable.d.ts +48 -0
- package/dist/types/roving.d.ts +44 -0
- package/dist/types/save-bar.d.ts +38 -0
- package/dist/types/saved-views.d.ts +72 -0
- package/dist/types/scatter-chart.d.ts +60 -0
- package/dist/types/schedule.d.ts +80 -0
- package/dist/types/secret-field.d.ts +33 -0
- package/dist/types/select.d.ts +44 -2
- package/dist/types/separator.d.ts +11 -0
- package/dist/types/settings.d.ts +39 -0
- package/dist/types/sheet.d.ts +1 -1
- package/dist/types/sparkline.d.ts +46 -0
- package/dist/types/split-button.d.ts +21 -0
- package/dist/types/stat.d.ts +54 -0
- package/dist/types/stepper.d.ts +6 -3
- package/dist/types/suggestions.d.ts +29 -0
- package/dist/types/suspense.d.ts +12 -1
- package/dist/types/sync-indicator.d.ts +24 -0
- package/dist/types/tag-input.d.ts +65 -0
- package/dist/types/terminal.d.ts +33 -0
- package/dist/types/thread-list.d.ts +58 -0
- package/dist/types/time-input.d.ts +33 -0
- package/dist/types/timeline.d.ts +38 -0
- package/dist/types/toggle.d.ts +46 -0
- package/dist/types/toolbar.d.ts +34 -0
- package/dist/types/tour.d.ts +23 -0
- package/dist/types/trace.d.ts +65 -0
- package/dist/types/tree.d.ts +71 -0
- package/dist/types-cjs/adapter-codemirror.d.cts +13 -0
- package/dist/types-cjs/agent-fleet.d.cts +166 -0
- package/dist/types-cjs/ai-label.d.cts +30 -0
- package/dist/types-cjs/app-shell.d.cts +83 -0
- package/dist/types-cjs/area-chart.d.cts +80 -0
- package/dist/types-cjs/artifact.d.cts +65 -0
- package/dist/types-cjs/bar-chart.d.cts +83 -0
- package/dist/types-cjs/bar-list.d.cts +35 -0
- package/dist/types-cjs/breadcrumb.d.cts +62 -0
- package/dist/types-cjs/chart-brush.d.cts +35 -0
- package/dist/types-cjs/chart-themes.d.cts +229 -0
- package/dist/types-cjs/chart.d.cts +570 -0
- package/dist/types-cjs/checklist.d.cts +71 -0
- package/dist/types-cjs/code-block.d.cts +32 -0
- package/dist/types-cjs/collections.d.cts +246 -0
- package/dist/types-cjs/color-picker.d.cts +38 -0
- package/dist/types-cjs/command.d.cts +66 -0
- package/dist/types-cjs/comment-thread.d.cts +48 -0
- package/dist/types-cjs/confirmation.d.cts +60 -0
- package/dist/types-cjs/context-menu.d.cts +17 -0
- package/dist/types-cjs/controls.d.cts +360 -0
- package/dist/types-cjs/conversation.d.cts +130 -0
- package/dist/types-cjs/copy-button.d.cts +19 -0
- package/dist/types-cjs/core.d.cts +256 -0
- package/dist/types-cjs/data-grid.d.cts +76 -0
- package/dist/types-cjs/date-picker.d.cts +96 -0
- package/dist/types-cjs/diff-view.d.cts +54 -0
- package/dist/types-cjs/dot-plot.d.cts +54 -0
- package/dist/types-cjs/edit-region.d.cts +121 -0
- package/dist/types-cjs/empty.d.cts +24 -0
- package/dist/types-cjs/feature-gate.d.cts +22 -0
- package/dist/types-cjs/filter-bar.d.cts +65 -0
- package/dist/types-cjs/formatted-number.d.cts +38 -0
- package/dist/types-cjs/heatmap.d.cts +64 -0
- package/dist/types-cjs/in-place.d.cts +24 -0
- package/dist/types-cjs/index.d.cts +154 -0
- package/dist/types-cjs/inline-citation.d.cts +35 -0
- package/dist/types-cjs/inline-edit.d.cts +71 -0
- package/dist/types-cjs/input-otp.d.cts +37 -0
- package/dist/types-cjs/item-group.d.cts +104 -0
- package/dist/types-cjs/line-chart.d.cts +116 -0
- package/dist/types-cjs/link.d.cts +11 -0
- package/dist/types-cjs/markdown.d.cts +88 -0
- package/dist/types-cjs/meter.d.cts +43 -0
- package/dist/types-cjs/modal-state.d.cts +62 -0
- package/dist/types-cjs/nav.d.cts +25 -0
- package/dist/types-cjs/notifications.d.cts +42 -0
- package/dist/types-cjs/number-input.d.cts +30 -0
- package/dist/types-cjs/overlays.d.cts +170 -0
- package/dist/types-cjs/page-header.d.cts +27 -0
- package/dist/types-cjs/pagination.d.cts +29 -0
- package/dist/types-cjs/palette.d.cts +64 -0
- package/dist/types-cjs/password-input.d.cts +22 -0
- package/dist/types-cjs/pattern-assistant-conversation.d.cts +55 -0
- package/dist/types-cjs/pattern-async-collection.d.cts +34 -0
- package/dist/types-cjs/pattern-consequential-action.d.cts +53 -0
- package/dist/types-cjs/pattern-edit-record.d.cts +72 -0
- package/dist/types-cjs/pattern-review-submit.d.cts +43 -0
- package/dist/types-cjs/permission-matrix.d.cts +34 -0
- package/dist/types-cjs/pile.d.cts +27 -0
- package/dist/types-cjs/plan-picker.d.cts +40 -0
- package/dist/types-cjs/prompt-input.d.cts +106 -0
- package/dist/types-cjs/property-list.d.cts +67 -0
- package/dist/types-cjs/question.d.cts +64 -0
- package/dist/types-cjs/relative-time.d.cts +21 -0
- package/dist/types-cjs/removal-receipt.d.cts +1180 -0
- package/dist/types-cjs/resizable.d.cts +48 -0
- package/dist/types-cjs/roving.d.cts +44 -0
- package/dist/types-cjs/save-bar.d.cts +38 -0
- package/dist/types-cjs/saved-views.d.cts +72 -0
- package/dist/types-cjs/scatter-chart.d.cts +60 -0
- package/dist/types-cjs/schedule.d.cts +80 -0
- package/dist/types-cjs/secret-field.d.cts +33 -0
- package/dist/types-cjs/select.d.cts +109 -0
- package/dist/types-cjs/separator.d.cts +11 -0
- package/dist/types-cjs/settings.d.cts +39 -0
- package/dist/types-cjs/sheet.d.cts +27 -0
- package/dist/types-cjs/sparkline.d.cts +46 -0
- package/dist/types-cjs/split-button.d.cts +21 -0
- package/dist/types-cjs/stat.d.cts +54 -0
- package/dist/types-cjs/stepper.d.cts +26 -0
- package/dist/types-cjs/suggestions.d.cts +29 -0
- package/dist/types-cjs/suspense.d.cts +85 -0
- package/dist/types-cjs/sync-indicator.d.cts +24 -0
- package/dist/types-cjs/tag-input.d.cts +65 -0
- package/dist/types-cjs/terminal.d.cts +33 -0
- package/dist/types-cjs/thread-list.d.cts +58 -0
- package/dist/types-cjs/time-input.d.cts +33 -0
- package/dist/types-cjs/timeline.d.cts +38 -0
- package/dist/types-cjs/toggle.d.cts +46 -0
- package/dist/types-cjs/toolbar.d.cts +34 -0
- package/dist/types-cjs/tour.d.cts +23 -0
- package/dist/types-cjs/trace.d.cts +65 -0
- package/dist/types-cjs/tree.d.cts +71 -0
- package/package.json +89 -9
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type Presentation } from './core.cjs';
|
|
3
|
+
/** The shared warm-up, for floating readouts outside this module (a chart's readout): warm if one closed within 400ms. */
|
|
4
|
+
export declare const tipIsWarm: () => boolean;
|
|
5
|
+
export declare const markTipClosed: () => void;
|
|
6
|
+
export interface TooltipProps {
|
|
7
|
+
content: React.ReactNode;
|
|
8
|
+
/** Default 'top'. 'right' is for a rail of icons, where above would cover the next one. */
|
|
9
|
+
side?: 'top' | 'bottom' | 'right';
|
|
10
|
+
delay?: number;
|
|
11
|
+
defaultOpen?: boolean;
|
|
12
|
+
children: React.ReactElement<any>;
|
|
13
|
+
}
|
|
14
|
+
export declare function Tooltip({ content, side, delay, defaultOpen, children }: TooltipProps): React.JSX.Element;
|
|
15
|
+
export interface PopoverProps {
|
|
16
|
+
trigger: React.ReactElement<any>;
|
|
17
|
+
children: React.ReactNode;
|
|
18
|
+
open?: boolean;
|
|
19
|
+
defaultOpen?: boolean;
|
|
20
|
+
onOpenChange?: (o: boolean) => void;
|
|
21
|
+
side?: 'top' | 'bottom';
|
|
22
|
+
align?: 'start' | 'center' | 'end';
|
|
23
|
+
className?: string;
|
|
24
|
+
'aria-label'?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function Popover({ trigger, children, open, defaultOpen, onOpenChange, side, align, className, ...rest }: PopoverProps): React.JSX.Element;
|
|
27
|
+
export interface MenuItem {
|
|
28
|
+
type?: 'item';
|
|
29
|
+
label: React.ReactNode;
|
|
30
|
+
icon?: React.ReactNode;
|
|
31
|
+
shortcut?: React.ReactNode;
|
|
32
|
+
onSelect?: () => void;
|
|
33
|
+
tone?: 'critical';
|
|
34
|
+
disabled?: boolean;
|
|
35
|
+
/** Ephemeral adaptation: predicted items appear at once, the rest fade in over dur-onset. Only worth it when predictions are right most of the time. */
|
|
36
|
+
predicted?: boolean;
|
|
37
|
+
/** A checkable item (role="menuitemcheckbox"), shown with a check when true: a toggle moved into a menu. */
|
|
38
|
+
checked?: boolean;
|
|
39
|
+
}
|
|
40
|
+
export type MenuEntry = MenuItem | {
|
|
41
|
+
type: 'separator';
|
|
42
|
+
} | {
|
|
43
|
+
type: 'label';
|
|
44
|
+
label: React.ReactNode;
|
|
45
|
+
};
|
|
46
|
+
export interface DropdownMenuProps {
|
|
47
|
+
trigger: React.ReactElement<any>;
|
|
48
|
+
items: MenuEntry[];
|
|
49
|
+
align?: 'start' | 'end';
|
|
50
|
+
side?: 'top' | 'bottom';
|
|
51
|
+
defaultOpen?: boolean;
|
|
52
|
+
className?: string;
|
|
53
|
+
/**
|
|
54
|
+
* 'auto' (default): anchored to the trigger, or on a narrow touch screen a sheet at the bottom edge, with a title and
|
|
55
|
+
* Close, where the thumb is (#249). 'anchored' or 'sheet' forces one.
|
|
56
|
+
*/
|
|
57
|
+
presentation?: Presentation;
|
|
58
|
+
/** The sheet's title. Default: the trigger's aria-label or text. */
|
|
59
|
+
title?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The menu itself, shared by DropdownMenu and ContextMenu: its items, the highlight that glides between them, the
|
|
63
|
+
* keyboard, and choosing. `onClose(true)` asks the owner to close and give focus back.
|
|
64
|
+
*/
|
|
65
|
+
export declare function MenuPanel({ items, id, state, side, align, className, style, startFirst, onClose, sheet, title }: {
|
|
66
|
+
items: MenuEntry[];
|
|
67
|
+
id: string;
|
|
68
|
+
state: string;
|
|
69
|
+
side?: 'top' | 'bottom';
|
|
70
|
+
align?: 'start' | 'end';
|
|
71
|
+
className?: string;
|
|
72
|
+
style?: React.CSSProperties;
|
|
73
|
+
/** Opened from the keyboard: the first item is active at once. */
|
|
74
|
+
startFirst?: boolean;
|
|
75
|
+
onClose: () => void;
|
|
76
|
+
/** Presented as a bottom sheet (#249), with this title. */
|
|
77
|
+
sheet?: boolean;
|
|
78
|
+
title?: React.ReactNode;
|
|
79
|
+
}): React.JSX.Element;
|
|
80
|
+
export declare function DropdownMenu({ trigger, items, align, side, defaultOpen, className, presentation, title }: DropdownMenuProps): React.JSX.Element;
|
|
81
|
+
export interface HoverCardProps {
|
|
82
|
+
/** What you hover or focus: usually a link or an avatar. It must do its own job (navigate, open) without the card. */
|
|
83
|
+
trigger: React.ReactElement<any>;
|
|
84
|
+
children: React.ReactNode;
|
|
85
|
+
/** Default 'bottom'. */
|
|
86
|
+
side?: 'top' | 'bottom';
|
|
87
|
+
/** Default 'start'. */
|
|
88
|
+
align?: 'start' | 'center' | 'end';
|
|
89
|
+
/** Hover intent: how long the pointer must rest before it opens. Default 400ms. */
|
|
90
|
+
openDelay?: number;
|
|
91
|
+
/** How long it stays after the pointer leaves, so the pointer can travel into it. Default 250ms. */
|
|
92
|
+
closeDelay?: number;
|
|
93
|
+
open?: boolean;
|
|
94
|
+
defaultOpen?: boolean;
|
|
95
|
+
onOpenChange?: (open: boolean) => void;
|
|
96
|
+
className?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* A richer preview that rises from its trigger at level 3, after hover intent or on keyboard focus. It shares Tooltip's
|
|
100
|
+
* warm-up: once one has shown, a neighbour opens at once. Its content is supplementary, never the only way to reach anything.
|
|
101
|
+
*/
|
|
102
|
+
export declare function HoverCard({ trigger, children, side, align, openDelay, closeDelay, open, defaultOpen, onOpenChange, className }: HoverCardProps): React.JSX.Element;
|
|
103
|
+
/** The summit is shared by every provider in the same document. */
|
|
104
|
+
export declare const summitTaken: (doc?: Document) => boolean;
|
|
105
|
+
export interface ModalOptions {
|
|
106
|
+
open: boolean;
|
|
107
|
+
onDismiss: () => void;
|
|
108
|
+
exitMs: number;
|
|
109
|
+
panel: React.RefObject<HTMLElement | null>;
|
|
110
|
+
modal?: boolean;
|
|
111
|
+
dismissible?: boolean;
|
|
112
|
+
summit?: boolean;
|
|
113
|
+
autoFocus?: boolean;
|
|
114
|
+
focusSelector?: string;
|
|
115
|
+
restoreFocus?: boolean;
|
|
116
|
+
background?: 'recede' | 'stationary';
|
|
117
|
+
returnFocus?: () => HTMLElement | null;
|
|
118
|
+
}
|
|
119
|
+
export declare const MODAL_FOCUS = "[data-autofocus], input, textarea, select";
|
|
120
|
+
export declare function useModal({ open, onDismiss, exitMs, panel, modal, dismissible, summit, autoFocus, focusSelector, restoreFocus, background, returnFocus }: ModalOptions): {
|
|
121
|
+
mounted: boolean;
|
|
122
|
+
onKeyDown: (e: React.KeyboardEvent) => void;
|
|
123
|
+
rootRef: (root: HTMLDivElement | null) => void;
|
|
124
|
+
captureInvoker: (el: HTMLElement) => void;
|
|
125
|
+
state: "open" | "closed";
|
|
126
|
+
};
|
|
127
|
+
export interface DialogProps {
|
|
128
|
+
open?: boolean;
|
|
129
|
+
defaultOpen?: boolean;
|
|
130
|
+
onOpenChange?: (o: boolean) => void;
|
|
131
|
+
/** Uncontrolled convenience: an element that opens the dialog. */
|
|
132
|
+
trigger?: React.ReactElement<any>;
|
|
133
|
+
title: React.ReactNode;
|
|
134
|
+
description?: React.ReactNode;
|
|
135
|
+
children?: React.ReactNode;
|
|
136
|
+
footer?: React.ReactNode;
|
|
137
|
+
size?: 'sm' | 'md' | 'lg';
|
|
138
|
+
/** Set false for decisions that must be answered: the scrim and Escape won't close it. */
|
|
139
|
+
dismissible?: boolean;
|
|
140
|
+
/** Initial focus: the first field (default), the title, or false for a safe panel fallback until the application moves focus inside. */
|
|
141
|
+
initialFocus?: 'first-field' | 'title' | false;
|
|
142
|
+
/** What 'first-field' looks for. Default '[data-autofocus], input, textarea, select'; the panel itself if nothing matches. */
|
|
143
|
+
focusSelector?: string;
|
|
144
|
+
/** Keep the background in place and remove scrim blur; default 'recede'. Modality is unchanged. */
|
|
145
|
+
background?: 'recede' | 'stationary';
|
|
146
|
+
/** Lazy fallback when the captured invoker can no longer receive focus. */
|
|
147
|
+
returnFocus?: () => HTMLElement | null;
|
|
148
|
+
className?: string;
|
|
149
|
+
}
|
|
150
|
+
export declare function Dialog({ open, defaultOpen, onOpenChange, trigger, title, description, children, footer, size, dismissible, initialFocus, focusSelector, background, returnFocus, className }: DialogProps): React.JSX.Element;
|
|
151
|
+
export type ToastTone = 'neutral' | 'positive' | 'caution' | 'critical';
|
|
152
|
+
export interface ToastOptions {
|
|
153
|
+
title: React.ReactNode;
|
|
154
|
+
description?: React.ReactNode;
|
|
155
|
+
tone?: ToastTone;
|
|
156
|
+
duration?: number;
|
|
157
|
+
action?: {
|
|
158
|
+
label: string;
|
|
159
|
+
onClick: () => void;
|
|
160
|
+
};
|
|
161
|
+
/** false: shown but not announced, because what it says was already announced where it happened. Default true. */
|
|
162
|
+
announce?: boolean;
|
|
163
|
+
}
|
|
164
|
+
export declare function toast(input: ToastOptions | string): number;
|
|
165
|
+
export declare namespace toast {
|
|
166
|
+
var dismiss: (id: number) => void;
|
|
167
|
+
}
|
|
168
|
+
export declare function Toaster({ className }: {
|
|
169
|
+
className?: string;
|
|
170
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { MenuEntry } from './overlays.cjs';
|
|
3
|
+
export interface PageHeaderProps extends Omit<React.HTMLAttributes<HTMLElement>, 'title'> {
|
|
4
|
+
/** A Breadcrumb above the title. */
|
|
5
|
+
breadcrumb?: React.ReactNode;
|
|
6
|
+
/** The page's one primary action: a single Button variant="primary". There's one slot, so there's one primary. */
|
|
7
|
+
primary?: React.ReactElement;
|
|
8
|
+
/** Secondary and ghost actions, before the primary. */
|
|
9
|
+
actions?: React.ReactNode;
|
|
10
|
+
/** Actions that don't need to be seen, in a "More actions" menu. */
|
|
11
|
+
overflow?: MenuEntry[];
|
|
12
|
+
/** Tabs under the title, for the page's sections. */
|
|
13
|
+
tabs?: React.ReactNode;
|
|
14
|
+
/** Stays at the top while the page scrolls, and rises one level when content passes under it. */
|
|
15
|
+
sticky?: boolean;
|
|
16
|
+
/** PageHeaderTitle and PageHeaderDescription. */
|
|
17
|
+
children?: React.ReactNode;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The block every page opens with: breadcrumb, title, description, actions and tabs. The page's name is the record, so
|
|
21
|
+
* the block lies on the ground; only its actions are live, and it has one slot for the primary action (law 1).
|
|
22
|
+
*/
|
|
23
|
+
export declare function PageHeader({ breadcrumb, primary, actions, overflow, tabs, sticky, className, children, ...rest }: PageHeaderProps): React.JSX.Element;
|
|
24
|
+
/** The page's h1. */
|
|
25
|
+
export declare function PageHeaderTitle({ className, ...rest }: React.HTMLAttributes<HTMLHeadingElement>): React.JSX.Element;
|
|
26
|
+
/** One line saying what the page is for. */
|
|
27
|
+
export declare function PageHeaderDescription({ className, ...rest }: React.HTMLAttributes<HTMLParagraphElement>): React.JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/** The pages shown: the first, the last, the current one and `siblings` either side, with a gap where pages are skipped. */
|
|
3
|
+
export declare function pageRange(page: number, count: number, siblings?: number): (number | 'gap')[];
|
|
4
|
+
export interface PaginationProps extends Omit<React.HTMLAttributes<HTMLElement>, 'onChange'> {
|
|
5
|
+
/** The current page, from 1. */
|
|
6
|
+
page: number;
|
|
7
|
+
/** How many pages. Leave it out for cursor paging: Previous and Next, and "Page 3". */
|
|
8
|
+
pageCount?: number;
|
|
9
|
+
onPageChange?: (page: number) => void;
|
|
10
|
+
/** With pageSize: the summary "21–40 of 214". */
|
|
11
|
+
total?: number;
|
|
12
|
+
pageSize?: number;
|
|
13
|
+
/** Pages have URLs: they're links. Without it they're buttons. */
|
|
14
|
+
hrefFor?: (page: number) => string;
|
|
15
|
+
/** For cursor paging: whether there's a next page. Default true. */
|
|
16
|
+
hasNext?: boolean;
|
|
17
|
+
/** Pages either side of the current one. Default 1. */
|
|
18
|
+
siblings?: number;
|
|
19
|
+
/** The next page is loading: the thumb is held pressed until it lands. */
|
|
20
|
+
loading?: boolean;
|
|
21
|
+
/** What's being paged, plural, for the summary ("invoices"). */
|
|
22
|
+
noun?: string;
|
|
23
|
+
locale?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Move through pages of a collection. The page numbers sit in a trench and the current page is one raised thumb that
|
|
27
|
+
* travels to it, as RadioGroup's does: "you are here, among these". They stay links (or buttons) in plain Tab order.
|
|
28
|
+
*/
|
|
29
|
+
export declare function Pagination({ page, pageCount, onPageChange, total, pageSize, hrefFor, hasNext, siblings, loading, noun, locale, className, 'aria-label': label, ...rest }: PaginationProps): React.JSX.Element;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
type Vec = [number, number, number];
|
|
2
|
+
/** [lightness 0–1, chroma, hue in degrees] */
|
|
3
|
+
export declare function oklch(hex: string): Vec;
|
|
4
|
+
/** OKLCH → hex, or null when the colour is outside sRGB. */
|
|
5
|
+
export declare function fromOklch(L: number, C: number, h: number): string | null;
|
|
6
|
+
/** The most chroma (to 0.001) that hue h holds at lightness L inside sRGB. */
|
|
7
|
+
export declare function maxChroma(L: number, h: number): number;
|
|
8
|
+
export type Vision = 'normal' | 'protan' | 'deutan';
|
|
9
|
+
/** OKLab ΔE × 100 between two hex colours, as seen with normal vision or simulated protanopia or deuteranopia. */
|
|
10
|
+
export declare function deltaE(a: string, b: string, kind?: Vision): number;
|
|
11
|
+
/** The smaller of the protan and deutan ΔE. */
|
|
12
|
+
export declare const cvdDeltaE: (a: string, b: string) => number;
|
|
13
|
+
export declare function contrastRatio(a: string, b: string): number;
|
|
14
|
+
export declare const hueGap: (a: number, b: number) => number;
|
|
15
|
+
/** A scheme is dark when its ground is, by the same test deriveAccent uses. */
|
|
16
|
+
export declare const isDarkGround: (ground: string) => boolean;
|
|
17
|
+
export declare const DATA_GATES: {
|
|
18
|
+
reserved: number;
|
|
19
|
+
normal: number;
|
|
20
|
+
hue: number;
|
|
21
|
+
cvd: number;
|
|
22
|
+
cvdAny: number;
|
|
23
|
+
contrast: number;
|
|
24
|
+
chroma: number;
|
|
25
|
+
band: Record<"light" | "dark", [number, number]>;
|
|
26
|
+
rampStep: number;
|
|
27
|
+
pole: number;
|
|
28
|
+
context: {
|
|
29
|
+
chroma: number;
|
|
30
|
+
line: number;
|
|
31
|
+
other: number;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
export declare const DATA_SLOTS: readonly ["data-1", "data-2", "data-3", "data-4", "data-5", "data-6"];
|
|
35
|
+
export declare const DATA_RESERVED: readonly ["accent", "positive", "caution", "critical", "presence-1", "presence-2", "presence-3"];
|
|
36
|
+
export declare const DATA_SEQ: readonly ["data-seq-1", "data-seq-2", "data-seq-3", "data-seq-4", "data-seq-5", "data-seq-6", "data-seq-7"];
|
|
37
|
+
export declare const DATA_DIV_NEG: readonly ["data-div-mid", "data-div-neg-1", "data-div-neg-2", "data-div-neg-3"];
|
|
38
|
+
export declare const DATA_DIV_POS: readonly ["data-div-mid", "data-div-pos-1", "data-div-pos-2", "data-div-pos-3"];
|
|
39
|
+
/** Every data-* token, in tokens.json order. */
|
|
40
|
+
export declare const DATA_TOKENS: readonly ["data-1", "data-2", "data-3", "data-4", "data-5", "data-6", "data-other", "data-context", "data-seq-1", "data-seq-2", "data-seq-3", "data-seq-4", "data-seq-5", "data-seq-6", "data-seq-7", "data-div-neg-3", "data-div-neg-2", "data-div-neg-1", "data-div-mid", "data-div-pos-1", "data-div-pos-2", "data-div-pos-3"];
|
|
41
|
+
/** Magnitude, low to high, in one hue: light schemes darken from near-white; dark schemes start near their ground and climb. */
|
|
42
|
+
export declare function sequentialRamp(h: number, dark: boolean): string[];
|
|
43
|
+
/**
|
|
44
|
+
* Measure the data-* tokens against every gate. `get` returns a token's value by name (without `--`); every value
|
|
45
|
+
* must already be a hex colour. Returns one sentence per problem.
|
|
46
|
+
*/
|
|
47
|
+
export declare function checkDataPalette(get: (name: string) => string): string[];
|
|
48
|
+
/**
|
|
49
|
+
* Colours that could be data-1 for a brand accent, best first: the accent's hue (then hues up to 30° either side), at
|
|
50
|
+
* lightnesses nearest the accent's, each clearing the band, chroma, 3:1 on ground and raised, and the reserved hues.
|
|
51
|
+
*/
|
|
52
|
+
export declare function accentCandidates(accent: string, get: (name: string) => string): string[];
|
|
53
|
+
/**
|
|
54
|
+
* A scheme's six slots, led by a brand accent. The slot nearest the accent makes way: the first candidate (see
|
|
55
|
+
* accentCandidates) that keeps every pairwise gate with the other five takes its place, or, if none does, that nearest
|
|
56
|
+
* slot leads unchanged. The other five are re-ordered behind data-1: every order is tried and the greatest minimum
|
|
57
|
+
* adjacent CVD ΔE wins, ties keeping the scheme's order; if none clears the adjacent gate, the slot closest to data-1
|
|
58
|
+
* is dropped and the rest tried again. Dropped slots leave the end of the palette to data-other. Deterministic.
|
|
59
|
+
*/
|
|
60
|
+
export declare function leadSlots(accent: string, candidates: string[], slots: string[]): {
|
|
61
|
+
slots: string[];
|
|
62
|
+
dropped: string[];
|
|
63
|
+
};
|
|
64
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { InputProps } from './controls.cjs';
|
|
3
|
+
export interface PasswordRequirement {
|
|
4
|
+
label: string;
|
|
5
|
+
test: (value: string) => boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface PasswordInputProps extends Omit<InputProps, 'type' | 'trailing'> {
|
|
8
|
+
/** Scores a password from 0 (weakest) to 4 (strongest); your app supplies the scoring (zxcvbn, your rules). Shown as a Meter. */
|
|
9
|
+
strength?: (value: string) => number;
|
|
10
|
+
/** The word for each score, 0 to 4. Default "Very weak", "Weak", "Fair", "Good", "Strong". */
|
|
11
|
+
strengthLabels?: [string, string, string, string, string];
|
|
12
|
+
/** Rules shown under the field, each stamped as met or not as the password changes. */
|
|
13
|
+
requirements?: PasswordRequirement[];
|
|
14
|
+
/** The reveal toggle's name. It never changes with its state. Default "Show password". */
|
|
15
|
+
revealLabel?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* A password field: an Input with a reveal Toggle in its end cap, a caps-lock notice, and, when creating one, its
|
|
19
|
+
* strength as a reading (a Meter, never a Progress) and its requirements stamped as met. Strength and requirements
|
|
20
|
+
* describe the field and are announced politely once typing pauses.
|
|
21
|
+
*/
|
|
22
|
+
export declare const PasswordInput: React.ForwardRefExoticComponent<PasswordInputProps & React.RefAttributes<HTMLInputElement>>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** What a turn is doing. 'interrupted' is an unfinished answer found after a reload; 'awaiting-input' is a Confirmation or Question open. */
|
|
2
|
+
export type AssistantTurnState = 'ready' | 'submitted' | 'streaming' | 'complete' | 'stopped' | 'failed' | 'interrupted' | 'awaiting-input';
|
|
3
|
+
export type AssistantErrorKind = 'offline' | 'rate-limited' | 'context-full' | 'refused' | 'outage' | 'unknown';
|
|
4
|
+
/** Throw this from `stream` to say what went wrong; anything else is 'unknown' (or 'offline' when the browser is offline). */
|
|
5
|
+
export declare class AssistantError extends Error {
|
|
6
|
+
kind: AssistantErrorKind;
|
|
7
|
+
/** For 'rate-limited': when it can be tried again. */
|
|
8
|
+
retryAt?: Date | number;
|
|
9
|
+
constructor(kind: AssistantErrorKind, message?: string, retryAt?: Date | number);
|
|
10
|
+
}
|
|
11
|
+
export interface AssistantTurnError {
|
|
12
|
+
kind: AssistantErrorKind;
|
|
13
|
+
retryAt?: Date | number;
|
|
14
|
+
message?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface AssistantTurnOptions<I> {
|
|
17
|
+
/** Starts the answer: yield text as it arrives; resolve when the stream says it's complete. Abort on `signal`. */
|
|
18
|
+
stream: (input: I, signal: AbortSignal) => AsyncIterable<string>;
|
|
19
|
+
/** An answer restored after a reload. If it wasn't complete it's 'interrupted', never shown as complete. */
|
|
20
|
+
restored?: {
|
|
21
|
+
input: I;
|
|
22
|
+
text: string;
|
|
23
|
+
complete: boolean;
|
|
24
|
+
};
|
|
25
|
+
locale?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface AssistantTurn<I> {
|
|
28
|
+
state: AssistantTurnState;
|
|
29
|
+
/** The answer so far: kept when stopped, failed or interrupted. */
|
|
30
|
+
text: string;
|
|
31
|
+
/** What was sent, kept until it's answered: put it back in the composer when sending fails. */
|
|
32
|
+
input: I | undefined;
|
|
33
|
+
error: AssistantTurnError | null;
|
|
34
|
+
/** The error in words, with what to do: "You've reached this hour's limit. Try again at 3:40 PM." */
|
|
35
|
+
errorText: string;
|
|
36
|
+
/** Map onto the components. */
|
|
37
|
+
promptStatus: 'ready' | 'submitted' | 'streaming' | 'error';
|
|
38
|
+
messageStatus: 'streaming' | 'complete' | 'stopped' | 'error' | undefined;
|
|
39
|
+
/** Sends unless a turn is already in flight (a double Enter sends once). Returns whether it started. */
|
|
40
|
+
submit: (input: I) => boolean;
|
|
41
|
+
stop: () => void;
|
|
42
|
+
/** Sends the last input again (after a failure, a stop or an interruption). */
|
|
43
|
+
retry: () => boolean;
|
|
44
|
+
/** A Confirmation or Question is open (true) or answered (false): the turn waits for the person. */
|
|
45
|
+
awaitInput: (waiting: boolean) => void;
|
|
46
|
+
}
|
|
47
|
+
/** Each error kind in words, with what to do. */
|
|
48
|
+
export declare function assistantErrorText(error: AssistantTurnError | null, locale?: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* The assistant-conversation contract's turn (project/framework/patterns/assistant-conversation.md, #285): a send that
|
|
51
|
+
* can't happen twice, a stream whose late events from a superseded turn are ignored, Stop that keeps the partial
|
|
52
|
+
* answer, completion only when the stream says so, an unfinished answer after a reload shown as interrupted, and each
|
|
53
|
+
* error kind in words. Map `promptStatus` to PromptInput and `messageStatus` to the answer's Message.
|
|
54
|
+
*/
|
|
55
|
+
export declare function useAssistantTurn<I>({ stream, restored, locale }: AssistantTurnOptions<I>): AssistantTurn<I>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type CollectionPhase = 'loading' | 'refreshing' | 'populated' | 'empty' | 'no-results' | 'failed';
|
|
2
|
+
export interface AsyncCollectionOptions<T, Q> {
|
|
3
|
+
initialQuery: Q;
|
|
4
|
+
/** Own query semantics, permissions, pagination and URL/history in the application. Abort is advisory. */
|
|
5
|
+
load: (query: Q, context: {
|
|
6
|
+
signal: AbortSignal;
|
|
7
|
+
}) => readonly T[] | Promise<readonly T[]>;
|
|
8
|
+
getKey: (item: T) => string;
|
|
9
|
+
isFiltered: (query: Q) => boolean;
|
|
10
|
+
/** preserve deliberately retains keys absent from the current page/filter; reconcile deleted identities in the app. */
|
|
11
|
+
selection: 'clear-on-query' | 'preserve';
|
|
12
|
+
messages?: Partial<{
|
|
13
|
+
loading: string;
|
|
14
|
+
refreshing: string;
|
|
15
|
+
empty: string;
|
|
16
|
+
noResults: string;
|
|
17
|
+
failed: string;
|
|
18
|
+
results: (count: number) => string;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
/** Stale-response-safe collection, with explicit selection policy. See altitude-design/guidance/patterns/async-collection.md. */
|
|
22
|
+
export declare function useAsyncCollection<T, Q>(options: AsyncCollectionOptions<T, Q>): {
|
|
23
|
+
setQuery: (query: Q) => void;
|
|
24
|
+
refresh: () => void;
|
|
25
|
+
reset: () => void;
|
|
26
|
+
clearSelection: () => void;
|
|
27
|
+
toggleSelection: (key: string) => void;
|
|
28
|
+
query: Q;
|
|
29
|
+
items: readonly T[];
|
|
30
|
+
phase: CollectionPhase;
|
|
31
|
+
error: string;
|
|
32
|
+
status: string;
|
|
33
|
+
selectedKeys: ReadonlySet<string>;
|
|
34
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export type ActionResult<T> = {
|
|
2
|
+
ok: true;
|
|
3
|
+
value: T;
|
|
4
|
+
} | {
|
|
5
|
+
ok: false;
|
|
6
|
+
error: string;
|
|
7
|
+
};
|
|
8
|
+
export type UndoResult = {
|
|
9
|
+
ok: true;
|
|
10
|
+
} | {
|
|
11
|
+
ok: false;
|
|
12
|
+
error: string;
|
|
13
|
+
};
|
|
14
|
+
export type ConsequentialPhase = 'idle' | 'confirming' | 'pending' | 'failed' | 'succeeded' | 'undoing' | 'undone';
|
|
15
|
+
interface ActionBase<T> {
|
|
16
|
+
/** Render target and consequence alongside the trigger and in any confirmation. */
|
|
17
|
+
target: string;
|
|
18
|
+
consequence: string;
|
|
19
|
+
execute: () => ActionResult<T> | Promise<ActionResult<T>>;
|
|
20
|
+
/** Connected, visible next logical destination when the original trigger disappears. */
|
|
21
|
+
focusFallback?: () => HTMLElement | null;
|
|
22
|
+
messages?: Partial<{
|
|
23
|
+
pending: string;
|
|
24
|
+
succeeded: string;
|
|
25
|
+
failed: string;
|
|
26
|
+
undoing: string;
|
|
27
|
+
undone: string;
|
|
28
|
+
}>;
|
|
29
|
+
}
|
|
30
|
+
export type ConsequentialActionOptions<T> = ActionBase<T> & ({
|
|
31
|
+
requiresConfirmation: true;
|
|
32
|
+
undo?: (result: T) => UndoResult | Promise<UndoResult>;
|
|
33
|
+
} | {
|
|
34
|
+
requiresConfirmation: false;
|
|
35
|
+
undo: (result: T) => UndoResult | Promise<UndoResult>;
|
|
36
|
+
});
|
|
37
|
+
/** Confirmation records intent; only execute success records completion. Undo is offered only with an application-supplied inverse.
|
|
38
|
+
* Compose Dialog/Alert/Button with the returned content and states. See altitude-design/guidance/patterns/consequential-action.md. */
|
|
39
|
+
export declare function useConsequentialAction<T>(options: ConsequentialActionOptions<T>): {
|
|
40
|
+
target: string;
|
|
41
|
+
consequence: string;
|
|
42
|
+
canUndo: boolean;
|
|
43
|
+
request: () => void;
|
|
44
|
+
confirm: () => void;
|
|
45
|
+
cancel: () => void;
|
|
46
|
+
retry: () => Promise<void> | undefined;
|
|
47
|
+
undo: (() => Promise<void>) | undefined;
|
|
48
|
+
phase: ConsequentialPhase;
|
|
49
|
+
error: string;
|
|
50
|
+
status: string;
|
|
51
|
+
result: T | undefined;
|
|
52
|
+
};
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type FieldErrors<T> = Partial<Record<keyof T, string>>;
|
|
3
|
+
export type EditRecordResult<T> = {
|
|
4
|
+
ok: true;
|
|
5
|
+
value: T;
|
|
6
|
+
} | {
|
|
7
|
+
ok: false;
|
|
8
|
+
error: string;
|
|
9
|
+
errors?: FieldErrors<T>;
|
|
10
|
+
};
|
|
11
|
+
export type EditRecordPhase = 'editing' | 'invalid' | 'submitting' | 'saved' | 'failed';
|
|
12
|
+
export type LeaveReason = 'cancel' | 'back' | 'navigation';
|
|
13
|
+
export interface EditRecordOptions<T extends object> {
|
|
14
|
+
/** Initial snapshot only. Use reset to deliberately adopt another record; keep snapshots immutable. */
|
|
15
|
+
initialValue: T;
|
|
16
|
+
validate: (draft: T) => FieldErrors<T>;
|
|
17
|
+
/** Submit validates every field; blur additionally validates the blurred field. Corrections revalidate visible errors. */
|
|
18
|
+
validationMode: 'submit' | 'blur';
|
|
19
|
+
save: (draft: T, context: {
|
|
20
|
+
previousValue: T;
|
|
21
|
+
}) => EditRecordResult<T> | Promise<EditRecordResult<T>>;
|
|
22
|
+
/** Supply semantic equality for nested values. The default compares top-level fields with Object.is. */
|
|
23
|
+
isEqual?: (a: T, b: T) => boolean;
|
|
24
|
+
messages?: Partial<{
|
|
25
|
+
saving: string;
|
|
26
|
+
saved: string;
|
|
27
|
+
failed: string;
|
|
28
|
+
invalid: string;
|
|
29
|
+
newerEdits: string;
|
|
30
|
+
}>;
|
|
31
|
+
}
|
|
32
|
+
/** Small record workflow. Persistence, concurrency/version checks, authorization and route interception belong to the app.
|
|
33
|
+
* See altitude-design/guidance/patterns/edit-record.md. A response never replaces edits made after dispatch.
|
|
34
|
+
*/
|
|
35
|
+
export declare function useEditRecord<T extends object>(options: EditRecordOptions<T>): {
|
|
36
|
+
dirty: boolean;
|
|
37
|
+
setDraft: (draft: T) => void;
|
|
38
|
+
setField: <K extends keyof T>(key: K, value: T[K]) => void;
|
|
39
|
+
validateField: (key: keyof T) => void;
|
|
40
|
+
validateAll: () => boolean;
|
|
41
|
+
submit: () => Promise<EditRecordResult<T> | undefined>;
|
|
42
|
+
reset: (value?: T) => boolean;
|
|
43
|
+
requestLeave: (reason: LeaveReason, confirmDiscard: (context: {
|
|
44
|
+
reason: LeaveReason;
|
|
45
|
+
draft: T;
|
|
46
|
+
}) => boolean | Promise<boolean>) => Promise<boolean>;
|
|
47
|
+
draft: T;
|
|
48
|
+
baseline: T;
|
|
49
|
+
errors: FieldErrors<T>;
|
|
50
|
+
error: string;
|
|
51
|
+
phase: EditRecordPhase;
|
|
52
|
+
status: string;
|
|
53
|
+
submitCount: number;
|
|
54
|
+
};
|
|
55
|
+
export interface ErrorSummaryProps {
|
|
56
|
+
errors: readonly {
|
|
57
|
+
id: string;
|
|
58
|
+
label: string;
|
|
59
|
+
message: string;
|
|
60
|
+
}[];
|
|
61
|
+
title?: string;
|
|
62
|
+
/** Change after an unsuccessful submit to focus the summary. Omit to keep focus where it is. */
|
|
63
|
+
focusKey?: number;
|
|
64
|
+
className?: string;
|
|
65
|
+
}
|
|
66
|
+
/** Render from the same errors passed to Field; use each input's actual id. Inline Field owns alert announcements. */
|
|
67
|
+
export declare function ErrorSummary({ errors, title, focusKey, className }: ErrorSummaryProps): React.JSX.Element | null;
|
|
68
|
+
/** Place outside any aria-busy region so pending and completion remain announced. */
|
|
69
|
+
export declare function WorkflowStatus({ children, className }: {
|
|
70
|
+
children?: React.ReactNode;
|
|
71
|
+
className?: string;
|
|
72
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { FieldErrors } from './pattern-edit-record.cjs';
|
|
2
|
+
export type ReviewSubmitResult<T, R> = {
|
|
3
|
+
ok: true;
|
|
4
|
+
receipt: R;
|
|
5
|
+
} | {
|
|
6
|
+
ok: false;
|
|
7
|
+
error: string;
|
|
8
|
+
errors?: FieldErrors<T>;
|
|
9
|
+
};
|
|
10
|
+
export interface ReviewSubmitOptions<T extends object, R> {
|
|
11
|
+
/** Supply any recovered draft here. Durable storage, step dependencies and cross-session resume are application responsibilities. */
|
|
12
|
+
initialValue: T;
|
|
13
|
+
validate: (draft: T) => FieldErrors<T>;
|
|
14
|
+
submit: (draft: T) => ReviewSubmitResult<T, R> | Promise<ReviewSubmitResult<T, R>>;
|
|
15
|
+
isEqual?: (a: T, b: T) => boolean;
|
|
16
|
+
messages?: Partial<{
|
|
17
|
+
submitting: string;
|
|
18
|
+
complete: string;
|
|
19
|
+
failed: string;
|
|
20
|
+
invalid: string;
|
|
21
|
+
}>;
|
|
22
|
+
}
|
|
23
|
+
/** Review/correct/submit composition with a persistent application-provided receipt. No automatic persistence or fabricated resume.
|
|
24
|
+
* See altitude-design/guidance/patterns/review-submit.md. Mount a new workflow to start a distinct transaction after completion. */
|
|
25
|
+
export declare function useReviewSubmit<T extends object, R>(options: ReviewSubmitOptions<T, R>): {
|
|
26
|
+
draft: T;
|
|
27
|
+
errors: Partial<Record<keyof T, string>>;
|
|
28
|
+
error: string;
|
|
29
|
+
status: string;
|
|
30
|
+
submitCount: number;
|
|
31
|
+
dirty: boolean;
|
|
32
|
+
phase: "review" | "editing" | "complete" | "submitting";
|
|
33
|
+
receipt: R | undefined;
|
|
34
|
+
setDraft: (value: T) => void;
|
|
35
|
+
setField: <K extends keyof T>(key: K, value: T[K]) => void;
|
|
36
|
+
review: () => void;
|
|
37
|
+
correct: () => void;
|
|
38
|
+
submit: () => Promise<void>;
|
|
39
|
+
requestLeave: (reason: import("./pattern-edit-record.cjs").LeaveReason, confirmDiscard: (context: {
|
|
40
|
+
reason: import("./pattern-edit-record.cjs").LeaveReason;
|
|
41
|
+
draft: T;
|
|
42
|
+
}) => boolean | Promise<boolean>) => Promise<boolean>;
|
|
43
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface MatrixRole {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string; /** Every permission is always granted (an owner). */
|
|
5
|
+
locked?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface MatrixPermission {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string; /** Rows with the same group sit under its heading. */
|
|
10
|
+
group?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface MatrixInherited {
|
|
13
|
+
granted: boolean; /** Where it comes from ("Admin"). */
|
|
14
|
+
from: string;
|
|
15
|
+
}
|
|
16
|
+
export interface PermissionMatrixProps {
|
|
17
|
+
roles: MatrixRole[];
|
|
18
|
+
permissions: MatrixPermission[];
|
|
19
|
+
/** Grants you can change: value[roleId][permissionId]. */
|
|
20
|
+
value: Record<string, Record<string, boolean>>;
|
|
21
|
+
/** A grant decided elsewhere (a parent role, a group): shown as a stamped mark, not a choice. */
|
|
22
|
+
inherited?: (roleId: string, permissionId: string) => MatrixInherited | undefined;
|
|
23
|
+
/** Called when a choice is toggled. Return a promise and the cell hovers as pending until it settles; a rejection reverts it. */
|
|
24
|
+
onChange?: (roleId: string, permissionId: string, granted: boolean) => void | Promise<unknown>;
|
|
25
|
+
/** Names the grid ("Role permissions"). */
|
|
26
|
+
'aria-label'?: string;
|
|
27
|
+
className?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Roles against permissions. The grid is settled (the record of who can do what). An editable grant is a choice, built
|
|
31
|
+
* like a Checkbox (a trench the accent pours into); an inherited or fixed grant is already decided, so it's a flush
|
|
32
|
+
* stamped check, not a disabled box. The active cell is a ring, never a height. A grid: arrows move, Space toggles.
|
|
33
|
+
*/
|
|
34
|
+
export declare function PermissionMatrix({ roles, permissions, value, inherited, onChange, 'aria-label': label, className }: PermissionMatrixProps): React.JSX.Element;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface PileProps<T = unknown> extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> {
|
|
3
|
+
/** How many items the pile holds; defaults to items.length. 1 → no sheets, 2–3 → one, 4–9 → two, 10+ → three. */
|
|
4
|
+
count?: number;
|
|
5
|
+
/** Hover and focus lift the top and fan the sheets. Implied when `items` is set. */
|
|
6
|
+
interactive?: boolean;
|
|
7
|
+
/** The items in the pile. With renderItem, clicking the pile fans these out below it, floating over the page. */
|
|
8
|
+
items?: T[];
|
|
9
|
+
renderItem?: (item: T, state: {
|
|
10
|
+
index: number;
|
|
11
|
+
}) => React.ReactNode;
|
|
12
|
+
getKey?: (item: T, index: number) => string;
|
|
13
|
+
/** Called when a fanned-out item is clicked. */
|
|
14
|
+
onSelect?: (item: T, index: number) => void;
|
|
15
|
+
open?: boolean;
|
|
16
|
+
defaultOpen?: boolean;
|
|
17
|
+
onOpenChange?: (open: boolean) => void;
|
|
18
|
+
/** Tallest the fanned-out list grows before it scrolls. Default 360px. */
|
|
19
|
+
maxHeight?: number | string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Quantity as thickness, and a pile you can fan out. Closed, the sheets beneath say roughly how many
|
|
23
|
+
* (the badge says exactly); reaching for it fans them a little. Click it and the items slide out from under
|
|
24
|
+
* the top card over the page below it, each casting its own shadow; click one to choose it; click the top,
|
|
25
|
+
* press Escape or click away and they slide back.
|
|
26
|
+
*/
|
|
27
|
+
export declare function Pile<T>({ count, interactive, items, renderItem, getKey, onSelect, open, defaultOpen, onOpenChange, maxHeight, className, children, ...rest }: PileProps<T>): React.JSX.Element;
|