trc-ui 0.0.0-stage → 0.5.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/CHANGELOG.md +72 -0
- package/LICENSE +21 -0
- package/README.md +126 -2
- package/dist/index.cjs +2710 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1021 -0
- package/dist/index.d.ts +1021 -0
- package/dist/index.js +2623 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +1 -0
- package/package.json +86 -4
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,1021 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ComponentPropsWithoutRef, ReactNode, ElementType, Ref, SVGProps, ReactElement, KeyboardEvent } from 'react';
|
|
3
|
+
|
|
4
|
+
/** Joins CSS class names, skipping empty values. */
|
|
5
|
+
declare function cx(...classes: (string | false | null | undefined)[]): string;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Colors the words between asterisks with the accent: "How it *works*".
|
|
9
|
+
* Without asterisks, `accentLast` colors the last words (titles coming from a CMS).
|
|
10
|
+
*/
|
|
11
|
+
declare function AccentText({ text, accentLast }: {
|
|
12
|
+
text: string;
|
|
13
|
+
accentLast?: number;
|
|
14
|
+
}): react.JSX.Element;
|
|
15
|
+
/** Plain text of a marked-up title, for attributes (`alt`, `title`, metadata). */
|
|
16
|
+
declare const plainText: (text: string) => string;
|
|
17
|
+
type HeadingSize = "display" | "xl" | "lg" | "md" | "sm";
|
|
18
|
+
type HeadingProps = Omit<ComponentPropsWithoutRef<"h2">, "children"> & {
|
|
19
|
+
/** Rendered tag; the visual size is set separately with `size`. */
|
|
20
|
+
as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | "span";
|
|
21
|
+
size?: HeadingSize;
|
|
22
|
+
/** When `children` is a string without asterisks, number of trailing words in the accent color. */
|
|
23
|
+
accentLast?: number;
|
|
24
|
+
children: ReactNode;
|
|
25
|
+
};
|
|
26
|
+
/** Thin Montserrat 400 heading; a string may contain an *accent word* between asterisks. */
|
|
27
|
+
declare function Heading({ as: Tag, size, accentLast, className, children, ...props }: HeadingProps): react.JSX.Element;
|
|
28
|
+
type TextProps<C extends ElementType = "p"> = {
|
|
29
|
+
as?: C;
|
|
30
|
+
size?: "lg" | "md" | "sm";
|
|
31
|
+
tone?: "default" | "muted" | "subtle";
|
|
32
|
+
} & Omit<ComponentPropsWithoutRef<C>, "as" | "size">;
|
|
33
|
+
/** Body text; `tone="muted"` (default) so that it does not compete with headings. */
|
|
34
|
+
declare function Text<C extends ElementType = "p">({ as, size, tone, className, ...props }: TextProps<C>): react.JSX.Element;
|
|
35
|
+
/** Large thin number in the accent color ("01", "02"…), reserved for steps in a real order. */
|
|
36
|
+
declare function StepNumber({ n, size, className }: {
|
|
37
|
+
n: number;
|
|
38
|
+
size?: "md" | "sm";
|
|
39
|
+
className?: string;
|
|
40
|
+
}): react.JSX.Element;
|
|
41
|
+
|
|
42
|
+
type PillStyle = {
|
|
43
|
+
/** White background: the main action of a screen. */
|
|
44
|
+
solid?: boolean;
|
|
45
|
+
/** Compact version (header, toolbars). */
|
|
46
|
+
size?: "md" | "sm";
|
|
47
|
+
/** Replaces the dot's arrow (for instance a left arrow for "Back"). */
|
|
48
|
+
icon?: ReactNode;
|
|
49
|
+
};
|
|
50
|
+
type PillButtonProps = ComponentPropsWithoutRef<"button"> & PillStyle & {
|
|
51
|
+
/** Replaces the icon with a spinner and disables the button. */
|
|
52
|
+
loading?: boolean;
|
|
53
|
+
};
|
|
54
|
+
/** Pill button: thin border, accent dot with an arrow that stretches on hover. */
|
|
55
|
+
declare const PillButton: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & PillStyle & {
|
|
56
|
+
/** Replaces the icon with a spinner and disables the button. */
|
|
57
|
+
loading?: boolean;
|
|
58
|
+
} & react.RefAttributes<HTMLButtonElement>>;
|
|
59
|
+
type PillLinkProps<C extends ElementType = "a"> = PillStyle & {
|
|
60
|
+
/** Router link component (Next.js or React Router `Link`…); `<a>` by default. */
|
|
61
|
+
as?: C;
|
|
62
|
+
} & Omit<ComponentPropsWithoutRef<C>, "as" | keyof PillStyle>;
|
|
63
|
+
/** Same pill as a link. With a router: `<PillLink as={Link} href="/">`. */
|
|
64
|
+
declare const PillLink: <C extends ElementType = "a">(props: PillLinkProps<C> & {
|
|
65
|
+
ref?: Ref<HTMLAnchorElement>;
|
|
66
|
+
}) => ReactNode;
|
|
67
|
+
|
|
68
|
+
type IconProps = SVGProps<SVGSVGElement>;
|
|
69
|
+
declare const ArrowRight: (props: IconProps) => react.JSX.Element;
|
|
70
|
+
declare const ArrowLeft: (props: IconProps) => react.JSX.Element;
|
|
71
|
+
declare const ChevronDown: (props: IconProps) => react.JSX.Element;
|
|
72
|
+
declare const Check: (props: IconProps) => react.JSX.Element;
|
|
73
|
+
declare const Menu: (props: IconProps) => react.JSX.Element;
|
|
74
|
+
declare const Close: (props: IconProps) => react.JSX.Element;
|
|
75
|
+
declare const ArrowUp: (props: IconProps) => react.JSX.Element;
|
|
76
|
+
declare const Calendar: (props: IconProps) => react.JSX.Element;
|
|
77
|
+
declare const ChevronLeft: (props: IconProps) => react.JSX.Element;
|
|
78
|
+
declare const ChevronRight: (props: IconProps) => react.JSX.Element;
|
|
79
|
+
|
|
80
|
+
type Polymorphic<C extends ElementType, P> = P & {
|
|
81
|
+
as?: C;
|
|
82
|
+
} & Omit<ComponentPropsWithoutRef<C>, "as" | keyof P>;
|
|
83
|
+
type ContainerProps<C extends ElementType = "div"> = Polymorphic<C, {
|
|
84
|
+
/** `default`: 1280 px, for text and grids; `wide`: 1600 px, for full-width cards; `narrow`: 768 px. */
|
|
85
|
+
size?: "default" | "wide" | "narrow";
|
|
86
|
+
}>;
|
|
87
|
+
/** Centered max width, with side gutters that grow with the screen. */
|
|
88
|
+
declare function Container<C extends ElementType = "div">({ as, size, className, ...props }: ContainerProps<C>): react.JSX.Element;
|
|
89
|
+
type SectionProps<C extends ElementType = "section"> = Polymorphic<C, {
|
|
90
|
+
/** Vertical spacing. */
|
|
91
|
+
spacing?: "sm" | "md" | "lg" | "none";
|
|
92
|
+
/**
|
|
93
|
+
* Card inset from the screen edges ("magazine" effect): graphite background and rounded corners,
|
|
94
|
+
* for banners, calls to action and heroes.
|
|
95
|
+
*/
|
|
96
|
+
inset?: boolean;
|
|
97
|
+
}>;
|
|
98
|
+
/** Vertical block of a page. With `inset`, it becomes a large rounded card a few pixels from the edges. */
|
|
99
|
+
declare function Section<C extends ElementType = "section">({ as, spacing, inset, className, children, ...props }: SectionProps<C>): react.JSX.Element;
|
|
100
|
+
type CardProps<C extends ElementType = "div"> = Polymorphic<C, {
|
|
101
|
+
/** `alt`: a slightly lighter grey, to tell two side-by-side blocks apart. */
|
|
102
|
+
tone?: "default" | "alt";
|
|
103
|
+
padding?: "none" | "sm" | "md" | "lg";
|
|
104
|
+
/** Lightens on hover (clickable cards: links, buttons). */
|
|
105
|
+
interactive?: boolean;
|
|
106
|
+
/** Decorative watermark icon: very large, thin stroke, half out of the corner; wakes up on hover. */
|
|
107
|
+
watermark?: ReactNode;
|
|
108
|
+
}>;
|
|
109
|
+
/** Graphite card, rounded corners, no shadow: depth comes from shades of grey. */
|
|
110
|
+
declare function Card<C extends ElementType = "div">({ as, tone, padding, interactive, watermark, className, children, ...props }: CardProps<C>): react.JSX.Element;
|
|
111
|
+
|
|
112
|
+
type FieldProps = {
|
|
113
|
+
label: ReactNode;
|
|
114
|
+
/** Hint shown under the control. */
|
|
115
|
+
hint?: ReactNode;
|
|
116
|
+
/** Error message: replaces the hint and marks the control as invalid. */
|
|
117
|
+
error?: ReactNode;
|
|
118
|
+
required?: boolean;
|
|
119
|
+
/** Control id; generated when omitted. */
|
|
120
|
+
id?: string;
|
|
121
|
+
className?: string;
|
|
122
|
+
children: ReactNode;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Label, hint and error of a form control. The control placed inside (`Input`, `Textarea`, `Select`)
|
|
126
|
+
* automatically receives its `id`, `aria-describedby` and `aria-invalid`.
|
|
127
|
+
*/
|
|
128
|
+
declare function Field({ label, hint, error, required, id, className, children }: FieldProps): react.JSX.Element;
|
|
129
|
+
type ControlProps = {
|
|
130
|
+
invalid?: boolean;
|
|
131
|
+
};
|
|
132
|
+
type InputProps = ComponentPropsWithoutRef<"input"> & ControlProps;
|
|
133
|
+
declare const Input: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref"> & ControlProps & react.RefAttributes<HTMLInputElement>>;
|
|
134
|
+
type TextareaProps = ComponentPropsWithoutRef<"textarea"> & ControlProps;
|
|
135
|
+
declare const Textarea: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>, "ref"> & ControlProps & react.RefAttributes<HTMLTextAreaElement>>;
|
|
136
|
+
type SelectProps = ComponentPropsWithoutRef<"select"> & ControlProps & {
|
|
137
|
+
/** Empty option shown until something is chosen. */
|
|
138
|
+
placeholder?: string;
|
|
139
|
+
};
|
|
140
|
+
/** Native select (accessible and mobile friendly), dressed with a thin chevron. */
|
|
141
|
+
declare const Select: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.SelectHTMLAttributes<HTMLSelectElement>, HTMLSelectElement>, "ref"> & ControlProps & {
|
|
142
|
+
/** Empty option shown until something is chosen. */
|
|
143
|
+
placeholder?: string;
|
|
144
|
+
} & react.RefAttributes<HTMLSelectElement>>;
|
|
145
|
+
|
|
146
|
+
type ToggleProps = Omit<ComponentPropsWithoutRef<"input">, "type"> & {
|
|
147
|
+
label: ReactNode;
|
|
148
|
+
/** Extra detail under the label. */
|
|
149
|
+
description?: ReactNode;
|
|
150
|
+
};
|
|
151
|
+
type CheckboxProps = ToggleProps;
|
|
152
|
+
/** Native checkbox, filled with the accent color once checked. */
|
|
153
|
+
declare const Checkbox: react.ForwardRefExoticComponent<Omit<Omit<react.DetailedHTMLProps<react.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref">, "type"> & {
|
|
154
|
+
label: ReactNode;
|
|
155
|
+
/** Extra detail under the label. */
|
|
156
|
+
description?: ReactNode;
|
|
157
|
+
} & react.RefAttributes<HTMLInputElement>>;
|
|
158
|
+
type SwitchProps = ToggleProps;
|
|
159
|
+
/** Switch: a native checkbox announced as a `switch` to screen readers. */
|
|
160
|
+
declare const Switch: react.ForwardRefExoticComponent<Omit<Omit<react.DetailedHTMLProps<react.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref">, "type"> & {
|
|
161
|
+
label: ReactNode;
|
|
162
|
+
/** Extra detail under the label. */
|
|
163
|
+
description?: ReactNode;
|
|
164
|
+
} & react.RefAttributes<HTMLInputElement>>;
|
|
165
|
+
|
|
166
|
+
type NavLink = {
|
|
167
|
+
label: ReactNode;
|
|
168
|
+
href: string;
|
|
169
|
+
/** Current page: marked with an accent dot. */
|
|
170
|
+
active?: boolean;
|
|
171
|
+
};
|
|
172
|
+
type NavMenu = {
|
|
173
|
+
label: ReactNode;
|
|
174
|
+
/** Dropdown items, with an optional short description (no numbers). */
|
|
175
|
+
items: (NavLink & {
|
|
176
|
+
description?: ReactNode;
|
|
177
|
+
})[];
|
|
178
|
+
};
|
|
179
|
+
type NavItem = NavLink | NavMenu;
|
|
180
|
+
type SiteHeaderProps = {
|
|
181
|
+
/** Logo (white), wrapped in a link to `homeHref`. */
|
|
182
|
+
logo: ReactNode;
|
|
183
|
+
/** Accessible name of the logo link, usually the brand name. */
|
|
184
|
+
logoLabel: string;
|
|
185
|
+
homeHref?: string;
|
|
186
|
+
nav?: NavItem[];
|
|
187
|
+
/** Main action, shown as a compact pill (and a large one in the mobile menu). */
|
|
188
|
+
cta?: {
|
|
189
|
+
label: ReactNode;
|
|
190
|
+
href: string;
|
|
191
|
+
};
|
|
192
|
+
/** Extra elements on the right on large screens (language switcher…). */
|
|
193
|
+
actions?: ReactNode;
|
|
194
|
+
/** Content added at the bottom of the mobile menu. */
|
|
195
|
+
mobileFooter?: ReactNode;
|
|
196
|
+
/** Router link component (Next.js `Link`…); `<a>` by default. */
|
|
197
|
+
linkAs?: ElementType;
|
|
198
|
+
/** Scroll offset (px) from which the bar becomes blurred graphite. */
|
|
199
|
+
scrollThreshold?: number;
|
|
200
|
+
menuLabel?: string;
|
|
201
|
+
closeLabel?: string;
|
|
202
|
+
className?: string;
|
|
203
|
+
};
|
|
204
|
+
/**
|
|
205
|
+
* Floating header: transparent over the hero at the top of the page, it becomes a blurred
|
|
206
|
+
* graphite bar as soon as the page scrolls. Dropdowns on large screens, side panel on mobile.
|
|
207
|
+
*/
|
|
208
|
+
declare function SiteHeader({ logo, logoLabel, homeHref, nav, cta, actions, mobileFooter, linkAs: LinkTag, scrollThreshold, menuLabel, closeLabel, className, }: SiteHeaderProps): react.JSX.Element;
|
|
209
|
+
|
|
210
|
+
type FooterLink = {
|
|
211
|
+
label: ReactNode;
|
|
212
|
+
href: string;
|
|
213
|
+
};
|
|
214
|
+
type SiteFooterProps = {
|
|
215
|
+
/** Logo (white), wrapped in a link to `homeHref`. */
|
|
216
|
+
logo?: ReactNode;
|
|
217
|
+
logoLabel?: string;
|
|
218
|
+
homeHref?: string;
|
|
219
|
+
/** Short sentence under the logo. */
|
|
220
|
+
tagline?: ReactNode;
|
|
221
|
+
/** Under the sentence: a pill, a contact… */
|
|
222
|
+
children?: ReactNode;
|
|
223
|
+
/** Site map in columns, each with a spaced small-caps title. */
|
|
224
|
+
columns?: {
|
|
225
|
+
title: ReactNode;
|
|
226
|
+
links: FooterLink[];
|
|
227
|
+
}[];
|
|
228
|
+
/** Accessible name of the site map. */
|
|
229
|
+
columnsLabel?: string;
|
|
230
|
+
/** Bottom line (copyright, credits…). */
|
|
231
|
+
copyright?: ReactNode;
|
|
232
|
+
/** Legal links, aligned right on large screens. */
|
|
233
|
+
legal?: FooterLink[];
|
|
234
|
+
legalLabel?: string;
|
|
235
|
+
/** Router link component (Next.js `Link`…); `<a>` by default. */
|
|
236
|
+
linkAs?: ElementType;
|
|
237
|
+
className?: string;
|
|
238
|
+
};
|
|
239
|
+
/** Graphite card footer: brand and call to action, site map in columns, legal links. */
|
|
240
|
+
declare function SiteFooter({ logo, logoLabel, homeHref, tagline, children, columns, columnsLabel, copyright, legal, legalLabel, linkAs: LinkTag, className, }: SiteFooterProps): react.JSX.Element;
|
|
241
|
+
|
|
242
|
+
type PageHeroProps = {
|
|
243
|
+
/** Title; the words between *asterisks* take the accent, otherwise the last words (`accentLast`). */
|
|
244
|
+
title: string;
|
|
245
|
+
/** Number of trailing words in the accent color when the title has no asterisks (2 for a long title, 1 otherwise). */
|
|
246
|
+
accentLast?: number;
|
|
247
|
+
description?: ReactNode;
|
|
248
|
+
/** Discreet line under the description (last updated date, breadcrumb…). */
|
|
249
|
+
meta?: ReactNode;
|
|
250
|
+
/**
|
|
251
|
+
* Background photo, heavily darkened: a URL, or a ready-made element (Next.js `<Image fill />`…).
|
|
252
|
+
* Without a photo, a subtle accent glow on a graphite background.
|
|
253
|
+
*/
|
|
254
|
+
image?: string | ReactNode;
|
|
255
|
+
/** Photo position (`object-position`). */
|
|
256
|
+
imagePosition?: string;
|
|
257
|
+
/** Content under the text (pills…). */
|
|
258
|
+
children?: ReactNode;
|
|
259
|
+
className?: string;
|
|
260
|
+
};
|
|
261
|
+
/**
|
|
262
|
+
* Header of inner pages: rounded card inset from the edges, darkened background photo,
|
|
263
|
+
* thin title whose last words take the accent. Leaves room for the floating header above.
|
|
264
|
+
*/
|
|
265
|
+
declare function PageHero({ title, accentLast, description, meta, image, imagePosition, children, className, }: PageHeroProps): react.JSX.Element;
|
|
266
|
+
type HeroClip = {
|
|
267
|
+
/** Muted video, 1280 px, without an audio track. Provide WebM and/or MP4. */
|
|
268
|
+
webm?: string;
|
|
269
|
+
mp4?: string;
|
|
270
|
+
/** Image shown before playback, and alone when the user prefers reduced motion. */
|
|
271
|
+
poster?: string;
|
|
272
|
+
};
|
|
273
|
+
type HeroVideoProps = {
|
|
274
|
+
/** Videos played one after another with a crossfade; the first one is picked at random. */
|
|
275
|
+
clips: HeroClip[];
|
|
276
|
+
/** Hero text (title, description, pills), pinned to the bottom left. */
|
|
277
|
+
children: ReactNode;
|
|
278
|
+
/** Optional block pinned to the bottom right on large screens. */
|
|
279
|
+
aside?: ReactNode;
|
|
280
|
+
/** Crossfade duration, in seconds. */
|
|
281
|
+
fade?: number;
|
|
282
|
+
/** Soft parallax: the video moves down slower than the page. */
|
|
283
|
+
parallax?: boolean;
|
|
284
|
+
className?: string;
|
|
285
|
+
};
|
|
286
|
+
/**
|
|
287
|
+
* Home page hero: rounded card inset from the edges, muted background videos that alternate with
|
|
288
|
+
* a crossfade, dark veils for legibility. No video in the server render: the pick happens
|
|
289
|
+
* after hydration, then the video fades in. Reduced motion: the still image only.
|
|
290
|
+
*/
|
|
291
|
+
declare function HeroVideo({ clips, children, aside, fade, parallax, className }: HeroVideoProps): react.JSX.Element;
|
|
292
|
+
|
|
293
|
+
type BackToTopProps = {
|
|
294
|
+
label?: string;
|
|
295
|
+
/** Scroll offset, in viewport heights, from which the button appears. */
|
|
296
|
+
threshold?: number;
|
|
297
|
+
className?: string;
|
|
298
|
+
};
|
|
299
|
+
/** Floating accent "Back to top" button: appears once the first screen is scrolled past. */
|
|
300
|
+
declare function BackToTop({ label, threshold, className }: BackToTopProps): react.JSX.Element;
|
|
301
|
+
|
|
302
|
+
type DialogProps = {
|
|
303
|
+
open: boolean;
|
|
304
|
+
/** Called on Escape, on the close button and on the overlay. */
|
|
305
|
+
onClose: () => void;
|
|
306
|
+
/** Title of the window, also its accessible name. */
|
|
307
|
+
title: ReactNode;
|
|
308
|
+
/** Short text under the title, announced with it. */
|
|
309
|
+
description?: ReactNode;
|
|
310
|
+
children?: ReactNode;
|
|
311
|
+
/** Actions at the bottom, usually pills: the main one solid, on the right. */
|
|
312
|
+
footer?: ReactNode;
|
|
313
|
+
size?: "sm" | "md" | "lg";
|
|
314
|
+
closeLabel?: string;
|
|
315
|
+
closeOnOverlay?: boolean;
|
|
316
|
+
className?: string;
|
|
317
|
+
};
|
|
318
|
+
/**
|
|
319
|
+
* Modal window: a graphite card centered over a dark overlay. Focus moves inside and stays there;
|
|
320
|
+
* Escape, the close button or the overlay close it, and focus returns to where it was.
|
|
321
|
+
* Put `data-autofocus` on the element that should receive focus first.
|
|
322
|
+
*/
|
|
323
|
+
declare function Dialog({ size, closeLabel, closeOnOverlay, className, ...props }: DialogProps): react.JSX.Element;
|
|
324
|
+
|
|
325
|
+
type DrawerProps = {
|
|
326
|
+
open: boolean;
|
|
327
|
+
onClose: () => void;
|
|
328
|
+
title: ReactNode;
|
|
329
|
+
description?: ReactNode;
|
|
330
|
+
children?: ReactNode;
|
|
331
|
+
/** Actions pinned to the bottom of the panel. */
|
|
332
|
+
footer?: ReactNode;
|
|
333
|
+
/** Edge the panel slides from. */
|
|
334
|
+
side?: "right" | "left";
|
|
335
|
+
size?: "sm" | "md";
|
|
336
|
+
closeLabel?: string;
|
|
337
|
+
closeOnOverlay?: boolean;
|
|
338
|
+
className?: string;
|
|
339
|
+
};
|
|
340
|
+
/** Side panel that slides over the page: filters, cart, settings, mobile navigation. Modal, like `Dialog`. */
|
|
341
|
+
declare function Drawer({ side, size, closeLabel, closeOnOverlay, className, ...props }: DrawerProps): react.JSX.Element;
|
|
342
|
+
|
|
343
|
+
type Side = "top" | "bottom";
|
|
344
|
+
type Align = "start" | "center" | "end";
|
|
345
|
+
|
|
346
|
+
type MenuAction = {
|
|
347
|
+
label: ReactNode;
|
|
348
|
+
/** Called when the item is chosen with a click, Enter or Space. */
|
|
349
|
+
onSelect?: () => void;
|
|
350
|
+
/** Turns the item into a link. */
|
|
351
|
+
href?: string;
|
|
352
|
+
/** Hint shown on the right, such as a keyboard shortcut. */
|
|
353
|
+
hint?: ReactNode;
|
|
354
|
+
disabled?: boolean;
|
|
355
|
+
/** Destructive action (delete, leave…), in the error color. */
|
|
356
|
+
danger?: boolean;
|
|
357
|
+
/** Text used for typeahead when the label is not a string. */
|
|
358
|
+
textValue?: string;
|
|
359
|
+
};
|
|
360
|
+
type MenuItem = MenuAction | "separator";
|
|
361
|
+
type TriggerProps$1 = {
|
|
362
|
+
ref?: Ref<HTMLElement>;
|
|
363
|
+
id?: string;
|
|
364
|
+
onClick?: (e: unknown) => void;
|
|
365
|
+
onKeyDown?: (e: KeyboardEvent) => void;
|
|
366
|
+
};
|
|
367
|
+
type DropdownMenuProps = {
|
|
368
|
+
/** Element that opens the menu, usually a pill or an icon button. */
|
|
369
|
+
trigger: ReactElement<TriggerProps$1>;
|
|
370
|
+
items: MenuItem[];
|
|
371
|
+
align?: Align;
|
|
372
|
+
/** Link component of your router, for items with an `href`. */
|
|
373
|
+
linkAs?: ElementType;
|
|
374
|
+
className?: string;
|
|
375
|
+
};
|
|
376
|
+
/**
|
|
377
|
+
* Menu of actions opened from a trigger. Keyboard: Enter, Space or the arrows open it; the arrows,
|
|
378
|
+
* Home and End move between items; typing a letter jumps to the next item starting with it;
|
|
379
|
+
* Escape closes and returns focus to the trigger; Tab closes and moves on.
|
|
380
|
+
*/
|
|
381
|
+
declare function DropdownMenu({ trigger, items, align, linkAs: LinkTag, className }: DropdownMenuProps): react.JSX.Element;
|
|
382
|
+
|
|
383
|
+
type TriggerProps = {
|
|
384
|
+
ref?: Ref<HTMLElement>;
|
|
385
|
+
onClick?: (e: unknown) => void;
|
|
386
|
+
};
|
|
387
|
+
type PopoverProps = {
|
|
388
|
+
/** Element that opens the panel. */
|
|
389
|
+
trigger: ReactElement<TriggerProps>;
|
|
390
|
+
/** Title of the panel, also its accessible name. */
|
|
391
|
+
title?: ReactNode;
|
|
392
|
+
/** Accessible name when there is no visible title. */
|
|
393
|
+
label?: string;
|
|
394
|
+
children: ReactNode;
|
|
395
|
+
side?: Side;
|
|
396
|
+
align?: Align;
|
|
397
|
+
/** Controlled state; leave out to let the popover manage itself. */
|
|
398
|
+
open?: boolean;
|
|
399
|
+
onOpenChange?: (open: boolean) => void;
|
|
400
|
+
className?: string;
|
|
401
|
+
};
|
|
402
|
+
/**
|
|
403
|
+
* Floating panel anchored to a trigger, for short content and small forms. Not modal: the page stays
|
|
404
|
+
* usable. Focus moves into the panel when it opens; Escape or a click outside closes it.
|
|
405
|
+
*/
|
|
406
|
+
declare function Popover({ trigger, title, label, children, side, align, open: controlled, onOpenChange, className, }: PopoverProps): react.JSX.Element;
|
|
407
|
+
|
|
408
|
+
type ChildProps = {
|
|
409
|
+
ref?: Ref<HTMLElement>;
|
|
410
|
+
"aria-describedby"?: string;
|
|
411
|
+
onMouseEnter?: (e: unknown) => void;
|
|
412
|
+
onMouseLeave?: (e: unknown) => void;
|
|
413
|
+
onFocus?: (e: unknown) => void;
|
|
414
|
+
onBlur?: (e: unknown) => void;
|
|
415
|
+
};
|
|
416
|
+
type TooltipProps = {
|
|
417
|
+
/** Short text describing the element; never the only way to get the information. */
|
|
418
|
+
label: ReactNode;
|
|
419
|
+
/** A single focusable element: a button, a link, an input. */
|
|
420
|
+
children: ReactElement<ChildProps>;
|
|
421
|
+
side?: Side;
|
|
422
|
+
/** Delay before showing on hover, in milliseconds. Keyboard focus shows it right away. */
|
|
423
|
+
delay?: number;
|
|
424
|
+
className?: string;
|
|
425
|
+
};
|
|
426
|
+
/**
|
|
427
|
+
* Small label shown on hover and keyboard focus, tied to its element with `aria-describedby`.
|
|
428
|
+
* It stays open while the pointer moves onto it, and Escape hides it (WCAG 1.4.13).
|
|
429
|
+
*/
|
|
430
|
+
declare function Tooltip({ label, children, side, delay, className }: TooltipProps): react.JSX.Element;
|
|
431
|
+
|
|
432
|
+
type ToastTone = "default" | "success" | "error";
|
|
433
|
+
type ToastOptions = {
|
|
434
|
+
description?: ReactNode;
|
|
435
|
+
tone?: ToastTone;
|
|
436
|
+
/** Time on screen in milliseconds; `Infinity` keeps it until dismissed. */
|
|
437
|
+
duration?: number;
|
|
438
|
+
/** One action, such as "Undo"; choosing it also dismisses the toast. */
|
|
439
|
+
action?: {
|
|
440
|
+
label: ReactNode;
|
|
441
|
+
onClick: () => void;
|
|
442
|
+
};
|
|
443
|
+
};
|
|
444
|
+
/**
|
|
445
|
+
* Shows a short message in the `<Toaster />`. Returns its id, for `toast.dismiss(id)`.
|
|
446
|
+
* `toast.success()` and `toast.error()` set the tone.
|
|
447
|
+
*/
|
|
448
|
+
declare function toast(title: ReactNode, options?: ToastOptions): number;
|
|
449
|
+
declare namespace toast {
|
|
450
|
+
var success: (title: ReactNode, options?: Omit<ToastOptions, "tone">) => number;
|
|
451
|
+
var error: (title: ReactNode, options?: Omit<ToastOptions, "tone">) => number;
|
|
452
|
+
var dismiss: (id?: number) => void;
|
|
453
|
+
}
|
|
454
|
+
type ToasterProps = {
|
|
455
|
+
position?: "bottom-right" | "bottom-center" | "top-right";
|
|
456
|
+
/** Default time on screen, in milliseconds. */
|
|
457
|
+
duration?: number;
|
|
458
|
+
/** Accessible name of the notification area. */
|
|
459
|
+
label?: string;
|
|
460
|
+
closeLabel?: string;
|
|
461
|
+
};
|
|
462
|
+
/**
|
|
463
|
+
* Notification area, placed once near the root of the app. New toasts are announced to screen
|
|
464
|
+
* readers (errors right away); timers pause while the pointer or the keyboard focus is inside.
|
|
465
|
+
*/
|
|
466
|
+
declare function Toaster({ position, duration, label, closeLabel, }: ToasterProps): react.JSX.Element;
|
|
467
|
+
|
|
468
|
+
type AlertProps = Omit<ComponentPropsWithoutRef<"div">, "title"> & {
|
|
469
|
+
title?: ReactNode;
|
|
470
|
+
/** `info` and `success` use the accent, `error` the error color. */
|
|
471
|
+
tone?: "info" | "success" | "error";
|
|
472
|
+
/** Actions under the text, such as a small pill. */
|
|
473
|
+
actions?: ReactNode;
|
|
474
|
+
};
|
|
475
|
+
/**
|
|
476
|
+
* Inline message in a graphite card, marked by a thin colored edge rather than an icon badge.
|
|
477
|
+
* Static by default; pass `role="alert"` (urgent) or `role="status"` when it appears after an action.
|
|
478
|
+
*/
|
|
479
|
+
declare function Alert({ title, tone, actions, className, children, ...props }: AlertProps): react.JSX.Element;
|
|
480
|
+
|
|
481
|
+
type TabItem = {
|
|
482
|
+
value: string;
|
|
483
|
+
label: ReactNode;
|
|
484
|
+
content: ReactNode;
|
|
485
|
+
disabled?: boolean;
|
|
486
|
+
};
|
|
487
|
+
type TabsProps = {
|
|
488
|
+
items: TabItem[];
|
|
489
|
+
value?: string;
|
|
490
|
+
defaultValue?: string;
|
|
491
|
+
onValueChange?: (value: string) => void;
|
|
492
|
+
/** Accessible name of the tab list. */
|
|
493
|
+
label?: string;
|
|
494
|
+
/**
|
|
495
|
+
* `automatic`: the arrows select the tab they move to. `manual`: they only move the focus,
|
|
496
|
+
* Enter or Space selects (for panels that are slow to render).
|
|
497
|
+
*/
|
|
498
|
+
activation?: "automatic" | "manual";
|
|
499
|
+
className?: string;
|
|
500
|
+
};
|
|
501
|
+
/**
|
|
502
|
+
* Tabs: thin labels, the selected one underlined with the accent. Keyboard: Left and Right arrows,
|
|
503
|
+
* Home and End; only the selected tab is in the Tab order (roving tabindex).
|
|
504
|
+
*/
|
|
505
|
+
declare function Tabs({ items, value, defaultValue, onValueChange, label, activation, className, }: TabsProps): react.JSX.Element;
|
|
506
|
+
|
|
507
|
+
type SegmentedOption = {
|
|
508
|
+
value: string;
|
|
509
|
+
label: ReactNode;
|
|
510
|
+
disabled?: boolean;
|
|
511
|
+
};
|
|
512
|
+
type SegmentedControlProps = {
|
|
513
|
+
options: SegmentedOption[];
|
|
514
|
+
value?: string;
|
|
515
|
+
defaultValue?: string;
|
|
516
|
+
onValueChange?: (value: string) => void;
|
|
517
|
+
/** Accessible name of the group. */
|
|
518
|
+
label: string;
|
|
519
|
+
/** Form field name; generated when omitted. */
|
|
520
|
+
name?: string;
|
|
521
|
+
size?: "md" | "sm";
|
|
522
|
+
className?: string;
|
|
523
|
+
};
|
|
524
|
+
/**
|
|
525
|
+
* Pill switch between a few options, built on native radio buttons: the arrows move the choice,
|
|
526
|
+
* forms and screen readers work as usual. For views of the same content; use Tabs to switch panels.
|
|
527
|
+
*/
|
|
528
|
+
declare function SegmentedControl({ options, value, defaultValue, onValueChange, label, name, size, className, }: SegmentedControlProps): react.JSX.Element;
|
|
529
|
+
|
|
530
|
+
type AccordionItem = {
|
|
531
|
+
value: string;
|
|
532
|
+
title: ReactNode;
|
|
533
|
+
content: ReactNode;
|
|
534
|
+
disabled?: boolean;
|
|
535
|
+
};
|
|
536
|
+
type AccordionProps = {
|
|
537
|
+
items: AccordionItem[];
|
|
538
|
+
/** `single`: one item open at a time. `multiple`: any number. */
|
|
539
|
+
type?: "single" | "multiple";
|
|
540
|
+
/** Open items. */
|
|
541
|
+
value?: string[];
|
|
542
|
+
defaultValue?: string[];
|
|
543
|
+
onValueChange?: (value: string[]) => void;
|
|
544
|
+
/** Level of the heading wrapping each button, to fit the page outline. */
|
|
545
|
+
headingLevel?: 2 | 3 | 4 | 5 | 6;
|
|
546
|
+
className?: string;
|
|
547
|
+
};
|
|
548
|
+
/**
|
|
549
|
+
* Items that open and close, for FAQs and details. Each title is a button inside a heading; the
|
|
550
|
+
* height animates; closed content is out of the accessibility tree. Up and Down arrows, Home and
|
|
551
|
+
* End move between titles.
|
|
552
|
+
*/
|
|
553
|
+
declare function Accordion({ items, type, value, defaultValue, onValueChange, headingLevel, className, }: AccordionProps): react.JSX.Element;
|
|
554
|
+
|
|
555
|
+
type StepItem = {
|
|
556
|
+
title: ReactNode;
|
|
557
|
+
description?: ReactNode;
|
|
558
|
+
};
|
|
559
|
+
type StepsProps = {
|
|
560
|
+
items: StepItem[];
|
|
561
|
+
/**
|
|
562
|
+
* Index of the step in progress (from 0): earlier steps are complete, later ones upcoming.
|
|
563
|
+
* Leave out for a plain list of steps, all alike.
|
|
564
|
+
*/
|
|
565
|
+
current?: number;
|
|
566
|
+
className?: string;
|
|
567
|
+
};
|
|
568
|
+
/**
|
|
569
|
+
* Vertical timeline of steps in a real order: large thin numbers in the accent, joined by a hairline.
|
|
570
|
+
* With `current`, the step in progress carries `aria-current="step"` and the upcoming ones fade.
|
|
571
|
+
*/
|
|
572
|
+
declare function Steps({ items, current, className }: StepsProps): react.JSX.Element;
|
|
573
|
+
|
|
574
|
+
type BreadcrumbItem = {
|
|
575
|
+
label: ReactNode;
|
|
576
|
+
href?: string;
|
|
577
|
+
};
|
|
578
|
+
type BreadcrumbsProps = {
|
|
579
|
+
/** From the home page to the current page; the last item is the current page and has no link. */
|
|
580
|
+
items: BreadcrumbItem[];
|
|
581
|
+
label?: string;
|
|
582
|
+
linkAs?: ElementType;
|
|
583
|
+
className?: string;
|
|
584
|
+
};
|
|
585
|
+
/** Trail from the home page to the current page, separated by thin slashes. */
|
|
586
|
+
declare function Breadcrumbs({ items, label, linkAs: LinkTag, className }: BreadcrumbsProps): react.JSX.Element;
|
|
587
|
+
|
|
588
|
+
type Entry = number | "ellipsis";
|
|
589
|
+
/**
|
|
590
|
+
* Pages to show: always the first and the last, the current one with `siblings` on each side, and
|
|
591
|
+
* ellipses in between. The number of entries stays constant, so the controls do not jump around.
|
|
592
|
+
*/
|
|
593
|
+
declare function paginationRange(page: number, total: number, siblings?: number): Entry[];
|
|
594
|
+
type PaginationProps = {
|
|
595
|
+
/** Current page, from 1. */
|
|
596
|
+
page: number;
|
|
597
|
+
/** Number of pages. */
|
|
598
|
+
total: number;
|
|
599
|
+
/** Buttons mode: called with the new page. */
|
|
600
|
+
onPageChange?: (page: number) => void;
|
|
601
|
+
/**
|
|
602
|
+
* Links mode (better for search engines): the address of each page, as a function or as a
|
|
603
|
+
* pattern with `{page}`, such as `"/blog/page/{page}"`. The pattern also works from a server component.
|
|
604
|
+
*/
|
|
605
|
+
href?: string | ((page: number) => string);
|
|
606
|
+
siblings?: number;
|
|
607
|
+
linkAs?: ElementType;
|
|
608
|
+
label?: string;
|
|
609
|
+
previousLabel?: string;
|
|
610
|
+
nextLabel?: string;
|
|
611
|
+
/** Accessible name of a page number: a template such as "Page {page}", or a function. */
|
|
612
|
+
pageLabel?: string | ((page: number) => string);
|
|
613
|
+
className?: string;
|
|
614
|
+
};
|
|
615
|
+
/** Page navigation: numbers with ellipses, previous and next. As buttons or as links. */
|
|
616
|
+
declare function Pagination({ page, total, onPageChange, href, siblings, linkAs: LinkTag, label, previousLabel, nextLabel, pageLabel, className, }: PaginationProps): react.JSX.Element | null;
|
|
617
|
+
|
|
618
|
+
type Language = {
|
|
619
|
+
/** Language code, shown in capitals: "en", "fr"… */
|
|
620
|
+
code: string;
|
|
621
|
+
/** Full name in that language ("English", "Français"), for screen readers. */
|
|
622
|
+
name: string;
|
|
623
|
+
/** Same page in that language; without it, the switch calls `onChange`. */
|
|
624
|
+
href?: string;
|
|
625
|
+
};
|
|
626
|
+
type LanguageSwitcherProps = {
|
|
627
|
+
languages: Language[];
|
|
628
|
+
/** Code of the current language. */
|
|
629
|
+
value: string;
|
|
630
|
+
onChange?: (code: string) => void;
|
|
631
|
+
label?: string;
|
|
632
|
+
linkAs?: ElementType;
|
|
633
|
+
className?: string;
|
|
634
|
+
};
|
|
635
|
+
/** EN | FR pill: links to the same page in each language (or buttons), the current one in the accent. */
|
|
636
|
+
declare function LanguageSwitcher({ languages, value, onChange, label, linkAs: LinkTag, className, }: LanguageSwitcherProps): react.JSX.Element;
|
|
637
|
+
|
|
638
|
+
type RadioOption = {
|
|
639
|
+
value: string;
|
|
640
|
+
label: ReactNode;
|
|
641
|
+
description?: ReactNode;
|
|
642
|
+
disabled?: boolean;
|
|
643
|
+
};
|
|
644
|
+
type RadioGroupProps = {
|
|
645
|
+
/** Question of the group, rendered as its legend. */
|
|
646
|
+
label: ReactNode;
|
|
647
|
+
options: RadioOption[];
|
|
648
|
+
value?: string;
|
|
649
|
+
defaultValue?: string;
|
|
650
|
+
onValueChange?: (value: string) => void;
|
|
651
|
+
name?: string;
|
|
652
|
+
hint?: ReactNode;
|
|
653
|
+
error?: ReactNode;
|
|
654
|
+
required?: boolean;
|
|
655
|
+
orientation?: "vertical" | "horizontal";
|
|
656
|
+
className?: string;
|
|
657
|
+
};
|
|
658
|
+
/**
|
|
659
|
+
* A choice among a few options, as native radio buttons in a fieldset: the legend is read with
|
|
660
|
+
* each option, the arrows move the choice, and the hint or error is tied to the group.
|
|
661
|
+
*/
|
|
662
|
+
declare function RadioGroup({ label, options, value, defaultValue, onValueChange, name, hint, error, required, orientation, className, }: RadioGroupProps): react.JSX.Element;
|
|
663
|
+
|
|
664
|
+
type PasswordInputProps = Omit<InputProps, "type"> & {
|
|
665
|
+
/** Visible text of the button: "Show", "Afficher"… */
|
|
666
|
+
showLabel?: string;
|
|
667
|
+
hideLabel?: string;
|
|
668
|
+
/** Completes the button's name for screen readers: "Show password". */
|
|
669
|
+
noun?: string;
|
|
670
|
+
};
|
|
671
|
+
/**
|
|
672
|
+
* Password field with a Show / Hide button. Works inside `Field` like `Input`. The button's
|
|
673
|
+
* accessible name includes its visible text ("Show password"), as WCAG 2.5.3 asks.
|
|
674
|
+
*/
|
|
675
|
+
declare const PasswordInput: react.ForwardRefExoticComponent<Omit<InputProps, "type"> & {
|
|
676
|
+
/** Visible text of the button: "Show", "Afficher"… */
|
|
677
|
+
showLabel?: string;
|
|
678
|
+
hideLabel?: string;
|
|
679
|
+
/** Completes the button's name for screen readers: "Show password". */
|
|
680
|
+
noun?: string;
|
|
681
|
+
} & react.RefAttributes<HTMLInputElement>>;
|
|
682
|
+
|
|
683
|
+
type PinInputProps = {
|
|
684
|
+
/** Number of characters. */
|
|
685
|
+
length?: number;
|
|
686
|
+
value?: string;
|
|
687
|
+
defaultValue?: string;
|
|
688
|
+
onChange?: (value: string) => void;
|
|
689
|
+
/** Called once every box is filled. */
|
|
690
|
+
onComplete?: (value: string) => void;
|
|
691
|
+
/** `numeric` opens the number keyboard on phones and accepts digits only. */
|
|
692
|
+
type?: "numeric" | "alphanumeric";
|
|
693
|
+
/** Hides the characters, like a password. */
|
|
694
|
+
mask?: boolean;
|
|
695
|
+
/** Accessible name of the group: "Verification code". */
|
|
696
|
+
label?: string;
|
|
697
|
+
/**
|
|
698
|
+
* Accessible name of each box: a template such as "Character {index} of {length}" ({index} starts
|
|
699
|
+
* at 1), or a function receiving the 0-based index.
|
|
700
|
+
*/
|
|
701
|
+
charLabel?: string | ((index: number, length: number) => string);
|
|
702
|
+
invalid?: boolean;
|
|
703
|
+
disabled?: boolean;
|
|
704
|
+
id?: string;
|
|
705
|
+
name?: string;
|
|
706
|
+
className?: string;
|
|
707
|
+
};
|
|
708
|
+
/**
|
|
709
|
+
* One box per character for one-time codes. Typing moves forward, Backspace moves back, pasting a code
|
|
710
|
+
* fills every box, and phones can fill it from a text message (`autocomplete="one-time-code"`).
|
|
711
|
+
* Inside a `Field`, the label focuses the first box and the hint or error describes the group.
|
|
712
|
+
*/
|
|
713
|
+
declare function PinInput({ length, value, defaultValue, onChange, onComplete, type, mask, label, charLabel, invalid, disabled, id, name, className, }: PinInputProps): react.JSX.Element;
|
|
714
|
+
|
|
715
|
+
type ComboboxOption = {
|
|
716
|
+
value: string;
|
|
717
|
+
label: string;
|
|
718
|
+
description?: ReactNode;
|
|
719
|
+
disabled?: boolean;
|
|
720
|
+
};
|
|
721
|
+
type ComboboxProps = {
|
|
722
|
+
options: ComboboxOption[];
|
|
723
|
+
value?: string | null;
|
|
724
|
+
defaultValue?: string | null;
|
|
725
|
+
onValueChange?: (value: string | null) => void;
|
|
726
|
+
placeholder?: string;
|
|
727
|
+
/** Shown when nothing matches the search. */
|
|
728
|
+
emptyText?: ReactNode;
|
|
729
|
+
invalid?: boolean;
|
|
730
|
+
disabled?: boolean;
|
|
731
|
+
required?: boolean;
|
|
732
|
+
id?: string;
|
|
733
|
+
/** Form field name: the chosen value is submitted. */
|
|
734
|
+
name?: string;
|
|
735
|
+
className?: string;
|
|
736
|
+
};
|
|
737
|
+
/**
|
|
738
|
+
* Search field with a list of suggestions. Typing filters (ignoring case and accents); the arrows
|
|
739
|
+
* move the active option while focus stays in the field; Enter chooses; Escape closes; leaving the
|
|
740
|
+
* field restores the chosen label. Works inside `Field` like `Input`.
|
|
741
|
+
*/
|
|
742
|
+
declare function Combobox({ options, value, defaultValue, onValueChange, placeholder, emptyText, invalid, disabled, required, id, name, className, }: ComboboxProps): react.JSX.Element;
|
|
743
|
+
|
|
744
|
+
/** Readable size: 820 B, 14.2 KB, 3.5 MB. */
|
|
745
|
+
declare function formatBytes(bytes: number): string;
|
|
746
|
+
/** Whether a file matches an `accept` list such as "image/*,.pdf". */
|
|
747
|
+
declare function acceptsFile(file: File, accept?: string): boolean;
|
|
748
|
+
type FileRejection = {
|
|
749
|
+
file: File;
|
|
750
|
+
reason: "type" | "size" | "count";
|
|
751
|
+
};
|
|
752
|
+
type Rules = {
|
|
753
|
+
accept?: string;
|
|
754
|
+
maxSize?: number;
|
|
755
|
+
maxFiles?: number;
|
|
756
|
+
};
|
|
757
|
+
/** Splits files into accepted and rejected ones, with the reason of each rejection. */
|
|
758
|
+
declare function validateFiles(files: File[], { accept, maxSize, maxFiles }: Rules, alreadyAccepted?: number): {
|
|
759
|
+
accepted: File[];
|
|
760
|
+
rejected: FileRejection[];
|
|
761
|
+
};
|
|
762
|
+
type FileInputProps = Omit<ComponentPropsWithoutRef<"input">, "type" | "value" | "defaultValue" | "onChange"> & {
|
|
763
|
+
onFilesChange?: (files: File[]) => void;
|
|
764
|
+
buttonLabel?: string;
|
|
765
|
+
placeholder?: string;
|
|
766
|
+
/** Text when several files are chosen: a template such as "{count} files", or a function. */
|
|
767
|
+
countLabel?: string | ((count: number) => string);
|
|
768
|
+
invalid?: boolean;
|
|
769
|
+
};
|
|
770
|
+
/**
|
|
771
|
+
* Compact file field: a "Choose a file" button and the chosen names, on the native file input
|
|
772
|
+
* (hidden but focusable). Works inside `Field` like `Input`.
|
|
773
|
+
*/
|
|
774
|
+
declare const FileInput: react.ForwardRefExoticComponent<Omit<Omit<react.DetailedHTMLProps<react.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref">, "type" | "value" | "defaultValue" | "onChange"> & {
|
|
775
|
+
onFilesChange?: (files: File[]) => void;
|
|
776
|
+
buttonLabel?: string;
|
|
777
|
+
placeholder?: string;
|
|
778
|
+
/** Text when several files are chosen: a template such as "{count} files", or a function. */
|
|
779
|
+
countLabel?: string | ((count: number) => string);
|
|
780
|
+
invalid?: boolean;
|
|
781
|
+
} & react.RefAttributes<HTMLInputElement>>;
|
|
782
|
+
type DropzoneProps = Rules & {
|
|
783
|
+
multiple?: boolean;
|
|
784
|
+
/** Called with every accepted file after each change. */
|
|
785
|
+
onFilesChange?: (files: File[]) => void;
|
|
786
|
+
/** Main text: "Drop files here or". */
|
|
787
|
+
title?: ReactNode;
|
|
788
|
+
/** Link-looking word that opens the file picker: "browse". */
|
|
789
|
+
browseLabel?: ReactNode;
|
|
790
|
+
/** Constraints shown under the title: "PNG or PDF, up to 5 MB". */
|
|
791
|
+
hint?: ReactNode;
|
|
792
|
+
/** Name of the remove button: a template such as "Remove {name}", or a function. */
|
|
793
|
+
removeLabel?: string | ((file: File) => string);
|
|
794
|
+
/**
|
|
795
|
+
* Message of a rejected file: one template per reason, with {name}, or a function.
|
|
796
|
+
*/
|
|
797
|
+
rejectionLabel?: Partial<Record<FileRejection["reason"], string>> | ((rejection: FileRejection) => string);
|
|
798
|
+
name?: string;
|
|
799
|
+
disabled?: boolean;
|
|
800
|
+
id?: string;
|
|
801
|
+
className?: string;
|
|
802
|
+
};
|
|
803
|
+
/**
|
|
804
|
+
* Area to drop files on, or to click (and reach with the keyboard) to browse. Accepted files are
|
|
805
|
+
* listed with their size and a remove button; rejected ones are announced with their reason.
|
|
806
|
+
*/
|
|
807
|
+
declare function Dropzone({ accept, maxSize, maxFiles, multiple, onFilesChange, title, browseLabel, hint, removeLabel, rejectionLabel, name, disabled, id, className, }: DropzoneProps): react.JSX.Element;
|
|
808
|
+
|
|
809
|
+
type SliderProps = Omit<ComponentPropsWithoutRef<"input">, "type" | "value" | "defaultValue" | "onChange"> & {
|
|
810
|
+
value?: number;
|
|
811
|
+
defaultValue?: number;
|
|
812
|
+
onValueChange?: (value: number) => void;
|
|
813
|
+
min?: number;
|
|
814
|
+
max?: number;
|
|
815
|
+
step?: number;
|
|
816
|
+
/** Shows the value next to the slider. */
|
|
817
|
+
showValue?: boolean;
|
|
818
|
+
/** Formats the shown and announced value: "€ 40", "75 %". */
|
|
819
|
+
formatValue?: (value: number) => ReactNode;
|
|
820
|
+
invalid?: boolean;
|
|
821
|
+
};
|
|
822
|
+
/**
|
|
823
|
+
* Range slider on the native input: keyboard (arrows, Page Up / Down, Home, End) and screen readers
|
|
824
|
+
* work as usual. The track fills with the accent up to the thumb. Works inside `Field` like `Input`.
|
|
825
|
+
*/
|
|
826
|
+
declare const Slider: react.ForwardRefExoticComponent<Omit<Omit<react.DetailedHTMLProps<react.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref">, "type" | "value" | "defaultValue" | "onChange"> & {
|
|
827
|
+
value?: number;
|
|
828
|
+
defaultValue?: number;
|
|
829
|
+
onValueChange?: (value: number) => void;
|
|
830
|
+
min?: number;
|
|
831
|
+
max?: number;
|
|
832
|
+
step?: number;
|
|
833
|
+
/** Shows the value next to the slider. */
|
|
834
|
+
showValue?: boolean;
|
|
835
|
+
/** Formats the shown and announced value: "€ 40", "75 %". */
|
|
836
|
+
formatValue?: (value: number) => ReactNode;
|
|
837
|
+
invalid?: boolean;
|
|
838
|
+
} & react.RefAttributes<HTMLInputElement>>;
|
|
839
|
+
|
|
840
|
+
type DatePickerProps = {
|
|
841
|
+
value?: Date | null;
|
|
842
|
+
defaultValue?: Date | null;
|
|
843
|
+
onValueChange?: (date: Date | null) => void;
|
|
844
|
+
/** Earliest and latest choosable dates. */
|
|
845
|
+
min?: Date;
|
|
846
|
+
max?: Date;
|
|
847
|
+
/** Locale of the month and day names, such as "fr-FR"; the browser's by default. */
|
|
848
|
+
locale?: string;
|
|
849
|
+
/** First day of the week: 0 for Sunday, 1 for Monday. */
|
|
850
|
+
weekStartsOn?: number;
|
|
851
|
+
placeholder?: string;
|
|
852
|
+
/** Formats the chosen date in the field. */
|
|
853
|
+
formatDate?: (date: Date) => string;
|
|
854
|
+
/** Form field name: the date is submitted as YYYY-MM-DD. */
|
|
855
|
+
name?: string;
|
|
856
|
+
label?: string;
|
|
857
|
+
previousMonthLabel?: string;
|
|
858
|
+
nextMonthLabel?: string;
|
|
859
|
+
invalid?: boolean;
|
|
860
|
+
disabled?: boolean;
|
|
861
|
+
required?: boolean;
|
|
862
|
+
id?: string;
|
|
863
|
+
className?: string;
|
|
864
|
+
};
|
|
865
|
+
/**
|
|
866
|
+
* Date field that opens a calendar. Keyboard in the calendar: arrows move by a day or a week, Home
|
|
867
|
+
* and End to the start and end of the week, Page Up and Page Down by a month (with Shift, a year),
|
|
868
|
+
* Enter or Space chooses, Escape closes. Each day is announced in full; works inside `Field`.
|
|
869
|
+
*/
|
|
870
|
+
declare function DatePicker({ value, defaultValue, onValueChange, min, max, locale, weekStartsOn, placeholder, formatDate, name, label, previousMonthLabel, nextMonthLabel, invalid, disabled, required, id, className, }: DatePickerProps): react.JSX.Element;
|
|
871
|
+
|
|
872
|
+
/** Up to two initials from a name: "Aurel Agbado" → "AA", "trc" → "T". */
|
|
873
|
+
declare function initials(name: string): string;
|
|
874
|
+
type AvatarProps = {
|
|
875
|
+
/** Person or organization shown: the accessible name, and the source of the initials. */
|
|
876
|
+
name: string;
|
|
877
|
+
src?: string;
|
|
878
|
+
size?: "sm" | "md" | "lg";
|
|
879
|
+
className?: string;
|
|
880
|
+
};
|
|
881
|
+
/** Round picture of a person, falling back to their initials on graphite when there is no image or it fails. */
|
|
882
|
+
declare function Avatar({ name, src, size, className }: AvatarProps): react.JSX.Element;
|
|
883
|
+
type AvatarGroupProps = {
|
|
884
|
+
children: ReactNode;
|
|
885
|
+
/** Avatars shown before the "+n" counter. */
|
|
886
|
+
max?: number;
|
|
887
|
+
/** Accessible name of the counter: a template such as "{count} more", or a function. */
|
|
888
|
+
moreLabel?: string | ((count: number) => string);
|
|
889
|
+
size?: AvatarProps["size"];
|
|
890
|
+
className?: string;
|
|
891
|
+
};
|
|
892
|
+
/** Overlapping avatars, the rest summed up in a "+n" counter. */
|
|
893
|
+
declare function AvatarGroup({ children, max, moreLabel, size, className, }: AvatarGroupProps): react.JSX.Element;
|
|
894
|
+
|
|
895
|
+
type TagProps = ComponentPropsWithoutRef<"span"> & {
|
|
896
|
+
/** `accent` for the one tag that matters on a card. */
|
|
897
|
+
tone?: "default" | "accent";
|
|
898
|
+
/** Shows a remove button. */
|
|
899
|
+
onRemove?: () => void;
|
|
900
|
+
removeLabel?: string;
|
|
901
|
+
children: ReactNode;
|
|
902
|
+
};
|
|
903
|
+
/** Small label for metadata (status, category, filter). Never placed over photos. */
|
|
904
|
+
declare function Tag({ tone, onRemove, removeLabel, className, children, ...props }: TagProps): react.JSX.Element;
|
|
905
|
+
|
|
906
|
+
type StatProps = {
|
|
907
|
+
label: ReactNode;
|
|
908
|
+
value: ReactNode;
|
|
909
|
+
/** Change since the previous period: "+12 %". */
|
|
910
|
+
change?: ReactNode;
|
|
911
|
+
/** Color of the change: accent when positive, error color when negative. */
|
|
912
|
+
changeTone?: "positive" | "negative" | "neutral";
|
|
913
|
+
/** Short context under the value: "vs last month". */
|
|
914
|
+
description?: ReactNode;
|
|
915
|
+
className?: string;
|
|
916
|
+
};
|
|
917
|
+
/** A key figure with its label, in a large thin number. */
|
|
918
|
+
declare function Stat({ label, value, change, changeTone, description, className }: StatProps): react.JSX.Element;
|
|
919
|
+
|
|
920
|
+
type TableColumn<Row> = {
|
|
921
|
+
key: string;
|
|
922
|
+
header: ReactNode;
|
|
923
|
+
/** `right` for numbers, so that digits line up. */
|
|
924
|
+
align?: "left" | "center" | "right";
|
|
925
|
+
sortable?: boolean;
|
|
926
|
+
/** Cell content; the row's `key` field by default. */
|
|
927
|
+
render?: (row: Row) => ReactNode;
|
|
928
|
+
/** Value used to sort; the row's `key` field by default. */
|
|
929
|
+
sortValue?: (row: Row) => string | number | Date;
|
|
930
|
+
};
|
|
931
|
+
type SortState = {
|
|
932
|
+
key: string;
|
|
933
|
+
direction: "ascending" | "descending";
|
|
934
|
+
};
|
|
935
|
+
type TableProps<Row> = {
|
|
936
|
+
columns: TableColumn<Row>[];
|
|
937
|
+
rows: Row[];
|
|
938
|
+
/** Unique key of each row. */
|
|
939
|
+
rowKey: (row: Row) => string;
|
|
940
|
+
/** Title of the table, read first by screen readers. */
|
|
941
|
+
caption: ReactNode;
|
|
942
|
+
/** Hides the caption visually; it stays for screen readers. */
|
|
943
|
+
hideCaption?: boolean;
|
|
944
|
+
defaultSort?: SortState;
|
|
945
|
+
dense?: boolean;
|
|
946
|
+
emptyText?: ReactNode;
|
|
947
|
+
className?: string;
|
|
948
|
+
};
|
|
949
|
+
/**
|
|
950
|
+
* Data table with a caption and sortable columns: each sortable header is a button, and the
|
|
951
|
+
* current order is announced with `aria-sort`. Scrolls sideways on small screens, in a focusable
|
|
952
|
+
* region so that keyboard users can scroll it too.
|
|
953
|
+
*/
|
|
954
|
+
declare function Table<Row>({ columns, rows, rowKey, caption, hideCaption, defaultSort, dense, emptyText, className, }: TableProps<Row>): react.JSX.Element;
|
|
955
|
+
|
|
956
|
+
type SkeletonProps = {
|
|
957
|
+
width?: number | string;
|
|
958
|
+
height?: number | string;
|
|
959
|
+
/** Round, for an avatar. */
|
|
960
|
+
circle?: boolean;
|
|
961
|
+
/** Several lines of text, the last one shorter. */
|
|
962
|
+
lines?: number;
|
|
963
|
+
className?: string;
|
|
964
|
+
};
|
|
965
|
+
/** Placeholder shapes while content loads. Hidden from screen readers: announce the loading state elsewhere. */
|
|
966
|
+
declare function Skeleton({ width, height, circle, lines, className }: SkeletonProps): react.JSX.Element;
|
|
967
|
+
type SpinnerProps = {
|
|
968
|
+
size?: "sm" | "md" | "lg";
|
|
969
|
+
/** Announced to screen readers. */
|
|
970
|
+
label?: string;
|
|
971
|
+
className?: string;
|
|
972
|
+
};
|
|
973
|
+
/** Accent arc turning while something loads, announced through `role="status"`. */
|
|
974
|
+
declare function Spinner({ size: s, label, className }: SpinnerProps): react.JSX.Element;
|
|
975
|
+
type ProgressProps = {
|
|
976
|
+
/** Progress from 0 to `max`; leave out while the total is unknown. */
|
|
977
|
+
value?: number | null;
|
|
978
|
+
max?: number;
|
|
979
|
+
/** Visible label above the bar, also its accessible name. */
|
|
980
|
+
label?: ReactNode;
|
|
981
|
+
/** Accessible name when there is no visible label. */
|
|
982
|
+
"aria-label"?: string;
|
|
983
|
+
showValue?: boolean;
|
|
984
|
+
formatValue?: (value: number, max: number) => string;
|
|
985
|
+
className?: string;
|
|
986
|
+
};
|
|
987
|
+
/** Progress bar filled with the accent; indeterminate without a value. */
|
|
988
|
+
declare function Progress({ value, max, label, "aria-label": ariaLabel, showValue, formatValue, className, }: ProgressProps): react.JSX.Element;
|
|
989
|
+
|
|
990
|
+
/** A key of the keyboard, for shortcuts: <Kbd>⌘</Kbd> <Kbd>K</Kbd>. */
|
|
991
|
+
declare function Kbd({ className, ...props }: ComponentPropsWithoutRef<"kbd">): react.JSX.Element;
|
|
992
|
+
type DividerProps = {
|
|
993
|
+
/** Text in the middle of the line: "or". */
|
|
994
|
+
label?: ReactNode;
|
|
995
|
+
orientation?: "horizontal" | "vertical";
|
|
996
|
+
className?: string;
|
|
997
|
+
};
|
|
998
|
+
/** Hairline between groups of content, optionally with a word in the middle. */
|
|
999
|
+
declare function Divider({ label, orientation, className }: DividerProps): react.JSX.Element;
|
|
1000
|
+
|
|
1001
|
+
type CodeBlockProps = {
|
|
1002
|
+
/** Source code, also what the copy button copies. */
|
|
1003
|
+
code: string;
|
|
1004
|
+
/** File name shown in a tab: "app/layout.tsx". */
|
|
1005
|
+
title?: ReactNode;
|
|
1006
|
+
/** Language, shown as a small badge next to the title. */
|
|
1007
|
+
language?: string;
|
|
1008
|
+
/** Highlighted rendering of the code, from your own highlighter; plain text by default. */
|
|
1009
|
+
children?: ReactNode;
|
|
1010
|
+
copyLabel?: string;
|
|
1011
|
+
copiedLabel?: string;
|
|
1012
|
+
className?: string;
|
|
1013
|
+
};
|
|
1014
|
+
/**
|
|
1015
|
+
* Code block with an optional file tab and a copy button that turns into an accent check for a
|
|
1016
|
+
* moment. Bring your own highlighting through `children`; the copied text is always `code`.
|
|
1017
|
+
*/
|
|
1018
|
+
declare function CodeBlock({ code, title, language, children, copyLabel, copiedLabel, className, }: CodeBlockProps): react.JSX.Element;
|
|
1019
|
+
|
|
1020
|
+
export { AccentText, Accordion, Alert, ArrowLeft, ArrowRight, ArrowUp, Avatar, AvatarGroup, BackToTop, Breadcrumbs, Calendar, Card, Check, Checkbox, ChevronDown, ChevronLeft, ChevronRight, Close, CodeBlock, Combobox, Container, DatePicker, Dialog, Divider, Drawer, DropdownMenu, Dropzone, Field, FileInput, Heading, HeroVideo, Input, Kbd, LanguageSwitcher, Menu, PageHero, Pagination, PasswordInput, PillButton, PillLink, PinInput, Popover, Progress, RadioGroup, Section, SegmentedControl, Select, SiteFooter, SiteHeader, Skeleton, Slider, Spinner, Stat, StepNumber, Steps, Switch, Table, Tabs, Tag, Text, Textarea, Toaster, Tooltip, acceptsFile, cx, formatBytes, initials, paginationRange, plainText, toast, validateFiles };
|
|
1021
|
+
export type { AccordionItem, AccordionProps, AlertProps, AvatarGroupProps, AvatarProps, BackToTopProps, BreadcrumbItem, BreadcrumbsProps, CardProps, CheckboxProps, CodeBlockProps, ComboboxOption, ComboboxProps, ContainerProps, DatePickerProps, DialogProps, DividerProps, DrawerProps, DropdownMenuProps, DropzoneProps, FieldProps, FileInputProps, FileRejection, FooterLink, HeadingProps, HeadingSize, HeroClip, HeroVideoProps, InputProps, Language, LanguageSwitcherProps, MenuAction, MenuItem, NavItem, NavLink, NavMenu, PageHeroProps, PaginationProps, PasswordInputProps, PillButtonProps, PillLinkProps, PinInputProps, PopoverProps, ProgressProps, RadioGroupProps, RadioOption, SectionProps, SegmentedControlProps, SegmentedOption, SelectProps, SiteFooterProps, SiteHeaderProps, SkeletonProps, SliderProps, SortState, SpinnerProps, StatProps, StepItem, StepsProps, SwitchProps, TabItem, TableColumn, TableProps, TabsProps, TagProps, TextProps, TextareaProps, ToastOptions, ToastTone, ToasterProps, TooltipProps };
|