@flytedan/flytebot-design-system 0.9.1 → 0.11.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/dist/index.cjs +1504 -1501
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +141 -19
- package/dist/index.d.ts +141 -19
- package/dist/index.js +1492 -1489
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/styles/components.css +165 -16
- package/styles/tokens.css +20 -0
package/dist/index.d.cts
CHANGED
|
@@ -29,24 +29,41 @@ interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>
|
|
|
29
29
|
/** Accessible name, also the title tooltip. Required. */
|
|
30
30
|
label: string;
|
|
31
31
|
size?: "sm" | "md" | "lg";
|
|
32
|
-
|
|
32
|
+
/** "ghost" and "outline" are quiet: no fill, the glyph carries the tone. "solid" is a
|
|
33
|
+
* filled button in the tone's colour — for the one action on a surface that has to be
|
|
34
|
+
* found at a glance, like the add/remove button on every row of a transfer list. */
|
|
35
|
+
variant?: "ghost" | "outline" | "solid";
|
|
36
|
+
/** What the action does. On "solid" it picks the fill; on "ghost"/"outline" it tints the
|
|
37
|
+
* glyph. "neutral" is the default look of each variant, which for "solid" is the brand
|
|
38
|
+
* fill. Every tone has hover, pressed and focus states and is legible in both themes —
|
|
39
|
+
* the fills are the --btn-solid-* tokens, measured against light and dark grounds. */
|
|
40
|
+
tone?: "neutral" | "ok" | "danger";
|
|
33
41
|
round?: boolean;
|
|
34
42
|
disabled?: boolean;
|
|
35
43
|
className?: string;
|
|
36
44
|
}
|
|
37
|
-
declare function IconButton({ icon, label, size, variant, round, disabled, className, ...rest }: IconButtonProps): React.JSX.Element;
|
|
45
|
+
declare function IconButton({ icon, label, size, variant, tone, round, disabled, className, ...rest }: IconButtonProps): React.JSX.Element;
|
|
38
46
|
|
|
39
47
|
type Placement = "bottom-start" | "bottom-end" | "bottom-center" | "top-start" | "top-end" | "top-center";
|
|
40
48
|
interface PopoverProps {
|
|
41
49
|
open?: boolean;
|
|
42
50
|
anchorRef: React.RefObject<HTMLElement>;
|
|
51
|
+
/** The element whose own clicks open and close this popover, when that is more than
|
|
52
|
+
* the anchor — a form field's label toggles it too, but the surface is positioned
|
|
53
|
+
* against the input box alone. A pointerdown inside it is not an "outside" press, so
|
|
54
|
+
* the toggle it is about to run is not undone by a dismissal a moment earlier.
|
|
55
|
+
* Defaults to `anchorRef`. */
|
|
56
|
+
triggerRef?: React.RefObject<HTMLElement>;
|
|
43
57
|
onClose?: () => void;
|
|
44
58
|
placement?: Placement;
|
|
45
59
|
offset?: number;
|
|
46
|
-
|
|
60
|
+
/** `true`: exactly the anchor's width. `"min"`: at least the anchor's width, growing
|
|
61
|
+
* with content past it (a select whose options are wider than its box). */
|
|
62
|
+
matchWidth?: boolean | "min";
|
|
47
63
|
width?: number;
|
|
48
64
|
minWidth?: number;
|
|
49
65
|
maxHeight?: number;
|
|
66
|
+
/** Standard content padding on the body. The header and footer own their own. */
|
|
50
67
|
padded?: boolean;
|
|
51
68
|
role?: string;
|
|
52
69
|
label?: string;
|
|
@@ -55,6 +72,13 @@ interface PopoverProps {
|
|
|
55
72
|
returnFocus?: boolean;
|
|
56
73
|
className?: string;
|
|
57
74
|
style?: React.CSSProperties;
|
|
75
|
+
/** Pinned above the body and never scrolled away: a back link, a title, a segmented
|
|
76
|
+
* toggle, a search field. */
|
|
77
|
+
header?: React.ReactNode;
|
|
78
|
+
/** Pinned below the body and never scrolled away: the Add / Apply / Confirm action and
|
|
79
|
+
* any summary beside it. */
|
|
80
|
+
footer?: React.ReactNode;
|
|
81
|
+
/** The body — the one region of the surface that scrolls. */
|
|
58
82
|
children?: React.ReactNode;
|
|
59
83
|
}
|
|
60
84
|
interface PopoverPosition {
|
|
@@ -82,6 +106,14 @@ interface PopoverPosition {
|
|
|
82
106
|
* only set when the geometry actually changed (see samePosition), so a stationary anchor
|
|
83
107
|
* causes no re-renders at all.
|
|
84
108
|
*
|
|
109
|
+
* The side is chosen from the layer's real size once `layerRef` has rendered (see
|
|
110
|
+
* measureLayer): it flips when what it needs does not fit on the preferred side and the
|
|
111
|
+
* other side has more room. Until then — the first frame, before there is anything to
|
|
112
|
+
* measure — `estHeight` stands in, and only a nearly-exhausted side (under 180px) flips,
|
|
113
|
+
* so a small layer of unknown size is not thrown to the far side on a guess. The real
|
|
114
|
+
* width replaces `estWidth` the same way, which is what keeps an end- or center-aligned
|
|
115
|
+
* layer of content width lined up with its anchor.
|
|
116
|
+
*
|
|
85
117
|
* The same loop is what notices the anchor being REMOVED — a virtualized row scrolled
|
|
86
118
|
* out of the mounted band, a menu item deleted — and reports it through `onDetach`, so
|
|
87
119
|
* an anchored layer can never end up pinned to an element that no longer exists.
|
|
@@ -90,12 +122,29 @@ declare function usePopoverPosition(open: boolean, anchorRef: React.RefObject<HT
|
|
|
90
122
|
estHeight?: number;
|
|
91
123
|
estWidth?: number;
|
|
92
124
|
onDetach?: () => void;
|
|
125
|
+
/** The rendered layer, so its real size replaces the estimates once it exists. */
|
|
126
|
+
layerRef?: React.RefObject<HTMLElement>;
|
|
93
127
|
}): PopoverPosition | null;
|
|
94
128
|
/**
|
|
95
129
|
* An anchored floating surface: menus, pickers, disclosure panels, meters.
|
|
96
|
-
* Owns
|
|
97
|
-
|
|
98
|
-
|
|
130
|
+
* Owns placement, dismissal, focus return — and its own layout, which is the one rule
|
|
131
|
+
* every popover shares: THE SURFACE NEVER SCROLLS.
|
|
132
|
+
*
|
|
133
|
+
* It is always three stacked regions: an optional `header`, the body (`children`), and
|
|
134
|
+
* an optional `footer`. Header and footer are pinned; the body is the only thing that
|
|
135
|
+
* scrolls, and it shrinks to whatever height is left once they are laid out. The surface
|
|
136
|
+
* is capped by the real room between the anchor and the viewport edge (or `maxHeight`, if
|
|
137
|
+
* that is smaller) and flips to the other side when it doesn't fit, so the footer is
|
|
138
|
+
* never the thing that gets cut off.
|
|
139
|
+
*
|
|
140
|
+
* This is structural rather than advice because the failure it prevents is structural:
|
|
141
|
+
* a surface that scrolls as a whole takes its Apply button below the fold with it, and a
|
|
142
|
+
* scrolling list inside a scrolling surface is two nested scrollbars. Anything inside
|
|
143
|
+
* the body that owns a scroll region of its own (a Menu, a Select's options) is laid out
|
|
144
|
+
* to shrink into the body rather than overflow it — see `.fd-pop-body` in
|
|
145
|
+
* components.css — so there is only ever one scrollbar.
|
|
146
|
+
*/
|
|
147
|
+
declare function Popover({ open, anchorRef, triggerRef, onClose, placement, offset, matchWidth, width, minWidth, maxHeight, padded, role, label, closeOnOutside, closeOnEscape, returnFocus, className, style, header, footer, children, }: PopoverProps): React.ReactElement<any, string | React.JSXElementConstructor<any>> | null;
|
|
99
148
|
interface MenuItem {
|
|
100
149
|
id?: string;
|
|
101
150
|
label?: React.ReactNode;
|
|
@@ -134,6 +183,10 @@ interface MenuProps {
|
|
|
134
183
|
* {id,label,icon,description,meta,shortcut,checked,disabled,submenu,onSelect}
|
|
135
184
|
* {kind:"separator"} · {kind:"section",label} · {kind:"custom",render}
|
|
136
185
|
* `shortcut` is a HINT — it renders a cap and binds nothing.
|
|
186
|
+
*
|
|
187
|
+
* `header` and `footer` are pinned and only the items scroll: the whole menu is one
|
|
188
|
+
* shrinkable frame, so inside a Popover body a search header stays put while a long list
|
|
189
|
+
* scrolls beneath it, instead of the header scrolling away with the items.
|
|
137
190
|
*/
|
|
138
191
|
declare function Menu({ items, onSelect, onClose, autoFocus, className, footer, header }: MenuProps): React.JSX.Element;
|
|
139
192
|
interface MenuButtonProps extends Omit<MenuProps, "onClose" | "autoFocus"> {
|
|
@@ -165,6 +218,15 @@ interface SegmentedControlProps {
|
|
|
165
218
|
}>;
|
|
166
219
|
value?: string;
|
|
167
220
|
onChange?: (value: string) => void;
|
|
221
|
+
/** Names the group. Each button already names itself from its own text, so the
|
|
222
|
+
* buttons were never the gap — the GROUP was: two segmented controls in one
|
|
223
|
+
* toolbar both announce as an unnamed group of buttons. There is no visible
|
|
224
|
+
* `label` prop because this control is used inline next to the thing it
|
|
225
|
+
* switches (a density toggle beside a table, a range toggle beside a chart),
|
|
226
|
+
* where a stacked field label would be wrong; aria-label is what names it.
|
|
227
|
+
* The rest spread below already forwarded this to the DOM — what was missing
|
|
228
|
+
* was any typed way for a caller to pass it. */
|
|
229
|
+
"aria-label"?: string;
|
|
168
230
|
className?: string;
|
|
169
231
|
}
|
|
170
232
|
declare function SegmentedControl({ options, value, onChange, className, ...rest }: SegmentedControlProps): React.JSX.Element;
|
|
@@ -486,13 +548,33 @@ interface ToastProps {
|
|
|
486
548
|
}
|
|
487
549
|
declare function Toast({ title, children, tone, onUndo, onDismiss, className, ...rest }: ToastProps): React.JSX.Element;
|
|
488
550
|
|
|
489
|
-
/** A short clarification on hover or
|
|
551
|
+
/** A short clarification on hover, focus or tap. Never the only place information lives. */
|
|
490
552
|
interface TooltipProps {
|
|
491
553
|
label: React.ReactNode;
|
|
492
554
|
placement?: "top" | "bottom";
|
|
493
555
|
children?: React.ReactNode;
|
|
494
556
|
className?: string;
|
|
495
557
|
}
|
|
558
|
+
/**
|
|
559
|
+
* Tooltip — the kit's one tooltip, for any trigger.
|
|
560
|
+
*
|
|
561
|
+
* Three ways in, because a tooltip reachable only by a mouse hides its text from
|
|
562
|
+
* everyone else: hover (mouse only), keyboard focus (`:focus-visible`, so a mouse click
|
|
563
|
+
* that happens to focus a button does not pin a tip open) and tap (touch or pen — there is
|
|
564
|
+
* no hover on a touchscreen, so a tap toggles it). Escape and a press anywhere else
|
|
565
|
+
* dismiss it; the pointer can move from the trigger onto the tip without it closing.
|
|
566
|
+
*
|
|
567
|
+
* The text is the trigger's accessible DESCRIPTION, not just a visual: a visually hidden
|
|
568
|
+
* copy is always in the document and the trigger points at it with aria-describedby, so a
|
|
569
|
+
* screen reader announces it on focus whether or not the bubble is showing at that
|
|
570
|
+
* instant. The trigger is the single child element when there is one (it receives the
|
|
571
|
+
* attribute); otherwise the wrapper does.
|
|
572
|
+
*
|
|
573
|
+
* The bubble is portaled to document.body and positioned with the same anchored-layer
|
|
574
|
+
* geometry as Popover (flip, clamp, follow a moving anchor), because a tooltip drawn
|
|
575
|
+
* inside its trigger's box is clipped by the first `overflow: hidden` ancestor — which in
|
|
576
|
+
* a fixed-width table cell or a list row is all of them.
|
|
577
|
+
*/
|
|
496
578
|
declare function Tooltip({ label, placement, children, className }: TooltipProps): React.JSX.Element;
|
|
497
579
|
|
|
498
580
|
interface ClampProps {
|
|
@@ -1221,8 +1303,11 @@ interface EntityRowAction {
|
|
|
1221
1303
|
/** Accessible name for the action button. */
|
|
1222
1304
|
label: string;
|
|
1223
1305
|
onClick: () => void;
|
|
1224
|
-
/**
|
|
1225
|
-
* (danger
|
|
1306
|
+
/** Picks the fill — "add" is the constructive (ok) fill, "remove" the destructive
|
|
1307
|
+
* (danger) fill, and no tone the brand fill. The button is always a filled
|
|
1308
|
+
* IconButton (variant "solid"): it is the one action on the row, repeated down a long
|
|
1309
|
+
* list, and has to be findable at a glance on a default card and on a danger-toned one
|
|
1310
|
+
* alike. No effect on layout, so a caller can still pass any icon. */
|
|
1226
1311
|
tone?: "add" | "remove";
|
|
1227
1312
|
}
|
|
1228
1313
|
/** Width in px a metric cell takes when it doesn't ask for its own. Wide enough for a
|
|
@@ -1234,9 +1319,17 @@ interface EntityRowMetric {
|
|
|
1234
1319
|
* columns legitimately share a label. */
|
|
1235
1320
|
id?: string;
|
|
1236
1321
|
/** What the number means — "students", "ad units". Never rendered as running text:
|
|
1237
|
-
* it is the metric's accessible name
|
|
1238
|
-
*
|
|
1322
|
+
* it is the metric's accessible name, so the row stays scannable as numbers while a
|
|
1323
|
+
* screen reader still hears "1,240 students". Without a `tooltip` it is also the
|
|
1324
|
+
* cell's native hover title. */
|
|
1239
1325
|
label: string;
|
|
1326
|
+
/** The long-form explanation of this figure — what it counts, why it is zero, what an
|
|
1327
|
+
* "unknown" means. Shown in the kit's Tooltip on hover, keyboard focus and tap, and
|
|
1328
|
+
* exposed as the cell's accessible description (`label` stays its short name). A cell
|
|
1329
|
+
* with a tooltip becomes a focusable button so the explanation is reachable without a
|
|
1330
|
+
* mouse, and drops the native `title` so two tooltips never show at once. A button is
|
|
1331
|
+
* also what keeps a tap on it from arming TransferList's row drag. */
|
|
1332
|
+
tooltip?: React.ReactNode;
|
|
1240
1333
|
value: React.ReactNode;
|
|
1241
1334
|
/** Phosphor icon name shown before the value, e.g. "student". */
|
|
1242
1335
|
icon?: string;
|
|
@@ -1507,6 +1600,11 @@ interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "
|
|
|
1507
1600
|
loading?: boolean;
|
|
1508
1601
|
/** Applied to the outer .fd-field element — this is where width belongs. */
|
|
1509
1602
|
style?: React.CSSProperties;
|
|
1603
|
+
/** Applied to the outer .fd-field element, like `style` and for the same reason: that
|
|
1604
|
+
* element is the field's box in whatever layout it sits in (a flex toolbar, a grid
|
|
1605
|
+
* cell). The input box inside it is a child of a vertical flex column, so a sizing
|
|
1606
|
+
* class landing THERE turns a row's `flex-basis` into a height. */
|
|
1607
|
+
className?: string;
|
|
1510
1608
|
/** Applied to the inner input element. Rarely needed. */
|
|
1511
1609
|
inputStyle?: React.CSSProperties;
|
|
1512
1610
|
}
|
|
@@ -1523,6 +1621,7 @@ interface SearchFieldProps {
|
|
|
1523
1621
|
onClear?: () => void;
|
|
1524
1622
|
/** Applied to the outer .fd-field element — this is where width belongs. */
|
|
1525
1623
|
style?: React.CSSProperties;
|
|
1624
|
+
/** Applied to the outer .fd-field element, like `style`. */
|
|
1526
1625
|
className?: string;
|
|
1527
1626
|
/** Visible field label, same as Input. Most search fields skip this and rely on placeholder. */
|
|
1528
1627
|
label?: string;
|
|
@@ -1554,8 +1653,10 @@ interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement
|
|
|
1554
1653
|
error?: string;
|
|
1555
1654
|
required?: boolean;
|
|
1556
1655
|
rows?: number;
|
|
1557
|
-
/** Applied to the field
|
|
1656
|
+
/** Applied to the outer .fd-field element — this is where width belongs. */
|
|
1558
1657
|
style?: React.CSSProperties;
|
|
1658
|
+
/** Applied to the outer .fd-field element, like `style` — the same rule as Input. */
|
|
1659
|
+
className?: string;
|
|
1559
1660
|
}
|
|
1560
1661
|
declare function Textarea({ label, help, error, required, rows, disabled, id, className, style, ...rest }: TextareaProps): React.JSX.Element;
|
|
1561
1662
|
|
|
@@ -1564,6 +1665,14 @@ interface NumberInputProps {
|
|
|
1564
1665
|
label?: string;
|
|
1565
1666
|
help?: string;
|
|
1566
1667
|
error?: string;
|
|
1668
|
+
/** Element id — lands on the <input> and on the label's `for`. Generated when
|
|
1669
|
+
* omitted, so `label` is always the input's accessible name either way. */
|
|
1670
|
+
id?: string;
|
|
1671
|
+
/** Names an instance that has no visible `label` — a bare bound inside a range
|
|
1672
|
+
* row whose heading lives elsewhere. Do not set both: aria-label OUTRANKS the
|
|
1673
|
+
* associated <label>, so a field carrying both is announced as something other
|
|
1674
|
+
* than what it visibly says. */
|
|
1675
|
+
"aria-label"?: string;
|
|
1567
1676
|
prefix?: string;
|
|
1568
1677
|
suffix?: string;
|
|
1569
1678
|
required?: boolean;
|
|
@@ -1582,7 +1691,7 @@ interface NumberInputProps {
|
|
|
1582
1691
|
style?: any;
|
|
1583
1692
|
className?: string;
|
|
1584
1693
|
}
|
|
1585
|
-
declare function NumberInput({ label, help, error, prefix, suffix, required, disabled, min, max, step, bigStep, value, onChange, format, className, style, placeholder }: NumberInputProps): React.JSX.Element;
|
|
1694
|
+
declare function NumberInput({ label, help, error, prefix, suffix, required, disabled, min, max, step, bigStep, value, onChange, format, className, style, placeholder, id, "aria-label": ariaLabel }: NumberInputProps): React.JSX.Element;
|
|
1586
1695
|
|
|
1587
1696
|
/** Rich popover select: animated listbox, keyboard nav + type-ahead, search over 8 options, option icons, descriptions, meta and groups. API-compatible with the old native select. */
|
|
1588
1697
|
interface SelectOption {
|
|
@@ -1616,14 +1725,14 @@ interface SelectProps {
|
|
|
1616
1725
|
value?: string | string[];
|
|
1617
1726
|
/** Called with {target:{value}} like a native select — an array when `multiple`. */
|
|
1618
1727
|
onChange?: (e: any) => void;
|
|
1619
|
-
name?: string;
|
|
1620
1728
|
/** Applied to the outer .fd-field element — this is where width belongs. */
|
|
1621
1729
|
style?: any;
|
|
1622
1730
|
className?: string;
|
|
1623
|
-
/** Element id —
|
|
1731
|
+
/** Element id — lands on the trigger button, with the label's own id derived
|
|
1732
|
+
* from it. Generated when omitted, so `label` names the trigger either way. */
|
|
1624
1733
|
id?: string;
|
|
1625
1734
|
}
|
|
1626
|
-
declare function Select({ label, help, error, options, placeholder, required, disabled, loading, value, onChange, searchable, clearable, multiple, summary, id, className, style
|
|
1735
|
+
declare function Select({ label, help, error, options, placeholder, required, disabled, loading, value, onChange, searchable, clearable, multiple, summary, id, className, style }: SelectProps): React.JSX.Element;
|
|
1627
1736
|
|
|
1628
1737
|
/** Calendar popover date field. Click the title to drill month -> year; range mode picks start then end with live hover preview. Values are ISO strings ("2026-03-01"). */
|
|
1629
1738
|
interface DatePickerProps {
|
|
@@ -1638,6 +1747,9 @@ interface DatePickerProps {
|
|
|
1638
1747
|
/** Called with {target:{value}} — string, or {start,end} in range mode. */
|
|
1639
1748
|
onChange?: (e: any) => void;
|
|
1640
1749
|
placeholder?: string;
|
|
1750
|
+
/** Element id — lands on the trigger button, with the label's own id derived
|
|
1751
|
+
* from it. Generated when omitted, so `label` names the trigger either way. */
|
|
1752
|
+
id?: string;
|
|
1641
1753
|
style?: any;
|
|
1642
1754
|
className?: string;
|
|
1643
1755
|
}
|
|
@@ -1650,7 +1762,7 @@ interface CalendarProps {
|
|
|
1650
1762
|
months?: number;
|
|
1651
1763
|
}
|
|
1652
1764
|
declare function Calendar({ value, range, onPick, initialMonth, months }: CalendarProps): React.JSX.Element;
|
|
1653
|
-
declare function DatePicker({ label, help, error, required, disabled, range, value, onChange, placeholder, className, style, ...rest }: DatePickerProps): React.JSX.Element;
|
|
1765
|
+
declare function DatePicker({ label, help, error, required, disabled, range, value, onChange, placeholder, id, className, style, ...rest }: DatePickerProps): React.JSX.Element;
|
|
1654
1766
|
|
|
1655
1767
|
/** Analog clock-face time field: tap or drag the hand to set the hour, auto-advances to minutes; AM/PM chips; "Now" shortcut. Value is 24h "HH:MM". */
|
|
1656
1768
|
interface TimePickerProps {
|
|
@@ -1664,6 +1776,9 @@ interface TimePickerProps {
|
|
|
1664
1776
|
/** Called with {target:{value}}. */
|
|
1665
1777
|
onChange?: (e: any) => void;
|
|
1666
1778
|
placeholder?: string;
|
|
1779
|
+
/** Element id — lands on the trigger button, with the label's own id derived
|
|
1780
|
+
* from it. Generated when omitted, so `label` names the trigger either way. */
|
|
1781
|
+
id?: string;
|
|
1667
1782
|
style?: any;
|
|
1668
1783
|
className?: string;
|
|
1669
1784
|
}
|
|
@@ -1673,7 +1788,7 @@ interface ClockFaceProps {
|
|
|
1673
1788
|
onChange: (v: string) => void;
|
|
1674
1789
|
}
|
|
1675
1790
|
declare function ClockFace({ value, onChange }: ClockFaceProps): React.JSX.Element;
|
|
1676
|
-
declare function TimePicker({ label, help, error, required, disabled, value, onChange, placeholder, className, style }: TimePickerProps): React.JSX.Element;
|
|
1791
|
+
declare function TimePicker({ label, help, error, required, disabled, value, onChange, placeholder, id, className, style }: TimePickerProps): React.JSX.Element;
|
|
1677
1792
|
|
|
1678
1793
|
/**
|
|
1679
1794
|
* Continuous value control. In the media planner this is the reallocation slider:
|
|
@@ -1690,9 +1805,16 @@ interface SliderProps {
|
|
|
1690
1805
|
format?: (value: number) => string;
|
|
1691
1806
|
showChip?: boolean;
|
|
1692
1807
|
help?: string;
|
|
1808
|
+
/** Element id — lands on the range input and on the label's `for`. Generated
|
|
1809
|
+
* when omitted, so `label` is always the slider's accessible name. */
|
|
1810
|
+
id?: string;
|
|
1811
|
+
/** Names an instance that has no visible `label`. Do not set both: aria-label
|
|
1812
|
+
* OUTRANKS the associated <label>, so a slider carrying both is announced as
|
|
1813
|
+
* something other than what it visibly says. */
|
|
1814
|
+
"aria-label"?: string;
|
|
1693
1815
|
className?: string;
|
|
1694
1816
|
}
|
|
1695
|
-
declare function Slider({ label, min, max, step, value, onChange, format, showChip, help, className, ...rest }: SliderProps): React.JSX.Element;
|
|
1817
|
+
declare function Slider({ label, min, max, step, value, onChange, format, showChip, help, id, "aria-label": ariaLabel, className, ...rest }: SliderProps): React.JSX.Element;
|
|
1696
1818
|
|
|
1697
1819
|
/** Dual-thumb range slider: drag either thumb or the rail, value bubbles while dragging or focused, tick marks with labels, optional magnetic snap, keyboard (arrows, shift for 10%, Home/End). */
|
|
1698
1820
|
interface RangeSliderProps {
|
package/dist/index.d.ts
CHANGED
|
@@ -29,24 +29,41 @@ interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>
|
|
|
29
29
|
/** Accessible name, also the title tooltip. Required. */
|
|
30
30
|
label: string;
|
|
31
31
|
size?: "sm" | "md" | "lg";
|
|
32
|
-
|
|
32
|
+
/** "ghost" and "outline" are quiet: no fill, the glyph carries the tone. "solid" is a
|
|
33
|
+
* filled button in the tone's colour — for the one action on a surface that has to be
|
|
34
|
+
* found at a glance, like the add/remove button on every row of a transfer list. */
|
|
35
|
+
variant?: "ghost" | "outline" | "solid";
|
|
36
|
+
/** What the action does. On "solid" it picks the fill; on "ghost"/"outline" it tints the
|
|
37
|
+
* glyph. "neutral" is the default look of each variant, which for "solid" is the brand
|
|
38
|
+
* fill. Every tone has hover, pressed and focus states and is legible in both themes —
|
|
39
|
+
* the fills are the --btn-solid-* tokens, measured against light and dark grounds. */
|
|
40
|
+
tone?: "neutral" | "ok" | "danger";
|
|
33
41
|
round?: boolean;
|
|
34
42
|
disabled?: boolean;
|
|
35
43
|
className?: string;
|
|
36
44
|
}
|
|
37
|
-
declare function IconButton({ icon, label, size, variant, round, disabled, className, ...rest }: IconButtonProps): React.JSX.Element;
|
|
45
|
+
declare function IconButton({ icon, label, size, variant, tone, round, disabled, className, ...rest }: IconButtonProps): React.JSX.Element;
|
|
38
46
|
|
|
39
47
|
type Placement = "bottom-start" | "bottom-end" | "bottom-center" | "top-start" | "top-end" | "top-center";
|
|
40
48
|
interface PopoverProps {
|
|
41
49
|
open?: boolean;
|
|
42
50
|
anchorRef: React.RefObject<HTMLElement>;
|
|
51
|
+
/** The element whose own clicks open and close this popover, when that is more than
|
|
52
|
+
* the anchor — a form field's label toggles it too, but the surface is positioned
|
|
53
|
+
* against the input box alone. A pointerdown inside it is not an "outside" press, so
|
|
54
|
+
* the toggle it is about to run is not undone by a dismissal a moment earlier.
|
|
55
|
+
* Defaults to `anchorRef`. */
|
|
56
|
+
triggerRef?: React.RefObject<HTMLElement>;
|
|
43
57
|
onClose?: () => void;
|
|
44
58
|
placement?: Placement;
|
|
45
59
|
offset?: number;
|
|
46
|
-
|
|
60
|
+
/** `true`: exactly the anchor's width. `"min"`: at least the anchor's width, growing
|
|
61
|
+
* with content past it (a select whose options are wider than its box). */
|
|
62
|
+
matchWidth?: boolean | "min";
|
|
47
63
|
width?: number;
|
|
48
64
|
minWidth?: number;
|
|
49
65
|
maxHeight?: number;
|
|
66
|
+
/** Standard content padding on the body. The header and footer own their own. */
|
|
50
67
|
padded?: boolean;
|
|
51
68
|
role?: string;
|
|
52
69
|
label?: string;
|
|
@@ -55,6 +72,13 @@ interface PopoverProps {
|
|
|
55
72
|
returnFocus?: boolean;
|
|
56
73
|
className?: string;
|
|
57
74
|
style?: React.CSSProperties;
|
|
75
|
+
/** Pinned above the body and never scrolled away: a back link, a title, a segmented
|
|
76
|
+
* toggle, a search field. */
|
|
77
|
+
header?: React.ReactNode;
|
|
78
|
+
/** Pinned below the body and never scrolled away: the Add / Apply / Confirm action and
|
|
79
|
+
* any summary beside it. */
|
|
80
|
+
footer?: React.ReactNode;
|
|
81
|
+
/** The body — the one region of the surface that scrolls. */
|
|
58
82
|
children?: React.ReactNode;
|
|
59
83
|
}
|
|
60
84
|
interface PopoverPosition {
|
|
@@ -82,6 +106,14 @@ interface PopoverPosition {
|
|
|
82
106
|
* only set when the geometry actually changed (see samePosition), so a stationary anchor
|
|
83
107
|
* causes no re-renders at all.
|
|
84
108
|
*
|
|
109
|
+
* The side is chosen from the layer's real size once `layerRef` has rendered (see
|
|
110
|
+
* measureLayer): it flips when what it needs does not fit on the preferred side and the
|
|
111
|
+
* other side has more room. Until then — the first frame, before there is anything to
|
|
112
|
+
* measure — `estHeight` stands in, and only a nearly-exhausted side (under 180px) flips,
|
|
113
|
+
* so a small layer of unknown size is not thrown to the far side on a guess. The real
|
|
114
|
+
* width replaces `estWidth` the same way, which is what keeps an end- or center-aligned
|
|
115
|
+
* layer of content width lined up with its anchor.
|
|
116
|
+
*
|
|
85
117
|
* The same loop is what notices the anchor being REMOVED — a virtualized row scrolled
|
|
86
118
|
* out of the mounted band, a menu item deleted — and reports it through `onDetach`, so
|
|
87
119
|
* an anchored layer can never end up pinned to an element that no longer exists.
|
|
@@ -90,12 +122,29 @@ declare function usePopoverPosition(open: boolean, anchorRef: React.RefObject<HT
|
|
|
90
122
|
estHeight?: number;
|
|
91
123
|
estWidth?: number;
|
|
92
124
|
onDetach?: () => void;
|
|
125
|
+
/** The rendered layer, so its real size replaces the estimates once it exists. */
|
|
126
|
+
layerRef?: React.RefObject<HTMLElement>;
|
|
93
127
|
}): PopoverPosition | null;
|
|
94
128
|
/**
|
|
95
129
|
* An anchored floating surface: menus, pickers, disclosure panels, meters.
|
|
96
|
-
* Owns
|
|
97
|
-
|
|
98
|
-
|
|
130
|
+
* Owns placement, dismissal, focus return — and its own layout, which is the one rule
|
|
131
|
+
* every popover shares: THE SURFACE NEVER SCROLLS.
|
|
132
|
+
*
|
|
133
|
+
* It is always three stacked regions: an optional `header`, the body (`children`), and
|
|
134
|
+
* an optional `footer`. Header and footer are pinned; the body is the only thing that
|
|
135
|
+
* scrolls, and it shrinks to whatever height is left once they are laid out. The surface
|
|
136
|
+
* is capped by the real room between the anchor and the viewport edge (or `maxHeight`, if
|
|
137
|
+
* that is smaller) and flips to the other side when it doesn't fit, so the footer is
|
|
138
|
+
* never the thing that gets cut off.
|
|
139
|
+
*
|
|
140
|
+
* This is structural rather than advice because the failure it prevents is structural:
|
|
141
|
+
* a surface that scrolls as a whole takes its Apply button below the fold with it, and a
|
|
142
|
+
* scrolling list inside a scrolling surface is two nested scrollbars. Anything inside
|
|
143
|
+
* the body that owns a scroll region of its own (a Menu, a Select's options) is laid out
|
|
144
|
+
* to shrink into the body rather than overflow it — see `.fd-pop-body` in
|
|
145
|
+
* components.css — so there is only ever one scrollbar.
|
|
146
|
+
*/
|
|
147
|
+
declare function Popover({ open, anchorRef, triggerRef, onClose, placement, offset, matchWidth, width, minWidth, maxHeight, padded, role, label, closeOnOutside, closeOnEscape, returnFocus, className, style, header, footer, children, }: PopoverProps): React.ReactElement<any, string | React.JSXElementConstructor<any>> | null;
|
|
99
148
|
interface MenuItem {
|
|
100
149
|
id?: string;
|
|
101
150
|
label?: React.ReactNode;
|
|
@@ -134,6 +183,10 @@ interface MenuProps {
|
|
|
134
183
|
* {id,label,icon,description,meta,shortcut,checked,disabled,submenu,onSelect}
|
|
135
184
|
* {kind:"separator"} · {kind:"section",label} · {kind:"custom",render}
|
|
136
185
|
* `shortcut` is a HINT — it renders a cap and binds nothing.
|
|
186
|
+
*
|
|
187
|
+
* `header` and `footer` are pinned and only the items scroll: the whole menu is one
|
|
188
|
+
* shrinkable frame, so inside a Popover body a search header stays put while a long list
|
|
189
|
+
* scrolls beneath it, instead of the header scrolling away with the items.
|
|
137
190
|
*/
|
|
138
191
|
declare function Menu({ items, onSelect, onClose, autoFocus, className, footer, header }: MenuProps): React.JSX.Element;
|
|
139
192
|
interface MenuButtonProps extends Omit<MenuProps, "onClose" | "autoFocus"> {
|
|
@@ -165,6 +218,15 @@ interface SegmentedControlProps {
|
|
|
165
218
|
}>;
|
|
166
219
|
value?: string;
|
|
167
220
|
onChange?: (value: string) => void;
|
|
221
|
+
/** Names the group. Each button already names itself from its own text, so the
|
|
222
|
+
* buttons were never the gap — the GROUP was: two segmented controls in one
|
|
223
|
+
* toolbar both announce as an unnamed group of buttons. There is no visible
|
|
224
|
+
* `label` prop because this control is used inline next to the thing it
|
|
225
|
+
* switches (a density toggle beside a table, a range toggle beside a chart),
|
|
226
|
+
* where a stacked field label would be wrong; aria-label is what names it.
|
|
227
|
+
* The rest spread below already forwarded this to the DOM — what was missing
|
|
228
|
+
* was any typed way for a caller to pass it. */
|
|
229
|
+
"aria-label"?: string;
|
|
168
230
|
className?: string;
|
|
169
231
|
}
|
|
170
232
|
declare function SegmentedControl({ options, value, onChange, className, ...rest }: SegmentedControlProps): React.JSX.Element;
|
|
@@ -486,13 +548,33 @@ interface ToastProps {
|
|
|
486
548
|
}
|
|
487
549
|
declare function Toast({ title, children, tone, onUndo, onDismiss, className, ...rest }: ToastProps): React.JSX.Element;
|
|
488
550
|
|
|
489
|
-
/** A short clarification on hover or
|
|
551
|
+
/** A short clarification on hover, focus or tap. Never the only place information lives. */
|
|
490
552
|
interface TooltipProps {
|
|
491
553
|
label: React.ReactNode;
|
|
492
554
|
placement?: "top" | "bottom";
|
|
493
555
|
children?: React.ReactNode;
|
|
494
556
|
className?: string;
|
|
495
557
|
}
|
|
558
|
+
/**
|
|
559
|
+
* Tooltip — the kit's one tooltip, for any trigger.
|
|
560
|
+
*
|
|
561
|
+
* Three ways in, because a tooltip reachable only by a mouse hides its text from
|
|
562
|
+
* everyone else: hover (mouse only), keyboard focus (`:focus-visible`, so a mouse click
|
|
563
|
+
* that happens to focus a button does not pin a tip open) and tap (touch or pen — there is
|
|
564
|
+
* no hover on a touchscreen, so a tap toggles it). Escape and a press anywhere else
|
|
565
|
+
* dismiss it; the pointer can move from the trigger onto the tip without it closing.
|
|
566
|
+
*
|
|
567
|
+
* The text is the trigger's accessible DESCRIPTION, not just a visual: a visually hidden
|
|
568
|
+
* copy is always in the document and the trigger points at it with aria-describedby, so a
|
|
569
|
+
* screen reader announces it on focus whether or not the bubble is showing at that
|
|
570
|
+
* instant. The trigger is the single child element when there is one (it receives the
|
|
571
|
+
* attribute); otherwise the wrapper does.
|
|
572
|
+
*
|
|
573
|
+
* The bubble is portaled to document.body and positioned with the same anchored-layer
|
|
574
|
+
* geometry as Popover (flip, clamp, follow a moving anchor), because a tooltip drawn
|
|
575
|
+
* inside its trigger's box is clipped by the first `overflow: hidden` ancestor — which in
|
|
576
|
+
* a fixed-width table cell or a list row is all of them.
|
|
577
|
+
*/
|
|
496
578
|
declare function Tooltip({ label, placement, children, className }: TooltipProps): React.JSX.Element;
|
|
497
579
|
|
|
498
580
|
interface ClampProps {
|
|
@@ -1221,8 +1303,11 @@ interface EntityRowAction {
|
|
|
1221
1303
|
/** Accessible name for the action button. */
|
|
1222
1304
|
label: string;
|
|
1223
1305
|
onClick: () => void;
|
|
1224
|
-
/**
|
|
1225
|
-
* (danger
|
|
1306
|
+
/** Picks the fill — "add" is the constructive (ok) fill, "remove" the destructive
|
|
1307
|
+
* (danger) fill, and no tone the brand fill. The button is always a filled
|
|
1308
|
+
* IconButton (variant "solid"): it is the one action on the row, repeated down a long
|
|
1309
|
+
* list, and has to be findable at a glance on a default card and on a danger-toned one
|
|
1310
|
+
* alike. No effect on layout, so a caller can still pass any icon. */
|
|
1226
1311
|
tone?: "add" | "remove";
|
|
1227
1312
|
}
|
|
1228
1313
|
/** Width in px a metric cell takes when it doesn't ask for its own. Wide enough for a
|
|
@@ -1234,9 +1319,17 @@ interface EntityRowMetric {
|
|
|
1234
1319
|
* columns legitimately share a label. */
|
|
1235
1320
|
id?: string;
|
|
1236
1321
|
/** What the number means — "students", "ad units". Never rendered as running text:
|
|
1237
|
-
* it is the metric's accessible name
|
|
1238
|
-
*
|
|
1322
|
+
* it is the metric's accessible name, so the row stays scannable as numbers while a
|
|
1323
|
+
* screen reader still hears "1,240 students". Without a `tooltip` it is also the
|
|
1324
|
+
* cell's native hover title. */
|
|
1239
1325
|
label: string;
|
|
1326
|
+
/** The long-form explanation of this figure — what it counts, why it is zero, what an
|
|
1327
|
+
* "unknown" means. Shown in the kit's Tooltip on hover, keyboard focus and tap, and
|
|
1328
|
+
* exposed as the cell's accessible description (`label` stays its short name). A cell
|
|
1329
|
+
* with a tooltip becomes a focusable button so the explanation is reachable without a
|
|
1330
|
+
* mouse, and drops the native `title` so two tooltips never show at once. A button is
|
|
1331
|
+
* also what keeps a tap on it from arming TransferList's row drag. */
|
|
1332
|
+
tooltip?: React.ReactNode;
|
|
1240
1333
|
value: React.ReactNode;
|
|
1241
1334
|
/** Phosphor icon name shown before the value, e.g. "student". */
|
|
1242
1335
|
icon?: string;
|
|
@@ -1507,6 +1600,11 @@ interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "
|
|
|
1507
1600
|
loading?: boolean;
|
|
1508
1601
|
/** Applied to the outer .fd-field element — this is where width belongs. */
|
|
1509
1602
|
style?: React.CSSProperties;
|
|
1603
|
+
/** Applied to the outer .fd-field element, like `style` and for the same reason: that
|
|
1604
|
+
* element is the field's box in whatever layout it sits in (a flex toolbar, a grid
|
|
1605
|
+
* cell). The input box inside it is a child of a vertical flex column, so a sizing
|
|
1606
|
+
* class landing THERE turns a row's `flex-basis` into a height. */
|
|
1607
|
+
className?: string;
|
|
1510
1608
|
/** Applied to the inner input element. Rarely needed. */
|
|
1511
1609
|
inputStyle?: React.CSSProperties;
|
|
1512
1610
|
}
|
|
@@ -1523,6 +1621,7 @@ interface SearchFieldProps {
|
|
|
1523
1621
|
onClear?: () => void;
|
|
1524
1622
|
/** Applied to the outer .fd-field element — this is where width belongs. */
|
|
1525
1623
|
style?: React.CSSProperties;
|
|
1624
|
+
/** Applied to the outer .fd-field element, like `style`. */
|
|
1526
1625
|
className?: string;
|
|
1527
1626
|
/** Visible field label, same as Input. Most search fields skip this and rely on placeholder. */
|
|
1528
1627
|
label?: string;
|
|
@@ -1554,8 +1653,10 @@ interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement
|
|
|
1554
1653
|
error?: string;
|
|
1555
1654
|
required?: boolean;
|
|
1556
1655
|
rows?: number;
|
|
1557
|
-
/** Applied to the field
|
|
1656
|
+
/** Applied to the outer .fd-field element — this is where width belongs. */
|
|
1558
1657
|
style?: React.CSSProperties;
|
|
1658
|
+
/** Applied to the outer .fd-field element, like `style` — the same rule as Input. */
|
|
1659
|
+
className?: string;
|
|
1559
1660
|
}
|
|
1560
1661
|
declare function Textarea({ label, help, error, required, rows, disabled, id, className, style, ...rest }: TextareaProps): React.JSX.Element;
|
|
1561
1662
|
|
|
@@ -1564,6 +1665,14 @@ interface NumberInputProps {
|
|
|
1564
1665
|
label?: string;
|
|
1565
1666
|
help?: string;
|
|
1566
1667
|
error?: string;
|
|
1668
|
+
/** Element id — lands on the <input> and on the label's `for`. Generated when
|
|
1669
|
+
* omitted, so `label` is always the input's accessible name either way. */
|
|
1670
|
+
id?: string;
|
|
1671
|
+
/** Names an instance that has no visible `label` — a bare bound inside a range
|
|
1672
|
+
* row whose heading lives elsewhere. Do not set both: aria-label OUTRANKS the
|
|
1673
|
+
* associated <label>, so a field carrying both is announced as something other
|
|
1674
|
+
* than what it visibly says. */
|
|
1675
|
+
"aria-label"?: string;
|
|
1567
1676
|
prefix?: string;
|
|
1568
1677
|
suffix?: string;
|
|
1569
1678
|
required?: boolean;
|
|
@@ -1582,7 +1691,7 @@ interface NumberInputProps {
|
|
|
1582
1691
|
style?: any;
|
|
1583
1692
|
className?: string;
|
|
1584
1693
|
}
|
|
1585
|
-
declare function NumberInput({ label, help, error, prefix, suffix, required, disabled, min, max, step, bigStep, value, onChange, format, className, style, placeholder }: NumberInputProps): React.JSX.Element;
|
|
1694
|
+
declare function NumberInput({ label, help, error, prefix, suffix, required, disabled, min, max, step, bigStep, value, onChange, format, className, style, placeholder, id, "aria-label": ariaLabel }: NumberInputProps): React.JSX.Element;
|
|
1586
1695
|
|
|
1587
1696
|
/** Rich popover select: animated listbox, keyboard nav + type-ahead, search over 8 options, option icons, descriptions, meta and groups. API-compatible with the old native select. */
|
|
1588
1697
|
interface SelectOption {
|
|
@@ -1616,14 +1725,14 @@ interface SelectProps {
|
|
|
1616
1725
|
value?: string | string[];
|
|
1617
1726
|
/** Called with {target:{value}} like a native select — an array when `multiple`. */
|
|
1618
1727
|
onChange?: (e: any) => void;
|
|
1619
|
-
name?: string;
|
|
1620
1728
|
/** Applied to the outer .fd-field element — this is where width belongs. */
|
|
1621
1729
|
style?: any;
|
|
1622
1730
|
className?: string;
|
|
1623
|
-
/** Element id —
|
|
1731
|
+
/** Element id — lands on the trigger button, with the label's own id derived
|
|
1732
|
+
* from it. Generated when omitted, so `label` names the trigger either way. */
|
|
1624
1733
|
id?: string;
|
|
1625
1734
|
}
|
|
1626
|
-
declare function Select({ label, help, error, options, placeholder, required, disabled, loading, value, onChange, searchable, clearable, multiple, summary, id, className, style
|
|
1735
|
+
declare function Select({ label, help, error, options, placeholder, required, disabled, loading, value, onChange, searchable, clearable, multiple, summary, id, className, style }: SelectProps): React.JSX.Element;
|
|
1627
1736
|
|
|
1628
1737
|
/** Calendar popover date field. Click the title to drill month -> year; range mode picks start then end with live hover preview. Values are ISO strings ("2026-03-01"). */
|
|
1629
1738
|
interface DatePickerProps {
|
|
@@ -1638,6 +1747,9 @@ interface DatePickerProps {
|
|
|
1638
1747
|
/** Called with {target:{value}} — string, or {start,end} in range mode. */
|
|
1639
1748
|
onChange?: (e: any) => void;
|
|
1640
1749
|
placeholder?: string;
|
|
1750
|
+
/** Element id — lands on the trigger button, with the label's own id derived
|
|
1751
|
+
* from it. Generated when omitted, so `label` names the trigger either way. */
|
|
1752
|
+
id?: string;
|
|
1641
1753
|
style?: any;
|
|
1642
1754
|
className?: string;
|
|
1643
1755
|
}
|
|
@@ -1650,7 +1762,7 @@ interface CalendarProps {
|
|
|
1650
1762
|
months?: number;
|
|
1651
1763
|
}
|
|
1652
1764
|
declare function Calendar({ value, range, onPick, initialMonth, months }: CalendarProps): React.JSX.Element;
|
|
1653
|
-
declare function DatePicker({ label, help, error, required, disabled, range, value, onChange, placeholder, className, style, ...rest }: DatePickerProps): React.JSX.Element;
|
|
1765
|
+
declare function DatePicker({ label, help, error, required, disabled, range, value, onChange, placeholder, id, className, style, ...rest }: DatePickerProps): React.JSX.Element;
|
|
1654
1766
|
|
|
1655
1767
|
/** Analog clock-face time field: tap or drag the hand to set the hour, auto-advances to minutes; AM/PM chips; "Now" shortcut. Value is 24h "HH:MM". */
|
|
1656
1768
|
interface TimePickerProps {
|
|
@@ -1664,6 +1776,9 @@ interface TimePickerProps {
|
|
|
1664
1776
|
/** Called with {target:{value}}. */
|
|
1665
1777
|
onChange?: (e: any) => void;
|
|
1666
1778
|
placeholder?: string;
|
|
1779
|
+
/** Element id — lands on the trigger button, with the label's own id derived
|
|
1780
|
+
* from it. Generated when omitted, so `label` names the trigger either way. */
|
|
1781
|
+
id?: string;
|
|
1667
1782
|
style?: any;
|
|
1668
1783
|
className?: string;
|
|
1669
1784
|
}
|
|
@@ -1673,7 +1788,7 @@ interface ClockFaceProps {
|
|
|
1673
1788
|
onChange: (v: string) => void;
|
|
1674
1789
|
}
|
|
1675
1790
|
declare function ClockFace({ value, onChange }: ClockFaceProps): React.JSX.Element;
|
|
1676
|
-
declare function TimePicker({ label, help, error, required, disabled, value, onChange, placeholder, className, style }: TimePickerProps): React.JSX.Element;
|
|
1791
|
+
declare function TimePicker({ label, help, error, required, disabled, value, onChange, placeholder, id, className, style }: TimePickerProps): React.JSX.Element;
|
|
1677
1792
|
|
|
1678
1793
|
/**
|
|
1679
1794
|
* Continuous value control. In the media planner this is the reallocation slider:
|
|
@@ -1690,9 +1805,16 @@ interface SliderProps {
|
|
|
1690
1805
|
format?: (value: number) => string;
|
|
1691
1806
|
showChip?: boolean;
|
|
1692
1807
|
help?: string;
|
|
1808
|
+
/** Element id — lands on the range input and on the label's `for`. Generated
|
|
1809
|
+
* when omitted, so `label` is always the slider's accessible name. */
|
|
1810
|
+
id?: string;
|
|
1811
|
+
/** Names an instance that has no visible `label`. Do not set both: aria-label
|
|
1812
|
+
* OUTRANKS the associated <label>, so a slider carrying both is announced as
|
|
1813
|
+
* something other than what it visibly says. */
|
|
1814
|
+
"aria-label"?: string;
|
|
1693
1815
|
className?: string;
|
|
1694
1816
|
}
|
|
1695
|
-
declare function Slider({ label, min, max, step, value, onChange, format, showChip, help, className, ...rest }: SliderProps): React.JSX.Element;
|
|
1817
|
+
declare function Slider({ label, min, max, step, value, onChange, format, showChip, help, id, "aria-label": ariaLabel, className, ...rest }: SliderProps): React.JSX.Element;
|
|
1696
1818
|
|
|
1697
1819
|
/** Dual-thumb range slider: drag either thumb or the rail, value bubbles while dragging or focused, tick marks with labels, optional magnetic snap, keyboard (arrows, shift for 10%, Home/End). */
|
|
1698
1820
|
interface RangeSliderProps {
|