altitude-design 0.1.2 → 0.2.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/README.md +8 -3
- package/dist/altitude.css +85 -16
- package/dist/altitude.iife.js +5 -3
- package/dist/altitude.no-fonts.css +1701 -0
- package/dist/fonts.css +1 -0
- package/dist/index.cjs +840 -417
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +840 -417
- package/dist/index.js.map +4 -4
- package/dist/types/collections.d.ts +6 -2
- package/dist/types/command.d.ts +5 -1
- package/dist/types/controls.d.ts +37 -8
- package/dist/types/core.d.ts +23 -2
- package/dist/types/empty.d.ts +24 -0
- package/dist/types/index.d.ts +6 -2
- package/dist/types/overlays.d.ts +9 -2
- package/dist/types/suspense.d.ts +74 -0
- package/package.json +5 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { Promised, SkeletonOption } from './suspense';
|
|
2
3
|
export interface TableProps extends React.TableHTMLAttributes<HTMLTableElement> {
|
|
3
4
|
/** The table scrolls under its header past this height. */
|
|
4
5
|
maxHeight?: number | string;
|
|
@@ -56,7 +57,10 @@ export type TableSort = {
|
|
|
56
57
|
} | null;
|
|
57
58
|
export interface DataTableProps<T> {
|
|
58
59
|
columns: DataTableColumn<T>[];
|
|
59
|
-
rows:
|
|
60
|
+
/** The rows. Undefined while your data loads, or a promise: until they arrive the table is its header over `skeleton.lines` imprinted rows (default 5). */
|
|
61
|
+
rows: Promised<T[]> | undefined;
|
|
62
|
+
/** While the rows are on their way: how many rows to imprint (`lines`). `false`: undefined rows render as empty, and a promise suspends to your own boundary. */
|
|
63
|
+
skeleton?: SkeletonOption;
|
|
60
64
|
getRowId: (row: T) => string;
|
|
61
65
|
/** A row's name, for screen readers (its checkbox, its move handle, announcements) and its button with onRowClick. */
|
|
62
66
|
getRowLabel?: (row: T) => string;
|
|
@@ -88,7 +92,7 @@ export interface DataTableProps<T> {
|
|
|
88
92
|
* A table from data: sortable columns whose rows are carried to their new places, a checkbox column whose selected rows
|
|
89
93
|
* rise (counted by a floating Badge in the toolbar), filtering in place, interactive rows and reordering by hand.
|
|
90
94
|
*/
|
|
91
|
-
export declare function DataTable<T>({
|
|
95
|
+
export declare function DataTable<T>({ skeleton, ...props }: DataTableProps<T>): React.JSX.Element;
|
|
92
96
|
export interface BoardPlace {
|
|
93
97
|
column: string;
|
|
94
98
|
index: number;
|
package/dist/types/command.d.ts
CHANGED
|
@@ -38,6 +38,10 @@ export interface CommandPaletteProps {
|
|
|
38
38
|
empty?: React.ReactNode | ((query: string) => React.ReactNode);
|
|
39
39
|
/** The letter that opens and closes the palette with ⌘ (macOS) or Ctrl. Default 'k'; false for none. */
|
|
40
40
|
shortcut?: string | false;
|
|
41
|
+
/** The query, controlled. The palette never clears it on opening: the caller owns it, e.g. a persistent field handing over what was typed. */
|
|
42
|
+
query?: string;
|
|
43
|
+
/** What the query is each time the palette opens, uncontrolled. Default ''. */
|
|
44
|
+
defaultQuery?: string;
|
|
41
45
|
onQueryChange?: (query: string) => void;
|
|
42
46
|
/** Close once an item is chosen. Default true. */
|
|
43
47
|
closeOnSelect?: boolean;
|
|
@@ -56,4 +60,4 @@ export declare function commandScore(text: string, query: string): number;
|
|
|
56
60
|
* as it does for Dialog. The query field is an opening built like Input; one highlight glides between results;
|
|
57
61
|
* when results change, surviving rows travel to their new places and new ones rise in, a few at a time.
|
|
58
62
|
*/
|
|
59
|
-
export declare function CommandPalette({ items, open, defaultOpen, onOpenChange, onSelect, placeholder, filter, empty, shortcut, onQueryChange, closeOnSelect, hints, className, ...rest }: CommandPaletteProps): React.JSX.Element | null;
|
|
63
|
+
export declare function CommandPalette({ items, open, defaultOpen, onOpenChange, onSelect, placeholder, filter, empty, shortcut, query: queryProp, defaultQuery, onQueryChange, closeOnSelect, hints, className, ...rest }: CommandPaletteProps): React.JSX.Element | null;
|
package/dist/types/controls.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { DepthProps } from './core';
|
|
3
|
+
import { Promised, SkeletonOption } from './suspense';
|
|
3
4
|
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
4
5
|
variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
|
|
5
6
|
size?: 'sm' | 'md' | 'lg';
|
|
@@ -13,12 +14,31 @@ export declare const Button: React.ForwardRefExoticComponent<ButtonProps & React
|
|
|
13
14
|
export interface CardProps extends React.HTMLAttributes<HTMLDivElement>, DepthProps {
|
|
14
15
|
/** Lifts on hover and presses on click. Only set it when the whole card does something. */
|
|
15
16
|
interactive?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* The card holds a Suspense boundary: while anything of yours inside it suspends, the card stays up and its body is an
|
|
19
|
+
* imprint (a title line and `lines` lines of text, default 3). `false` lets it suspend to your own boundary.
|
|
20
|
+
* It's also a loading scope: its optional parts (description, body text) wait while its required parts do.
|
|
21
|
+
*/
|
|
22
|
+
skeleton?: SkeletonOption;
|
|
16
23
|
}
|
|
17
24
|
export declare const Card: React.ForwardRefExoticComponent<CardProps & React.RefAttributes<HTMLDivElement>>;
|
|
18
25
|
export declare const CardHeader: ({ className, ...p }: React.HTMLAttributes<HTMLDivElement>) => React.JSX.Element;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Text that may still be on its way: `undefined` while your data loads (`{user?.name}`), a promise, or one promise among
|
|
28
|
+
* plain text. `null` renders nothing.
|
|
29
|
+
*/
|
|
30
|
+
type PromisedText<E> = Omit<React.HTMLAttributes<E>, 'children'> & {
|
|
31
|
+
children?: React.ReactNode | PromiseLike<React.ReactNode> | Array<React.ReactNode | PromiseLike<React.ReactNode>>;
|
|
32
|
+
/** While the text is on its way, its imprint: `lines` (one for a title, two for a description) and `width`. `false`: render what you pass as it is, and let promises suspend to your own boundary. */
|
|
33
|
+
skeleton?: SkeletonOption;
|
|
34
|
+
};
|
|
35
|
+
export declare const CardTitle: ({ className, children, skeleton, ...p }: PromisedText<HTMLHeadingElement>) => React.JSX.Element;
|
|
36
|
+
export declare const CardDescription: ({ className, children, skeleton, ...p }: PromisedText<HTMLParagraphElement>) => React.JSX.Element;
|
|
37
|
+
export interface CardContentProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
38
|
+
/** The body holds a Suspense boundary: while anything of yours inside it suspends, or its text (`{user?.bio}`) is undefined while the card's other parts are, it's `lines` lines of imprint (default 3). `false` suspends to your own boundary. */
|
|
39
|
+
skeleton?: SkeletonOption;
|
|
40
|
+
}
|
|
41
|
+
export declare const CardContent: ({ className, skeleton, children, ...p }: CardContentProps) => React.JSX.Element;
|
|
22
42
|
export declare const CardFooter: ({ className, ...p }: React.HTMLAttributes<HTMLDivElement>) => React.JSX.Element;
|
|
23
43
|
export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {
|
|
24
44
|
invalid?: boolean;
|
|
@@ -115,7 +135,7 @@ export interface ProgressProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
115
135
|
'aria-label'?: string;
|
|
116
136
|
}
|
|
117
137
|
export declare function Progress({ value, max, className, ...rest }: ProgressProps): React.JSX.Element;
|
|
118
|
-
export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
138
|
+
export interface BadgeProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'children'> {
|
|
119
139
|
tone?: 'neutral' | 'accent' | 'positive' | 'caution' | 'critical';
|
|
120
140
|
/**
|
|
121
141
|
* plate (default): an indicator plate set flush into the page. tinted: the plate takes its tone's colour.
|
|
@@ -127,12 +147,18 @@ export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
|
127
147
|
lamp?: boolean | 'pulse';
|
|
128
148
|
/** @deprecated Use `lamp`. */
|
|
129
149
|
dot?: boolean;
|
|
150
|
+
/** The label. Undefined while your data loads, or a promise: until it arrives the badge is a plate-shaped imprint. */
|
|
151
|
+
children?: React.ReactNode | PromiseLike<React.ReactNode> | Array<React.ReactNode | PromiseLike<React.ReactNode>>;
|
|
152
|
+
/** While the label is on its way: the imprint's `width` (default 64px; a count is round). `false`: render what you pass as it is, and let promises suspend to your own boundary. */
|
|
153
|
+
skeleton?: SkeletonOption;
|
|
130
154
|
}
|
|
131
155
|
/** A label stamped into the record. Status carries a lamp that relights when it changes; a changed label is re-stamped. */
|
|
132
|
-
export declare function Badge({
|
|
156
|
+
export declare function Badge({ children, skeleton, ...props }: BadgeProps): React.JSX.Element;
|
|
133
157
|
export interface AvatarProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
134
|
-
name:
|
|
135
|
-
|
|
158
|
+
/** The accessible label. Undefined while your data loads (`user?.name`), or a promise: until it arrives the avatar is a round imprint of its size. */
|
|
159
|
+
name: Promised<string> | undefined;
|
|
160
|
+
/** May be a promise, like `name`. */
|
|
161
|
+
src?: Promised<string | undefined>;
|
|
136
162
|
size?: number;
|
|
137
163
|
/** Presence as height: active people hover above the page (their shadow drops away), idle ones rest on it, offline ones lie flat and grey. */
|
|
138
164
|
status?: 'active' | 'idle' | 'offline';
|
|
@@ -142,9 +168,11 @@ export interface AvatarProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
|
142
168
|
presence?: 1 | 2 | 3;
|
|
143
169
|
/** The status lamp (green active, amber idle). Default: shown when there is a status and the avatar is 24px or larger. Never shown inside AvatarGroup. */
|
|
144
170
|
lamp?: boolean;
|
|
171
|
+
/** `false`: no imprint. An undefined `name` renders an empty face; a promised one suspends to your own boundary. */
|
|
172
|
+
skeleton?: boolean;
|
|
145
173
|
}
|
|
146
174
|
/** A disc above its own shadow. The gap between them is how high the person is: how present they are right now. */
|
|
147
|
-
export declare function Avatar({
|
|
175
|
+
export declare function Avatar({ skeleton, ...props }: AvatarProps): React.JSX.Element;
|
|
148
176
|
export declare function AvatarGroup({ className, children, max, style, ...rest }: React.HTMLAttributes<HTMLDivElement> & {
|
|
149
177
|
max?: number;
|
|
150
178
|
}): React.JSX.Element;
|
|
@@ -246,3 +274,4 @@ export interface SortableListProps<T> {
|
|
|
246
274
|
}
|
|
247
275
|
/** Possession as depth: the item you pick up comes into your hand (level 3), the slot it will land in opens as a well, and it lands with a settle. */
|
|
248
276
|
export declare function SortableList<T>({ items, getKey, onReorder, renderItem, getLabel, gap, className, ...rest }: SortableListProps<T>): React.JSX.Element;
|
|
277
|
+
export {};
|
package/dist/types/core.d.ts
CHANGED
|
@@ -43,14 +43,35 @@ export declare const contrast: (a: string, b: string) => number;
|
|
|
43
43
|
* every surface passed) and `accent-soft` (a tint of the ground).
|
|
44
44
|
*/
|
|
45
45
|
export declare function deriveAccent(accent: string, surfaces: string[]): React.CSSProperties;
|
|
46
|
-
|
|
46
|
+
declare const SURFACES: readonly ["surface-trench", "surface-well", "surface-ground", "surface-raised", "surface-lifted", "surface-floating", "surface-overlay", "surface-modal"];
|
|
47
|
+
export type SchemeColorToken = typeof SURFACES[number] | 'ink' | 'ink-muted' | 'ink-faint' | 'line' | 'line-control' | 'accent' | 'on-accent' | 'accent-ink' | 'accent-soft' | 'positive' | 'positive-soft' | 'caution' | 'caution-soft' | 'critical' | 'critical-soft' | 'on-critical' | 'presence-1' | 'presence-2' | 'presence-3' | 'on-presence' | 'scrim';
|
|
48
|
+
export type SchemeShadowToken = 'trench' | 'well' | 'elev-0' | 'elev-1' | 'elev-2' | 'elev-3' | 'elev-4' | 'elev-5' | 'lip-top' | 'lip-bottom';
|
|
49
|
+
/**
|
|
50
|
+
* Check a scheme against the invariants every scheme keeps: the surfaces climb in lightness (trench < well < ground
|
|
51
|
+
* < raised ≤ … ≤ modal) and text, control edges and presence colours hold their contrast on every surface. Pass the
|
|
52
|
+
* colour tokens by name (without `--`), or an element to read them from. Returns one sentence per problem; [] passes.
|
|
53
|
+
* Only hex values can be measured; any other value of a checked token is reported.
|
|
54
|
+
*/
|
|
55
|
+
export declare function checkScheme(colors: Partial<Record<SchemeColorToken, string>> | Element): string[];
|
|
56
|
+
export interface CustomScheme {
|
|
57
|
+
/** Stamped as data-scheme on the provider's root. */
|
|
58
|
+
name: string;
|
|
59
|
+
/** The built-in scheme your tokens are laid over: any token you leave out comes from it, and so does light or dark
|
|
60
|
+
* handling (casts, rims, walls). Use nightfall or alpine for a dark scheme. Default 'daylight'. */
|
|
61
|
+
base?: BuiltInScheme;
|
|
62
|
+
/** Colour and shadow tokens by name, without `--`. */
|
|
63
|
+
tokens: Partial<Record<SchemeColorToken | SchemeShadowToken, string>>;
|
|
64
|
+
}
|
|
65
|
+
export type BuiltInScheme = 'daylight' | 'nightfall' | 'mesa' | 'alpine';
|
|
66
|
+
/** A built-in scheme, the name of your own [data-theme="…"] block, or a CustomScheme. */
|
|
67
|
+
export type Scheme = BuiltInScheme | (string & {});
|
|
47
68
|
type Ctx = {
|
|
48
69
|
host: HTMLElement | null;
|
|
49
70
|
pushLayer: () => () => void;
|
|
50
71
|
};
|
|
51
72
|
export declare const useAltitude: () => Ctx | null;
|
|
52
73
|
export interface AltitudeProviderProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
53
|
-
scheme?: Scheme;
|
|
74
|
+
scheme?: Scheme | CustomScheme;
|
|
54
75
|
accent?: string;
|
|
55
76
|
motion?: 'system' | 'full' | 'reduced';
|
|
56
77
|
/** 'more' renders elevation as hard, high-contrast slabs (offset = height). 'system' follows prefers-contrast. */
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface EmptyStateProps extends Omit<React.HTMLAttributes<HTMLElement>, 'title'> {
|
|
3
|
+
/** A line icon, drawn in ink-muted: 24px, or 18px at size sm. */
|
|
4
|
+
icon?: React.ReactNode;
|
|
5
|
+
/** What is empty, as a statement: "No gift ideas yet". It names the region. */
|
|
6
|
+
title: React.ReactNode;
|
|
7
|
+
/** Why it's empty, or what will appear here. Linked as the region's description. */
|
|
8
|
+
description?: React.ReactNode;
|
|
9
|
+
/** The one obvious next step: usually a primary Button. */
|
|
10
|
+
action?: React.ReactNode;
|
|
11
|
+
/** A quieter alternative beside it: usually a ghost Button or a link. */
|
|
12
|
+
secondary?: React.ReactNode;
|
|
13
|
+
/** md fills a page or a panel; sm fits a widget or a list. Default 'md'. */
|
|
14
|
+
size?: 'sm' | 'md';
|
|
15
|
+
/** The title's heading level. Default 3. */
|
|
16
|
+
headingLevel?: 2 | 3 | 4;
|
|
17
|
+
/** Say it politely when it appears, for an empty that follows a change (a filter, a search). true says the title, if it's text; a string says that. */
|
|
18
|
+
announce?: boolean | string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* An opening the first record will fill. Nothing here yet is a well cut into the page (not a raised card, not an
|
|
22
|
+
* alert), with a dashed rim, a title that names what's empty and one next action standing in it.
|
|
23
|
+
*/
|
|
24
|
+
export declare function EmptyState({ icon, title, description, action, secondary, size, headingLevel, announce, className, children, ...rest }: EmptyStateProps): React.JSX.Element;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* altitude-design: a React component library where height is the interface.
|
|
3
|
-
* Docs and live previews: https://richlaconte.github.io/altitude/
|
|
3
|
+
* Docs and live previews: https://richlaconte.github.io/altitude/storybook/
|
|
4
4
|
* Bugs, feature requests and new components: https://github.com/richlaconte/altitude/issues/new/choose
|
|
5
5
|
* Agents: you may file issues too; see https://github.com/richlaconte/altitude/blob/main/AGENTS.md
|
|
6
6
|
*/
|
|
7
|
-
export { AltitudeProvider, useAltitude, useDepth, useApproach, riseDelay, Layer, Surface, Kbd, Icons, Spinner, deriveAccent, contrast, usePresence } from './core';
|
|
7
|
+
export { AltitudeProvider, useAltitude, useDepth, useApproach, riseDelay, Layer, Surface, Kbd, Icons, Spinner, deriveAccent, contrast, checkScheme, usePresence } from './core';
|
|
8
|
+
export type { Scheme, BuiltInScheme, CustomScheme, SchemeColorToken, SchemeShadowToken } from './core';
|
|
8
9
|
export { Button, Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, Input, Textarea, Field, Checkbox, RadioGroup, Radio, Switch, Tabs, TabsList, TabsTrigger, TabsContent, Slider, Progress, Badge, Avatar, AvatarGroup, Skeleton, Alert, AlertStack, Accordion, HoldButton, ScrollArea, DropZone, SortableList, } from './controls';
|
|
9
10
|
export { Pile } from './pile';
|
|
10
11
|
export { Tooltip, HoverCard, Popover, DropdownMenu, Dialog, Toaster, toast } from './overlays';
|
|
@@ -13,4 +14,7 @@ export { Sheet, SheetHeader, SheetTitle, SheetDescription, SheetFooter } from '.
|
|
|
13
14
|
export { CommandPalette, commandScore } from './command';
|
|
14
15
|
export { Select, SelectItem, Combobox } from './select';
|
|
15
16
|
export { Stepper } from './stepper';
|
|
17
|
+
export { EmptyState } from './empty';
|
|
16
18
|
export { Table, TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell, TableCaption, DataTable, Board, BoardColumn, BoardCard } from './collections';
|
|
19
|
+
export { Await, RevealGroup, readPromised, LoadingScope } from './suspense';
|
|
20
|
+
export type { Promised, Pending, SkeletonOption, AwaitProps } from './suspense';
|
package/dist/types/overlays.d.ts
CHANGED
|
@@ -83,12 +83,15 @@ export interface ModalOptions {
|
|
|
83
83
|
/** Move focus into the panel once it has risen. Default true. */
|
|
84
84
|
autoFocus?: boolean;
|
|
85
85
|
focusSelector?: string;
|
|
86
|
+
/** Put focus back where it was on close. Default: autoFocus. */
|
|
87
|
+
restoreFocus?: boolean;
|
|
86
88
|
}
|
|
87
89
|
/**
|
|
88
90
|
* The machinery every layer above the page shares: presence (mount, rise, exit), the receding page,
|
|
89
91
|
* scroll lock, focus in and back out, Escape and the Tab trap. Dialog, Sheet and CommandPalette use it.
|
|
90
92
|
*/
|
|
91
|
-
export declare
|
|
93
|
+
export declare const MODAL_FOCUS = "[data-autofocus], input, textarea, select";
|
|
94
|
+
export declare function useModal({ open, onDismiss, exitMs, panel, modal, dismissible, summit, autoFocus, focusSelector, restoreFocus }: ModalOptions): {
|
|
92
95
|
onKeyDown: (e: React.KeyboardEvent) => void;
|
|
93
96
|
mounted: boolean;
|
|
94
97
|
state: "open" | "closed";
|
|
@@ -106,9 +109,13 @@ export interface DialogProps {
|
|
|
106
109
|
size?: 'sm' | 'md' | 'lg';
|
|
107
110
|
/** Set false for decisions that must be answered: the scrim and Escape won't close it. */
|
|
108
111
|
dismissible?: boolean;
|
|
112
|
+
/** Where focus goes once it has risen: the first field (the default), the title (for a read surface), or nowhere (you move it yourself). */
|
|
113
|
+
initialFocus?: 'first-field' | 'title' | false;
|
|
114
|
+
/** What 'first-field' looks for. Default '[data-autofocus], input, textarea, select'; the panel itself if nothing matches. */
|
|
115
|
+
focusSelector?: string;
|
|
109
116
|
className?: string;
|
|
110
117
|
}
|
|
111
|
-
export declare function Dialog({ open, defaultOpen, onOpenChange, trigger, title, description, children, footer, size, dismissible, className }: DialogProps): React.JSX.Element;
|
|
118
|
+
export declare function Dialog({ open, defaultOpen, onOpenChange, trigger, title, description, children, footer, size, dismissible, initialFocus, focusSelector, className }: DialogProps): React.JSX.Element;
|
|
112
119
|
export type ToastTone = 'neutral' | 'positive' | 'caution' | 'critical';
|
|
113
120
|
export interface ToastOptions {
|
|
114
121
|
title: React.ReactNode;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/** A value, or a promise of one. A component that takes one shows its own imprint until it lands. */
|
|
3
|
+
export type Promised<T> = T | PromiseLike<T>;
|
|
4
|
+
/** Hints for a component's imprint, or `false` to let it suspend to your own boundary instead. */
|
|
5
|
+
export type SkeletonOption = boolean | {
|
|
6
|
+
lines?: number;
|
|
7
|
+
width?: number | string;
|
|
8
|
+
};
|
|
9
|
+
export declare const isPromise: (v: unknown) => v is PromiseLike<unknown>;
|
|
10
|
+
/** Content that may still be on its way: `undefined` while your data loads, or a promise. `null` means there is nothing. */
|
|
11
|
+
export type Pending<T> = T | PromiseLike<T> | undefined;
|
|
12
|
+
/** Children that hold a promise, at the top level or one level down (`Welcome back, {name}`). */
|
|
13
|
+
export declare const hasPromise: (children: unknown) => boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Reads a promised value, suspending until it lands. React 19's `use()` when it's there; on React 18, the same contract
|
|
16
|
+
* by hand (the promise is thrown to the nearest Suspense boundary and its result remembered).
|
|
17
|
+
*/
|
|
18
|
+
export declare function readPromised<T>(v: Promised<T>): T;
|
|
19
|
+
/** Reads promised children, at the top level or one level down. */
|
|
20
|
+
export declare function readChildren(children: unknown): React.ReactNode;
|
|
21
|
+
/**
|
|
22
|
+
* Turns "not here yet" into a suspension: while `waiting`, returns a promise that resolves once it stops, for the
|
|
23
|
+
* component's inner part to read (see Arrive), so its own boundary shows the imprint. Call it in the outer part, which
|
|
24
|
+
* stays mounted and re-renders when your data arrives.
|
|
25
|
+
*/
|
|
26
|
+
export declare function useArrival(waiting: boolean): PromiseLike<void> | null;
|
|
27
|
+
/** Suspends while `when` is pending; renders its children once it isn't. */
|
|
28
|
+
export declare function Arrive({ when, children }: {
|
|
29
|
+
when: PromiseLike<void> | null;
|
|
30
|
+
children?: React.ReactNode;
|
|
31
|
+
}): React.JSX.Element;
|
|
32
|
+
/** True from the first render that waited onwards, so the boundary stays mounted and the content can rise out of it. */
|
|
33
|
+
export declare function useHasWaited(waiting: boolean): boolean;
|
|
34
|
+
export declare function LoadingScope({ children }: {
|
|
35
|
+
children?: React.ReactNode;
|
|
36
|
+
}): React.JSX.Element;
|
|
37
|
+
/** For required content (an avatar's name, a title, a badge's label, a table's rows): says whether it's still on its way. */
|
|
38
|
+
export declare function useReportWaiting(waiting: boolean): void;
|
|
39
|
+
/** For optional content: is the card it's in still waiting for its required parts? */
|
|
40
|
+
export declare const useScopeWaiting: () => boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Imprints inside a RevealGroup land together: each one that finishes waits, still an imprint, until the slowest has
|
|
43
|
+
* landed, then they all rise at once (four at a time, as always). Group things that load from the same place.
|
|
44
|
+
*/
|
|
45
|
+
export declare function RevealGroup({ children }: {
|
|
46
|
+
children?: React.ReactNode;
|
|
47
|
+
}): React.JSX.Element;
|
|
48
|
+
export interface AwaitProps {
|
|
49
|
+
/** The imprint: the fallback while the children suspend. */
|
|
50
|
+
imprint: React.ReactNode;
|
|
51
|
+
/** The shape left behind as content rises out of it. `none` for containers: their content just rises. */
|
|
52
|
+
shape?: 'circle' | 'text' | 'block' | 'none';
|
|
53
|
+
/** Sits in a line of text or a row of controls (an avatar, a badge) rather than as a block. */
|
|
54
|
+
inline?: boolean;
|
|
55
|
+
/** `false`: no boundary; the children suspend to yours. */
|
|
56
|
+
enabled?: boolean;
|
|
57
|
+
className?: string;
|
|
58
|
+
children?: React.ReactNode;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A Suspense boundary whose fallback is an imprint, and whose content rises out of it. Every Suspense-native Altitude
|
|
62
|
+
* component holds one; use it in your own components to give them the same behaviour.
|
|
63
|
+
*/
|
|
64
|
+
export declare function Await({ imprint, shape, inline, enabled, className, children }: AwaitProps): React.JSX.Element;
|
|
65
|
+
/** Lines of text, as tall as the text they stand for (each line is one line-height of the surrounding type). */
|
|
66
|
+
export declare function TextImprint({ lines, width, className }: {
|
|
67
|
+
lines?: number;
|
|
68
|
+
width?: number | string;
|
|
69
|
+
className?: string;
|
|
70
|
+
}): React.JSX.Element;
|
|
71
|
+
export declare const hint: (s: SkeletonOption | undefined) => {
|
|
72
|
+
lines?: number;
|
|
73
|
+
width?: number | string;
|
|
74
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "altitude-design",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "A React component library where height is the interface: the ground is the record.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
"require": "./dist/index.cjs"
|
|
30
30
|
},
|
|
31
31
|
"./altitude.css": "./dist/altitude.css",
|
|
32
|
+
"./altitude.no-fonts.css": "./dist/altitude.no-fonts.css",
|
|
33
|
+
"./fonts.css": "./dist/fonts.css",
|
|
32
34
|
"./tokens.css": "./dist/tokens.css",
|
|
33
35
|
"./tokens.json": "./dist/tokens.json",
|
|
34
36
|
"./altitude.iife.js": "./dist/altitude.iife.js",
|
|
@@ -51,7 +53,8 @@
|
|
|
51
53
|
"build": "node scripts/build-package.mjs",
|
|
52
54
|
"typecheck": "tsc -p tsconfig.json --noEmit --declaration false --emitDeclarationOnly false",
|
|
53
55
|
"storybook": "node scripts/stories.mjs && storybook dev -p 6006",
|
|
54
|
-
"build-storybook": "node scripts/stories.mjs && storybook build -o storybook-static --quiet"
|
|
56
|
+
"build-storybook": "node scripts/stories.mjs && storybook build -o storybook-static --quiet",
|
|
57
|
+
"build-site": "node scripts/build-site.mjs"
|
|
55
58
|
},
|
|
56
59
|
"devDependencies": {
|
|
57
60
|
"@storybook/addon-docs": "10.6.1",
|