@3gs/ui 0.1.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 +43 -0
- package/dist/components/ActionSheet/ActionSheet.d.ts +40 -0
- package/dist/components/ActionSheet/index.d.ts +2 -0
- package/dist/components/Alert/Alert.d.ts +36 -0
- package/dist/components/Alert/index.d.ts +2 -0
- package/dist/components/Badge/Badge.d.ts +13 -0
- package/dist/components/Badge/index.d.ts +2 -0
- package/dist/components/Button/Button.d.ts +32 -0
- package/dist/components/Button/index.d.ts +2 -0
- package/dist/components/DatePicker/DatePicker.d.ts +57 -0
- package/dist/components/DatePicker/index.d.ts +2 -0
- package/dist/components/HUD/HUD.d.ts +56 -0
- package/dist/components/HUD/index.d.ts +2 -0
- package/dist/components/Icon/Icon.d.ts +27 -0
- package/dist/components/Icon/index.d.ts +2 -0
- package/dist/components/Keyboard/Keyboard.d.ts +38 -0
- package/dist/components/Keyboard/index.d.ts +2 -0
- package/dist/components/List/List.d.ts +55 -0
- package/dist/components/List/index.d.ts +2 -0
- package/dist/components/ModalSheet/ModalSheet.d.ts +36 -0
- package/dist/components/ModalSheet/index.d.ts +2 -0
- package/dist/components/NavigationBar/NavigationBar.d.ts +41 -0
- package/dist/components/NavigationBar/index.d.ts +2 -0
- package/dist/components/NotificationBanner/NotificationBanner.d.ts +50 -0
- package/dist/components/NotificationBanner/index.d.ts +2 -0
- package/dist/components/PageControl/PageControl.d.ts +32 -0
- package/dist/components/PageControl/index.d.ts +2 -0
- package/dist/components/Picker/Picker.d.ts +45 -0
- package/dist/components/Picker/index.d.ts +2 -0
- package/dist/components/Popover/Popover.d.ts +40 -0
- package/dist/components/Popover/index.d.ts +2 -0
- package/dist/components/Progress/Progress.d.ts +37 -0
- package/dist/components/Progress/index.d.ts +2 -0
- package/dist/components/SearchBar/SearchBar.d.ts +61 -0
- package/dist/components/SearchBar/index.d.ts +2 -0
- package/dist/components/SegmentedControl/SegmentedControl.d.ts +50 -0
- package/dist/components/SegmentedControl/index.d.ts +2 -0
- package/dist/components/Slider/Slider.d.ts +39 -0
- package/dist/components/Slider/index.d.ts +2 -0
- package/dist/components/StatusBar/StatusBar.d.ts +24 -0
- package/dist/components/StatusBar/index.d.ts +2 -0
- package/dist/components/Stepper/Stepper.d.ts +55 -0
- package/dist/components/Stepper/index.d.ts +2 -0
- package/dist/components/Switch/Switch.d.ts +26 -0
- package/dist/components/Switch/index.d.ts +2 -0
- package/dist/components/TabBar/TabBar.d.ts +33 -0
- package/dist/components/TabBar/index.d.ts +2 -0
- package/dist/components/TextField/TextField.d.ts +38 -0
- package/dist/components/TextField/index.d.ts +2 -0
- package/dist/components/Toolbar/Toolbar.d.ts +58 -0
- package/dist/components/Toolbar/index.d.ts +2 -0
- package/dist/index.cjs +73 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +2803 -0
- package/dist/lib/cn.d.ts +2 -0
- package/dist/lib/i18n.d.ts +89 -0
- package/dist/ui.css +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export interface PickerOption {
|
|
3
|
+
value: string;
|
|
4
|
+
label: ReactNode;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface PickerColumn {
|
|
8
|
+
/** Identifies the column; the key under which its value is reported. */
|
|
9
|
+
key: string;
|
|
10
|
+
options: PickerOption[];
|
|
11
|
+
/** `aria-label` for the drum. Defaults to `key`. */
|
|
12
|
+
label?: string;
|
|
13
|
+
/** CSS width of the column. Without it, columns share the width equally. */
|
|
14
|
+
width?: number | string;
|
|
15
|
+
/** Text alignment inside the drum. Default `center`. */
|
|
16
|
+
align?: "left" | "center" | "right";
|
|
17
|
+
}
|
|
18
|
+
/** `{ [column.key]: option.value }` */
|
|
19
|
+
export type PickerValue = Record<string, string>;
|
|
20
|
+
export interface PickerProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue"> {
|
|
21
|
+
columns: PickerColumn[];
|
|
22
|
+
/** Controlled selection. */
|
|
23
|
+
value?: PickerValue;
|
|
24
|
+
/** Uncontrolled initial selection; missing keys default to the first (enabled) option. */
|
|
25
|
+
defaultValue?: PickerValue;
|
|
26
|
+
onChange?: (value: PickerValue, changed: {
|
|
27
|
+
key: string;
|
|
28
|
+
value: string;
|
|
29
|
+
}) => void;
|
|
30
|
+
/** Visible rows per drum (44 px each). Default `5`. */
|
|
31
|
+
rows?: 3 | 5 | 7;
|
|
32
|
+
/** `aria-label` for the whole picker. */
|
|
33
|
+
label?: string;
|
|
34
|
+
disabled?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The iOS 3 spinning wheel (`UIPickerView`): one drum per column inside black
|
|
38
|
+
* chrome, each showing `rows` 44 px rows shaded into darkness toward the top
|
|
39
|
+
* and bottom edges to fake a cylinder, with a translucent blue-glass bar over
|
|
40
|
+
* the middle row. Flick a drum and it snaps to a row; click a row to select it.
|
|
41
|
+
*
|
|
42
|
+
* Keyboard (on a focused drum): Up/Down one row, PageUp/PageDown a screenful,
|
|
43
|
+
* Home/End first/last — disabled rows are skipped.
|
|
44
|
+
*/
|
|
45
|
+
export declare const Picker: import('react').ForwardRefExoticComponent<PickerProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export type PopoverPlacement = "top" | "bottom" | "left" | "right";
|
|
3
|
+
export interface PopoverProps extends HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
open: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* The element the arrow points at — pass `ref.current`. Re-measured on
|
|
7
|
+
* open, on window resize and on any scroll.
|
|
8
|
+
*/
|
|
9
|
+
anchor: HTMLElement | null;
|
|
10
|
+
/** Called on Escape and on an outside click / tap (when `dismissOnOutside`). */
|
|
11
|
+
onClose?: () => void;
|
|
12
|
+
/** Preferred side. Default `"bottom"`; flips to the opposite side when there is no room. */
|
|
13
|
+
placement?: PopoverPlacement;
|
|
14
|
+
/**
|
|
15
|
+
* Panel width (the box inside the 8 px rim). Default `240` — iPad popovers
|
|
16
|
+
* were 320, a phone screen wants narrower.
|
|
17
|
+
*/
|
|
18
|
+
width?: number | string;
|
|
19
|
+
/**
|
|
20
|
+
* Default `false` → portal to `document.body`, `position: fixed`, viewport
|
|
21
|
+
* coordinates. `true` → render in place with `position: absolute`,
|
|
22
|
+
* coordinates relative to the nearest positioned ancestor's padding box
|
|
23
|
+
* (e.g. a phone screen in a showcase) and clamped within it.
|
|
24
|
+
*/
|
|
25
|
+
contained?: boolean;
|
|
26
|
+
/** Default `true` — a click outside the panel closes it. */
|
|
27
|
+
dismissOnOutside?: boolean;
|
|
28
|
+
/** `aria-label` for the `role="dialog"` panel when there is no heading inside. Default `strings.dialog`. */
|
|
29
|
+
label?: string;
|
|
30
|
+
children: ReactNode;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The iOS 3.2 popover (`UIPopoverController`): a dark navy-black bubble with
|
|
34
|
+
* a thick translucent rim and a triangular arrow pointing at its anchor, used
|
|
35
|
+
* for menus and dropdowns. Positioned on the preferred side of the anchor
|
|
36
|
+
* (flipping when there is no room), centred on it and clamped inside the
|
|
37
|
+
* container; the arrow keeps pointing at the anchor after clamping. Renders
|
|
38
|
+
* nothing while `open` is false. The ref points at the panel.
|
|
39
|
+
*/
|
|
40
|
+
export declare const Popover: import('react').ForwardRefExoticComponent<PopoverProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'react';
|
|
2
|
+
export interface ProgressBarProps extends HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
/** `0..max`. Omit for an indeterminate bar (a gel segment sliding back and forth). */
|
|
4
|
+
value?: number;
|
|
5
|
+
/** Default 100. */
|
|
6
|
+
max?: number;
|
|
7
|
+
/** Track height: `sm` 9 px (default) or `md` 12 px. */
|
|
8
|
+
size?: "sm" | "md";
|
|
9
|
+
/** Show the percentage ("42 %") to the right of the track. */
|
|
10
|
+
showValue?: boolean;
|
|
11
|
+
/** Accessible name (`aria-label`). */
|
|
12
|
+
label?: string;
|
|
13
|
+
/** Fill gel: `blue` (App Store, default) or the silver iPod scrubber. */
|
|
14
|
+
tint?: "blue" | "gray";
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A thin sunken pill track (inset shadow, black outline) holding a blue gel
|
|
18
|
+
* fill with its own hard 50 % highlight — the App Store download bar.
|
|
19
|
+
* Without `value` it is indeterminate: a 35 % segment slides left and right.
|
|
20
|
+
*/
|
|
21
|
+
export declare const ProgressBar: import('react').ForwardRefExoticComponent<ProgressBarProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
22
|
+
export interface ActivityIndicatorProps extends HTMLAttributes<HTMLSpanElement> {
|
|
23
|
+
/** Diameter in px. 20 (default) is the "white" / "gray" style, 37 the "whiteLarge" style. */
|
|
24
|
+
size?: number;
|
|
25
|
+
/** Spoke colour: `white` (default, for dark surfaces) or `gray`. */
|
|
26
|
+
tone?: "white" | "gray";
|
|
27
|
+
/** Accessible name, announced via `role="status"`. Default `strings.loading` ("Loading"). */
|
|
28
|
+
label?: string;
|
|
29
|
+
/** `false` renders nothing — `hidesWhenStopped`. Default `true`. */
|
|
30
|
+
animating?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The 12-spoke spinner. The fading spokes are static; the whole wheel turns
|
|
34
|
+
* 360° in 12 discrete 30° steps per second, exactly like the frame-stepped
|
|
35
|
+
* original — a smooth rotation would give it away.
|
|
36
|
+
*/
|
|
37
|
+
export declare const ActivityIndicator: import('react').ForwardRefExoticComponent<ActivityIndicatorProps & import('react').RefAttributes<HTMLSpanElement>>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { HTMLAttributes, InputHTMLAttributes } from 'react';
|
|
2
|
+
import { NavigationBarTint } from '../NavigationBar';
|
|
3
|
+
/** One scope button under the field. */
|
|
4
|
+
export interface SearchScope {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface SearchBarProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue"> {
|
|
10
|
+
/** Controlled query. */
|
|
11
|
+
value?: string;
|
|
12
|
+
/** Uncontrolled initial query. */
|
|
13
|
+
defaultValue?: string;
|
|
14
|
+
/** Fires on every keystroke, on ⓧ and on Cancel (with `""`). */
|
|
15
|
+
onChange?: (query: string) => void;
|
|
16
|
+
/** Enter key — the keyboard's "Search". */
|
|
17
|
+
onSearch?: (query: string) => void;
|
|
18
|
+
/**
|
|
19
|
+
* Cancel tapped. The bar clears the query (reports `onChange("")` when
|
|
20
|
+
* controlled — keep your `value` to override) and gives up focus first.
|
|
21
|
+
*/
|
|
22
|
+
onCancel?: () => void;
|
|
23
|
+
/** Defaults to the SearchField's placeholder (`strings.search`, "Search"). */
|
|
24
|
+
placeholder?: string;
|
|
25
|
+
/** When given, a `SegmentedControl size="sm" block` row of scope buttons appears under the field. */
|
|
26
|
+
scopes?: SearchScope[];
|
|
27
|
+
/** Controlled scope. */
|
|
28
|
+
scope?: string;
|
|
29
|
+
/** Uncontrolled initial scope; falls back to the first one. */
|
|
30
|
+
defaultScope?: string;
|
|
31
|
+
onScopeChange?: (scope: string) => void;
|
|
32
|
+
/** `always` (default) or fold the scope row open only while editing. */
|
|
33
|
+
showsScopeBar?: "always" | "whileEditing";
|
|
34
|
+
/**
|
|
35
|
+
* `whileEditing` (default): Cancel slides in while the field is focused
|
|
36
|
+
* or has text. `always` keeps it; `never` drops it.
|
|
37
|
+
*/
|
|
38
|
+
showsCancel?: "whileEditing" | "always" | "never";
|
|
39
|
+
/** Default `strings.cancel` ("Cancel"). */
|
|
40
|
+
cancelLabel?: string;
|
|
41
|
+
/** `black` glass (default) or the classic blue-gray bar — like NavigationBar. */
|
|
42
|
+
tint?: NavigationBarTint;
|
|
43
|
+
autoFocus?: boolean;
|
|
44
|
+
disabled?: boolean;
|
|
45
|
+
/** `aria-label` of the search landmark (and the input). Default `strings.search` ("Search"). */
|
|
46
|
+
label?: string;
|
|
47
|
+
/** Escape hatch for the inner `<input>`; `onChange` / `onKeyDown` given here are called too. */
|
|
48
|
+
inputProps?: InputHTMLAttributes<HTMLInputElement>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* UISearchBar: the strip of bar glass above a table — the pill search field,
|
|
52
|
+
* a gel Cancel button that slides in while editing, and optional scope
|
|
53
|
+
* buttons underneath. Same chrome as the NavigationBar, so it stacks straight
|
|
54
|
+
* under one.
|
|
55
|
+
*
|
|
56
|
+
* "Editing" = focus is somewhere inside the bar (input, Cancel or a scope
|
|
57
|
+
* button) or the field has text. Focus is tracked on the bar rather than the
|
|
58
|
+
* input alone, so tabbing from the input to Cancel — or into the scope row —
|
|
59
|
+
* doesn't fold those controls away from under the focus.
|
|
60
|
+
*/
|
|
61
|
+
export declare const SearchBar: import('react').ForwardRefExoticComponent<SearchBarProps & import('react').RefAttributes<HTMLInputElement>>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ButtonHTMLAttributes, HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import { LucideIcon } from 'lucide-react';
|
|
3
|
+
export type SegmentedControlSize =
|
|
4
|
+
/** 30 px tall, 13 px text — fits inside a NavigationBar */
|
|
5
|
+
"sm"
|
|
6
|
+
/** 44 px tall, 15 px text — the standard touch target (default) */
|
|
7
|
+
| "md";
|
|
8
|
+
export type SegmentedControlTint =
|
|
9
|
+
/** dark gel (default) */
|
|
10
|
+
"dark"
|
|
11
|
+
/** the blue-gray gel used inside a `tint="blue"` NavigationBar */
|
|
12
|
+
| "blue";
|
|
13
|
+
export interface SegmentedControlProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange"> {
|
|
14
|
+
/** Controlled selected segment. */
|
|
15
|
+
value?: string;
|
|
16
|
+
/** Uncontrolled initial segment. Defaults to the first one — a segmented control always has a selection. */
|
|
17
|
+
defaultValue?: string;
|
|
18
|
+
onChange?: (value: string) => void;
|
|
19
|
+
size?: SegmentedControlSize;
|
|
20
|
+
tint?: SegmentedControlTint;
|
|
21
|
+
/** `aria-label` for the group. Default `strings.segments` ("Segments"). */
|
|
22
|
+
label?: string;
|
|
23
|
+
/** Stretch to the container width. Default: intrinsic — every segment as wide as the widest. */
|
|
24
|
+
block?: boolean;
|
|
25
|
+
/** `<Segment>`s. */
|
|
26
|
+
children: ReactNode;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The iOS 3 segmented control (`UISegmentedControlStyleBar`): one rounded gel
|
|
30
|
+
* bar cut into equal segments by 1 px black dividers. The selected segment is
|
|
31
|
+
* pressed in — sunken, blue-black gel — while the others stay raised glass.
|
|
32
|
+
*
|
|
33
|
+
* Keyboard: Left/Right (and Home/End) move focus *and* select, skipping
|
|
34
|
+
* disabled segments — roving tabindex, so the control is a single Tab stop.
|
|
35
|
+
*/
|
|
36
|
+
export declare const SegmentedControl: import('react').ForwardRefExoticComponent<SegmentedControlProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
37
|
+
export interface SegmentProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "value"> {
|
|
38
|
+
/** Identifies the segment; what `SegmentedControl` reports through `onChange`. */
|
|
39
|
+
value: string;
|
|
40
|
+
/** Any `lucide-react` icon, rendered flat in white before the text — or alone. */
|
|
41
|
+
icon?: LucideIcon;
|
|
42
|
+
/**
|
|
43
|
+
* Accessible name. Required for an icon-only segment (it becomes the
|
|
44
|
+
* `aria-label`); without an icon or `children` it is the visible text.
|
|
45
|
+
*/
|
|
46
|
+
label?: string;
|
|
47
|
+
/** The visible text. */
|
|
48
|
+
children?: ReactNode;
|
|
49
|
+
}
|
|
50
|
+
export declare const Segment: import('react').ForwardRefExoticComponent<SegmentProps & import('react').RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { InputHTMLAttributes } from 'react';
|
|
2
|
+
import { LucideIcon } from 'lucide-react';
|
|
3
|
+
export interface SliderProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "value" | "defaultValue" | "onChange" | "size" | "type" | "min" | "max" | "step"> {
|
|
4
|
+
/** Controlled value. Leave undefined to let the slider manage its own state. */
|
|
5
|
+
value?: number;
|
|
6
|
+
/** Initial value when uncontrolled. Default: `min`. */
|
|
7
|
+
defaultValue?: number;
|
|
8
|
+
/** Fires continuously while dragging (and on every key press). */
|
|
9
|
+
onChange?: (value: number) => void;
|
|
10
|
+
/** Fires when the value is committed — pointer release / key release (the native `change` event). */
|
|
11
|
+
onChangeEnd?: (value: number) => void;
|
|
12
|
+
/** Default `0`. */
|
|
13
|
+
min?: number;
|
|
14
|
+
/** Default `100`. */
|
|
15
|
+
max?: number;
|
|
16
|
+
/** Default `1`. */
|
|
17
|
+
step?: number;
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
/** Accessible name (`aria-label`). Required unless `aria-labelledby` is passed. */
|
|
20
|
+
label?: string;
|
|
21
|
+
/** Small flat gray icon left of the track (e.g. `Volume`, `Sun`). */
|
|
22
|
+
minIcon?: LucideIcon;
|
|
23
|
+
/** Larger flat gray icon right of the track (e.g. `Volume2`, `Sun`). */
|
|
24
|
+
maxIcon?: LucideIcon;
|
|
25
|
+
/** Renders the numeric value right of the track. */
|
|
26
|
+
showValue?: boolean;
|
|
27
|
+
/** `className` goes to the `<input>`; this one to the outer wrapper. */
|
|
28
|
+
wrapperClassName?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The iOS 3 volume / brightness slider: a thin sunken track, blue gel fill to
|
|
32
|
+
* the left of the knob, dark inset to the right, and a round silver gel knob
|
|
33
|
+
* (the Switch's) with a black outline. Optional flat icons at each end.
|
|
34
|
+
*
|
|
35
|
+
* Built on a native `<input type="range">` so keyboard, touch, forms and
|
|
36
|
+
* assistive tech come for free; the ref points at that input. The blue fill
|
|
37
|
+
* is driven by the `--gs-slider-pct` custom property on the wrapper.
|
|
38
|
+
*/
|
|
39
|
+
export declare const Slider: import('react').ForwardRefExoticComponent<SliderProps & import('react').RefAttributes<HTMLInputElement>>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'react';
|
|
2
|
+
export type StatusBarNetwork = "3G" | "E" | "wifi" | "none";
|
|
3
|
+
export interface StatusBarProps extends HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
/** Clock text, e.g. "3:53 PM". */
|
|
5
|
+
time?: string;
|
|
6
|
+
/** Signal strength 0–5 bars. */
|
|
7
|
+
signal?: 0 | 1 | 2 | 3 | 4 | 5;
|
|
8
|
+
/** Data indicator right of the signal bars. */
|
|
9
|
+
network?: StatusBarNetwork;
|
|
10
|
+
/** Carrier name instead of the signal bars' implicit "iPhone" — rendered after the network glyph. */
|
|
11
|
+
carrier?: string;
|
|
12
|
+
/** Battery level 0–100. */
|
|
13
|
+
battery?: number;
|
|
14
|
+
charging?: boolean;
|
|
15
|
+
bluetooth?: boolean;
|
|
16
|
+
/** Black glass (default) or the translucent gray used over photos. */
|
|
17
|
+
tint?: "black" | "gray";
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The 20 px iOS 3 status bar: signal bars, network glyph, bold clock, Bluetooth
|
|
21
|
+
* and battery. Purely presentational (`aria-hidden` by default — pass
|
|
22
|
+
* `aria-hidden={false}` and a `role` if the values matter to assistive tech).
|
|
23
|
+
*/
|
|
24
|
+
export declare const StatusBar: import('react').ForwardRefExoticComponent<StatusBarProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'react';
|
|
2
|
+
export type StepperSize =
|
|
3
|
+
/** 30 px tall — fits a 44 px list row (default) */
|
|
4
|
+
"sm"
|
|
5
|
+
/** 44 px tall — the standard touch target */
|
|
6
|
+
| "md";
|
|
7
|
+
export type StepperTint =
|
|
8
|
+
/** the bar-button gel of the current theme (default) */
|
|
9
|
+
"dark"
|
|
10
|
+
/** the blue-gray gel of a `tint="blue"` NavigationBar, in either theme */
|
|
11
|
+
| "blue";
|
|
12
|
+
export interface StepperProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue"> {
|
|
13
|
+
/** Controlled value. */
|
|
14
|
+
value?: number;
|
|
15
|
+
/** Uncontrolled initial value. Defaults to `min`. */
|
|
16
|
+
defaultValue?: number;
|
|
17
|
+
/** Fires with the new value on every step (click, hold, key). */
|
|
18
|
+
onChange?: (value: number) => void;
|
|
19
|
+
/** Default `0`. */
|
|
20
|
+
min?: number;
|
|
21
|
+
/** Default `100`. */
|
|
22
|
+
max?: number;
|
|
23
|
+
/** Default `1`. Values are rounded to the step's decimal precision. */
|
|
24
|
+
step?: number;
|
|
25
|
+
/** At the bounds the button disables (default); `true` wraps around instead. */
|
|
26
|
+
wraps?: boolean;
|
|
27
|
+
/** Hold a button to repeat: 500 ms delay, then every 100 ms, every 50 ms after 2 s. Default `true`. */
|
|
28
|
+
autoRepeat?: boolean;
|
|
29
|
+
/** Show the value in a sunken well on the inline-start side of the buttons. */
|
|
30
|
+
showValue?: boolean;
|
|
31
|
+
/** Formats the shown value, e.g. `(v) => v + " %"`. */
|
|
32
|
+
formatValue?: (value: number) => string;
|
|
33
|
+
/** 30 px (fits a 44 px list row) or 44 px. Default `"sm"`. */
|
|
34
|
+
size?: StepperSize;
|
|
35
|
+
/** The bar-button gel of the theme, or the blue-gray gel of a blue NavigationBar. Default `"dark"`. */
|
|
36
|
+
tint?: StepperTint;
|
|
37
|
+
/** Dims the whole control; both buttons disable. */
|
|
38
|
+
disabled?: boolean;
|
|
39
|
+
/** `aria-label` for the group, e.g. `"Quantity"`. */
|
|
40
|
+
label?: string;
|
|
41
|
+
/** `aria-label` of the − button. Default `"Decrease"`. */
|
|
42
|
+
decrementLabel?: string;
|
|
43
|
+
/** `aria-label` of the + button. Default `"Increase"`. */
|
|
44
|
+
incrementLabel?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The joined "− | +" gel control (`UIStepper`) for a list row: two glass
|
|
48
|
+
* segments cut by a 1 px black divider, like a two-segment SegmentedControl,
|
|
49
|
+
* with an optional sunken value well beside them.
|
|
50
|
+
*
|
|
51
|
+
* The buttons are ordinary buttons (Tab / Enter / Space); on either one
|
|
52
|
+
* ArrowUp/ArrowRight increment, ArrowDown/ArrowLeft decrement and Home/End
|
|
53
|
+
* jump to the bounds. Holding a button repeats.
|
|
54
|
+
*/
|
|
55
|
+
export declare const Stepper: import('react').ForwardRefExoticComponent<StepperProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ButtonHTMLAttributes } from 'react';
|
|
2
|
+
export interface SwitchProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "onChange" | "value"> {
|
|
3
|
+
/** Controlled state. Leave undefined to let the switch manage its own state. */
|
|
4
|
+
checked?: boolean;
|
|
5
|
+
/** Initial state when uncontrolled. */
|
|
6
|
+
defaultChecked?: boolean;
|
|
7
|
+
onChange?: (checked: boolean) => void;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
/** Text on the blue half. Default `strings.on` ("ON"). */
|
|
10
|
+
onLabel?: string;
|
|
11
|
+
/** Text on the dark half. Default `strings.off` ("OFF"). */
|
|
12
|
+
offLabel?: string;
|
|
13
|
+
/** Accessible name (`aria-label`) when there is no visible label. */
|
|
14
|
+
label?: string;
|
|
15
|
+
/** When set, a hidden `<input type="checkbox">` carries the value in form submissions. */
|
|
16
|
+
name?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The iOS 3 ON/OFF slider: a 94×27 gel pill whose two-tone strip (blue "ON",
|
|
20
|
+
* dark "OFF") slides under a silver gel knob.
|
|
21
|
+
*
|
|
22
|
+
* Rendered as `<button role="switch">`. Space and Enter already dispatch
|
|
23
|
+
* `click` on a native button, so a single click handler covers pointer and
|
|
24
|
+
* keyboard activation.
|
|
25
|
+
*/
|
|
26
|
+
export declare const Switch: import('react').ForwardRefExoticComponent<SwitchProps & import('react').RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ButtonHTMLAttributes, HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import { LucideIcon } from 'lucide-react';
|
|
3
|
+
export interface TabBarProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange"> {
|
|
4
|
+
/** Controlled selected tab. */
|
|
5
|
+
value?: string;
|
|
6
|
+
/** Uncontrolled initial tab. Defaults to the first item — an iOS tab bar always has a selection. */
|
|
7
|
+
defaultValue?: string;
|
|
8
|
+
onChange?: (value: string) => void;
|
|
9
|
+
/** `aria-label` for the tablist. Default `strings.tabs` ("Tabs"). */
|
|
10
|
+
label?: string;
|
|
11
|
+
/** `<TabBarItem>`s. */
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The 49 px black-glass bottom bar (`UITabBar`, `UIBarStyleBlack`): evenly
|
|
16
|
+
* spaced items, each a gray gel icon over a tiny bold label; the selected one
|
|
17
|
+
* turns blue on a subtly lighter, slightly sunken rounded rectangle.
|
|
18
|
+
*
|
|
19
|
+
* Keyboard: Left/Right (and Home/End) move focus *and* select — roving
|
|
20
|
+
* tabindex, so the bar is a single Tab stop.
|
|
21
|
+
*/
|
|
22
|
+
export declare const TabBar: import('react').ForwardRefExoticComponent<TabBarProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
23
|
+
export interface TabBarItemProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "value"> {
|
|
24
|
+
/** Identifies the tab; what `TabBar` reports through `onChange`. */
|
|
25
|
+
value: string;
|
|
26
|
+
/** Any `lucide-react` icon — gray glass when idle, blue glass when selected. */
|
|
27
|
+
icon: LucideIcon;
|
|
28
|
+
/** The 10 px bold caption under the icon. */
|
|
29
|
+
label: string;
|
|
30
|
+
/** Red gel badge on the icon's top-right corner (`43`, `"New"`; numbers > 99 render `99+`). */
|
|
31
|
+
badge?: number | string;
|
|
32
|
+
}
|
|
33
|
+
export declare const TabBarItem: import('react').ForwardRefExoticComponent<TabBarItemProps & import('react').RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { InputHTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import { LucideIcon } from 'lucide-react';
|
|
3
|
+
export interface TextFieldProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size"> {
|
|
4
|
+
/** Bold inline label on the left of the well — the iOS grouped-form "Name | value" pattern. */
|
|
5
|
+
label?: ReactNode;
|
|
6
|
+
/** Secondary hint under the field. */
|
|
7
|
+
helper?: ReactNode;
|
|
8
|
+
/** Error message under the field; also tints the rim red and sets `aria-invalid`. */
|
|
9
|
+
error?: ReactNode;
|
|
10
|
+
/** Shows the gray ⓧ button while the field has a value. Clearing fires `onChange` (empty) and `onClear`. */
|
|
11
|
+
clearable?: boolean;
|
|
12
|
+
onClear?: () => void;
|
|
13
|
+
/** Flat gray lucide icon on the left. */
|
|
14
|
+
leadingIcon?: LucideIcon;
|
|
15
|
+
/** 44 px (default) or 50 px tall. */
|
|
16
|
+
size?: "md" | "lg";
|
|
17
|
+
/** `className` goes to the `<input>`; this one to the outer wrapper. */
|
|
18
|
+
wrapperClassName?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Sunken text input. Unlike the raised gel buttons, iOS 3 text fields were
|
|
22
|
+
* pressed *into* the surface: dark well, inset shadow, hairline black edge.
|
|
23
|
+
* Controlled (`value`) and uncontrolled (`defaultValue`) both work; the
|
|
24
|
+
* clear button clears either way and reports through `onChange`.
|
|
25
|
+
*/
|
|
26
|
+
export declare const TextField: import('react').ForwardRefExoticComponent<TextFieldProps & import('react').RefAttributes<HTMLInputElement>>;
|
|
27
|
+
export interface SearchFieldProps extends Omit<TextFieldProps, "label" | "leadingIcon" | "size"> {
|
|
28
|
+
/** Renders the small dark-gel "Cancel" button to the right of the pill. */
|
|
29
|
+
showCancel?: boolean;
|
|
30
|
+
/** Default `strings.cancel` ("Cancel"). */
|
|
31
|
+
cancelLabel?: string;
|
|
32
|
+
onCancel?: () => void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The iOS 3 search bar: a short pill well with a magnifier, a ⓧ once you type,
|
|
36
|
+
* and an optional gel "Cancel" button beside it.
|
|
37
|
+
*/
|
|
38
|
+
export declare const SearchField: import('react').ForwardRefExoticComponent<SearchFieldProps & import('react').RefAttributes<HTMLInputElement>>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ButtonHTMLAttributes, HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import { LucideIcon } from 'lucide-react';
|
|
3
|
+
export type ToolbarTint =
|
|
4
|
+
/** black glass — `UIBarStyleBlack` (default) */
|
|
5
|
+
"black"
|
|
6
|
+
/** the classic iOS 3 blue-gray bar */
|
|
7
|
+
| "blue";
|
|
8
|
+
export type ToolbarPosition =
|
|
9
|
+
/** pinned under the content: 1 px black top edge + light rim (default) */
|
|
10
|
+
"bottom"
|
|
11
|
+
/** pinned above the content: 1 px black bottom edge, like a nav bar */
|
|
12
|
+
| "top";
|
|
13
|
+
export interface ToolbarProps extends HTMLAttributes<HTMLDivElement> {
|
|
14
|
+
/** `black` glass (default) or the classic blue-gray bar. */
|
|
15
|
+
tint?: ToolbarTint;
|
|
16
|
+
/** Which edge of the screen the bar sits on — decides where the 1 px black outline goes. */
|
|
17
|
+
position?: ToolbarPosition;
|
|
18
|
+
/** `aria-label` for the toolbar. Default `strings.toolbar` ("Toolbar"). */
|
|
19
|
+
label?: string;
|
|
20
|
+
/** `<ToolbarButton>`s, `<ToolbarSpacer>`s, a `<ToolbarTitle>`, or `<BarButton>`s when an action needs a label. */
|
|
21
|
+
children: ReactNode;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The 44 px black-glass bottom bar of Safari / Mail (`UIToolbar`,
|
|
25
|
+
* `UIBarStyleBlack`): a flex row of plain glossy icon buttons, flexible
|
|
26
|
+
* spacers and an optional centred status text. Gel `<BarButton>`s drop
|
|
27
|
+
* straight in when an action needs a label ("Edit", "Done").
|
|
28
|
+
*/
|
|
29
|
+
export declare const Toolbar: import('react').ForwardRefExoticComponent<ToolbarProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
30
|
+
/** Takes up all free width; put one on each side of an item to centre it. */
|
|
31
|
+
export declare function ToolbarSpacer(): import("react").JSX.Element;
|
|
32
|
+
export interface ToolbarButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
33
|
+
/** Any `lucide-react` icon — gray glass when idle, blue glass when `active`. */
|
|
34
|
+
icon: LucideIcon;
|
|
35
|
+
/** Accessible name for the icon-only button; also shown as the native `title` tooltip. */
|
|
36
|
+
label: string;
|
|
37
|
+
/** Blue glass — the current page, a bookmarked item… Pass `aria-pressed` yourself for real toggles. */
|
|
38
|
+
active?: boolean;
|
|
39
|
+
/** Red gel badge on the icon's top-right corner (`3`, `"New"`; numbers > 99 render `99+`). */
|
|
40
|
+
badge?: number | string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The 44 × 44 tappable icon in a toolbar. There is no button chrome: the
|
|
44
|
+
* icon itself is the glass. Pressing darkens it and sinks it by 1 px.
|
|
45
|
+
*/
|
|
46
|
+
export declare const ToolbarButton: import('react').ForwardRefExoticComponent<ToolbarButtonProps & import('react').RefAttributes<HTMLButtonElement>>;
|
|
47
|
+
export interface ToolbarTitleProps extends HTMLAttributes<HTMLDivElement> {
|
|
48
|
+
/** Primary line, e.g. `"5 Unread"`. */
|
|
49
|
+
children: ReactNode;
|
|
50
|
+
/** Small second line, e.g. `"Updated 9/21/26 9:41 AM"`. */
|
|
51
|
+
subtitle?: ReactNode;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Bold 12 px gray text centred between the toolbar's items (flank it with
|
|
55
|
+
* `<ToolbarSpacer>`s). With a `subtitle` it becomes the Mail two-liner: the
|
|
56
|
+
* main line turns white, the subtitle stays small and gray. Never interactive.
|
|
57
|
+
*/
|
|
58
|
+
export declare const ToolbarTitle: import('react').ForwardRefExoticComponent<ToolbarTitleProps & import('react').RefAttributes<HTMLDivElement>>;
|