@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,18 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface SheetProps {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
className?: string;
|
|
5
|
+
/** Label for the close control; also names the dialog when no title is set. */
|
|
6
|
+
closeLabel?: string;
|
|
7
|
+
footer?: ReactNode;
|
|
8
|
+
onClose: () => void;
|
|
9
|
+
open: boolean;
|
|
10
|
+
title?: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The bottom sheet is nim's modal surface. It owns the three things that are
|
|
14
|
+
* always forgotten in hand-rolled sheets: the page behind it must not scroll,
|
|
15
|
+
* Escape must close it, and focus must move into it on open and be restorable
|
|
16
|
+
* on close.
|
|
17
|
+
*/
|
|
18
|
+
export declare function Sheet({ children, className, closeLabel, footer, onClose, open, title }: SheetProps): import('react').ReactPortal | null;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export type SignInMethod = 'code' | 'password';
|
|
3
|
+
export interface SignInCopy {
|
|
4
|
+
back: string;
|
|
5
|
+
codeLabel: string;
|
|
6
|
+
codeSubtitle: (destination: string) => ReactNode;
|
|
7
|
+
codeTitle: string;
|
|
8
|
+
identifierLabel: string;
|
|
9
|
+
passwordLabel: string;
|
|
10
|
+
passwordSubtitle: ReactNode;
|
|
11
|
+
passwordTitle: string;
|
|
12
|
+
phoneLabel: string;
|
|
13
|
+
phoneSubtitle: ReactNode;
|
|
14
|
+
phoneTitle: string;
|
|
15
|
+
resend: string;
|
|
16
|
+
resendIn: (seconds: number) => string;
|
|
17
|
+
sendCode: string;
|
|
18
|
+
signIn: string;
|
|
19
|
+
usePassword: string;
|
|
20
|
+
usePhone: string;
|
|
21
|
+
verify: string;
|
|
22
|
+
}
|
|
23
|
+
export interface SignInFlowProps {
|
|
24
|
+
brand?: ReactNode;
|
|
25
|
+
className?: string;
|
|
26
|
+
codeLength?: number;
|
|
27
|
+
copy?: Partial<SignInCopy>;
|
|
28
|
+
/** ISO 3166-1 alpha-2 the phone step opens on. */
|
|
29
|
+
defaultCountry?: string;
|
|
30
|
+
/** Which door the flow opens on. With both methods enabled the viewer can
|
|
31
|
+
switch; with one, the other is never offered. */
|
|
32
|
+
defaultMethod?: SignInMethod;
|
|
33
|
+
/** Terms line, support link — under the action on every step. */
|
|
34
|
+
footer?: ReactNode;
|
|
35
|
+
methods?: SignInMethod[];
|
|
36
|
+
/** Ask the backend for a code. Rejecting shows the message on the step. */
|
|
37
|
+
onRequestCode?: (e164: string) => Promise<void> | void;
|
|
38
|
+
/** Verify it. Resolving is success — routing afterwards is the caller's. */
|
|
39
|
+
onVerifyCode?: (e164: string, code: string) => Promise<void> | void;
|
|
40
|
+
onPasswordSignIn?: (identifier: string, password: string) => Promise<void> | void;
|
|
41
|
+
/** Countries floated to the top of the picker. */
|
|
42
|
+
priority?: string[];
|
|
43
|
+
/** Seconds before "send it again" is offered. */
|
|
44
|
+
resendSeconds?: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The whole sign-in, ready to mount: phone → code, or email → password, with
|
|
48
|
+
* the resend countdown, the loading and error states, and the step machine
|
|
49
|
+
* already wired.
|
|
50
|
+
*
|
|
51
|
+
* The caller supplies three async functions and gets a working screen. Nothing
|
|
52
|
+
* here knows about a router or an API client — `onVerifyCode` resolving *is*
|
|
53
|
+
* success, and where the viewer goes next is the app's decision, made in one
|
|
54
|
+
* place instead of at each of the flow's five exits.
|
|
55
|
+
*
|
|
56
|
+
* Compose `AuthScreen`, `PhoneField`, `OtpInput` and `PasswordField` by hand
|
|
57
|
+
* instead when the product's flow differs — an invite code step, a captcha, a
|
|
58
|
+
* tenant picker. This is the common shape, not the only one.
|
|
59
|
+
*/
|
|
60
|
+
export declare function SignInFlow({ brand, className, codeLength, copy, defaultCountry, defaultMethod, footer, methods, onPasswordSignIn, onRequestCode, onVerifyCode, priority, resendSeconds, }: SignInFlowProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { InputHTMLAttributes } from 'react';
|
|
2
|
+
export interface SliderProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {
|
|
3
|
+
label?: string;
|
|
4
|
+
max?: number;
|
|
5
|
+
min?: number;
|
|
6
|
+
/** Rendered beneath the track, evenly spaced — e.g. ['1M', '8M', '15M']. */
|
|
7
|
+
scale?: string[];
|
|
8
|
+
value: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function Slider({ className, label, max, min, scale, step, value, ...props }: SliderProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export interface StatProps extends HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
/** Signed change, e.g. `+12%`. Direction colours it and picks the arrow. */
|
|
4
|
+
delta?: string;
|
|
5
|
+
deltaDirection?: 'down' | 'up';
|
|
6
|
+
label: ReactNode;
|
|
7
|
+
unit?: ReactNode;
|
|
8
|
+
value: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
export declare function Stat({ className, delta, deltaDirection, label, unit, value, ...props }: StatProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface StepperProps {
|
|
2
|
+
className?: string;
|
|
3
|
+
decrementLabel?: string;
|
|
4
|
+
incrementLabel?: string;
|
|
5
|
+
label: string;
|
|
6
|
+
max?: number;
|
|
7
|
+
min?: number;
|
|
8
|
+
onChange: (value: number) => void;
|
|
9
|
+
step?: number;
|
|
10
|
+
value: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A number with two full-size targets. Both buttons are control-height
|
|
14
|
+
* squares, so the pair clears the touch minimum rather than shrinking into the
|
|
15
|
+
* cramped ± chevrons this control usually becomes.
|
|
16
|
+
*/
|
|
17
|
+
export declare function Stepper({ className, decrementLabel, incrementLabel, label, max, min, onChange, step, value, }: StepperProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { IconName } from './icon';
|
|
3
|
+
export interface TabBarItem {
|
|
4
|
+
/** Lifted and filled: the one action the product is for. At most one item
|
|
5
|
+
should carry it — two centres is no centre. */
|
|
6
|
+
center?: boolean;
|
|
7
|
+
href?: string;
|
|
8
|
+
icon: IconName;
|
|
9
|
+
/** Full name for assistive tech when `label` is shortened to fit. */
|
|
10
|
+
fullLabel?: string;
|
|
11
|
+
key: string;
|
|
12
|
+
label: string;
|
|
13
|
+
onSelect?: () => void;
|
|
14
|
+
}
|
|
15
|
+
export interface TabBarProps {
|
|
16
|
+
/** Accessible name for the bar itself. */
|
|
17
|
+
label: string;
|
|
18
|
+
className?: string;
|
|
19
|
+
items: TabBarItem[];
|
|
20
|
+
/** `key` of the active item. */
|
|
21
|
+
value: string;
|
|
22
|
+
/** Wrap items in the app's own router link. Given the item and the rendered
|
|
23
|
+
content, returns the element to use — nim never imports a router. */
|
|
24
|
+
renderItem?: (item: TabBarItem, content: ReactNode, props: Record<string, unknown>) => ReactNode;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The floating bottom navigation of a mobile app: three to five destinations,
|
|
28
|
+
* one of them optionally lifted into a primary action.
|
|
29
|
+
*
|
|
30
|
+
* It renders real links or buttons and marks the active one with
|
|
31
|
+
* `aria-current="page"`, so the bar is navigable by keyboard and readable by
|
|
32
|
+
* assistive tech. Routing stays outside: `renderItem` hands the caller the
|
|
33
|
+
* content and the props to spread onto their own `<Link>`, which is why the
|
|
34
|
+
* kit ships no router dependency.
|
|
35
|
+
*
|
|
36
|
+
* It sits above the safe-area inset rather than under the home indicator, and
|
|
37
|
+
* the page below owes it `padding-block-end` — a bar that covers the last row
|
|
38
|
+
* of a list is the most common way this pattern goes wrong.
|
|
39
|
+
*/
|
|
40
|
+
export declare function TabBar({ className, items, label, renderItem, value }: TabBarProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export type SortDirection = 'ascending' | 'descending';
|
|
3
|
+
export interface TableColumn<Row> {
|
|
4
|
+
/** Aligns to the trailing edge in tabular figures. Use it for money, counts,
|
|
5
|
+
and dates — anything a reader compares down a column. */
|
|
6
|
+
numeric?: boolean;
|
|
7
|
+
header: ReactNode;
|
|
8
|
+
key: string;
|
|
9
|
+
render: (row: Row) => ReactNode;
|
|
10
|
+
sortable?: boolean;
|
|
11
|
+
width?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface TableProps<Row> {
|
|
14
|
+
caption?: string;
|
|
15
|
+
className?: string;
|
|
16
|
+
columns: TableColumn<Row>[];
|
|
17
|
+
onSort?: (key: string) => void;
|
|
18
|
+
rowKey: (row: Row) => string;
|
|
19
|
+
rows: Row[];
|
|
20
|
+
sort?: {
|
|
21
|
+
direction: SortDirection;
|
|
22
|
+
key: string;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A table, not a grid of divs: the caller supplies columns and rows and gets
|
|
27
|
+
* real `<table>` semantics, which is what lets a screen reader announce "row 3
|
|
28
|
+
* of 84, Amount 4,200".
|
|
29
|
+
*
|
|
30
|
+
* Row height follows `--nim-density`, the same multiplier that drives control
|
|
31
|
+
* heights — the reason density is a token rather than a prop here.
|
|
32
|
+
*/
|
|
33
|
+
export declare function Table<Row>({ caption, className, columns, onSort, rowKey, rows, sort }: TableProps<Row>): import("react").JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'react';
|
|
2
|
+
export interface TabOption<T extends string> {
|
|
3
|
+
/** A trailing figure — a count, never a decoration. */
|
|
4
|
+
count?: number | string;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
label: string;
|
|
7
|
+
value: T;
|
|
8
|
+
}
|
|
9
|
+
export interface TabsProps<T extends string> extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {
|
|
10
|
+
label: string;
|
|
11
|
+
onChange: (value: T) => void;
|
|
12
|
+
options: TabOption<T>[];
|
|
13
|
+
value: T;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Tabs switch a region of the page. A Segmented control sets a value. They
|
|
17
|
+
* look similar and mean different things, and 0.1 had the segmented control
|
|
18
|
+
* carrying both jobs.
|
|
19
|
+
*
|
|
20
|
+
* Arrow keys move between tabs and select as they go — the pattern a tablist
|
|
21
|
+
* is expected to follow when its panels are cheap to render.
|
|
22
|
+
*/
|
|
23
|
+
export declare function Tabs<T extends string>({ className, label, onChange, options, value, ...props }: TabsProps<T>): import("react").JSX.Element;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export type TaskStepStatus = 'active' | 'done' | 'failed' | 'pending' | 'skipped';
|
|
3
|
+
export interface TaskStep {
|
|
4
|
+
/** What went wrong, or what is happening. Shown under the label — a status
|
|
5
|
+
word alone leaves a stuck viewer with nothing to act on. */
|
|
6
|
+
detail?: ReactNode;
|
|
7
|
+
id: string;
|
|
8
|
+
label: ReactNode;
|
|
9
|
+
status: TaskStepStatus;
|
|
10
|
+
}
|
|
11
|
+
export interface TaskProgressProps {
|
|
12
|
+
/** Rendered under the steps: a cancel control, a support line. */
|
|
13
|
+
action?: ReactNode;
|
|
14
|
+
className?: string;
|
|
15
|
+
/** The headline under the ring — what the job is doing right now. */
|
|
16
|
+
caption?: ReactNode;
|
|
17
|
+
labels?: {
|
|
18
|
+
of: (done: number, total: number) => string;
|
|
19
|
+
status: Record<TaskStepStatus, string>;
|
|
20
|
+
};
|
|
21
|
+
steps: TaskStep[];
|
|
22
|
+
title?: ReactNode;
|
|
23
|
+
/** 0–100. Omit to derive it from the steps, which is what a job with equal
|
|
24
|
+
stages wants; pass it when the server knows better. */
|
|
25
|
+
value?: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A long-running job the viewer is waiting on: a scan, an import, a render.
|
|
29
|
+
*
|
|
30
|
+
* The steps are the point. A bare percentage tells someone how long to wait;
|
|
31
|
+
* a named stage tells them what is happening and, when it fails, which part
|
|
32
|
+
* failed — which is the difference between "try again" and "try again with a
|
|
33
|
+
* better photo". Failure is a state of a step, not a replacement for the list.
|
|
34
|
+
*
|
|
35
|
+
* The region is `aria-live="polite"`, so a stage completing is announced
|
|
36
|
+
* without the viewer having to keep looking at it.
|
|
37
|
+
*/
|
|
38
|
+
export declare function TaskProgress({ action, caption, className, labels, steps, title, value, }: TaskProgressProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* nim has two independent appearance axes.
|
|
4
|
+
*
|
|
5
|
+
* A STYLE owns how the interface is shaped: radii, elevation geometry, type
|
|
6
|
+
* voice, press behaviour. A COLOURWAY owns how it is coloured: surfaces, ink,
|
|
7
|
+
* lines, accent, status. They compose freely — `ledger` + `teal` is a legal
|
|
8
|
+
* pairing, not a mistake — which is why they are two attributes rather than
|
|
9
|
+
* one `theme` name multiplying out into a file per combination.
|
|
10
|
+
*/
|
|
11
|
+
export type NimStyle = 'ledger' | 'vlora';
|
|
12
|
+
export type NimColorway = 'coral' | 'oxblood' | 'teal' | 'vermilion';
|
|
13
|
+
/** `system` follows the OS and is resolved by CSS, not by JavaScript. */
|
|
14
|
+
export type NimScheme = 'dark' | 'light' | 'system';
|
|
15
|
+
export type NimDirection = 'ltr' | 'rtl';
|
|
16
|
+
interface NimContextValue {
|
|
17
|
+
colorway: NimColorway;
|
|
18
|
+
direction: NimDirection;
|
|
19
|
+
/** BCP 47 tag. Components that format dates or numbers use it; the script
|
|
20
|
+
corrections in `persian.css` key off the `lang` attribute it writes. */
|
|
21
|
+
locale: string | undefined;
|
|
22
|
+
scheme: NimScheme;
|
|
23
|
+
setColorway: (colorway: NimColorway) => void;
|
|
24
|
+
setScheme: (scheme: NimScheme) => void;
|
|
25
|
+
setStyle: (style: NimStyle) => void;
|
|
26
|
+
style: NimStyle;
|
|
27
|
+
}
|
|
28
|
+
export interface NimProviderProps {
|
|
29
|
+
children: ReactNode;
|
|
30
|
+
className?: string;
|
|
31
|
+
defaultColorway?: NimColorway;
|
|
32
|
+
defaultScheme?: NimScheme;
|
|
33
|
+
defaultStyle?: NimStyle;
|
|
34
|
+
direction?: NimDirection;
|
|
35
|
+
/** BCP 47 tag, e.g. `fa-IR`. Written to `lang`, which is what turns on the
|
|
36
|
+
Persian script corrections and gives Calendar its month and weekday
|
|
37
|
+
names and its digits. Direction is separate: `dir` says which way the
|
|
38
|
+
line runs, `lang` says which script is being set. */
|
|
39
|
+
locale?: string;
|
|
40
|
+
/** Writes the appearance attributes onto <html> as well, so portalled
|
|
41
|
+
surfaces (sheets, dialogs, menus, toasts) inherit them from outside the
|
|
42
|
+
React tree. */
|
|
43
|
+
syncDocument?: boolean;
|
|
44
|
+
}
|
|
45
|
+
export declare function NimProvider({ children, className, defaultColorway, defaultScheme, defaultStyle, direction, locale, syncDocument, }: NimProviderProps): import("react").JSX.Element;
|
|
46
|
+
export declare function useNim(): NimContextValue;
|
|
47
|
+
/** Convenience for a header toggle: flips light ⇄ dark, leaving `system`. */
|
|
48
|
+
export declare function useSchemeToggle(): () => void;
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export type ToastTone = 'accent' | 'danger' | 'neutral' | 'success';
|
|
3
|
+
export interface ToastOptions {
|
|
4
|
+
action?: {
|
|
5
|
+
label: string;
|
|
6
|
+
onPress: () => void;
|
|
7
|
+
};
|
|
8
|
+
/** Milliseconds on screen. Pass 0 to require a manual dismissal. */
|
|
9
|
+
duration?: number;
|
|
10
|
+
message: string;
|
|
11
|
+
tone?: ToastTone;
|
|
12
|
+
}
|
|
13
|
+
export declare function ToastProvider({ children }: {
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
}): import("react").JSX.Element;
|
|
16
|
+
/** Throws when used outside the provider — a silent no-op would hide the bug. */
|
|
17
|
+
export declare function useToast(): (options: ToastOptions) => void;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface TooltipProps {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
className?: string;
|
|
5
|
+
/** The text shown on hover. Never the only place the name lives. */
|
|
6
|
+
label: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A name for a control that shows only an icon.
|
|
10
|
+
*
|
|
11
|
+
* The bubble is `aria-hidden`: the trigger inside must already carry its own
|
|
12
|
+
* accessible name (IconButton does), so a screen reader is never read the same
|
|
13
|
+
* label twice, and a viewer who cannot hover never depends on this.
|
|
14
|
+
*
|
|
15
|
+
* Hover waits 200ms; keyboard focus does not, because a viewer who tabbed here
|
|
16
|
+
* has already asked.
|
|
17
|
+
*/
|
|
18
|
+
export declare function Tooltip({ children, className, label }: TooltipProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ElementType, HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
interface TextProps extends HTMLAttributes<HTMLElement> {
|
|
3
|
+
as?: ElementType;
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
}
|
|
6
|
+
/** The largest role: page-opening statements only, one per screen. */
|
|
7
|
+
export declare function Display({ as: Component, children, className, ...props }: TextProps): import("react").JSX.Element;
|
|
8
|
+
export declare function Title({ as: Component, children, className, size, ...props }: TextProps & {
|
|
9
|
+
size?: 'lg' | 'md';
|
|
10
|
+
}): import("react").JSX.Element;
|
|
11
|
+
export declare function Body({ as: Component, children, className, size, ...props }: TextProps & {
|
|
12
|
+
size?: 'md' | 'sm';
|
|
13
|
+
}): import("react").JSX.Element;
|
|
14
|
+
/** Mono/uppercase in Ledger, sentence case in Vlora — the theme decides. */
|
|
15
|
+
export declare function Label({ as: Component, children, className, ...props }: TextProps): import("react").JSX.Element;
|
|
16
|
+
export declare function Caption({ as: Component, children, className, ...props }: TextProps): import("react").JSX.Element;
|
|
17
|
+
export declare function Rule({ className, ...props }: HTMLAttributes<HTMLHRElement>): import("react").JSX.Element;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface WizardStep {
|
|
3
|
+
/** The step itself. A function receives nothing — the caller already holds
|
|
4
|
+
the answers, because they are the app's, not the wizard's. */
|
|
5
|
+
content: ReactNode;
|
|
6
|
+
/** Blocks the CTA until the step is answered. */
|
|
7
|
+
canContinue?: boolean;
|
|
8
|
+
/** Overrides the CTA label on this step alone. */
|
|
9
|
+
continueLabel?: string;
|
|
10
|
+
id: string;
|
|
11
|
+
/** The one thing being asked. Kept short: a wizard step is a question. */
|
|
12
|
+
question?: ReactNode;
|
|
13
|
+
subtitle?: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
export interface WizardProps {
|
|
16
|
+
className?: string;
|
|
17
|
+
continueLabel: string;
|
|
18
|
+
/** Label on the last step. */
|
|
19
|
+
finishLabel: string;
|
|
20
|
+
labels?: {
|
|
21
|
+
back: string;
|
|
22
|
+
close: string;
|
|
23
|
+
step: (index: number, total: number) => string;
|
|
24
|
+
};
|
|
25
|
+
onClose?: () => void;
|
|
26
|
+
/** Fired from the last step's CTA. */
|
|
27
|
+
onDone: () => void;
|
|
28
|
+
/** Every step change, including backwards — for analytics and autosave. */
|
|
29
|
+
onStep?: (index: number) => void;
|
|
30
|
+
steps: WizardStep[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A short, one-question-per-screen flow: mood → cause → note, or any other
|
|
34
|
+
* sequence a viewer walks once and abandons easily.
|
|
35
|
+
*
|
|
36
|
+
* The step index is the wizard's; the answers are not. A wizard that owned the
|
|
37
|
+
* answers would have to know their shape, and every product's are different —
|
|
38
|
+
* so each step is given its content and reports back through `canContinue`,
|
|
39
|
+
* which is the only thing the shell needs to know.
|
|
40
|
+
*
|
|
41
|
+
* Progress is dots rather than a bar: a bar implies a percentage of work done,
|
|
42
|
+
* and three questions are three questions. The close control is always present
|
|
43
|
+
* — a flow the viewer cannot leave is a trap, and leaving is the most common
|
|
44
|
+
* thing anyone does with one of these.
|
|
45
|
+
*/
|
|
46
|
+
export declare function Wizard({ className, continueLabel, finishLabel, labels, onClose, onDone, onStep, steps, }: WizardProps): import("react").JSX.Element;
|
|
47
|
+
export interface ChoiceGridOption {
|
|
48
|
+
disabled?: boolean;
|
|
49
|
+
icon?: ReactNode;
|
|
50
|
+
id: string;
|
|
51
|
+
label: ReactNode;
|
|
52
|
+
}
|
|
53
|
+
export interface ChoiceGridProps {
|
|
54
|
+
className?: string;
|
|
55
|
+
/** Cap a multi-select. Options past the cap disable rather than disappear,
|
|
56
|
+
so the grid does not reflow under the viewer's finger. */
|
|
57
|
+
max?: number;
|
|
58
|
+
multiple?: boolean;
|
|
59
|
+
onChange: (selected: string[]) => void;
|
|
60
|
+
options: ChoiceGridOption[];
|
|
61
|
+
selected: string[];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The grid of icon tiles a wizard step is usually made of.
|
|
65
|
+
*
|
|
66
|
+
* Single-select renders radios and multi-select renders checkboxes — stated in
|
|
67
|
+
* ARIA rather than implied by how many are lit, because "pick one" and "pick
|
|
68
|
+
* any" are different promises and only one of them is visible in a grid.
|
|
69
|
+
*/
|
|
70
|
+
export declare function ChoiceGrid({ className, max, multiple, onChange, options, selected, }: ChoiceGridProps): import("react").JSX.Element;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
export { ActivityFeed, AdminShell, DetailHeader, FilterChips } from './components/admin-shell';
|
|
2
|
+
export type { ActivityEvent, ActivityFeedProps, AdminNavGroup, AdminNavItem, AdminShellProps, DetailHeaderProps, FilterChip, FilterChipsProps, } from './components/admin-shell';
|
|
3
|
+
export { AppShell } from './components/app-shell';
|
|
4
|
+
export type { AppShellProps } from './components/app-shell';
|
|
5
|
+
export { AuthScreen } from './components/auth-screen';
|
|
6
|
+
export type { AuthScreenProps } from './components/auth-screen';
|
|
7
|
+
export { Avatar } from './components/avatar';
|
|
8
|
+
export type { AvatarProps, AvatarSize } from './components/avatar';
|
|
9
|
+
export { AvatarRing, ProfileHeader } from './components/profile-header';
|
|
10
|
+
export type { AvatarRingProps, ProfileHeaderProps } from './components/profile-header';
|
|
11
|
+
export { Badge } from './components/badge';
|
|
12
|
+
export type { BadgeProps, BadgeSize, BadgeTone, BadgeVariant } from './components/badge';
|
|
13
|
+
export { Banner } from './components/banner';
|
|
14
|
+
export type { BannerProps, BannerTone } from './components/banner';
|
|
15
|
+
export { Breadcrumb } from './components/breadcrumb';
|
|
16
|
+
export type { BreadcrumbProps, Crumb } from './components/breadcrumb';
|
|
17
|
+
export { Button } from './components/button';
|
|
18
|
+
export type { ButtonProps, ButtonSize, ButtonVariant } from './components/button';
|
|
19
|
+
export { Card } from './components/card';
|
|
20
|
+
export type { CardPadding, CardProps, CardVariant } from './components/card';
|
|
21
|
+
export { ActionBar, OptionCard, OrderSummary } from './components/checkout';
|
|
22
|
+
export type { ActionBarProps, OptionCardProps, OrderSummaryProps, SummaryLine, } from './components/checkout';
|
|
23
|
+
export { Chat } from './components/chat';
|
|
24
|
+
export type { ChatAttachment, ChatMediaKind, ChatMessage, ChatProps } from './components/chat';
|
|
25
|
+
export { ChatComposer } from './components/chat-composer';
|
|
26
|
+
export type { ChatComposerProps, ChatDraft } from './components/chat-composer';
|
|
27
|
+
export { Checkbox, Switch } from './components/choice';
|
|
28
|
+
export type { CheckboxProps, SwitchProps } from './components/choice';
|
|
29
|
+
export { Combobox } from './components/combobox';
|
|
30
|
+
export type { ComboboxOption, ComboboxProps } from './components/combobox';
|
|
31
|
+
export { Calendar, DateField, DatePicker } from './components/date-field';
|
|
32
|
+
export type { CalendarProps, CalendarSystem, DateFieldProps, DatePickerProps, IsoDate, } from './components/date-field';
|
|
33
|
+
export { addDays, addMonths, formatNumeric, monthLength, parseNumeric, partsOf, fromParts, startOfMonth, todayIso, } from './lib/calendars';
|
|
34
|
+
export type { CalendarParts } from './lib/calendars';
|
|
35
|
+
export { Dialog } from './components/dialog';
|
|
36
|
+
export type { DialogProps } from './components/dialog';
|
|
37
|
+
export { EmptyState } from './components/empty-state';
|
|
38
|
+
export type { EmptyStateProps } from './components/empty-state';
|
|
39
|
+
export { Progress, Skeleton, Spinner } from './components/feedback';
|
|
40
|
+
export type { ProgressProps, SkeletonProps, SpinnerProps } from './components/feedback';
|
|
41
|
+
export { ResourceMeter } from './components/resource-meter';
|
|
42
|
+
export type { ResourceMeterProps, ResourceMeterTone } from './components/resource-meter';
|
|
43
|
+
export { Input, Select, Textarea } from './components/field';
|
|
44
|
+
export type { InputProps, SelectOption, SelectProps, TextareaProps } from './components/field';
|
|
45
|
+
export { Icon, iconNames } from './components/icon';
|
|
46
|
+
export type { IconName, IconProps, IconSize, IconTone } from './components/icon';
|
|
47
|
+
export { IconButton } from './components/icon-button';
|
|
48
|
+
export type { IconButtonProps, IconButtonSize, IconButtonVariant } from './components/icon-button';
|
|
49
|
+
export { AppFrame, Inline, Stack } from './components/layout';
|
|
50
|
+
export { List, ListRow } from './components/list';
|
|
51
|
+
export type { ListProps, ListRowProps } from './components/list';
|
|
52
|
+
export { Menu, Popover } from './components/menu';
|
|
53
|
+
export type { MenuAction, MenuHeading, MenuItem, MenuProps, MenuSeparator, PopoverProps } from './components/menu';
|
|
54
|
+
export { Onboarding } from './components/onboarding';
|
|
55
|
+
export type { OnboardingProps, OnboardingSlide } from './components/onboarding';
|
|
56
|
+
export { OtpInput } from './components/otp-input';
|
|
57
|
+
export type { OtpInputProps } from './components/otp-input';
|
|
58
|
+
export { Pagination } from './components/pagination';
|
|
59
|
+
export type { PaginationProps } from './components/pagination';
|
|
60
|
+
export { PasswordField, scorePassword } from './components/password-field';
|
|
61
|
+
export type { PasswordFieldProps, PasswordStrength } from './components/password-field';
|
|
62
|
+
export { PhoneField, toE164 } from './components/phone-field';
|
|
63
|
+
export type { PhoneFieldProps } from './components/phone-field';
|
|
64
|
+
export { PlanCard } from './components/plan-card';
|
|
65
|
+
export type { PlanCardProps, PlanFeature } from './components/plan-card';
|
|
66
|
+
export { PlanPicker } from './components/plan-picker';
|
|
67
|
+
export type { BillingCycle, PlanOffer, PlanPickerProps } from './components/plan-picker';
|
|
68
|
+
export { ProfileScreen } from './components/profile-screen';
|
|
69
|
+
export type { ProfileRow, ProfileScreenProps, ProfileSection } from './components/profile-screen';
|
|
70
|
+
export { SectionHeader } from './components/section-header';
|
|
71
|
+
export type { SectionHeaderProps } from './components/section-header';
|
|
72
|
+
export { Segmented } from './components/segmented';
|
|
73
|
+
export type { SegmentedOption, SegmentedProps } from './components/segmented';
|
|
74
|
+
export { SignInFlow } from './components/sign-in-flow';
|
|
75
|
+
export type { SignInCopy, SignInFlowProps, SignInMethod } from './components/sign-in-flow';
|
|
76
|
+
export { Sheet } from './components/sheet';
|
|
77
|
+
export type { SheetProps } from './components/sheet';
|
|
78
|
+
export { Slider } from './components/slider';
|
|
79
|
+
export type { SliderProps } from './components/slider';
|
|
80
|
+
export { Stat } from './components/stat';
|
|
81
|
+
export type { StatProps } from './components/stat';
|
|
82
|
+
export { Stepper } from './components/stepper';
|
|
83
|
+
export type { StepperProps } from './components/stepper';
|
|
84
|
+
export { TaskProgress } from './components/task-progress';
|
|
85
|
+
export type { TaskProgressProps, TaskStep, TaskStepStatus } from './components/task-progress';
|
|
86
|
+
export { Table } from './components/table';
|
|
87
|
+
export type { SortDirection, TableColumn, TableProps } from './components/table';
|
|
88
|
+
export { TabBar } from './components/tab-bar';
|
|
89
|
+
export type { TabBarItem, TabBarProps } from './components/tab-bar';
|
|
90
|
+
export { Tabs } from './components/tabs';
|
|
91
|
+
export type { TabOption, TabsProps } from './components/tabs';
|
|
92
|
+
export { NimProvider, useNim, useSchemeToggle } from './components/theme';
|
|
93
|
+
export type { NimColorway, NimDirection, NimProviderProps, NimScheme, NimStyle, } from './components/theme';
|
|
94
|
+
export { ToastProvider, useToast } from './components/toast';
|
|
95
|
+
export type { ToastOptions, ToastTone } from './components/toast';
|
|
96
|
+
export { Tooltip } from './components/tooltip';
|
|
97
|
+
export type { TooltipProps } from './components/tooltip';
|
|
98
|
+
export { ChoiceGrid, Wizard } from './components/wizard';
|
|
99
|
+
export type { ChoiceGridOption, ChoiceGridProps, WizardProps, WizardStep, } from './components/wizard';
|
|
100
|
+
export { Body, Caption, Display, Label, Rule, Title } from './components/typography';
|
|
101
|
+
export { COUNTRIES, countryByDial, countryByIso2, countryNamer, toAsciiDigits, } from './lib/countries';
|
|
102
|
+
export type { Country } from './lib/countries';
|
|
103
|
+
export { cn } from './lib/cn';
|
|
104
|
+
export type { ClassValue } from './lib/cn';
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calendar arithmetic for the two systems the kit draws: Gregorian and
|
|
3
|
+
* Jalali (Solar Hijri).
|
|
4
|
+
*
|
|
5
|
+
* There is no conversion table and no leap-year rule in this file, because the
|
|
6
|
+
* platform already ships one: `Intl.DateTimeFormat` with `-u-ca-persian` is
|
|
7
|
+
* ICU's Persian calendar, and it is the same implementation a browser uses to
|
|
8
|
+
* label a date anywhere else. So the direction that is hard — Gregorian to
|
|
9
|
+
* Jalali — is asked of `Intl`, and the direction that is easy — Jalali back to
|
|
10
|
+
* Gregorian — is a close estimate corrected against that same answer until it
|
|
11
|
+
* round-trips. Every value this module returns has therefore been checked
|
|
12
|
+
* against the platform's own calendar rather than against a table that has to
|
|
13
|
+
* be maintained here and goes wrong in 1403 or 2049.
|
|
14
|
+
*
|
|
15
|
+
* The kit's value type never changes: an `IsoDate` is always the Gregorian
|
|
16
|
+
* `YYYY-MM-DD`, in every calendar system. What the viewer reads and what the
|
|
17
|
+
* API receives are different questions, and only the first one has a calendar.
|
|
18
|
+
*/
|
|
19
|
+
/** ISO `YYYY-MM-DD`, Gregorian, always. The kit never invents a date type. */
|
|
20
|
+
export type IsoDate = string;
|
|
21
|
+
/** The calendar a grid is drawn in — never what a value is stored in. */
|
|
22
|
+
export type CalendarSystem = 'gregory' | 'persian';
|
|
23
|
+
export interface CalendarParts {
|
|
24
|
+
day: number;
|
|
25
|
+
month: number;
|
|
26
|
+
year: number;
|
|
27
|
+
}
|
|
28
|
+
export declare const isoOf: (date: Date) => IsoDate;
|
|
29
|
+
export declare const dateOf: (value: IsoDate) => Date;
|
|
30
|
+
export declare const todayIso: () => IsoDate;
|
|
31
|
+
/** The calendar fields a viewer of `system` would read off this instant. */
|
|
32
|
+
export declare function partsOf(value: IsoDate, system: CalendarSystem): CalendarParts;
|
|
33
|
+
/**
|
|
34
|
+
* The Gregorian date on which `parts` falls in `system`.
|
|
35
|
+
*
|
|
36
|
+
* For Jalali this starts from the mean-year estimate and walks to the answer,
|
|
37
|
+
* comparing against `partsOf` — which is ICU. The estimate is never more than
|
|
38
|
+
* a few days out, and the loop is bounded, so a bad input fails by returning
|
|
39
|
+
* its best effort rather than by spinning.
|
|
40
|
+
*/
|
|
41
|
+
export declare function fromParts(parts: CalendarParts, system: CalendarSystem): IsoDate;
|
|
42
|
+
/** The first day of the month `value` falls in, in `system`. */
|
|
43
|
+
export declare function startOfMonth(value: IsoDate, system: CalendarSystem): IsoDate;
|
|
44
|
+
/** `delta` months on from `value`, clamped into the target month's length. */
|
|
45
|
+
export declare function addMonths(value: IsoDate, delta: number, system: CalendarSystem): IsoDate;
|
|
46
|
+
/**
|
|
47
|
+
* How many days that month holds — measured, not tabulated. The distance to
|
|
48
|
+
* the first of the next month is the length, whatever the leap rule says, so
|
|
49
|
+
* an Esfand of 30 days needs no special case here.
|
|
50
|
+
*/
|
|
51
|
+
export declare function monthLength(year: number, month: number, system: CalendarSystem): number;
|
|
52
|
+
export declare const addDays: (value: IsoDate, days: number) => IsoDate;
|
|
53
|
+
/** 0 = Sunday. The week's shape is the same fact in every calendar. */
|
|
54
|
+
export declare const weekdayOf: (value: IsoDate) => number;
|
|
55
|
+
/**
|
|
56
|
+
* The locale tag that puts `Intl` into `system`. A `-u-ca-` extension already
|
|
57
|
+
* on the tag wins, so an app asking for `fa-IR-u-ca-gregory` keeps it.
|
|
58
|
+
*/
|
|
59
|
+
export declare function localeFor(locale: string | undefined, system: CalendarSystem): string;
|
|
60
|
+
/**
|
|
61
|
+
* The calendar an `fa` reader expects. Persian interfaces run on the Jalali
|
|
62
|
+
* calendar; everything else this kit ships in runs on the Gregorian one.
|
|
63
|
+
*/
|
|
64
|
+
export declare const defaultSystem: (locale: string | undefined) => CalendarSystem;
|
|
65
|
+
/** Persian weeks begin on Saturday; the Gregorian ones here on Monday. */
|
|
66
|
+
export declare const defaultWeekStart: (system: CalendarSystem) => number;
|
|
67
|
+
/**
|
|
68
|
+
* `۱۴۰۴/۰۶/۰۱` — year first, zero-padded, in the locale's digits.
|
|
69
|
+
*
|
|
70
|
+
* Deliberately not `Intl`'s numeric pattern, which would give `۰۱/۰۶/۱۴۰۴ ه.ش`
|
|
71
|
+
* under an English locale on the Jalali calendar: field order and an era
|
|
72
|
+
* suffix that no Iranian writes and this module's parser cannot read back. A
|
|
73
|
+
* Jalali date is written biggest-unit-first everywhere it is written at all,
|
|
74
|
+
* so `formatNumeric` and `parseNumeric` agree by construction.
|
|
75
|
+
*/
|
|
76
|
+
export declare function formatNumeric(value: IsoDate, locale: string | undefined, system: CalendarSystem): string;
|
|
77
|
+
/**
|
|
78
|
+
* Reads `1404/06/01`, `۱۴۰۴-۰۶-۰۱`, or anything else with three numbers in
|
|
79
|
+
* year, month, day order. Returns null rather than guessing at two.
|
|
80
|
+
*/
|
|
81
|
+
export declare function parseNumeric(input: string, system: CalendarSystem): IsoDate | null;
|
package/dist/lib/cn.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The kit's only class-name helper. nim components compose a small, fixed set
|
|
3
|
+
* of semantic class names, so a full `clsx`-style dependency would buy nothing
|
|
4
|
+
* that this does not already do.
|
|
5
|
+
*/
|
|
6
|
+
export type ClassValue = string | false | null | undefined;
|
|
7
|
+
export declare const cn: (...values: ClassValue[]) => string;
|