@nim.zone/ui 0.6.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/LICENSE +21 -0
- package/README.md +681 -0
- package/dist/components/admin-shell.d.ts +121 -0
- package/dist/components/app-shell.d.ts +23 -0
- package/dist/components/auth-screen.d.ts +33 -0
- package/dist/components/avatar.d.ts +10 -0
- package/dist/components/badge.d.ts +14 -0
- package/dist/components/banner.d.ts +11 -0
- package/dist/components/breadcrumb.d.ts +12 -0
- package/dist/components/button.d.ts +21 -0
- package/dist/components/card.d.ts +15 -0
- package/dist/components/chat-composer.d.ts +52 -0
- package/dist/components/chat.d.ts +77 -0
- package/dist/components/checkout.d.ts +79 -0
- package/dist/components/choice.d.ts +15 -0
- package/dist/components/combobox.d.ts +31 -0
- package/dist/components/date-field.d.ts +58 -0
- package/dist/components/dialog.d.ts +20 -0
- package/dist/components/empty-state.d.ts +9 -0
- package/dist/components/feedback.d.ts +18 -0
- package/dist/components/field.d.ts +47 -0
- package/dist/components/icon-button.d.ts +12 -0
- package/dist/components/icon.d.ts +72 -0
- package/dist/components/layout.d.ts +13 -0
- package/dist/components/list.d.ts +16 -0
- package/dist/components/menu.d.ts +56 -0
- package/dist/components/onboarding.d.ts +50 -0
- package/dist/components/otp-input.d.ts +29 -0
- package/dist/components/pagination.d.ts +12 -0
- package/dist/components/password-field.d.ts +33 -0
- package/dist/components/phone-field.d.ts +44 -0
- package/dist/components/plan-card.d.ts +45 -0
- package/dist/components/plan-picker.d.ts +52 -0
- package/dist/components/profile-header.d.ts +47 -0
- package/dist/components/profile-screen.d.ts +44 -0
- package/dist/components/resource-meter.d.ts +22 -0
- package/dist/components/section-header.d.ts +8 -0
- package/dist/components/segmented.d.ts +18 -0
- package/dist/components/sheet.d.ts +18 -0
- package/dist/components/sign-in-flow.d.ts +60 -0
- package/dist/components/slider.d.ts +10 -0
- package/dist/components/stat.d.ts +10 -0
- package/dist/components/stepper.d.ts +17 -0
- package/dist/components/tab-bar.d.ts +40 -0
- package/dist/components/table.d.ts +33 -0
- package/dist/components/tabs.d.ts +23 -0
- package/dist/components/task-progress.d.ts +38 -0
- package/dist/components/theme.d.ts +49 -0
- package/dist/components/toast.d.ts +17 -0
- package/dist/components/tooltip.d.ts +18 -0
- package/dist/components/typography.d.ts +18 -0
- package/dist/components/wizard.d.ts +70 -0
- package/dist/index.d.ts +104 -0
- package/dist/lib/calendars.d.ts +81 -0
- package/dist/lib/cn.d.ts +7 -0
- package/dist/lib/countries.d.ts +33 -0
- package/dist/lib/use-anchor.d.ts +22 -0
- package/dist/nim.css +1 -0
- package/dist/nim.js +3266 -0
- package/package.json +83 -0
- package/src/components/admin-shell.tsx +338 -0
- package/src/components/app-shell.tsx +36 -0
- package/src/components/auth-screen.tsx +71 -0
- package/src/components/avatar.tsx +32 -0
- package/src/components/badge.tsx +44 -0
- package/src/components/banner.tsx +47 -0
- package/src/components/breadcrumb.tsx +45 -0
- package/src/components/button.tsx +64 -0
- package/src/components/card.tsx +46 -0
- package/src/components/chat-composer.tsx +331 -0
- package/src/components/chat.tsx +352 -0
- package/src/components/checkout.tsx +173 -0
- package/src/components/choice.tsx +46 -0
- package/src/components/combobox.tsx +157 -0
- package/src/components/date-field.tsx +394 -0
- package/src/components/dialog.tsx +77 -0
- package/src/components/empty-state.tsx +23 -0
- package/src/components/feedback.tsx +61 -0
- package/src/components/field.tsx +177 -0
- package/src/components/icon-button.tsx +35 -0
- package/src/components/icon.tsx +167 -0
- package/src/components/layout.tsx +38 -0
- package/src/components/list.tsx +78 -0
- package/src/components/menu.tsx +172 -0
- package/src/components/onboarding.tsx +157 -0
- package/src/components/otp-input.tsx +144 -0
- package/src/components/pagination.tsx +86 -0
- package/src/components/password-field.tsx +112 -0
- package/src/components/phone-field.tsx +242 -0
- package/src/components/plan-card.tsx +124 -0
- package/src/components/plan-picker.tsx +144 -0
- package/src/components/profile-header.tsx +134 -0
- package/src/components/profile-screen.tsx +104 -0
- package/src/components/resource-meter.tsx +60 -0
- package/src/components/section-header.tsx +31 -0
- package/src/components/segmented.tsx +53 -0
- package/src/components/sheet.tsx +74 -0
- package/src/components/sign-in-flow.tsx +322 -0
- package/src/components/slider.tsx +50 -0
- package/src/components/stat.tsx +30 -0
- package/src/components/stepper.tsx +77 -0
- package/src/components/tab-bar.tsx +82 -0
- package/src/components/table.tsx +81 -0
- package/src/components/tabs.tsx +72 -0
- package/src/components/task-progress.tsx +111 -0
- package/src/components/theme.tsx +112 -0
- package/src/components/toast.tsx +87 -0
- package/src/components/tooltip.tsx +30 -0
- package/src/components/typography.tsx +65 -0
- package/src/components/wizard.tsx +192 -0
- package/src/index.ts +216 -0
- package/src/lib/calendars.ts +227 -0
- package/src/lib/cn.ts +8 -0
- package/src/lib/countries.ts +110 -0
- package/src/lib/use-anchor.ts +92 -0
- package/src/theme/colorways/coral.css +62 -0
- package/src/theme/colorways/oxblood.css +23 -0
- package/src/theme/colorways/paper.css +68 -0
- package/src/theme/colorways/teal.css +56 -0
- package/src/theme/colorways/vermilion.css +21 -0
- package/src/theme/components.css +4606 -0
- package/src/theme/contract.css +204 -0
- package/src/theme/fonts.css +67 -0
- package/src/theme/index.css +33 -0
- package/src/theme/persian.css +47 -0
- package/src/theme/reset.css +118 -0
- package/src/theme/styles/ledger.css +106 -0
- package/src/theme/styles/vlora.css +91 -0
- package/src/vite-env.d.ts +1 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { InputHTMLAttributes, ReactNode, SelectHTMLAttributes, TextareaHTMLAttributes } from 'react';
|
|
2
|
+
import { IconName } from './icon';
|
|
3
|
+
export interface FieldShellProps {
|
|
4
|
+
children: (ids: {
|
|
5
|
+
control: string;
|
|
6
|
+
describedBy?: string;
|
|
7
|
+
}) => ReactNode;
|
|
8
|
+
className?: string;
|
|
9
|
+
error?: string;
|
|
10
|
+
hint?: string;
|
|
11
|
+
id?: string;
|
|
12
|
+
label?: string;
|
|
13
|
+
required?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Every nim form control shares this frame, which is what guarantees that a
|
|
17
|
+
* label, a hint, and an error are wired to the control with the right ids on
|
|
18
|
+
* every screen — the part teams most often get wrong by hand.
|
|
19
|
+
*/
|
|
20
|
+
export declare function FieldShell({ children, className, error, hint, id, label, required }: FieldShellProps): import("react").JSX.Element;
|
|
21
|
+
export interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {
|
|
22
|
+
error?: string;
|
|
23
|
+
hint?: string;
|
|
24
|
+
iconEnd?: IconName;
|
|
25
|
+
iconStart?: IconName;
|
|
26
|
+
label?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function Input({ className, error, hint, iconEnd, iconStart, id, label, required, ...props }: InputProps): import("react").JSX.Element;
|
|
29
|
+
export interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
30
|
+
error?: string;
|
|
31
|
+
hint?: string;
|
|
32
|
+
label?: string;
|
|
33
|
+
}
|
|
34
|
+
export declare function Textarea({ className, error, hint, id, label, required, rows, ...props }: TextareaProps): import("react").JSX.Element;
|
|
35
|
+
export interface SelectOption {
|
|
36
|
+
disabled?: boolean;
|
|
37
|
+
label: string;
|
|
38
|
+
value: string;
|
|
39
|
+
}
|
|
40
|
+
export interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'children'> {
|
|
41
|
+
error?: string;
|
|
42
|
+
hint?: string;
|
|
43
|
+
label?: string;
|
|
44
|
+
options: SelectOption[];
|
|
45
|
+
placeholder?: string;
|
|
46
|
+
}
|
|
47
|
+
export declare function Select({ className, error, hint, id, label, options, placeholder, required, ...props }: SelectProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ButtonHTMLAttributes } from 'react';
|
|
2
|
+
import { IconName } from './icon';
|
|
3
|
+
export type IconButtonSize = 'sm' | 'md' | 'lg';
|
|
4
|
+
export type IconButtonVariant = 'ghost' | 'outline' | 'solid';
|
|
5
|
+
export interface IconButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
|
|
6
|
+
/** Required: an icon-only control has no other accessible name. */
|
|
7
|
+
label: string;
|
|
8
|
+
name: IconName;
|
|
9
|
+
size?: IconButtonSize;
|
|
10
|
+
variant?: IconButtonVariant;
|
|
11
|
+
}
|
|
12
|
+
export declare const IconButton: import('react').ForwardRefExoticComponent<IconButtonProps & import('react').RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { SVGProps } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Icons are addressed by role, not by vendor name. The registry is the whole
|
|
4
|
+
* point: it keeps the icon set finite and reviewable, it stops two screens
|
|
5
|
+
* meaning "delete" with two different glyphs, and it means swapping icon
|
|
6
|
+
* libraries later is one file rather than a codebase sweep.
|
|
7
|
+
*/
|
|
8
|
+
declare const REGISTRY: {
|
|
9
|
+
alert: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
10
|
+
'arrow-forward': import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
11
|
+
bell: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
12
|
+
bookmark: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
13
|
+
calendar: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
14
|
+
camera: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
15
|
+
check: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
16
|
+
'check-circle': import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
17
|
+
'chevron-back': import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
18
|
+
'chevron-down': import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
19
|
+
'chevron-forward': import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
20
|
+
'chevron-up': import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
21
|
+
clock: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
22
|
+
close: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
23
|
+
copy: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
24
|
+
danger: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
25
|
+
document: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
26
|
+
download: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
27
|
+
edit: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
28
|
+
external: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
29
|
+
eye: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
30
|
+
filter: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
31
|
+
heart: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
32
|
+
home: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
33
|
+
info: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
34
|
+
loading: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
35
|
+
menu: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
36
|
+
mic: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
37
|
+
minus: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
38
|
+
moon: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
39
|
+
paperclip: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
40
|
+
pause: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
41
|
+
play: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
42
|
+
plus: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
43
|
+
search: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
44
|
+
send: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
45
|
+
settings: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
46
|
+
share: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
47
|
+
'sign-out': import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
48
|
+
stop: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
49
|
+
sparkle: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
50
|
+
star: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
51
|
+
sun: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
52
|
+
trash: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
53
|
+
'trend-down': import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
54
|
+
'trend-up': import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
55
|
+
upload: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
56
|
+
video: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
57
|
+
user: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
58
|
+
wallet: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
59
|
+
};
|
|
60
|
+
export type IconName = keyof typeof REGISTRY;
|
|
61
|
+
export type IconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
62
|
+
export type IconTone = 'accent' | 'danger' | 'default' | 'muted' | 'success' | 'warning';
|
|
63
|
+
export interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'ref'> {
|
|
64
|
+
/** Give a label only when the icon is the sole carrier of meaning. */
|
|
65
|
+
label?: string;
|
|
66
|
+
name: IconName;
|
|
67
|
+
size?: IconSize;
|
|
68
|
+
tone?: IconTone;
|
|
69
|
+
}
|
|
70
|
+
export declare function Icon({ className, label, name, size, tone, ...props }: IconProps): import("react").JSX.Element;
|
|
71
|
+
export declare const iconNames: IconName[];
|
|
72
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
interface BoxProps extends HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
}
|
|
5
|
+
/** The mobile app viewport, centred on a desktop screen. */
|
|
6
|
+
export declare function AppFrame({ children, className, ...props }: BoxProps): import("react").JSX.Element;
|
|
7
|
+
/** Vertical rhythm. Spacing between components belongs to the page, not to
|
|
8
|
+
the components, and this is where the page expresses it. */
|
|
9
|
+
export declare function Stack({ children, className, gap, ...props }: BoxProps & {
|
|
10
|
+
gap?: 'loose' | 'md' | 'tight';
|
|
11
|
+
}): import("react").JSX.Element;
|
|
12
|
+
export declare function Inline({ children, className, ...props }: BoxProps): import("react").JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export interface ListProps extends HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
/** Drops the surrounding plate and keeps only the dividers. */
|
|
5
|
+
plain?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function List({ children, className, plain, ...props }: ListProps): import("react").JSX.Element;
|
|
8
|
+
export interface ListRowProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
|
|
9
|
+
/** Renders the row as a link. Mutually exclusive with `onClick`. */
|
|
10
|
+
href?: string;
|
|
11
|
+
leading?: ReactNode;
|
|
12
|
+
subtitle?: ReactNode;
|
|
13
|
+
title: ReactNode;
|
|
14
|
+
trailing?: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
export declare function ListRow({ className, href, leading, onClick, subtitle, title, trailing, ...props }: ListRowProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ReactElement, ReactNode, Ref, RefObject } from 'react';
|
|
2
|
+
import { IconName } from './icon';
|
|
3
|
+
export interface MenuAction {
|
|
4
|
+
danger?: boolean;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
icon?: IconName;
|
|
7
|
+
kind?: 'action';
|
|
8
|
+
label: string;
|
|
9
|
+
onSelect: () => void;
|
|
10
|
+
/** Rendered in the mono, on the trailing edge — a hint, never a binding. */
|
|
11
|
+
shortcut?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface MenuHeading {
|
|
14
|
+
kind: 'heading';
|
|
15
|
+
label: string;
|
|
16
|
+
}
|
|
17
|
+
export interface MenuSeparator {
|
|
18
|
+
kind: 'separator';
|
|
19
|
+
}
|
|
20
|
+
export type MenuItem = MenuAction | MenuHeading | MenuSeparator;
|
|
21
|
+
export interface MenuProps {
|
|
22
|
+
/** The trigger is the caller's, so the menu has no opinion about what opens
|
|
23
|
+
it — it only needs the ref to anchor against. */
|
|
24
|
+
children: (props: {
|
|
25
|
+
open: boolean;
|
|
26
|
+
ref: Ref<HTMLButtonElement>;
|
|
27
|
+
toggle: () => void;
|
|
28
|
+
}) => ReactElement;
|
|
29
|
+
className?: string;
|
|
30
|
+
items: MenuItem[];
|
|
31
|
+
label: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* A list of actions, dismissed by choosing one. A menu holds actions and never
|
|
35
|
+
* inputs — something the viewer types into is a Popover.
|
|
36
|
+
*
|
|
37
|
+
* The trigger is supplied by the caller as a render prop so the menu never has
|
|
38
|
+
* an opinion about what opens it; it only needs the ref to anchor against.
|
|
39
|
+
* Arrow keys move a roving active item, Enter and Space choose it, Escape and
|
|
40
|
+
* an outside click dismiss, and focus returns to the trigger either way.
|
|
41
|
+
*/
|
|
42
|
+
export declare function Menu({ children, className, items, label }: MenuProps): import("react").JSX.Element;
|
|
43
|
+
export interface PopoverProps {
|
|
44
|
+
children: ReactNode;
|
|
45
|
+
className?: string;
|
|
46
|
+
label: string;
|
|
47
|
+
onClose: () => void;
|
|
48
|
+
open: boolean;
|
|
49
|
+
/** The element the panel is placed against. */
|
|
50
|
+
triggerRef: RefObject<HTMLElement | null>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* A menu's geometry with a form's contents. Unlike a menu it does not close on
|
|
54
|
+
* a click inside, because the thing inside is what the viewer came for.
|
|
55
|
+
*/
|
|
56
|
+
export declare function Popover({ children, className, label, onClose, open, triggerRef }: PopoverProps): import('react').ReactPortal | null;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface OnboardingSlide {
|
|
3
|
+
/** Illustration, video, or anything else. Sized by the caller. */
|
|
4
|
+
art?: ReactNode;
|
|
5
|
+
body?: ReactNode;
|
|
6
|
+
id: string;
|
|
7
|
+
/** The chip above the title — the promise, in three or four words. */
|
|
8
|
+
label?: string;
|
|
9
|
+
/** A caption card under the art: a headline and its supporting points. */
|
|
10
|
+
proof?: {
|
|
11
|
+
icon?: ReactNode;
|
|
12
|
+
points?: string[];
|
|
13
|
+
title: ReactNode;
|
|
14
|
+
};
|
|
15
|
+
title: ReactNode;
|
|
16
|
+
}
|
|
17
|
+
export interface OnboardingProps {
|
|
18
|
+
className?: string;
|
|
19
|
+
/** Label for the button on the last slide. */
|
|
20
|
+
finishLabel: string;
|
|
21
|
+
/** Label for the button on every other slide. */
|
|
22
|
+
nextLabel: string;
|
|
23
|
+
/** Reached from the finish button, or from skip. */
|
|
24
|
+
onDone: () => void;
|
|
25
|
+
onSkip?: () => void;
|
|
26
|
+
/** Notified on every slide change, including from a dot. */
|
|
27
|
+
onStep?: (index: number) => void;
|
|
28
|
+
slides: OnboardingSlide[];
|
|
29
|
+
skipLabel?: string;
|
|
30
|
+
/** Version string, support line — whatever sits under the CTA. */
|
|
31
|
+
footnote?: ReactNode;
|
|
32
|
+
/** Brand mark in the top bar. */
|
|
33
|
+
brand?: ReactNode;
|
|
34
|
+
/** Accessible names for the controls. */
|
|
35
|
+
labels?: {
|
|
36
|
+
back: string;
|
|
37
|
+
dot: (index: number) => string;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The three-screen intro a product opens with: art, a promise, a body, and one
|
|
42
|
+
* CTA that advances.
|
|
43
|
+
*
|
|
44
|
+
* State is the component's, because a first-run carousel is never resumed from
|
|
45
|
+
* a URL — `onStep` reports it for analytics and `onDone` fires when the viewer
|
|
46
|
+
* either finishes or skips, so the caller routes in one place instead of two.
|
|
47
|
+
* Slides are announced through a live region rather than by moving focus,
|
|
48
|
+
* which would yank a screen reader out of the CTA it is already on.
|
|
49
|
+
*/
|
|
50
|
+
export declare function Onboarding({ brand, className, finishLabel, footnote, labels, nextLabel, onDone, onSkip, onStep, skipLabel, slides, }: OnboardingProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface OtpInputProps {
|
|
2
|
+
/** Fires as soon as the last box is filled — by typing, pasting, or SMS
|
|
3
|
+
autofill. The caller does not need to watch `value.length` itself. */
|
|
4
|
+
autoFocus?: boolean;
|
|
5
|
+
className?: string;
|
|
6
|
+
error?: string;
|
|
7
|
+
label: string;
|
|
8
|
+
length?: number;
|
|
9
|
+
onChange: (value: string) => void;
|
|
10
|
+
onComplete?: (value: string) => void;
|
|
11
|
+
/** Per-box accessible name, e.g. `(i) => `Digit ${i + 1}``. */
|
|
12
|
+
digitLabel?: (index: number) => string;
|
|
13
|
+
/** The code so far, ASCII digits only, shorter than `length` while typing. */
|
|
14
|
+
value: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The boxed one-time code.
|
|
18
|
+
*
|
|
19
|
+
* One `<input>` per digit, but the string is the caller's: the component never
|
|
20
|
+
* holds a per-box array, so a paste, an SMS autofill, and a keystroke all take
|
|
21
|
+
* the same path and cannot disagree. The row is pinned `dir="ltr"` even inside
|
|
22
|
+
* a Persian page — a code is a number, and the first digit belongs on the left
|
|
23
|
+
* in every script. Input is normalised through `toAsciiDigits`, so ۱۲۳۴۵ typed
|
|
24
|
+
* on a Persian keyboard arrives as `12345`.
|
|
25
|
+
*
|
|
26
|
+
* `autocomplete="one-time-code"` on the first box is what lets iOS and Android
|
|
27
|
+
* offer the code from the SMS itself.
|
|
28
|
+
*/
|
|
29
|
+
export declare function OtpInput({ autoFocus, className, digitLabel, error, label, length, onChange, onComplete, value, }: OtpInputProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface PaginationProps {
|
|
2
|
+
className?: string;
|
|
3
|
+
label?: string;
|
|
4
|
+
nextLabel?: string;
|
|
5
|
+
onChange: (page: number) => void;
|
|
6
|
+
page: number;
|
|
7
|
+
pageCount: number;
|
|
8
|
+
previousLabel?: string;
|
|
9
|
+
/** Free text on the leading edge — "Showing 1–6 of 84". */
|
|
10
|
+
summary?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function Pagination({ className, label, nextLabel, onChange, page, pageCount, previousLabel, summary, }: PaginationProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { InputHTMLAttributes } from 'react';
|
|
2
|
+
export type PasswordStrength = 'fair' | 'good' | 'strong' | 'weak';
|
|
3
|
+
export interface PasswordFieldProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {
|
|
4
|
+
error?: string;
|
|
5
|
+
hint?: string;
|
|
6
|
+
label?: string;
|
|
7
|
+
/** Draws the meter. Omit on a sign-in field: scoring a password someone
|
|
8
|
+
already has tells them nothing they can act on. */
|
|
9
|
+
strength?: PasswordStrength;
|
|
10
|
+
/** Accessible names for the reveal toggle and the meter. */
|
|
11
|
+
labels?: {
|
|
12
|
+
hide: string;
|
|
13
|
+
show: string;
|
|
14
|
+
strength: (level: PasswordStrength) => string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* A password input with a reveal toggle and an optional strength meter.
|
|
19
|
+
*
|
|
20
|
+
* Revealing is a real `type` swap rather than a font trick, so a password
|
|
21
|
+
* manager still sees a password field, and the toggle is a button with a
|
|
22
|
+
* label — an icon that changes silently leaves a screen reader unable to tell
|
|
23
|
+
* whether the characters are showing.
|
|
24
|
+
*
|
|
25
|
+
* Scoring is the caller's: strength depends on the policy being enforced, and
|
|
26
|
+
* a meter that disagrees with the server's rules is worse than none.
|
|
27
|
+
*/
|
|
28
|
+
export declare function PasswordField({ className, error, hint, id, label, labels, required, strength, ...props }: PasswordFieldProps): import("react").JSX.Element;
|
|
29
|
+
/**
|
|
30
|
+
* A default score for products without a policy of their own: length first,
|
|
31
|
+
* then variety. Deliberately blunt — it is a hint, never a gate.
|
|
32
|
+
*/
|
|
33
|
+
export declare function scorePassword(password: string): PasswordStrength;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface PhoneFieldProps {
|
|
2
|
+
className?: string;
|
|
3
|
+
/** ISO 3166-1 alpha-2 of the selected country, e.g. `IR`. */
|
|
4
|
+
country: string;
|
|
5
|
+
error?: string;
|
|
6
|
+
hint?: string;
|
|
7
|
+
id?: string;
|
|
8
|
+
label?: string;
|
|
9
|
+
/** Locale the country names are shown in. Defaults to the document's. */
|
|
10
|
+
locale?: string;
|
|
11
|
+
onChange: (value: string) => void;
|
|
12
|
+
onCountryChange: (iso2: string) => void;
|
|
13
|
+
onSubmit?: () => void;
|
|
14
|
+
placeholder?: string;
|
|
15
|
+
/** Countries to float above the alphabetical list — the ones most viewers
|
|
16
|
+
of this product will pick. */
|
|
17
|
+
priority?: string[];
|
|
18
|
+
required?: boolean;
|
|
19
|
+
/** Accessible names for the picker. */
|
|
20
|
+
labels?: {
|
|
21
|
+
pickCountry: string;
|
|
22
|
+
search: string;
|
|
23
|
+
noMatch: string;
|
|
24
|
+
};
|
|
25
|
+
/** The national number, ASCII digits only, without the dialling code. */
|
|
26
|
+
value: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Phone number entry: a country picker welded to a number input.
|
|
30
|
+
*
|
|
31
|
+
* The two halves are separate props on purpose. A field that owns one E.164
|
|
32
|
+
* string has to re-parse it on every keystroke to know which flag to draw, and
|
|
33
|
+
* gets it wrong the moment someone types a `+` themselves; keeping the country
|
|
34
|
+
* and the national digits apart means `+${dial}${value}` is the whole
|
|
35
|
+
* serialisation and there is nothing to guess.
|
|
36
|
+
*
|
|
37
|
+
* The picker lists every ISO country, named in the viewer's locale, searchable
|
|
38
|
+
* by name, code, or ISO letters. The input is `dir="ltr"` in every direction —
|
|
39
|
+
* a phone number reads left to right in Persian too — and Persian digits are
|
|
40
|
+
* normalised to ASCII on the way in.
|
|
41
|
+
*/
|
|
42
|
+
export declare function PhoneField({ className, country, error, hint, id, label, labels, locale, onChange, onCountryChange, onSubmit, placeholder, priority, required, value, }: PhoneFieldProps): import("react").JSX.Element;
|
|
43
|
+
/** `+${dial}${national}` — what an auth API actually wants. */
|
|
44
|
+
export declare function toE164(country: string, national: string): string;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { IconName } from './icon';
|
|
3
|
+
export interface PlanFeature {
|
|
4
|
+
label: ReactNode;
|
|
5
|
+
/** `included` is shipped, `pending` is bought but not released yet, and
|
|
6
|
+
`excluded` is what this plan does not get. All three are worth showing:
|
|
7
|
+
a plan card that lists only wins tells the viewer nothing to choose on. */
|
|
8
|
+
state?: 'excluded' | 'included' | 'pending';
|
|
9
|
+
/** A short status word beside a pending row — "soon", "beta". */
|
|
10
|
+
note?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface PlanCardProps {
|
|
13
|
+
/** The one plan being recommended. At most one card in a set. */
|
|
14
|
+
badge?: string;
|
|
15
|
+
className?: string;
|
|
16
|
+
features?: PlanFeature[];
|
|
17
|
+
icon?: IconName;
|
|
18
|
+
/** The headline figure, already formatted and localised by the caller. */
|
|
19
|
+
price: ReactNode;
|
|
20
|
+
/** What the price buys — "per month", "6 months". */
|
|
21
|
+
priceCaption?: ReactNode;
|
|
22
|
+
/** The comparable unit price, so plans of different lengths can be read
|
|
23
|
+
against each other. */
|
|
24
|
+
secondary?: {
|
|
25
|
+
caption: ReactNode;
|
|
26
|
+
value: ReactNode;
|
|
27
|
+
};
|
|
28
|
+
name: ReactNode;
|
|
29
|
+
onSelect?: () => void;
|
|
30
|
+
selected?: boolean;
|
|
31
|
+
tagline?: ReactNode;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* One subscription tier, as a card the viewer chooses.
|
|
35
|
+
*
|
|
36
|
+
* The whole card is the control — a radio hidden behind a tap target the size
|
|
37
|
+
* of a fingernail is the reason plan pickers feel fussy — so it renders as a
|
|
38
|
+
* `<button>` with `aria-pressed` when selectable, and as a plain plate when it
|
|
39
|
+
* is only being displayed.
|
|
40
|
+
*
|
|
41
|
+
* Prices are `ReactNode` rather than numbers: currency, digit shaping and
|
|
42
|
+
* grouping are the product's locale decisions, and a kit that formats them
|
|
43
|
+
* would be wrong in Persian first.
|
|
44
|
+
*/
|
|
45
|
+
export declare function PlanCard({ badge, className, features, icon, name, onSelect, price, priceCaption, secondary, selected, tagline, }: PlanCardProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { PlanCardProps } from './plan-card';
|
|
3
|
+
export interface BillingCycle {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
/** "Save 15%" — the reason to pick the longer commitment. */
|
|
7
|
+
note?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface PlanOffer extends Omit<PlanCardProps, 'onSelect' | 'price' | 'secondary' | 'selected'> {
|
|
10
|
+
id: string;
|
|
11
|
+
/** Price per billing cycle, keyed by cycle id. Already formatted: currency
|
|
12
|
+
and digit shaping are the product's locale decision, not the kit's. */
|
|
13
|
+
prices: Record<string, {
|
|
14
|
+
monthly?: ReactNode;
|
|
15
|
+
price: ReactNode;
|
|
16
|
+
}>;
|
|
17
|
+
}
|
|
18
|
+
export interface PlanPickerProps {
|
|
19
|
+
className?: string;
|
|
20
|
+
/** Billing periods. One cycle, or none at all, hides the switch. */
|
|
21
|
+
cycles?: BillingCycle[];
|
|
22
|
+
cycle?: string;
|
|
23
|
+
defaultCycle?: string;
|
|
24
|
+
defaultPlan?: string;
|
|
25
|
+
labels?: {
|
|
26
|
+
cycle: string;
|
|
27
|
+
monthly: string;
|
|
28
|
+
price: string;
|
|
29
|
+
};
|
|
30
|
+
/** Fine print under the action — renewal terms, store rules. */
|
|
31
|
+
note?: ReactNode;
|
|
32
|
+
onCycleChange?: (cycle: string) => void;
|
|
33
|
+
onPlanChange?: (plan: string) => void;
|
|
34
|
+
/** Fires with the chosen plan and cycle. Payment is the app's business. */
|
|
35
|
+
onSubmit?: (plan: string, cycle: string) => void;
|
|
36
|
+
plans: PlanOffer[];
|
|
37
|
+
plan?: string;
|
|
38
|
+
submitLabel?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The subscription screen: billing period, the tiers, and one action.
|
|
42
|
+
*
|
|
43
|
+
* Ready to mount — it holds the selection, keeps the cycle and the prices in
|
|
44
|
+
* step, and hands `onSubmit` the pair the checkout needs. Pass `plan`/`cycle`
|
|
45
|
+
* to drive it from outside instead, e.g. when a deep link opens the screen on
|
|
46
|
+
* a specific tier.
|
|
47
|
+
*
|
|
48
|
+
* It deliberately does not take a payment handler, a store SDK, or a currency:
|
|
49
|
+
* a plan picker that also knows how to charge is two screens welded together,
|
|
50
|
+
* and only one of them is the same across products.
|
|
51
|
+
*/
|
|
52
|
+
export declare function PlanPicker({ className, cycle, cycles, defaultCycle, defaultPlan, labels, note, onCycleChange, onPlanChange, onSubmit, plan, plans, submitLabel, }: PlanPickerProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface AvatarRingProps {
|
|
3
|
+
className?: string;
|
|
4
|
+
/** What the ring is measuring, for assistive tech. */
|
|
5
|
+
label: string;
|
|
6
|
+
/** Initials, or a small caption under them. */
|
|
7
|
+
caption?: ReactNode;
|
|
8
|
+
/** Image URL. Falls back to `initials` when absent or broken. */
|
|
9
|
+
src?: string;
|
|
10
|
+
initials: string;
|
|
11
|
+
size?: number;
|
|
12
|
+
/** 0–100. The ring is the progress; the number belongs in the caption. */
|
|
13
|
+
value: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* An avatar wearing a progress ring: profile completion, a skin score, a
|
|
17
|
+
* streak — one figure the viewer is meant to want to finish.
|
|
18
|
+
*
|
|
19
|
+
* The ring is an SVG arc rather than a conic gradient so it keeps a rounded
|
|
20
|
+
* cap and stays crisp at any size, and it carries `role="img"` with the label,
|
|
21
|
+
* because the arc is the only place the value is stated for a sighted viewer.
|
|
22
|
+
*/
|
|
23
|
+
export declare function AvatarRing({ caption, className, initials, label, size, src, value, }: AvatarRingProps): import("react").JSX.Element;
|
|
24
|
+
export interface ProfileHeaderProps {
|
|
25
|
+
/** The row of quick figures under the identity block. */
|
|
26
|
+
stats?: {
|
|
27
|
+
label: ReactNode;
|
|
28
|
+
value: ReactNode;
|
|
29
|
+
}[];
|
|
30
|
+
/** Small pills: plan, skin type, billing cycle. */
|
|
31
|
+
chips?: ReactNode;
|
|
32
|
+
actions?: ReactNode;
|
|
33
|
+
avatar: ReactNode;
|
|
34
|
+
className?: string;
|
|
35
|
+
/** The line above the name — "vlora account", the tenant, the role. */
|
|
36
|
+
eyebrow?: ReactNode;
|
|
37
|
+
name: ReactNode;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The plate at the top of a profile: who this is, what they have, and the two
|
|
41
|
+
* things they should do next.
|
|
42
|
+
*
|
|
43
|
+
* It is a header, not a dashboard. Anything that needs a chart or a list goes
|
|
44
|
+
* in the sections beneath it — this block stays readable at a glance, which is
|
|
45
|
+
* the only reason it earns the space it takes.
|
|
46
|
+
*/
|
|
47
|
+
export declare function ProfileHeader({ actions, avatar, chips, className, eyebrow, name, stats, }: ProfileHeaderProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ProfileHeaderProps } from './profile-header';
|
|
3
|
+
import { IconName } from './icon';
|
|
4
|
+
export interface ProfileRow {
|
|
5
|
+
/** A switch instead of a chevron. With `onToggle` the row is the control. */
|
|
6
|
+
checked?: boolean;
|
|
7
|
+
danger?: boolean;
|
|
8
|
+
href?: string;
|
|
9
|
+
icon?: IconName;
|
|
10
|
+
key: string;
|
|
11
|
+
label: ReactNode;
|
|
12
|
+
onSelect?: () => void;
|
|
13
|
+
onToggle?: (next: boolean) => void;
|
|
14
|
+
subtitle?: ReactNode;
|
|
15
|
+
/** A badge, a count, a version string. */
|
|
16
|
+
value?: ReactNode;
|
|
17
|
+
}
|
|
18
|
+
export interface ProfileSection {
|
|
19
|
+
description?: ReactNode;
|
|
20
|
+
key: string;
|
|
21
|
+
rows: ProfileRow[];
|
|
22
|
+
title?: ReactNode;
|
|
23
|
+
}
|
|
24
|
+
export interface ProfileScreenProps extends ProfileHeaderProps {
|
|
25
|
+
className?: string;
|
|
26
|
+
/** Sign out, delete account — whatever ends the session, kept away from the
|
|
27
|
+
rows above so it is never the thing a thumb reaches by accident. */
|
|
28
|
+
footer?: ReactNode;
|
|
29
|
+
sections?: ProfileSection[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The account screen: the identity plate, then grouped rows of settings.
|
|
33
|
+
*
|
|
34
|
+
* Ready to mount — hand it the header's props and a list of sections and it is
|
|
35
|
+
* the screen. Rows are declared, not composed, so the whole of a settings page
|
|
36
|
+
* is data the app already has: a label, an icon, and either somewhere to go or
|
|
37
|
+
* something to toggle.
|
|
38
|
+
*
|
|
39
|
+
* State stays the caller's. A switch here reports the change and redraws from
|
|
40
|
+
* the prop, because the truth about whether notifications are on lives on a
|
|
41
|
+
* server, and a row that flips optimistically and then disagrees with it is
|
|
42
|
+
* worse than one that waits.
|
|
43
|
+
*/
|
|
44
|
+
export declare function ProfileScreen({ className, footer, sections, ...header }: ProfileScreenProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export type ResourceMeterTone = 'accent' | 'danger' | 'success' | 'warning';
|
|
3
|
+
export interface ResourceMeterProps extends HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
/** A concise description of the capacity being measured. */
|
|
5
|
+
label: ReactNode;
|
|
6
|
+
/** A readable measurement such as `18.4 / 32 GiB`; formatting stays in the product. */
|
|
7
|
+
value: ReactNode;
|
|
8
|
+
/** Optional secondary context, for example a node's one-minute load. */
|
|
9
|
+
detail?: ReactNode;
|
|
10
|
+
/** Percentage used, clamped to the meter's valid 0–100 range. Omit for capacity-only data. */
|
|
11
|
+
percent?: number;
|
|
12
|
+
tone?: ResourceMeterTone;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A compact, accessible capacity reading for operator interfaces.
|
|
16
|
+
*
|
|
17
|
+
* `Progress` is intentionally unlabelled composition; a resource figure needs
|
|
18
|
+
* its numerator, denominator, and qualitative state to travel together. The
|
|
19
|
+
* product supplies formatting because bytes, vCPU, and retention windows do
|
|
20
|
+
* not share a unit.
|
|
21
|
+
*/
|
|
22
|
+
export declare function ResourceMeter({ className, detail, label, percent, tone, value, ...props }: ResourceMeterProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export interface SectionHeaderProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
|
|
3
|
+
action?: ReactNode;
|
|
4
|
+
description?: ReactNode;
|
|
5
|
+
eyebrow?: ReactNode;
|
|
6
|
+
title: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
export declare function SectionHeader({ action, className, description, eyebrow, title, ...props }: SectionHeaderProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'react';
|
|
2
|
+
export interface SegmentedOption<T extends string> {
|
|
3
|
+
disabled?: boolean;
|
|
4
|
+
label: string;
|
|
5
|
+
value: T;
|
|
6
|
+
}
|
|
7
|
+
export interface SegmentedProps<T extends string> extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {
|
|
8
|
+
fullWidth?: boolean;
|
|
9
|
+
label: string;
|
|
10
|
+
onChange: (value: T) => void;
|
|
11
|
+
options: SegmentedOption<T>[];
|
|
12
|
+
value: T;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A tablist rather than a row of buttons: arrow-key navigation and the
|
|
16
|
+
* selected state both come from the platform's tab semantics.
|
|
17
|
+
*/
|
|
18
|
+
export declare function Segmented<T extends string>({ className, fullWidth, label, onChange, options, value, ...props }: SegmentedProps<T>): import("react").JSX.Element;
|