@antadesign/anta 0.3.34 → 0.3.35
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.md +14 -1
- package/README.md +9 -0
- package/dist/anta_helpers.d.ts +46 -30
- package/dist/anta_helpers.js +66 -25
- package/dist/bundle.css +1 -1
- package/dist/bundle.js +2 -1333
- package/dist/components/Banner.d.ts +25 -40
- package/dist/components/Banner.js +15 -17
- package/dist/components/Button.js +1 -0
- package/dist/components/ButtonCopy.js +3 -2
- package/dist/components/Calendar.js +13 -13
- package/dist/components/Card.d.ts +9 -17
- package/dist/components/Card.js +50 -46
- package/dist/components/Dialog.d.ts +1 -0
- package/dist/components/Dialog.js +16 -10
- package/dist/components/Expander.d.ts +6 -21
- package/dist/components/Expander.js +24 -23
- package/dist/components/Icon.d.ts +8 -14
- package/dist/components/Input.d.ts +77 -96
- package/dist/components/Input.js +23 -27
- package/dist/components/InputAutocomplete.d.ts +29 -10
- package/dist/components/InputAutocomplete.js +25 -8
- package/dist/components/InputDate.js +2 -2
- package/dist/components/InputTime.d.ts +10 -4
- package/dist/components/InputTime.js +20 -16
- package/dist/components/Loader.d.ts +2 -2
- package/dist/components/Menu.d.ts +5 -4
- package/dist/components/Menu.js +13 -8
- package/dist/components/MenuItem.js +1 -14
- package/dist/components/MenuItemCopy.js +2 -2
- package/dist/components/Panel.d.ts +3 -1
- package/dist/components/Panel.js +17 -11
- package/dist/components/Progress.d.ts +21 -23
- package/dist/components/Progress.js +13 -9
- package/dist/components/RadioGroup.js +6 -8
- package/dist/components/{select-parts.css → Select.css} +1 -1
- package/dist/components/Select.d.ts +53 -35
- package/dist/components/Select.js +53 -97
- package/dist/components/SelectFaceted.d.ts +7 -3
- package/dist/components/SelectFaceted.js +21 -9
- package/dist/components/Slider.d.ts +28 -11
- package/dist/components/Slider.js +20 -20
- package/dist/components/Steps.css +1 -1
- package/dist/components/Steps.js +1 -11
- package/dist/components/Tabs.d.ts +17 -20
- package/dist/components/Tabs.js +5 -8
- package/dist/components/Text.d.ts +55 -36
- package/dist/components/Text.js +35 -22
- package/dist/components/Title.d.ts +16 -26
- package/dist/components/Title.js +2 -1
- package/dist/components/Toaster.js +9 -2
- package/dist/components/Tooltip.d.ts +10 -15
- package/dist/components/copy-props.d.ts +14 -3
- package/dist/components/copy-props.js +14 -3
- package/dist/components/select-tree.d.ts +24 -0
- package/dist/components/select-tree.js +35 -0
- package/dist/element-base.d.ts +10 -0
- package/dist/element-base.js +15 -0
- package/dist/elements/a-banner.css +1 -1
- package/dist/elements/a-banner.d.ts +4 -1
- package/dist/elements/a-banner.js +22 -112
- package/dist/elements/a-button.d.ts +2 -1
- package/dist/elements/a-button.js +18 -1
- package/dist/elements/a-calendar.d.ts +14 -13
- package/dist/elements/a-calendar.js +29 -24
- package/dist/elements/a-card.css +1 -1
- package/dist/elements/a-card.d.ts +0 -9
- package/dist/elements/a-card.js +0 -184
- package/dist/elements/a-checkbox.css +1 -1
- package/dist/elements/a-copy.css +1 -1
- package/dist/elements/a-copy.d.ts +1 -5
- package/dist/elements/a-copy.js +129 -108
- package/dist/elements/a-dialog.css +1 -1
- package/dist/elements/a-dialog.d.ts +1 -1
- package/dist/elements/a-dialog.js +66 -194
- package/dist/elements/a-expander.css +1 -1
- package/dist/elements/a-expander.d.ts +4 -30
- package/dist/elements/a-expander.js +85 -344
- package/dist/elements/a-icon.d.ts +5 -23
- package/dist/elements/a-icon.js +1 -2
- package/dist/elements/a-input-time.css +1 -1
- package/dist/elements/a-input-time.d.ts +2 -1
- package/dist/elements/a-input-time.js +101 -168
- package/dist/elements/a-input.css +1 -1
- package/dist/elements/a-input.d.ts +10 -8
- package/dist/elements/a-input.js +155 -230
- package/dist/elements/a-loader.d.ts +5 -8
- package/dist/elements/a-loader.js +1 -2
- package/dist/elements/a-menu-item.css +1 -1
- package/dist/elements/a-menu-item.d.ts +5 -3
- package/dist/elements/a-menu-item.js +5 -1
- package/dist/elements/a-menu.css +1 -1
- package/dist/elements/a-menu.d.ts +5 -7
- package/dist/elements/a-menu.js +383 -299
- package/dist/elements/a-panel.css +1 -1
- package/dist/elements/a-panel.js +19 -37
- package/dist/elements/a-progress.css +1 -1
- package/dist/elements/a-progress.d.ts +0 -22
- package/dist/elements/a-progress.js +0 -100
- package/dist/elements/a-radio-group.d.ts +1 -1
- package/dist/elements/a-radio-group.js +6 -4
- package/dist/elements/a-select-faceted.d.ts +1 -1
- package/dist/elements/a-select-faceted.js +1 -1
- package/dist/elements/a-select.d.ts +1 -1
- package/dist/elements/a-select.js +1 -1
- package/dist/elements/a-slider.css +1 -1
- package/dist/elements/a-slider.d.ts +11 -3
- package/dist/elements/a-slider.js +244 -242
- package/dist/elements/a-switch.css +1 -1
- package/dist/elements/a-tab.css +1 -1
- package/dist/elements/a-tabs.css +1 -1
- package/dist/elements/a-tabs.d.ts +1 -1
- package/dist/elements/a-tabs.js +6 -4
- package/dist/elements/a-tag.css +1 -1
- package/dist/elements/a-text.css +1 -1
- package/dist/elements/a-text.d.ts +6 -43
- package/dist/elements/a-text.js +110 -193
- package/dist/elements/a-title.css +1 -1
- package/dist/elements/a-toast.css +1 -1
- package/dist/elements/a-toast.d.ts +10 -45
- package/dist/elements/a-toast.js +80 -66
- package/dist/elements/a-toaster.css +1 -1
- package/dist/elements/a-toaster.js +9 -44
- package/dist/elements/a-tooltip.css +1 -1
- package/dist/elements/a-tooltip.d.ts +1 -1
- package/dist/elements/a-tooltip.js +142 -136
- package/dist/elements/copy-behavior.d.ts +1 -1
- package/dist/elements/copy-behavior.js +21 -21
- package/dist/elements/index.d.ts +3 -3
- package/dist/elements/index.js +3 -7
- package/dist/elements/input-focus-modality.d.ts +15 -0
- package/dist/elements/input-focus-modality.js +44 -0
- package/dist/elements/input-trailing-actions.d.ts +5 -0
- package/dist/elements/input-trailing-actions.js +38 -0
- package/dist/elements/shadow-aria.d.ts +2 -0
- package/dist/elements/shadow-aria.js +2 -1
- package/dist/elements/value-input.d.ts +3 -0
- package/dist/elements/value-input.js +12 -0
- package/dist/general_types.d.ts +103 -96
- package/dist/index.d.ts +1 -1
- package/dist/input-events.d.ts +4 -0
- package/dist/input-events.js +15 -0
- package/dist/jsx-runtime.d.ts +70 -23
- package/dist/jsx-runtime.js +26 -19
- package/dist/native-event-props.d.ts +2 -0
- package/dist/native-event-props.js +10 -0
- package/dist/reset.css +1 -1
- package/dist/theme-antithesis.css +10 -1
- package/dist/theme-antune.css +1 -1
- package/docs/accessibility.md +17 -3
- package/docs/changelog.md +348 -2
- package/docs/comparison.md +2 -2
- package/docs/components/avatar.md +5 -0
- package/docs/components/banner.md +117 -187
- package/docs/components/button.md +22 -0
- package/docs/components/card.md +74 -28
- package/docs/components/checkbox.md +9 -10
- package/docs/components/dialog.md +83 -32
- package/docs/components/expander.md +198 -435
- package/docs/components/icon.md +11 -17
- package/docs/components/input-autocomplete.md +152 -52
- package/docs/components/input-date.md +175 -148
- package/docs/components/input-time.md +81 -38
- package/docs/components/input.md +343 -349
- package/docs/components/loader.md +2 -1
- package/docs/components/menu.md +35 -6
- package/docs/components/panel.md +18 -0
- package/docs/components/progress.md +83 -49
- package/docs/components/radio.md +39 -43
- package/docs/components/select-faceted.md +54 -7
- package/docs/components/select.md +390 -386
- package/docs/components/slider.md +136 -19
- package/docs/components/steps.md +2 -1
- package/docs/components/switch.md +8 -9
- package/docs/components/tabs.md +110 -104
- package/docs/components/text.md +110 -86
- package/docs/components/title.md +47 -33
- package/docs/components/toaster.md +242 -84
- package/docs/components/tooltip.md +204 -113
- package/docs/install-config.md +183 -26
- package/docs/packages/plot.md +170 -148
- package/docs/theming.md +7 -0
- package/package.json +41 -3
- package/theme-antithesis-license.md +66 -0
|
@@ -35,7 +35,8 @@ export interface SelectOption<V extends OptionValue = string> extends OptionPres
|
|
|
35
35
|
/** Tooltip for this option's row — a string or any node. In a `multiple`
|
|
36
36
|
* select with `selectAll`, a row with no `tooltip` falls back to a default
|
|
37
37
|
* hint for the Alt/Option-click "select only this" accelerator; set `tooltip`
|
|
38
|
-
* to override that, or `''` to suppress it.
|
|
38
|
+
* to override that, or `''` to suppress it. Hovering a row reveals the default
|
|
39
|
+
* shortcut hint; moving to another row restarts its delay. */
|
|
39
40
|
tooltip?: React.ReactNode;
|
|
40
41
|
/** Additional application data. Read it in `renderOption`. */
|
|
41
42
|
[key: string]: unknown;
|
|
@@ -95,9 +96,9 @@ export interface EmptyState {
|
|
|
95
96
|
export interface TriggerState<V extends OptionValue = string> {
|
|
96
97
|
/** Whether the menu is open — use it for `aria-expanded` and a chevron. */
|
|
97
98
|
open: boolean;
|
|
98
|
-
/** The current selection: a
|
|
99
|
-
*
|
|
100
|
-
value: V | V[] |
|
|
99
|
+
/** The current selection: a value or `null` in single mode, an array in
|
|
100
|
+
* multiple mode. An empty array means no multiple selection. */
|
|
101
|
+
value: V | V[] | null;
|
|
101
102
|
/** The resolved option objects for the current selection (empty when none).
|
|
102
103
|
* `selected.length` is the multi-select count. */
|
|
103
104
|
selected: SelectOption<V>[];
|
|
@@ -168,9 +169,18 @@ export interface SelectCommonProps<V extends OptionValue = string> extends Omit<
|
|
|
168
169
|
icon?: IconShape;
|
|
169
170
|
/** Content before the default trigger's value, such as a key prefix
|
|
170
171
|
* before the value. It replaces the icon derived from `icon`. Include an
|
|
171
|
-
* `<Icon>` in this content when both are needed.
|
|
172
|
+
* `<Icon>` in this content when both are needed. Hidden from assistive
|
|
173
|
+
* technologies. Include any meaningful prefix in `label` or `aria-label`.
|
|
174
|
+
* Ignored by `renderTrigger`. */
|
|
172
175
|
leading?: React.ReactNode;
|
|
173
|
-
/**
|
|
176
|
+
/** Dim the default trigger's leading content and chevron at rest. They brighten
|
|
177
|
+
* on hover or focus. Ignored by `renderTrigger`.
|
|
178
|
+
* @defaultValue true */
|
|
179
|
+
dimActions?: boolean;
|
|
180
|
+
/** Visible field label and accessible name for the default trigger. If omitted,
|
|
181
|
+
* provide `aria-label` or `aria-labelledby` that identifies the field.
|
|
182
|
+
* Leading content and the chevron are hidden from assistive technologies and
|
|
183
|
+
* do not label the trigger. */
|
|
174
184
|
label?: string;
|
|
175
185
|
/** Helper text under the field. */
|
|
176
186
|
hint?: string;
|
|
@@ -195,10 +205,14 @@ export interface SelectCommonProps<V extends OptionValue = string> extends Omit<
|
|
|
195
205
|
* option's own `toneScope` wins.
|
|
196
206
|
* @defaultValue 'all' */
|
|
197
207
|
toneScope?: ToneScope;
|
|
198
|
-
/** Add a search field
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
208
|
+
/** Add a search field that filters option values, labels, and hints.
|
|
209
|
+
* `true` uses case-insensitive substring matching. A space in the trimmed
|
|
210
|
+
* query matches a run of whitespace. Built-in row text highlights matches.
|
|
211
|
+
* A custom `(option, query) => boolean` receives the trimmed query and returns
|
|
212
|
+
* whether to keep the option, without automatic highlighting. It runs once
|
|
213
|
+
* per option on each render, including for an empty query. Rows, empty content,
|
|
214
|
+
* and filtered Select all use the same results. A query flattens groups and
|
|
215
|
+
* submenus into grouped results. Closing the popup resets the query. */
|
|
202
216
|
filter?: boolean | ((option: SelectOption<V>, query: string) => boolean);
|
|
203
217
|
/** `multiple` only: shows a "Select all" row that toggles every enabled option,
|
|
204
218
|
* or only the visible options when a filter query is active. Its checkbox is
|
|
@@ -210,7 +224,7 @@ export interface SelectCommonProps<V extends OptionValue = string> extends Omit<
|
|
|
210
224
|
* @defaultValue Select all */
|
|
211
225
|
selectAllLabel?: string;
|
|
212
226
|
/** Add a "Clear" row pinned in the menu **footer** that empties the selection
|
|
213
|
-
* (single →
|
|
227
|
+
* (single → `null`, multiple → `[]`). Shown only while something is selected, so
|
|
214
228
|
* it never scrolls away in a long or filtered list. */
|
|
215
229
|
clearable?: boolean;
|
|
216
230
|
/** Label for the `clearable` footer row.
|
|
@@ -233,15 +247,15 @@ export interface SelectCommonProps<V extends OptionValue = string> extends Omit<
|
|
|
233
247
|
* A, B, C` (labels comma-joined) in place of the bare `3 selected`. Applies
|
|
234
248
|
* to the multi-count case only: `All` stays `All`, a single pick stays its
|
|
235
249
|
* own label, and an empty selection stays the `placeholder`. The list flows
|
|
236
|
-
* into the
|
|
250
|
+
* into the default trigger's value, so it ellipsizes at the field's width when long
|
|
237
251
|
* (`3 selected: Engineering, Des… `). `renderSummary` overrides this. */
|
|
238
252
|
verbose?: boolean;
|
|
239
253
|
/** `multiple` only: build the trigger's selection summary text yourself,
|
|
240
254
|
* replacing the built-in "`All` / one label / `N selected`" logic. Receives
|
|
241
255
|
* the resolved selected options (`selected.length` is the count) and runs only
|
|
242
256
|
* while something is selected — an empty selection still shows the
|
|
243
|
-
* `placeholder`. Return a **string**: it
|
|
244
|
-
*
|
|
257
|
+
* `placeholder`. Return a **string**: it becomes the default trigger's
|
|
258
|
+
* value, so a long summary ellipsizes at the field's width just
|
|
245
259
|
* like a long value (`Engineering, Design, … `). Return `undefined` to fall
|
|
246
260
|
* back to the default for that case (e.g. customize only the count, keeping
|
|
247
261
|
* the single-label case built-in). For rich content (chips, multiple nodes)
|
|
@@ -270,7 +284,7 @@ export interface SelectCommonProps<V extends OptionValue = string> extends Omit<
|
|
|
270
284
|
}
|
|
271
285
|
/**
|
|
272
286
|
* `<Select>` props. `selection` discriminates the value shape: single mode
|
|
273
|
-
* (`value:
|
|
287
|
+
* (`value: V | null`) or `multiple` (`value: V[]`).
|
|
274
288
|
*/
|
|
275
289
|
export type SelectProps<V extends OptionValue = string> = SelectCommonProps<V> & ({
|
|
276
290
|
/** Selection mode. `'single'` (the default) keeps `value` a single value and
|
|
@@ -278,27 +292,31 @@ export type SelectProps<V extends OptionValue = string> = SelectCommonProps<V> &
|
|
|
278
292
|
* array value.
|
|
279
293
|
* @defaultValue single */
|
|
280
294
|
selection?: 'single';
|
|
281
|
-
/** Controlled value
|
|
282
|
-
* `
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
*
|
|
289
|
-
|
|
295
|
+
/** Controlled option value. Use `null` for an empty selection; clearing
|
|
296
|
+
* to `null` keeps the Select controlled. Omit or pass `undefined` for
|
|
297
|
+
* uncontrolled use. Empty strings, `0`, and `false` remain option values. */
|
|
298
|
+
value?: V | null;
|
|
299
|
+
/** Initial option value for uncontrolled use. `null` starts empty. */
|
|
300
|
+
defaultValue?: V | null;
|
|
301
|
+
/** Reports the new value and a `{ value, option }` snapshot after a pick.
|
|
302
|
+
* Clear reports `null` with `{ all: true, selected: false }`.
|
|
303
|
+
* Narrow on `'all' in attrs` before reading `option`.
|
|
304
|
+
* Update `value` to accept a controlled change. There is no cancelable
|
|
305
|
+
* `onStateChange`; see the Input event-model note. */
|
|
306
|
+
onValueChange?: (value: V | null, attrs: SelectChangeAttrs<V>) => void;
|
|
290
307
|
} | {
|
|
291
308
|
/** Multi-select: checkboxes on every row, the menu stays open while
|
|
292
309
|
* toggling, the field shows an "N selected" count, and `value` is an array. */
|
|
293
310
|
selection: 'multiple';
|
|
294
|
-
/** Controlled values
|
|
295
|
-
*
|
|
311
|
+
/** Controlled option values. Use `[]` for an empty selection. Omit or
|
|
312
|
+
* pass `undefined` for uncontrolled use. */
|
|
296
313
|
value?: V[];
|
|
297
314
|
/** Initial values (option `value`s) for the uncontrolled case. */
|
|
298
315
|
defaultValue?: V[];
|
|
299
|
-
/**
|
|
300
|
-
*
|
|
301
|
-
*
|
|
316
|
+
/** Reports the new value array and a `{ value, option, selected }` snapshot
|
|
317
|
+
* after a row toggle. Select all and Clear report `{ all: true, selected }`
|
|
318
|
+
* without a single option. Narrow on `'all' in attrs` before reading `option`.
|
|
319
|
+
* Update `value` to accept a controlled change. */
|
|
302
320
|
onValueChange?: (value: V[], attrs: SelectChangeAttrs<V>) => void;
|
|
303
321
|
});
|
|
304
322
|
/** Rolled-up selection of a group / submenu subtree: `'none'` / `'all'` of the
|
|
@@ -336,8 +354,8 @@ export type SelectedItem<V extends OptionValue = string> = SelectedOption<V> | S
|
|
|
336
354
|
*
|
|
337
355
|
* A pure function of `(options, values)` — it needs no `Select` instance and reads
|
|
338
356
|
* nothing off the change event, so it behaves identically in controlled and
|
|
339
|
-
* uncontrolled code. Pass the current `value` (
|
|
340
|
-
* and render a grouped summary, drive section indicators, or diff picks.
|
|
357
|
+
* uncontrolled code. Pass the current `value` (an option value, an array,
|
|
358
|
+
* `null`, or `undefined`) and render a grouped summary, drive section indicators, or diff picks.
|
|
341
359
|
*
|
|
342
360
|
* A value that appears under more than one section marks the leaf in *every* place it
|
|
343
361
|
* occurs (selection is value-keyed), mirroring how the menu itself renders it.
|
|
@@ -349,12 +367,12 @@ export type SelectedItem<V extends OptionValue = string> = SelectedOption<V> | S
|
|
|
349
367
|
* // { value: 'eng-fe', label: 'Frontend', selected: false }, … ] }
|
|
350
368
|
* ```
|
|
351
369
|
*/
|
|
352
|
-
export declare function optionsWithSelection<V extends OptionValue = string>(options: SelectItem<V>[], values: V | V[] | undefined): SelectedItem<V>[];
|
|
370
|
+
export declare function optionsWithSelection<V extends OptionValue = string>(options: SelectItem<V>[], values: V | V[] | null | undefined): SelectedItem<V>[];
|
|
353
371
|
/**
|
|
354
372
|
* `<Select>` lets people choose one or more options from a dropdown. It uses a
|
|
355
|
-
* `<
|
|
356
|
-
* `'single'` (default;
|
|
357
|
-
* (checkboxes,
|
|
373
|
+
* `<Input button>` as its trigger and a `<Menu>` for its options. `selection` sets behavior:
|
|
374
|
+
* `'single'` (default; an option value or `null`, menu closes on pick) or `'multiple'`
|
|
375
|
+
* (checkboxes, an option-value array, menu stays open while toggling, the
|
|
358
376
|
* field shows an "N selected" count). For single-select, `indicator` picks the
|
|
359
377
|
* per-row mark: `'none'` (tint only, default), `'check'` (trailing checkmark), or
|
|
360
378
|
* `'radio'` (leading radio).
|
|
@@ -2,8 +2,8 @@ import { Fragment, jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
|
2
2
|
import { useState } from "../jsx-runtime";
|
|
3
3
|
import { ISOLATE_HINT, ISOLATE_HINT_DELAY, optionPresentationAttrs } from "../anta_helpers";
|
|
4
4
|
import { normalizeOpt, matchQueryRegex, matchesQuery, highlight } from "./select-options";
|
|
5
|
+
import { prepareSelectOptions } from "./select-tree";
|
|
5
6
|
import { Input } from "./Input";
|
|
6
|
-
import { Button } from "./Button";
|
|
7
7
|
import { Icon } from "./Icon";
|
|
8
8
|
import { Menu } from "./Menu";
|
|
9
9
|
import { MenuItem } from "./MenuItem";
|
|
@@ -47,6 +47,7 @@ const Select = (props) => {
|
|
|
47
47
|
placeholder,
|
|
48
48
|
icon,
|
|
49
49
|
leading,
|
|
50
|
+
dimActions = true,
|
|
50
51
|
label,
|
|
51
52
|
hint,
|
|
52
53
|
size,
|
|
@@ -72,30 +73,22 @@ const Select = (props) => {
|
|
|
72
73
|
...rest
|
|
73
74
|
} = props;
|
|
74
75
|
const multiple = selection === "multiple";
|
|
75
|
-
const statusColor = status && status !== "neutral" ? `var(--text-2-${status})` : void 0;
|
|
76
76
|
const mark = multiple ? "checkbox" : indicator ?? "none";
|
|
77
77
|
const menuItemIndicator = mark === "none" ? void 0 : mark;
|
|
78
78
|
const emit = onValueChange;
|
|
79
79
|
const controlled = value !== void 0;
|
|
80
|
-
const [internal, setInternal] = useState(defaultValue);
|
|
80
|
+
const [internal, setInternal] = useState(defaultValue ?? (multiple ? [] : null));
|
|
81
81
|
const currentRaw = controlled ? value : internal;
|
|
82
82
|
const [open, setOpen] = useState(false);
|
|
83
83
|
const [query, setQuery] = useState("");
|
|
84
84
|
const popupLabel = `${label ?? rest["aria-label"] ?? "Select"} options`;
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const o = normalizeOpt(raw);
|
|
93
|
-
out.push({ opt: o, disabled: disabled2 || !!o.disabled, group });
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
const allLeaves = [];
|
|
98
|
-
collectLeaves(options, void 0, false, allLeaves);
|
|
85
|
+
const filtering = filter !== void 0 && filter !== false;
|
|
86
|
+
const q = query.trim();
|
|
87
|
+
const queryRegex = filtering && typeof filter !== "function" ? matchQueryRegex(q) : null;
|
|
88
|
+
const prune = typeof filter === "function" || filtering && !!q;
|
|
89
|
+
const matches = (o) => typeof filter === "function" ? filter(o, q) : matchesQuery(o, queryRegex);
|
|
90
|
+
const { tree, allLeaves, visibleLeaves } = prepareSelectOptions(options, prune ? matches : void 0);
|
|
91
|
+
const flattening = filtering && !!q;
|
|
99
92
|
const seenValues = /* @__PURE__ */ new Set();
|
|
100
93
|
for (const l of allLeaves) {
|
|
101
94
|
const key = String(l.opt.value);
|
|
@@ -104,13 +97,6 @@ const Select = (props) => {
|
|
|
104
97
|
seenValues.add(key);
|
|
105
98
|
}
|
|
106
99
|
const byValue = new Map(allLeaves.map((l) => [l.opt.value, l.opt]));
|
|
107
|
-
const filtering = filter !== void 0 && filter !== false;
|
|
108
|
-
const q = query.trim();
|
|
109
|
-
const queryRe = filtering && typeof filter !== "function" ? matchQueryRegex(q) : null;
|
|
110
|
-
const matches = (o) => typeof filter === "function" ? filter(o, q) : matchesQuery(o, queryRe);
|
|
111
|
-
const prune = typeof filter === "function" || filtering && !!q;
|
|
112
|
-
const visibleLeaves = prune ? allLeaves.filter((l) => matches(l.opt)) : allLeaves;
|
|
113
|
-
const flattening = filtering && !!q;
|
|
114
100
|
const selectedValues = Array.isArray(currentRaw) ? currentRaw : currentRaw != null ? [currentRaw] : [];
|
|
115
101
|
const isSelected = (v) => selectedValues.includes(v);
|
|
116
102
|
const selectedOptions = selectedValues.map((v) => byValue.get(v)).filter(Boolean);
|
|
@@ -159,7 +145,7 @@ const Select = (props) => {
|
|
|
159
145
|
emit?.(next, { all: true, selected: !allSelected });
|
|
160
146
|
};
|
|
161
147
|
const clear = () => {
|
|
162
|
-
const next = multiple ? [] :
|
|
148
|
+
const next = multiple ? [] : null;
|
|
163
149
|
if (!controlled) setInternal(next);
|
|
164
150
|
emit?.(next, { all: true, selected: false });
|
|
165
151
|
};
|
|
@@ -179,8 +165,8 @@ const Select = (props) => {
|
|
|
179
165
|
selectionIndicator: menuItemIndicator,
|
|
180
166
|
...ariaSelectable,
|
|
181
167
|
indicator: customMark ?? void 0,
|
|
182
|
-
label: custom ? void 0 : highlight(o.label ?? String(o.value),
|
|
183
|
-
hint: custom ? void 0 : o.hint ? highlight(o.hint,
|
|
168
|
+
label: custom ? void 0 : highlight(o.label ?? String(o.value), queryRegex),
|
|
169
|
+
hint: custom ? void 0 : o.hint ? highlight(o.hint, queryRegex) : o.hint,
|
|
184
170
|
icon: custom ? void 0 : o.icon,
|
|
185
171
|
tone: o.tone ?? tone,
|
|
186
172
|
toneScope: o.toneScope ?? toneScope,
|
|
@@ -198,78 +184,65 @@ const Select = (props) => {
|
|
|
198
184
|
String(o.value)
|
|
199
185
|
);
|
|
200
186
|
};
|
|
201
|
-
const renderTree = (
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
},
|
|
219
|
-
`sub-${i}-${raw.label}`
|
|
220
|
-
)
|
|
221
|
-
);
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
if (typeof raw !== "string" && isGroup(raw)) {
|
|
225
|
-
const dis = disabled2 || !!raw.disabled;
|
|
226
|
-
const inner = renderTree(raw.options, dis);
|
|
227
|
-
if (inner.length) out.push(/* @__PURE__ */ jsx(MenuGroup, { label: raw.label, children: inner }, `grp-${i}-${raw.label}`));
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
const o = normalizeOpt(raw);
|
|
231
|
-
if (typeof filter === "function" && !matches(o)) return;
|
|
232
|
-
out.push(renderOptionRow(o, disabled2 || !!o.disabled));
|
|
233
|
-
});
|
|
234
|
-
return out;
|
|
235
|
-
};
|
|
187
|
+
const renderTree = (nodes) => nodes.map((node) => {
|
|
188
|
+
if (node.kind === "option") return renderOptionRow(node.opt, node.disabled);
|
|
189
|
+
const inner = renderTree(node.children);
|
|
190
|
+
if (node.kind === "group") return /* @__PURE__ */ jsx(MenuGroup, { label: node.source.label, children: inner }, node.key);
|
|
191
|
+
return /* @__PURE__ */ jsx(
|
|
192
|
+
MenuItem,
|
|
193
|
+
{
|
|
194
|
+
submenu: true,
|
|
195
|
+
label: node.source.label,
|
|
196
|
+
icon: node.source.icon,
|
|
197
|
+
disabled: node.disabled || void 0,
|
|
198
|
+
"data-menu-open": multiple ? "" : void 0,
|
|
199
|
+
children: /* @__PURE__ */ jsx(Menu, { children: inner })
|
|
200
|
+
},
|
|
201
|
+
node.key
|
|
202
|
+
);
|
|
203
|
+
});
|
|
236
204
|
const renderFlat = () => {
|
|
237
|
-
const shown = allLeaves.filter((l) => matches(l.opt));
|
|
238
205
|
const out = [];
|
|
239
|
-
for (let i = 0; i <
|
|
240
|
-
const label2 =
|
|
206
|
+
for (let i = 0; i < visibleLeaves.length; ) {
|
|
207
|
+
const label2 = visibleLeaves[i].group;
|
|
241
208
|
if (label2 === void 0) {
|
|
242
|
-
out.push(renderOptionRow(
|
|
209
|
+
out.push(renderOptionRow(visibleLeaves[i].opt, visibleLeaves[i].disabled));
|
|
243
210
|
i++;
|
|
244
211
|
continue;
|
|
245
212
|
}
|
|
246
213
|
const rows = [];
|
|
247
214
|
const start = i;
|
|
248
|
-
while (i <
|
|
249
|
-
rows.push(renderOptionRow(
|
|
215
|
+
while (i < visibleLeaves.length && visibleLeaves[i].group === label2) {
|
|
216
|
+
rows.push(renderOptionRow(visibleLeaves[i].opt, visibleLeaves[i].disabled));
|
|
250
217
|
i++;
|
|
251
218
|
}
|
|
252
219
|
out.push(/* @__PURE__ */ jsx(MenuGroup, { label: label2, children: rows }, `flat-${start}-${label2}`));
|
|
253
220
|
}
|
|
254
221
|
return out;
|
|
255
222
|
};
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
223
|
+
const triggerLeading = leading ?? (icon ? /* @__PURE__ */ jsx(Icon, { shape: icon }) : void 0);
|
|
224
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
225
|
+
renderTrigger ? renderTrigger({ open, value: currentRaw, selected: selectedOptions, disabled: !!disabled, icon }) : /* @__PURE__ */ jsx(
|
|
226
|
+
Input,
|
|
259
227
|
{
|
|
228
|
+
button: true,
|
|
229
|
+
dimActions,
|
|
230
|
+
label,
|
|
231
|
+
hint,
|
|
232
|
+
value: display,
|
|
233
|
+
placeholder,
|
|
234
|
+
leading: triggerLeading != null ? /* @__PURE__ */ jsx("a-select-leading", { "aria-hidden": "true", children: triggerLeading }) : void 0,
|
|
260
235
|
disabled,
|
|
261
236
|
size,
|
|
237
|
+
status,
|
|
238
|
+
statusIcon,
|
|
262
239
|
round,
|
|
263
|
-
|
|
264
|
-
|
|
240
|
+
className,
|
|
241
|
+
style,
|
|
265
242
|
"aria-haspopup": filtering ? "dialog" : "menu",
|
|
266
243
|
"aria-expanded": open ? "true" : "false",
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
(leading ?? icon) && /* @__PURE__ */ jsx("a-select-leading", { "aria-hidden": "true", children: leading ?? /* @__PURE__ */ jsx(Icon, { shape: icon }) }),
|
|
270
|
-
/* @__PURE__ */ jsx("a-button-label", { "data-placeholder": !display ? "" : void 0, children: display || placeholder }),
|
|
271
|
-
/* @__PURE__ */ jsx("a-select-chevron", { open: open ? "" : void 0, "aria-hidden": "true", style: statusColor ? { color: statusColor } : void 0, children: /* @__PURE__ */ jsx(Icon, { shape: "chevron-down" }) })
|
|
272
|
-
]
|
|
244
|
+
trailing: /* @__PURE__ */ jsx("a-select-chevron", { open: open ? "" : void 0, "aria-hidden": "true", children: /* @__PURE__ */ jsx(Icon, { shape: "chevron-down" }) }),
|
|
245
|
+
...rest
|
|
273
246
|
}
|
|
274
247
|
),
|
|
275
248
|
/* @__PURE__ */ jsxs(
|
|
@@ -314,7 +287,7 @@ const Select = (props) => {
|
|
|
314
287
|
),
|
|
315
288
|
/* @__PURE__ */ jsx(MenuSeparator, {})
|
|
316
289
|
] }),
|
|
317
|
-
visibleLeaves.length === 0 ? renderEmpty?.({ query: q }) : flattening ? renderFlat() : renderTree(
|
|
290
|
+
visibleLeaves.length === 0 ? renderEmpty?.({ query: q }) : flattening ? renderFlat() : renderTree(tree),
|
|
318
291
|
clearable && selectedValues.length > 0 && // Pinned in the footer so it never scrolls away in a long / filtered list.
|
|
319
292
|
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
320
293
|
/* @__PURE__ */ jsx(MenuSeparator, { slot: "footer" }),
|
|
@@ -333,23 +306,6 @@ const Select = (props) => {
|
|
|
333
306
|
}
|
|
334
307
|
)
|
|
335
308
|
] });
|
|
336
|
-
if (renderTrigger) return content;
|
|
337
|
-
const statusGlyph = {
|
|
338
|
-
brand: "circle-small-solid",
|
|
339
|
-
info: "info",
|
|
340
|
-
success: "circle-check",
|
|
341
|
-
warning: "warning-triangle",
|
|
342
|
-
critical: "warning-diamond"
|
|
343
|
-
};
|
|
344
|
-
const glyph = statusIcon === void 0 ? status ? statusGlyph[status] : void 0 : statusIcon;
|
|
345
|
-
return /* @__PURE__ */ jsxs("a-select-field", { size, status, disabled: disabled ? "" : void 0, class: className, style, children: [
|
|
346
|
-
label != null && /* @__PURE__ */ jsx("a-select-label", { children: label }),
|
|
347
|
-
content,
|
|
348
|
-
hint != null && /* @__PURE__ */ jsxs("a-select-hint", { children: [
|
|
349
|
-
glyph && /* @__PURE__ */ jsx(Icon, { shape: glyph, "aria-hidden": "true" }),
|
|
350
|
-
hint
|
|
351
|
-
] })
|
|
352
|
-
] });
|
|
353
309
|
};
|
|
354
310
|
export {
|
|
355
311
|
Select,
|
|
@@ -11,9 +11,13 @@ interface FacetBase {
|
|
|
11
11
|
/** Leading icon on the facet's row. */
|
|
12
12
|
icon?: IconShape;
|
|
13
13
|
}
|
|
14
|
-
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
/** Filter the options within a facet. `true` uses case-insensitive substring
|
|
15
|
+
* matching on the option's value, label, and hint, with trimmed, flexible
|
|
16
|
+
* whitespace. A custom `(option, query) => boolean` receives the original query,
|
|
17
|
+
* including leading and trailing whitespace, in both per-facet and global
|
|
18
|
+
* search. Custom predicates also run for an empty per-facet query. A whitespace-only
|
|
19
|
+
* global query does not activate global results. `false` hides the facet's search
|
|
20
|
+
* field; global search still matches its options with the built-in matcher. */
|
|
17
21
|
export type FacetFilter = boolean | ((option: SelectOption<OptionValue>, query: string) => boolean);
|
|
18
22
|
/** Pick **one** option. Value: the chosen option's `value` (or `undefined` when
|
|
19
23
|
* cleared). Re-picking the selected option clears it. Options are `Select`'s
|
|
@@ -22,7 +22,11 @@ const leavesOf = (items) => {
|
|
|
22
22
|
return out;
|
|
23
23
|
};
|
|
24
24
|
const isEmpty = (v) => v == null || v === "" || Array.isArray(v) && v.length === 0;
|
|
25
|
-
const
|
|
25
|
+
const prepareMatch = (query) => {
|
|
26
|
+
const queryRe = matchQueryRegex(query);
|
|
27
|
+
return (option) => matchesQuery(option, queryRe);
|
|
28
|
+
};
|
|
29
|
+
const matcherFor = (filter, query, preparedMatch) => typeof filter === "function" ? (option) => filter(option, query) : preparedMatch ?? prepareMatch(query);
|
|
26
30
|
const SelectFaceted = (props) => {
|
|
27
31
|
const {
|
|
28
32
|
facets,
|
|
@@ -94,10 +98,11 @@ const SelectFaceted = (props) => {
|
|
|
94
98
|
const clearAll = () => commit({}, { all: true });
|
|
95
99
|
const visibleLeavesOf = (facet) => {
|
|
96
100
|
const leaves = leavesByKey.get(facet.key) ?? [];
|
|
97
|
-
|
|
101
|
+
const filter = facet.filter;
|
|
102
|
+
if (!filter) return leaves;
|
|
98
103
|
const q = queries[facet.key] ?? "";
|
|
99
|
-
|
|
100
|
-
return leaves.filter((
|
|
104
|
+
if (typeof filter !== "function" && !q.trim()) return leaves;
|
|
105
|
+
return leaves.filter(matcherFor(filter, q));
|
|
101
106
|
};
|
|
102
107
|
const filterHeader = (facet) => facet.filter ? /* @__PURE__ */ jsx("a-select-header", { slot: "header", "data-menu-open": "", children: /* @__PURE__ */ jsx(
|
|
103
108
|
Input,
|
|
@@ -108,7 +113,10 @@ const SelectFaceted = (props) => {
|
|
|
108
113
|
placeholder: "Filter\u2026",
|
|
109
114
|
"aria-label": `Filter ${facet.label}`,
|
|
110
115
|
"aria-autocomplete": "list",
|
|
111
|
-
onInput: (e) =>
|
|
116
|
+
onInput: (e) => {
|
|
117
|
+
const query = e.currentTarget.value;
|
|
118
|
+
setQueries((s) => ({ ...s, [facet.key]: query }));
|
|
119
|
+
}
|
|
112
120
|
}
|
|
113
121
|
) }) : null;
|
|
114
122
|
const optionRow = (facet, opt, keyPrefix = "") => {
|
|
@@ -190,9 +198,10 @@ const SelectFaceted = (props) => {
|
|
|
190
198
|
] });
|
|
191
199
|
};
|
|
192
200
|
const renderFlatResults = () => {
|
|
201
|
+
const match = prepareMatch(rootQuery);
|
|
193
202
|
const groups = facets.filter((f) => f.kind === "single" || f.kind === "multiple").map((facet) => {
|
|
194
|
-
const
|
|
195
|
-
return { facet, matched
|
|
203
|
+
const matched = (leavesByKey.get(facet.key) ?? []).filter(matcherFor(facet.filter, rootQuery, match));
|
|
204
|
+
return { facet, matched };
|
|
196
205
|
}).filter((g) => g.matched.length > 0);
|
|
197
206
|
return groups.map(({ facet, matched }) => /* @__PURE__ */ jsx(MenuGroup, { label: facet.label, children: matched.map((opt) => optionRow(facet, opt, `${facet.key}:`)) }, facet.key));
|
|
198
207
|
};
|
|
@@ -206,14 +215,17 @@ const SelectFaceted = (props) => {
|
|
|
206
215
|
return (
|
|
207
216
|
// `data-menu-open` keeps the menu open through typing; the value commits on
|
|
208
217
|
// Enter / blur, not per keystroke.
|
|
209
|
-
/* @__PURE__ */ jsx("
|
|
218
|
+
/* @__PURE__ */ jsx("a-select-faceted-text", { "data-menu-open": "", children: /* @__PURE__ */ jsx(
|
|
210
219
|
Input,
|
|
211
220
|
{
|
|
212
221
|
size: "small",
|
|
213
222
|
value: draft,
|
|
214
223
|
placeholder: facet.placeholder,
|
|
215
224
|
"aria-label": facet.label,
|
|
216
|
-
onInput: (e) =>
|
|
225
|
+
onInput: (e) => {
|
|
226
|
+
const draft2 = e.currentTarget.value;
|
|
227
|
+
setDrafts((d) => ({ ...d, [facet.key]: draft2 }));
|
|
228
|
+
},
|
|
217
229
|
onKeyDown: (e) => {
|
|
218
230
|
if (e.key === "Enter") {
|
|
219
231
|
e.preventDefault();
|
|
@@ -20,18 +20,27 @@ export interface SliderProps extends BaseProps, DOMEventHandlers {
|
|
|
20
20
|
/** Visible field label, shown above the rail. A string supplies the slider's
|
|
21
21
|
* accessible name; give a rich label an explicit `aria-label`. */
|
|
22
22
|
label?: React.ReactNode;
|
|
23
|
-
/** Controlled value. A pair
|
|
23
|
+
/** Controlled numeric value. A pair selects a range, ordered low to high.
|
|
24
|
+
* Omit or pass `undefined` for uncontrolled use; `0` stays controlled.
|
|
25
|
+
* Runtime `null` is treated as omission; it is not a controlled empty value.
|
|
26
|
+
* Takes precedence over `defaultValue`, including on form reset. Values are
|
|
27
|
+
* clamped to the bounds and rounded to a step measured from `min`.
|
|
28
|
+
* Releasing control retains the last applied value. There is no empty numeric state. */
|
|
24
29
|
value?: number | SliderRangeValue;
|
|
25
|
-
/** Initial uncontrolled value.
|
|
26
|
-
*
|
|
30
|
+
/** Initial uncontrolled value and form-reset baseline. Changes while pristine
|
|
31
|
+
* update the value; after interaction they affect the next reset. Without a
|
|
32
|
+
* default, scalar reset uses `min` and range reset uses `[min, max]`.
|
|
33
|
+
* @defaultValue min */
|
|
27
34
|
defaultValue?: number | SliderRangeValue;
|
|
28
|
-
/** Lowest permitted value.
|
|
35
|
+
/** Lowest permitted value and step origin. Nonfinite values use 0.
|
|
29
36
|
* @defaultValue 0 */
|
|
30
37
|
min?: number;
|
|
31
|
-
/** Highest permitted value.
|
|
38
|
+
/** Highest permitted value. A lower bound than `min` collapses the range to
|
|
39
|
+
* `min`. Nonfinite values use 100.
|
|
32
40
|
* @defaultValue 100 */
|
|
33
41
|
max?: number;
|
|
34
|
-
/** Smallest keyboard and drag increment.
|
|
42
|
+
/** Smallest keyboard and drag increment. Nonpositive and nonfinite values
|
|
43
|
+
* use 1. Page keys move by at least one step, or one tenth of the range.
|
|
35
44
|
* @defaultValue 1 */
|
|
36
45
|
step?: number;
|
|
37
46
|
/** Form field name. A range submits two values under this name. */
|
|
@@ -43,8 +52,8 @@ export interface SliderProps extends BaseProps, DOMEventHandlers {
|
|
|
43
52
|
* @defaultValue 'neutral' */
|
|
44
53
|
tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
|
|
45
54
|
/** Color of the thumb stroke. Pass a named tone or a literal CSS color for a
|
|
46
|
-
* one-off custom tone.
|
|
47
|
-
* @defaultValue 'neutral' */
|
|
55
|
+
* one-off custom tone. An explicit `neutral` keeps the thumb neutral in every theme.
|
|
56
|
+
* @defaultValue 'neutral' (the Antithesis theme follows `tone`) */
|
|
48
57
|
thumbTone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
|
|
49
58
|
/** Size variant. small=24px, medium=28px, large=32px tall.
|
|
50
59
|
* @defaultValue 'medium' */
|
|
@@ -81,9 +90,17 @@ export interface SliderProps extends BaseProps, DOMEventHandlers {
|
|
|
81
90
|
trackClick?: 'drag-only' | 'jump';
|
|
82
91
|
/** Fill the rail outside the selected value or range. */
|
|
83
92
|
inverted?: boolean;
|
|
84
|
-
/**
|
|
93
|
+
/** Reports each distinct requested value during a drag and each keyboard step.
|
|
94
|
+
* `onInput` runs first. The snapshot contains the requested value and effective
|
|
95
|
+
* constraints; the element's `value` remains the applied value. Controlled
|
|
96
|
+
* sliders accept by updating `value` and reject by leaving it unchanged.
|
|
97
|
+
* Events are notifications; `preventDefault()` does not veto a value request. */
|
|
85
98
|
onValueChange?: (event: any, attrs: SliderChangeAttrs<SliderValue>) => void;
|
|
86
|
-
/**
|
|
99
|
+
/** Reports the final requested value after a drag, cancellation, or capture loss,
|
|
100
|
+
* and after each keyboard step. `onChange` runs first. A drag ending at its
|
|
101
|
+
* starting value is silent. Controlled requests can commit without being accepted.
|
|
102
|
+
* Uncontrolled form reset emits both callbacks when it changes the value;
|
|
103
|
+
* state restoration and application updates are silent. */
|
|
87
104
|
onValueCommit?: (event: any, attrs: SliderChangeAttrs<SliderValue>) => void;
|
|
88
105
|
}
|
|
89
106
|
type TypedSliderProps<T extends SliderValue> = Omit<SliderProps, 'value' | 'defaultValue' | 'onValueChange' | 'onValueCommit'> & {
|
|
@@ -97,5 +114,5 @@ type TypedSliderProps<T extends SliderValue> = Omit<SliderProps, 'value' | 'defa
|
|
|
97
114
|
* starts a relative drag by default, so the thumb never jumps to the press point.
|
|
98
115
|
* Requires `@antadesign/anta/elements` on the client.
|
|
99
116
|
*/
|
|
100
|
-
export declare const Slider: <T extends SliderValue = number>({ label, value, defaultValue, min: minProp, max: maxProp, step: stepProp, name, disabled, tone, thumbTone, size, trackSize, thumbSize, thumbFill, round, valueDisplay, valuePrefix, valueSuffix, markers, trackClick, inverted, onInput, onChange, onValueChange, onValueCommit, className, style, children, tabIndex, ...rest }: TypedSliderProps<T>) => any;
|
|
117
|
+
export declare const Slider: <T extends SliderValue = number>({ label, value, defaultValue, min: minProp, max: maxProp, step: stepProp, name, disabled, tone, thumbTone, size, trackSize, thumbSize, thumbFill, round, valueDisplay, valuePrefix, valueSuffix, markers, trackClick, inverted, onInput, onChange, onValueChange, onValueCommit, onKeyDown, onPointerDown, onPointerMove, className, style, children, tabIndex, ...rest }: TypedSliderProps<T>) => any;
|
|
101
118
|
export {};
|