@allxsmith/bestax-bulma 5.61.0 → 5.62.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.
Files changed (59) hide show
  1. package/dist/bestax.css +1 -1
  2. package/dist/bestax.css.map +1 -1
  3. package/dist/esm/components/TreeView.js +14 -10
  4. package/dist/esm/components/TreeView.js.map +1 -1
  5. package/dist/esm/form/Combobox.js +8 -13
  6. package/dist/esm/form/Combobox.js.map +1 -1
  7. package/dist/esm/form/Field.js.map +1 -1
  8. package/dist/esm/form/TreeSelect.js +395 -0
  9. package/dist/esm/form/TreeSelect.js.map +1 -0
  10. package/dist/esm/form/_pickerInternals/PickerPopover.js +5 -1
  11. package/dist/esm/form/_pickerInternals/PickerPopover.js.map +1 -1
  12. package/dist/esm/form/_selectInternals/DialogSelect.js +208 -0
  13. package/dist/esm/form/_selectInternals/DialogSelect.js.map +1 -0
  14. package/dist/esm/form/_selectInternals/ValueTags.js +28 -0
  15. package/dist/esm/form/_selectInternals/ValueTags.js.map +1 -0
  16. package/dist/esm/helpers/treeData.js +97 -0
  17. package/dist/esm/helpers/treeData.js.map +1 -0
  18. package/dist/esm/helpers/useComboboxEngine.js +2 -2
  19. package/dist/esm/helpers/useComboboxEngine.js.map +1 -1
  20. package/dist/esm/helpers/useControlled.js +30 -0
  21. package/dist/esm/helpers/useControlled.js.map +1 -0
  22. package/dist/esm/helpers/useTreeView.js +15 -13
  23. package/dist/esm/helpers/useTreeView.js.map +1 -1
  24. package/dist/extras.css +1 -1
  25. package/dist/extras.css.map +1 -1
  26. package/dist/index.cjs +1099 -392
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.esm.js +1 -0
  29. package/dist/index.esm.js.map +1 -1
  30. package/dist/types/form/Field.d.ts +1 -1
  31. package/dist/types/form/TreeSelect.d.ts +308 -0
  32. package/dist/types/form/_pickerInternals/PickerPopover.d.ts +8 -0
  33. package/dist/types/form/_selectInternals/DialogSelect.d.ts +86 -0
  34. package/dist/types/form/_selectInternals/ValueTags.d.ts +40 -0
  35. package/dist/types/helpers/treeData.d.ts +48 -0
  36. package/dist/types/helpers/useControlled.d.ts +14 -0
  37. package/dist/types/helpers/useTreeView.d.ts +30 -0
  38. package/dist/types/index.d.ts +1 -0
  39. package/dist/types-cjs/form/Field.d.ts +1 -1
  40. package/dist/types-cjs/form/TreeSelect.d.ts +308 -0
  41. package/dist/types-cjs/form/_pickerInternals/PickerPopover.d.ts +8 -0
  42. package/dist/types-cjs/form/_selectInternals/DialogSelect.d.ts +86 -0
  43. package/dist/types-cjs/form/_selectInternals/ValueTags.d.ts +40 -0
  44. package/dist/types-cjs/helpers/treeData.d.ts +48 -0
  45. package/dist/types-cjs/helpers/useControlled.d.ts +14 -0
  46. package/dist/types-cjs/helpers/useTreeView.d.ts +30 -0
  47. package/dist/types-cjs/index.d.ts +1 -0
  48. package/dist/versions/bestax-no-dark-mode.css +1 -1
  49. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  50. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  51. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  52. package/dist/versions/bestax-no-helpers.css +1 -1
  53. package/dist/versions/bestax-no-helpers.css.map +1 -1
  54. package/dist/versions/bestax-prefixed.css +1 -1
  55. package/dist/versions/bestax-prefixed.css.map +1 -1
  56. package/package.json +1 -1
  57. package/src/scss/form/_index.scss +1 -0
  58. package/src/scss/form/_picker-popover.scss +6 -0
  59. package/src/scss/form/_treeselect.scss +146 -0
@@ -0,0 +1,308 @@
1
+ import React from 'react';
2
+ import type { BulmaClassesProps } from '../helpers/useBulmaClasses.js';
3
+ import type { FormFieldProps } from './fieldProps.js';
4
+ import type { PickerPosition } from './_pickerInternals/pickerTypes.js';
5
+ /**
6
+ * One node in a TreeSelect's `data`: Combobox's item fields plus
7
+ * TreeView.Item's, with `children` for the nodes under it.
8
+ */
9
+ export interface TreeItemData {
10
+ /** **Required.** What the value holds and `name` posts. Unique in the whole tree. */
11
+ value: string;
12
+ /** What the row, the field and the tags show, and what search matches. The `value` when it's left out. */
13
+ label?: string;
14
+ /** Reachable, but never picked, checked, opened or closed. */
15
+ disabled?: boolean;
16
+ /** A picture before the label: an `Icon` name, or a node. Hidden from assistive tech. */
17
+ icon?: React.ReactNode;
18
+ /** The nodes under this one. */
19
+ children?: TreeItemData[];
20
+ /** Shows the node as a parent before its children are known, for a branch that loads when it opens. */
21
+ hasChildren?: boolean;
22
+ /** Its children are on their way: an open branch ends in a row that says so, and the live region says it too. */
23
+ isLoading?: boolean;
24
+ /** Its children didn't load: an open branch ends in this message, with a Retry button when there's an `onRetry`. */
25
+ loadError?: React.ReactNode;
26
+ /** Called by the Retry button on a failed load's row. Set `isLoading` while the retry runs. */
27
+ onRetry?: () => void;
28
+ }
29
+ /** What a checked branch puts in the value a check makes. */
30
+ export type TreeSelectCheckedStrategy = 'child' | 'parent' | 'all';
31
+ /** The visible and accessible strings, in your app's language. */
32
+ export interface TreeSelectLabels {
33
+ /**
34
+ * Names the panel and the tree in it.
35
+ * @defaultValue the field's label
36
+ */
37
+ choose?: string;
38
+ /**
39
+ * Names the search box.
40
+ * @defaultValue 'Search'
41
+ */
42
+ search?: string;
43
+ /**
44
+ * Names the clear button.
45
+ * @defaultValue 'Clear'
46
+ */
47
+ clear?: string;
48
+ /**
49
+ * What a loading branch's row says, as on TreeView.
50
+ * @defaultValue 'Loading…'
51
+ */
52
+ loading?: string;
53
+ /**
54
+ * The Retry button's text on a failed load's row, as on TreeView.
55
+ * @defaultValue 'Retry'
56
+ */
57
+ retry?: string;
58
+ /**
59
+ * What the live region says when an open branch starts loading, built
60
+ * from its name, as on TreeView.
61
+ * @defaultValue name => `Loading ${name}`
62
+ */
63
+ loadingAnnouncement?: (name: string) => string;
64
+ /**
65
+ * What the live region says when that load finishes, as on TreeView.
66
+ * @defaultValue name => `${name} loaded`
67
+ */
68
+ loadedAnnouncement?: (name: string) => string;
69
+ }
70
+ /**
71
+ * What every TreeSelect takes. The helper props and the other attributes
72
+ * land on the root `<div>`, as Combobox's do, and the `ref` on the field.
73
+ */
74
+ interface TreeSelectBaseProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'onChange' | 'defaultValue' | 'children'>, Omit<BulmaClassesProps, 'color'>, FormFieldProps {
75
+ /** **Required.** The tree, as nodes nested through `children`. */
76
+ data: TreeItemData[];
77
+ /**
78
+ * The field's label, which names the field through `htmlFor`, and the
79
+ * panel and the tree in it through `aria-labelledby`. Dropped inside an
80
+ * outer `Field`, whose label names them instead.
81
+ */
82
+ label?: React.ReactNode;
83
+ /** The field's `id`, which the label then points at. The panel's is this one with `-panel` after it. */
84
+ id?: string;
85
+ /** Names the field, and the panel and the tree, in place of a `label`. */
86
+ 'aria-label'?: string;
87
+ /** The ids of what names the field, and the panel and the tree, in place of a `label`. */
88
+ 'aria-labelledby'?: string;
89
+ /** The ids of what describes the field, ahead of the tags. */
90
+ 'aria-describedby'?: string;
91
+ /** The open branches' values when you hold the state, as TreeView's `expanded`. */
92
+ expanded?: string[];
93
+ /** The branches open to begin with, when TreeSelect holds its own state. */
94
+ defaultExpanded?: string[];
95
+ /**
96
+ * Called with the new list whenever a branch opens or closes, opening the
97
+ * panel on the picked item's branch included. Fetch a lazy branch's
98
+ * children from here. The branches a search opens aren't in it.
99
+ */
100
+ onExpandedChange?: (expanded: string[]) => void;
101
+ /** Whether the panel is open, controlled: opening and closing then only call `onOpenChange`. */
102
+ open?: boolean;
103
+ /** The panel is open to begin with. */
104
+ defaultOpen?: boolean;
105
+ /** Called with the new state when the panel opens or closes. */
106
+ onOpenChange?: (open: boolean) => void;
107
+ /**
108
+ * Puts a search box at the top of the panel. It matches labels, keeps a
109
+ * match's ancestors and the nodes under it, and opens every branch with a
110
+ * match. A printable key on the field opens the panel with it in the box,
111
+ * and the search empties when the panel closes.
112
+ */
113
+ searchable?: boolean;
114
+ /** The search text when you hold the state. */
115
+ query?: string;
116
+ /** The search text to begin with. */
117
+ defaultQuery?: string;
118
+ /** Called with the search text as it changes. */
119
+ onQueryChange?: (query: string) => void;
120
+ /**
121
+ * Whether a node matches the search, in place of the locale-aware match on
122
+ * its label. It's handed the search text trimmed, the node, and its path
123
+ * from the top node down, the node last, as Cascader's `filter` is. A
124
+ * match's ancestors stay either way. The search runs again when the search
125
+ * text or `data` changes, not when only this does, so one written inline
126
+ * costs nothing.
127
+ */
128
+ filter?: (query: string, item: TreeItemData, path: TreeItemData[]) => boolean;
129
+ /** What the panel shows when the search matches nothing, such as "No folders match". Announced once. */
130
+ empty?: React.ReactNode;
131
+ /** Renders a row's content in place of its label. The field and the tags still show the label. */
132
+ itemTemplate?: (item: TreeItemData) => React.ReactNode;
133
+ /** What the field shows while nothing is picked. */
134
+ placeholder?: string;
135
+ /** A form field name. A hidden input posts the value, or one per value in the checkbox modes. */
136
+ name?: string;
137
+ /** The id of the form the hidden inputs belong to, when it isn't an ancestor. */
138
+ form?: string;
139
+ /**
140
+ * A value is needed: the field is `aria-required`, and the form won't
141
+ * submit while nothing is picked. The browser's message points at the
142
+ * field, which shows focus, and the next key goes to it.
143
+ */
144
+ required?: boolean;
145
+ /** The field can't be used: it can't be focused or opened, its tags lose their buttons, and its hidden inputs don't post. */
146
+ disabled?: boolean;
147
+ /**
148
+ * Shows a clear button at the field's inline end while something it can
149
+ * take off is picked. It leaves checked disabled items, which no control
150
+ * unchecks.
151
+ */
152
+ clearable?: boolean;
153
+ /** Bulma color modifier for the field. */
154
+ color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';
155
+ /** The field's size, which the tree in the panel follows. */
156
+ size?: 'small' | 'medium' | 'large';
157
+ /** Rounds the field's corners (Bulma's `is-rounded`). */
158
+ isRounded?: boolean;
159
+ /**
160
+ * Where the panel opens, relative to the field, as on the pickers.
161
+ * @defaultValue 'bottom-left'
162
+ */
163
+ position?: PickerPosition;
164
+ /** Renders the panel through a portal, into a `ConfigProvider`'s `portalContainer`, `document.body` by default. */
165
+ appendToBody?: boolean;
166
+ /** The visible and accessible strings, in your app's language. */
167
+ labels?: TreeSelectLabels;
168
+ }
169
+ /** Props for a TreeSelect that picks one item. */
170
+ export interface TreeSelectSingleProps extends TreeSelectBaseProps {
171
+ /**
172
+ * `'single'`: one item, picked with Enter, Space or a click on its row.
173
+ * `'checkbox'`: any number, with a box on every item. A check reaches every
174
+ * enabled item under it, and a parent with some of them checked is mixed.
175
+ * `'checkbox-independent'`: any number, each box checking its own item, so
176
+ * a parent means the parent alone (Mantine's and Ant Design's
177
+ * `checkStrictly`). The checkbox modes show the value as tags.
178
+ */
179
+ selectionMode?: 'single';
180
+ /**
181
+ * The value when you hold the state: in `'single'` the picked item's
182
+ * value, or `null` for none, and in the checkbox modes the checked values.
183
+ * In `'checkbox'` a parent's value checks its whole branch, so the list any
184
+ * `checkedStrategy` gives checks the same boxes.
185
+ */
186
+ value?: string | null;
187
+ /** The value to begin with, when TreeSelect holds its own state: a value or `null`, or a list in the checkbox modes. */
188
+ defaultValue?: string | null;
189
+ /**
190
+ * Called with the new value: in `'single'` the picked item's value, or
191
+ * `null` when it's cleared, and in the checkbox modes the new list, after a
192
+ * check, an uncheck, a tag's button or the clear button, each shaped by
193
+ * `checkedStrategy`. A reset of the field's form calls it too, with
194
+ * `defaultValue` as it was given, or with `null` or `[]` when you hold
195
+ * the value, for you to set.
196
+ */
197
+ onChange?: (value: string | null) => void;
198
+ /**
199
+ * A parent's row picks the parent. `false` makes the row, Enter and Space
200
+ * open it instead, so only leaves are picked.
201
+ * @defaultValue true
202
+ */
203
+ parentsSelectable?: boolean;
204
+ /**
205
+ * Closes the panel after a pick and puts focus back on the field.
206
+ * @defaultValue true
207
+ */
208
+ closeOnSelect?: boolean;
209
+ /** @internal Read with the checkbox modes only. */
210
+ checkedStrategy?: never;
211
+ /** @internal Read with the checkbox modes only. */
212
+ ariaCloseLabel?: never;
213
+ }
214
+ /** Props for a TreeSelect with a box on every item. */
215
+ export interface TreeSelectCheckboxProps extends TreeSelectBaseProps {
216
+ /**
217
+ * `'checkbox'`: a check reaches every enabled item under it, and a parent
218
+ * with some of them checked is mixed. `'checkbox-independent'`: each box
219
+ * checks its own item, so a parent means the parent alone.
220
+ */
221
+ selectionMode: 'checkbox' | 'checkbox-independent';
222
+ /**
223
+ * The checked values when you hold the state. In `'checkbox'`, a parent's
224
+ * value checks its whole branch, so the list any `checkedStrategy` gives
225
+ * checks the same boxes.
226
+ */
227
+ value?: string[];
228
+ /** The values checked to begin with, when TreeSelect holds its own state. */
229
+ defaultValue?: string[];
230
+ /**
231
+ * Called with the new list after a check, an uncheck, a tag's button or
232
+ * the clear button, shaped by `checkedStrategy`, and after a reset of the
233
+ * field's form, with `defaultValue` as given, or `[]` when you hold the
234
+ * value.
235
+ */
236
+ onChange?: (value: string[]) => void;
237
+ /**
238
+ * What a checked branch puts in the value, in `'checkbox'`: `'child'` its
239
+ * leaves, `'parent'` its topmost checked item, `'all'` every checked item,
240
+ * parents included. A checked disabled item is in all three, since only
241
+ * its own value checks it. It shapes the value a check, an uncheck, a
242
+ * tag's button or the clear button makes, which `onChange` reports, and
243
+ * not `defaultValue`, a value you pass or the one a form reset puts back.
244
+ * The tags and the hidden
245
+ * inputs show the value as it's held, so a value you pass shows as you
246
+ * pass it, and a branch that loads later changes nothing the form posts.
247
+ * `'checkbox-independent'` always reports exactly the checked items.
248
+ * @defaultValue 'child'
249
+ */
250
+ checkedStrategy?: TreeSelectCheckedStrategy;
251
+ /** Names each tag's button, in place of "Remove" and the item's label, as on Combobox. */
252
+ ariaCloseLabel?: string;
253
+ /** @internal Read with `'single'` only. */
254
+ parentsSelectable?: never;
255
+ /** @internal Read with `'single'` only: the panel stays open while boxes are checked. */
256
+ closeOnSelect?: never;
257
+ }
258
+ /**
259
+ * Props for the TreeSelect component. The helper props and the other
260
+ * attributes land on the `div.tree-select` around the field, and the `ref`
261
+ * on the field. It renders the `Field` and the label itself, unless an outer
262
+ * `Field` already does.
263
+ *
264
+ * @extraProp {React.Ref<HTMLInputElement>} [ref] - Ref forwarded to the field, the read-only `<input role="combobox">`.
265
+ */
266
+ export type TreeSelectProps = TreeSelectSingleProps | TreeSelectCheckboxProps;
267
+ /**
268
+ * The `TreeSelect` component is a form field whose options are a tree, such as categories, places or teams: it opens a panel holding a real `TreeView`, picks one item or checks a branch at a time, and searches labels.
269
+ *
270
+ * The field is a read-only `role="combobox"` that opens a dialog, wired as
271
+ * DateInput's is, so focus moves into the tree for real and the tree keeps
272
+ * TreeView's keys, type-ahead and spoken output. The tree is given as `data`,
273
+ * so the field and the tags can name what's picked while the panel is shut,
274
+ * and on the server.
275
+ *
276
+ * `selectionMode` picks the kind. `'single'` picks one item and closes. With
277
+ * `'checkbox'`, a check reaches every enabled item under it, closed or hidden
278
+ * by a search, and `checkedStrategy` decides what the value holds: the
279
+ * leaves, the topmost checked items or every one. With
280
+ * `'checkbox-independent'`, each box is its own item's, so a parent means
281
+ * itself alone (Mantine's and Ant Design's `checkStrictly`). The value shows
282
+ * as tags under the field.
283
+ *
284
+ * A value no node has is kept and shown as it is, with a warning in
285
+ * development, so a value under a branch that hasn't loaded survives until
286
+ * it does.
287
+ *
288
+ * @function
289
+ * @param {TreeSelectProps} props - Props for the TreeSelect component.
290
+ * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the field.
291
+ * @returns {JSX.Element} The field, its tags and its panel, in a `Field` with the label unless one is around it.
292
+ * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/combobox/ | APG Combobox Pattern}
293
+ *
294
+ * @example
295
+ * <TreeSelect
296
+ * label="Save to"
297
+ * data={[
298
+ * { value: 'docs', label: 'Documents', children: [{ value: 'invoices', label: 'Invoices' }] },
299
+ * { value: 'photos', label: 'Photos' },
300
+ * ]}
301
+ * searchable
302
+ * />
303
+ *
304
+ * @example
305
+ * <TreeSelect label="Regions" selectionMode="checkbox" checkedStrategy="parent" data={regions} />
306
+ */
307
+ export declare const TreeSelect: React.ForwardRefExoticComponent<TreeSelectProps & React.RefAttributes<HTMLInputElement>>;
308
+ export default TreeSelect;
@@ -35,6 +35,14 @@ export interface PickerPopoverProps {
35
35
  * `LocaleProvider`'s: the picker's own, from `usePickerLocaleScope`.
36
36
  */
37
37
  localeScope?: PortalLocale;
38
+ /**
39
+ * At least as wide as the anchor: in place through its partial's
40
+ * `has-anchor-width` rule, which needs the anchor to be the element it's
41
+ * placed against, and portaled through the anchor's width set inline.
42
+ */
43
+ matchWidth?: boolean;
44
+ /** Placed again after each render, for content that changes size while it's open. */
45
+ followContent?: boolean;
38
46
  }
39
47
  export declare const PickerPopover: React.FC<PickerPopoverProps>;
40
48
  export default PickerPopover;
@@ -0,0 +1,86 @@
1
+ import React from 'react';
2
+ import { type BulmaClassesProps } from '../../helpers/useBulmaClasses.js';
3
+ import type { FormFieldProps } from '../fieldProps.js';
4
+ import { type PickerPosition } from '../_pickerInternals/pickerTypes.js';
5
+ /** What names the panel, for what's in it to take as well. */
6
+ export interface PanelName {
7
+ 'aria-label'?: string;
8
+ 'aria-labelledby'?: string;
9
+ }
10
+ /** Props for the field a tree picker opens its panel from. */
11
+ export interface DialogSelectProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'onChange' | 'defaultValue' | 'children'>, Omit<BulmaClassesProps, 'color'>, FormFieldProps {
12
+ /** The component's name, for development warnings. */
13
+ component: string;
14
+ /** The root's own class, before any prefix, such as `tree-select`. */
15
+ rootClass: string;
16
+ /** The panel's own class, beside `picker-popover`, before any prefix. */
17
+ panelClass: string;
18
+ /** What the field shows. */
19
+ text: string;
20
+ /** What `name` posts, a hidden input each. */
21
+ values: string[];
22
+ /** Something is picked: `required` is met, and the clear button shows. */
23
+ hasValue: boolean;
24
+ /** Whether the panel is open. */
25
+ open: boolean;
26
+ /**
27
+ * Asked to open or close the panel: by a click on the field, its keys,
28
+ * Escape, Alt+Up, a press outside and the clear button.
29
+ */
30
+ onOpenChange: (open: boolean) => void;
31
+ /**
32
+ * Called once a reset of the field's form has gone ahead, so the picker
33
+ * can put its value back.
34
+ */
35
+ onFormReset: () => void;
36
+ /**
37
+ * A printable key on the field. Returns whether it used the key, as a
38
+ * search box opening with it does.
39
+ */
40
+ onPrintableKey?: (key: string) => boolean;
41
+ /** Empties the value, from the clear button. */
42
+ onClear: () => void;
43
+ /** Shows the clear button while something is picked. */
44
+ clearable?: boolean;
45
+ /** Names the clear button. */
46
+ clearLabel: string;
47
+ /** Names the panel in place of the field's label. */
48
+ chooseLabel?: string;
49
+ placeholder?: string;
50
+ name?: string;
51
+ form?: string;
52
+ required?: boolean;
53
+ /** Already including a disabled `Fieldset` around it. */
54
+ disabled: boolean;
55
+ color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';
56
+ size?: 'small' | 'medium' | 'large';
57
+ isRounded?: boolean;
58
+ position?: PickerPosition;
59
+ appendToBody?: boolean;
60
+ /** Holds the field, which focus goes back to. */
61
+ inputRef: React.RefObject<HTMLInputElement | null>;
62
+ /**
63
+ * Set on the field: the picker's callback that fills `inputRef` and the
64
+ * ref its caller gave.
65
+ */
66
+ fieldRef: React.RefCallback<HTMLInputElement>;
67
+ /** The ids of the tags that describe the field. */
68
+ describedBy?: string;
69
+ /** Shown under the field, inside its Field: the tags. */
70
+ below?: React.ReactNode;
71
+ /** Selects what takes focus as the panel opens. */
72
+ initialFocusSelector?: string;
73
+ /** The panel's content, handed the panel's name. */
74
+ children: (name: PanelName) => React.ReactNode;
75
+ }
76
+ /**
77
+ * A read-only `role="combobox"` field, wired as the date pickers' are, that
78
+ * opens a `PickerPopover` dialog panel: in a `Field` of its own unless one is
79
+ * around it, with a chevron at its inline end, a clear button, the hidden
80
+ * inputs for `name` and what the browser's `required` check reads. A click,
81
+ * Enter, Space, Down or Alt+Down opens the panel, which holds focus, as the
82
+ * date pickers' does: Tab and Shift+Tab wrap inside it. Escape and Alt+Up
83
+ * close it and put focus back on the field, and a press outside closes it
84
+ * where the press put focus.
85
+ */
86
+ export declare function DialogSelect({ component, rootClass, panelClass, text, values, hasValue, open, onOpenChange, onFormReset, onPrintableKey, onClear, clearable, clearLabel, chooseLabel, placeholder, name, form, required, disabled, color, size, isRounded, position, appendToBody, inputRef, fieldRef, describedBy, below, initialFocusSelector, children, label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, className, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, 'aria-describedby': ariaDescribedBy, ...props }: DialogSelectProps): React.JSX.Element;
@@ -0,0 +1,40 @@
1
+ /** Props for the tags of a field holding several values. */
2
+ export interface ValueTagsProps {
3
+ /** The values, in the order they show. */
4
+ values: string[];
5
+ /** The id of each tag's label, from `tagIds`, which the field's description lists. */
6
+ ids: string[];
7
+ /** What a value shows. */
8
+ labelFor: (value: string) => string;
9
+ /** The field can't be used, so the tags have no buttons. */
10
+ disabled?: boolean;
11
+ /**
12
+ * Names each button in place of "Remove" and the value's label. The
13
+ * button is then described by its tag's label, so it still says which.
14
+ */
15
+ ariaCloseLabel?: string;
16
+ /** Called with a value when its tag's button is pressed. */
17
+ onRemove: (value: string) => void;
18
+ /** Whether a value's tag has a button. Every tag has one without it. */
19
+ removable?: (value: string) => boolean;
20
+ }
21
+ /**
22
+ * The values of a field holding several, as Bulma tags under it, each with a
23
+ * `Delete` that takes its value off. Nothing while there are none.
24
+ */
25
+ export declare function ValueTags({ values, ids, labelFor, disabled, ariaCloseLabel, onRemove, removable, }: ValueTagsProps): import("react").JSX.Element | null;
26
+ /** The ids `ValueTags` gives its labels, built from one id of the field's. */
27
+ export declare const tagIds: (base: string, values: string[]) => string[];
28
+ /** Props for the hidden inputs that post a field's values. */
29
+ export interface HiddenValuesProps {
30
+ /** The form field name. Nothing renders without one. */
31
+ name?: string;
32
+ /** One hidden input each. */
33
+ values: string[];
34
+ /** The id of the form they post with, for a field outside it. */
35
+ form?: string;
36
+ /** They don't post, as a disabled field's value doesn't. */
37
+ disabled?: boolean;
38
+ }
39
+ /** A hidden input for each value, so a form posts them under `name`. */
40
+ export declare function HiddenValues({ name, values, form, disabled, }: HiddenValuesProps): import("react").JSX.Element | null;
@@ -0,0 +1,48 @@
1
+ import type { TreeItemData, TreeSelectCheckedStrategy } from '../form/TreeSelect.js';
2
+ import { type TreeViewItemRecord } from './useTreeView.js';
3
+ /** A node, and the values of the nodes above it, from the top. */
4
+ export interface TreeNodeEntry {
5
+ node: TreeItemData;
6
+ path: string[];
7
+ }
8
+ /**
9
+ * Every node by its value, in the order the tree reads from top to bottom.
10
+ * Values are meant to be unique, and the first node with a value wins.
11
+ */
12
+ export declare function indexTree(data: TreeItemData[]): Map<string, TreeNodeEntry>;
13
+ /** What a node is called: its `label`, or its `value` when that's empty. */
14
+ export declare const nodeLabel: (node: TreeItemData) => string;
15
+ /** The nodes under a node, none when it has no `children`. */
16
+ export declare const childNodes: (node: TreeItemData) => TreeItemData[];
17
+ /** Whether a node is a parent: it has children, or `hasChildren` says it will. */
18
+ export declare const isParentNode: (node: TreeItemData) => boolean;
19
+ /**
20
+ * The records TreeView's check rules read, built from the nodes rather than
21
+ * from the items on the page, so the checked list can be worked out while
22
+ * the tree isn't there.
23
+ */
24
+ export declare function checkRecords(index: Map<string, TreeNodeEntry>): Map<string, TreeViewItemRecord>;
25
+ /**
26
+ * The checked list a `checkedStrategy` reports for the items `listed` checks
27
+ * by TreeView's rules, in the tree's order. `all` is every checked item;
28
+ * `child` the checked items with no enabled item under them; `parent` the
29
+ * checked items whose parent isn't. A disabled item is checked by its own
30
+ * value only, so a checked one is in every list. Values no node has are
31
+ * kept, at the end. Passed back in, each list checks the same items.
32
+ */
33
+ export declare function checkedByStrategy(records: Map<string, TreeViewItemRecord>, listed: string[], strategy: TreeSelectCheckedStrategy): string[];
34
+ /** What a search leaves of a tree. */
35
+ export interface TreeSearch {
36
+ /** The values of the nodes it hides. */
37
+ hidden: Set<string>;
38
+ /** The values of the nodes with a match under them, which open. */
39
+ open: string[];
40
+ /** Whether anything matched. */
41
+ found: boolean;
42
+ }
43
+ /**
44
+ * What a search shows of a tree: the nodes that match, the nodes above them,
45
+ * so the results stay a tree, and the nodes under them, so a matching branch
46
+ * can still be opened.
47
+ */
48
+ export declare function searchTree(data: TreeItemData[], matches: (node: TreeItemData, path: TreeItemData[]) => boolean): TreeSearch;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * A value the caller holds, or one this hook holds when the caller doesn't:
3
+ * the `x` / `defaultX` pair of a component's props. The caller holds it
4
+ * whenever `controlled` isn't `undefined`, so `null` is a held value. The
5
+ * setter changes only the value held here, so a held one changes when the
6
+ * caller passes the new value, and it reports nothing: the component calls
7
+ * its own `onXChange`.
8
+ *
9
+ * @function useControlled
10
+ * @param controlled - The caller's value, or `undefined` to hold one here.
11
+ * @param initial - The value held here to begin with.
12
+ * @returns The current value, and the setter for the one held here.
13
+ */
14
+ export declare function useControlled<T>(controlled: T | undefined, initial: T): readonly [T, (next: T) => void];
@@ -37,6 +37,36 @@ export interface TreeViewItemState {
37
37
  selected?: boolean;
38
38
  checked?: TreeViewCheckState;
39
39
  }
40
+ /**
41
+ * The values of the items a tree hides while they stay in it, as TreeSelect's
42
+ * search hides the items that don't match. A hidden item renders as one under
43
+ * a closed parent does: nothing on the page, and in a `checkbox` tree it and
44
+ * its children still register, so a check still reaches them. Internal, for
45
+ * the components that put a TreeView inside them.
46
+ */
47
+ export declare const TreeViewHiddenContext: React.Context<ReadonlySet<string>>;
48
+ /**
49
+ * Every known item's check state, by the rules in #1096:
50
+ *
51
+ * - a disabled item is checked only when its own value is listed;
52
+ * - an enabled item with no enabled items anywhere under it is checked when
53
+ * it, or any item above it, is listed;
54
+ * - any other enabled item follows the items of that second kind in its
55
+ * branch: checked when they all are, unchecked when none is, mixed between.
56
+ *
57
+ * Also returns the items of the second kind, which are what a toggle sets.
58
+ */
59
+ export declare function readChecks(records: Map<string, TreeViewItemRecord>, listed: Set<string>): {
60
+ states: Map<string, TreeViewCheckState>;
61
+ ends: string[];
62
+ };
63
+ /**
64
+ * The list a toggle of `value` leaves: it and every enabled item under it
65
+ * take the opposite of its state (a mixed one checks), and the rest is read
66
+ * back by the rules. That's every item that shows checked, parents
67
+ * included, plus any listed value no item has.
68
+ */
69
+ export declare function toggledList(records: Map<string, TreeViewItemRecord>, list: string[], value: string): string[];
40
70
  /** Options for `useTreeView`: the TreeView's own props. */
41
71
  export interface TreeViewOptions {
42
72
  mode: TreeViewSelectionMode;
@@ -96,6 +96,7 @@ export * from './form/PinInput.js';
96
96
  export * from './form/Rate.js';
97
97
  export * from './form/Autocomplete.js';
98
98
  export * from './form/Combobox.js';
99
+ export * from './form/TreeSelect.js';
99
100
  export * from './form/Taginput.js';
100
101
  export * from './form/ColorPicker.js';
101
102
  export { InputBase } from './form/InputBase.js';