ionbase-ui 0.84.0 → 0.88.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 (57) hide show
  1. package/dist/components/Checkbox.d.ts +39 -0
  2. package/dist/components/Checkbox.d.ts.map +1 -1
  3. package/dist/components/Checkbox.js +77 -4
  4. package/dist/components/Checkbox.js.map +1 -1
  5. package/dist/components/Fieldset.d.ts +62 -0
  6. package/dist/components/Fieldset.d.ts.map +1 -0
  7. package/dist/components/Fieldset.js +58 -0
  8. package/dist/components/Fieldset.js.map +1 -0
  9. package/dist/components/MultiSelect.d.ts +90 -0
  10. package/dist/components/MultiSelect.d.ts.map +1 -0
  11. package/dist/components/MultiSelect.js +189 -0
  12. package/dist/components/MultiSelect.js.map +1 -0
  13. package/dist/components/Radio.d.ts +14 -0
  14. package/dist/components/Radio.d.ts.map +1 -1
  15. package/dist/components/Radio.js +15 -4
  16. package/dist/components/Radio.js.map +1 -1
  17. package/dist/components/SearchField.d.ts +36 -0
  18. package/dist/components/SearchField.d.ts.map +1 -0
  19. package/dist/components/SearchField.js +76 -0
  20. package/dist/components/SearchField.js.map +1 -0
  21. package/dist/components/Toolbar.d.ts +35 -0
  22. package/dist/components/Toolbar.d.ts.map +1 -0
  23. package/dist/components/Toolbar.js +81 -0
  24. package/dist/components/Toolbar.js.map +1 -0
  25. package/dist/components/index.d.ts +10 -2
  26. package/dist/components/index.d.ts.map +1 -1
  27. package/dist/components/index.js +5 -1
  28. package/dist/components/index.js.map +1 -1
  29. package/dist/figma-descriptions.json +97 -77
  30. package/dist/figma-map.json +228 -4
  31. package/dist/meta/Checkbox.json +8 -6
  32. package/dist/meta/CheckboxGroup.json +268 -0
  33. package/dist/meta/Combobox.json +8 -0
  34. package/dist/meta/Divider.json +2 -2
  35. package/dist/meta/Fieldset.json +162 -0
  36. package/dist/meta/MultiSelect.json +269 -0
  37. package/dist/meta/Radio.json +0 -1
  38. package/dist/meta/RadioGroup.json +59 -7
  39. package/dist/meta/SearchField.json +487 -0
  40. package/dist/meta/Select.json +2 -1
  41. package/dist/meta/Stepper.json +2 -2
  42. package/dist/meta/Tabs.json +3 -3
  43. package/dist/meta/Toolbar.json +130 -0
  44. package/dist/meta/components.json +1616 -238
  45. package/dist/meta/contrast.json +398 -74
  46. package/dist/meta/index.json +84 -8
  47. package/dist/meta/patterns/DataTable.json +33 -6
  48. package/dist/meta/patterns/Form.json +27 -2
  49. package/dist/meta/patterns/index.json +6 -2
  50. package/dist/styles/fieldset.css +65 -0
  51. package/dist/styles/index.css +4 -0
  52. package/dist/styles/multi-select.css +104 -0
  53. package/dist/styles/radio.css +0 -20
  54. package/dist/styles/search-field.css +70 -0
  55. package/dist/styles/toolbar.css +36 -0
  56. package/llms.txt +2 -2
  57. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { type FieldsetOrientation } from './Fieldset.js';
2
3
  import { type SelectionProps } from './resolve-selection.js';
3
4
  export type CheckboxSize = 'sm' | 'md' | 'lg';
4
5
  export type CheckboxIntent = 'brand' | 'neutral' | 'danger';
@@ -34,4 +35,42 @@ export interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputE
34
35
  * declaratively and it must be written after every render.
35
36
  */
36
37
  export declare const Checkbox: React.ForwardRefExoticComponent<CheckboxProps & React.RefAttributes<HTMLInputElement>>;
38
+ export interface CheckboxGroupProps extends Omit<React.FieldsetHTMLAttributes<HTMLFieldSetElement>, 'onChange' | 'defaultValue' | 'disabled'> {
39
+ /** The question the options answer. Renders as the `<legend>`. */
40
+ label?: React.ReactNode;
41
+ /** Help text beneath the options. Replaced by `errorMessage` while invalid. */
42
+ description?: React.ReactNode;
43
+ /** Shown in the description's place while `isInvalid` is set. */
44
+ errorMessage?: React.ReactNode;
45
+ /** Marks every box invalid and shows `errorMessage`. */
46
+ isInvalid?: boolean;
47
+ /** At least one option must be selected — enforced by native validation. */
48
+ isRequired?: boolean;
49
+ /** The selected values (controlled). */
50
+ value?: readonly string[];
51
+ /** The initially selected values (uncontrolled). */
52
+ defaultValue?: readonly string[];
53
+ /** Receives the whole new selection, in the order the options were ticked. */
54
+ onChange?: (value: string[]) => void;
55
+ /** Shared input name, so a form submits every ticked value under it. */
56
+ name?: string;
57
+ size?: CheckboxSize;
58
+ intent?: CheckboxIntent;
59
+ /** Whether every checkbox in the group is disabled. */
60
+ isDisabled?: boolean;
61
+ orientation?: FieldsetOrientation;
62
+ /** Checkboxes, each with a `value`. */
63
+ children?: React.ReactNode;
64
+ }
65
+ /**
66
+ * A set of checkboxes that answers one question — "notify me when…", "which
67
+ * regions". Owns the selected values, the group's label, help text and error,
68
+ * and "select at least one".
69
+ *
70
+ * A row of loose Checkboxes can do none of that accessibly: the question is
71
+ * not announced with the options, an error has nothing to attach to, and
72
+ * "at least one" has no native expression at all. See the `required` note in
73
+ * Checkbox for how that last one is done.
74
+ */
75
+ export declare const CheckboxGroup: React.ForwardRefExoticComponent<CheckboxGroupProps & React.RefAttributes<HTMLFieldSetElement>>;
37
76
  //# sourceMappingURL=Checkbox.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../../src/components/Checkbox.tsx"],"names":[],"mappings":"AAEA,OAAO,KAKN,MAAM,OAAO,CAAC;AAEf,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE/E,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC9C,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE5D,MAAM,WAAW,aACf,SACE,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,EAClE,cAAc;IAChB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,iEAAiE;IACjE,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AA2BD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,QAAQ,wFA8DpB,CAAC"}
1
+ {"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../../src/components/Checkbox.tsx"],"names":[],"mappings":"AAEA,OAAO,KAQN,MAAM,OAAO,CAAC;AACf,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE/E,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC9C,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAwB5D,MAAM,WAAW,aACf,SACE,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,EAClE,cAAc;IAChB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,iEAAiE;IACjE,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AA2BD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,QAAQ,wFAsGpB,CAAC;AAIF,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAC9C,KAAK,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,EACjD,UAAU,GAAG,cAAc,GAAG,UAAU,CACzC;IACC,kEAAkE;IAClE,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,iEAAiE;IACjE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wCAAwC;IACxC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,oDAAoD;IACpD,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,uDAAuD;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,uCAAuC;IACvC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,gGA+DxB,CAAC"}
@@ -1,8 +1,16 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { forwardRef, useRef, useImperativeHandle, useEffect, } from 'react';
3
+ import { createContext, forwardRef, useContext, useEffect, useImperativeHandle, useRef, useState, } from 'react';
4
+ import { FieldsetShell, useFieldsetHelper, } from './Fieldset.js';
4
5
  import { resolveDisabled } from './resolve-disabled.js';
5
6
  import { resolveSelection } from './resolve-selection.js';
7
+ /**
8
+ * Lets CheckboxGroup own the selected values the way RadioGroup owns the
9
+ * selected value: each Checkbox reads whether its `value` is in the set and
10
+ * reports its toggles, and the caller wires one `onChange` instead of one per
11
+ * option.
12
+ */
13
+ const CheckboxGroupContext = createContext(null);
6
14
  /** Figma's check glyph. Inlined for the same reason as Select's chevron: it is
7
15
  * part of the control, not a slot a caller fills. */
8
16
  const CheckMark = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", focusable: "false", children: _jsx("path", { d: "m5 13 4 4L19 7", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round" }) }));
@@ -20,9 +28,35 @@ const DashMark = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", "aria-
20
28
  * declaratively and it must be written after every render.
21
29
  */
22
30
  export const Checkbox = forwardRef((props, forwardedRef) => {
23
- const { size = 'md', intent = 'brand', isIndeterminate = false, className, children, isDisabled, disabled, isSelected, checked, onChange, onSelectionChange, ...rest } = props;
24
- const resolvedDisabled = resolveDisabled(isDisabled, disabled);
31
+ const group = useContext(CheckboxGroupContext);
32
+ const { size = group?.size ?? 'md', intent = group?.intent ?? 'brand', isIndeterminate = false, className, children, isDisabled, disabled, isSelected, checked, onChange, onSelectionChange, name = group?.name, 'aria-describedby': describedBy, ...rest } = props;
33
+ const resolvedDisabled = resolveDisabled(isDisabled, disabled) ?? group?.isDisabled;
25
34
  const selection = resolveSelection(isSelected, checked, onChange, onSelectionChange);
35
+ /*
36
+ * Inside a group the group owns `checked`, and the box's own handlers still
37
+ * fire after it — the contract RadioGroup settled on, so neither control
38
+ * honours a handler in one mode and drops it in the other.
39
+ */
40
+ const value = rest.value === undefined ? '' : String(rest.value);
41
+ const groupSelection = group
42
+ ? {
43
+ checked: group.selected.includes(value),
44
+ onChange: (event) => {
45
+ group.toggle(value, event.target.checked);
46
+ selection.onChange?.(event);
47
+ },
48
+ }
49
+ : selection;
50
+ /*
51
+ * "Select at least one", in the platform's own words. `required` on a
52
+ * checkbox means "this one must be ticked", so it is set on every box while
53
+ * none is and dropped from all of them the moment one is: native
54
+ * validation then blocks the submit with the browser's localised message,
55
+ * and each box announces "required" exactly while the rule is unmet.
56
+ */
57
+ const required = group?.isRequired
58
+ ? group.selected.length === 0
59
+ : rest.required;
26
60
  const domRef = useRef(null);
27
61
  useImperativeHandle(forwardedRef, () => domRef.current);
28
62
  useEffect(() => {
@@ -38,7 +72,46 @@ export const Checkbox = forwardRef((props, forwardedRef) => {
38
72
  ]
39
73
  .filter(Boolean)
40
74
  .join(' ');
41
- return (_jsxs("label", { className: classNames, children: [_jsx("input", { ...rest, ref: domRef, type: "checkbox", checked: selection.checked, onChange: selection.onChange, disabled: resolvedDisabled, className: "ion-checkbox__input" }), _jsx("span", { className: "ion-checkbox__indicator", "aria-hidden": "true", children: _jsx("span", { className: "ion-checkbox__mark", children: isIndeterminate ? _jsx(DashMark, {}) : _jsx(CheckMark, {}) }) }), children && _jsx("span", { className: "ion-checkbox__label", children: children })] }));
75
+ return (_jsxs("label", { className: classNames, children: [_jsx("input", { ...rest, ref: domRef, type: "checkbox", name: name, required: required, checked: groupSelection.checked, onChange: groupSelection.onChange, disabled: resolvedDisabled, "aria-invalid": group?.isInvalid || rest['aria-invalid'], "aria-describedby": [describedBy, group?.helperId].filter(Boolean).join(' ') ||
76
+ undefined, className: "ion-checkbox__input" }), _jsx("span", { className: "ion-checkbox__indicator", "aria-hidden": "true", children: _jsx("span", { className: "ion-checkbox__mark", children: isIndeterminate ? _jsx(DashMark, {}) : _jsx(CheckMark, {}) }) }), children && _jsx("span", { className: "ion-checkbox__label", children: children })] }));
42
77
  });
43
78
  Checkbox.displayName = 'Checkbox';
79
+ /**
80
+ * A set of checkboxes that answers one question — "notify me when…", "which
81
+ * regions". Owns the selected values, the group's label, help text and error,
82
+ * and "select at least one".
83
+ *
84
+ * A row of loose Checkboxes can do none of that accessibly: the question is
85
+ * not announced with the options, an error has nothing to attach to, and
86
+ * "at least one" has no native expression at all. See the `required` note in
87
+ * Checkbox for how that last one is done.
88
+ */
89
+ export const CheckboxGroup = forwardRef((props, ref) => {
90
+ const { value: controlledValue, defaultValue, onChange, name, size, intent, isDisabled, isRequired, description, errorMessage, ...rest } = props;
91
+ const [uncontrolled, setUncontrolled] = useState(defaultValue ?? []);
92
+ const selected = controlledValue ?? uncontrolled;
93
+ const toggle = (value, isSelected) => {
94
+ const next = isSelected
95
+ ? selected.includes(value)
96
+ ? [...selected]
97
+ : [...selected, value]
98
+ : selected.filter((v) => v !== value);
99
+ if (controlledValue === undefined)
100
+ setUncontrolled(next);
101
+ onChange?.(next);
102
+ };
103
+ const { helper, helperId } = useFieldsetHelper(description, errorMessage, rest.isInvalid);
104
+ return (_jsx(CheckboxGroupContext.Provider, { value: {
105
+ name,
106
+ selected,
107
+ toggle,
108
+ size,
109
+ intent,
110
+ isDisabled,
111
+ isInvalid: rest.isInvalid,
112
+ isRequired,
113
+ helperId,
114
+ }, children: _jsx(FieldsetShell, { ...rest, ref: ref, disabled: isDisabled, isChoiceGroup: true, helper: helper, helperId: helperId }) }));
115
+ });
116
+ CheckboxGroup.displayName = 'CheckboxGroup';
44
117
  //# sourceMappingURL=Checkbox.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.js","sourceRoot":"","sources":["../../src/components/Checkbox.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAc,EACZ,UAAU,EACV,MAAM,EACN,mBAAmB,EACnB,SAAS,GACV,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAuB,MAAM,wBAAwB,CAAC;AA4B/E;sDACsD;AACtD,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,CACtB,cAAK,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,iBAAa,MAAM,EAAC,SAAS,EAAC,OAAO,YACvE,eACE,CAAC,EAAC,gBAAgB,EAClB,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,GACtB,GACE,CACP,CAAC;AAEF,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,CACrB,cAAK,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,iBAAa,MAAM,EAAC,SAAS,EAAC,OAAO,YACvE,eACE,CAAC,EAAC,UAAU,EACZ,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,GACrB,GACE,CACP,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAChC,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE;IACtB,MAAM,EACJ,IAAI,GAAG,IAAI,EACX,MAAM,GAAG,OAAO,EAChB,eAAe,GAAG,KAAK,EACvB,SAAS,EACT,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,UAAU,EACV,OAAO,EACP,QAAQ,EACR,iBAAiB,EACjB,GAAG,IAAI,EACR,GAAG,KAAK,CAAC;IAEV,MAAM,gBAAgB,GAAG,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,gBAAgB,CAChC,UAAU,EACV,OAAO,EACP,QAAQ,EACR,iBAAiB,CAClB,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;IAC9C,mBAAmB,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAQ,CAAC,CAAC;IAEzD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,CAAC,OAAO;YAAE,MAAM,CAAC,OAAO,CAAC,aAAa,GAAG,eAAe,CAAC;IACrE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;IAEtB,MAAM,UAAU,GAAG;QACjB,cAAc;QACd,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;QAC5C,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,iBAAiB,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE;QACnD,gBAAgB,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE;QAChD,SAAS,IAAI,EAAE;KAChB;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,OAAO,CACL,iBAAO,SAAS,EAAE,UAAU,aAC1B,mBACM,IAAI,EACR,GAAG,EAAE,MAAM,EACX,IAAI,EAAC,UAAU,EACf,OAAO,EAAE,SAAS,CAAC,OAAO,EAC1B,QAAQ,EAAE,SAAS,CAAC,QAAQ,EAC5B,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAC,qBAAqB,GAC/B,EACF,eAAM,SAAS,EAAC,yBAAyB,iBAAa,MAAM,YAC1D,eAAM,SAAS,EAAC,oBAAoB,YACjC,eAAe,CAAC,CAAC,CAAC,KAAC,QAAQ,KAAG,CAAC,CAAC,CAAC,KAAC,SAAS,KAAG,GAC1C,GACF,EACN,QAAQ,IAAI,eAAM,SAAS,EAAC,qBAAqB,YAAE,QAAQ,GAAQ,IAC9D,CACT,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,QAAQ,CAAC,WAAW,GAAG,UAAU,CAAC"}
1
+ {"version":3,"file":"Checkbox.js","sourceRoot":"","sources":["../../src/components/Checkbox.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAc,EACZ,aAAa,EACb,UAAU,EACV,UAAU,EACV,SAAS,EACT,mBAAmB,EACnB,MAAM,EACN,QAAQ,GACT,MAAM,OAAO,CAAC;AACf,OAAO,EACL,aAAa,EACb,iBAAiB,GAElB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAuB,MAAM,wBAAwB,CAAC;AAiB/E;;;;;GAKG;AACH,MAAM,oBAAoB,GAAG,aAAa,CACxC,IAAI,CACL,CAAC;AAyBF;sDACsD;AACtD,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,CACtB,cAAK,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,iBAAa,MAAM,EAAC,SAAS,EAAC,OAAO,YACvE,eACE,CAAC,EAAC,gBAAgB,EAClB,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,GACtB,GACE,CACP,CAAC;AAEF,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,CACrB,cAAK,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,iBAAa,MAAM,EAAC,SAAS,EAAC,OAAO,YACvE,eACE,CAAC,EAAC,UAAU,EACZ,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,GACrB,GACE,CACP,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAChC,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE;IACtB,MAAM,KAAK,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;IAC/C,MAAM,EACJ,IAAI,GAAG,KAAK,EAAE,IAAI,IAAI,IAAI,EAC1B,MAAM,GAAG,KAAK,EAAE,MAAM,IAAI,OAAO,EACjC,eAAe,GAAG,KAAK,EACvB,SAAS,EACT,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,UAAU,EACV,OAAO,EACP,QAAQ,EACR,iBAAiB,EACjB,IAAI,GAAG,KAAK,EAAE,IAAI,EAClB,kBAAkB,EAAE,WAAW,EAC/B,GAAG,IAAI,EACR,GAAG,KAAK,CAAC;IAEV,MAAM,gBAAgB,GACpB,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,KAAK,EAAE,UAAU,CAAC;IAC7D,MAAM,SAAS,GAAG,gBAAgB,CAChC,UAAU,EACV,OAAO,EACP,QAAQ,EACR,iBAAiB,CAClB,CAAC;IAEF;;;;OAIG;IACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjE,MAAM,cAAc,GAAG,KAAK;QAC1B,CAAC,CAAC;YACE,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;YACvC,QAAQ,EAAE,CAAC,KAA0C,EAAE,EAAE;gBACvD,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAC1C,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;YAC9B,CAAC;SACF;QACH,CAAC,CAAC,SAAS,CAAC;IAEd;;;;;;OAMG;IACH,MAAM,QAAQ,GAAG,KAAK,EAAE,UAAU;QAChC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;QAC7B,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;IAElB,MAAM,MAAM,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;IAC9C,mBAAmB,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAQ,CAAC,CAAC;IAEzD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,CAAC,OAAO;YAAE,MAAM,CAAC,OAAO,CAAC,aAAa,GAAG,eAAe,CAAC;IACrE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;IAEtB,MAAM,UAAU,GAAG;QACjB,cAAc;QACd,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;QAC5C,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,iBAAiB,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE;QACnD,gBAAgB,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE;QAChD,SAAS,IAAI,EAAE;KAChB;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,OAAO,CACL,iBAAO,SAAS,EAAE,UAAU,aAC1B,mBACM,IAAI,EACR,GAAG,EAAE,MAAM,EACX,IAAI,EAAC,UAAU,EACf,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,cAAc,CAAC,OAAO,EAC/B,QAAQ,EAAE,cAAc,CAAC,QAAQ,EACjC,QAAQ,EAAE,gBAAgB,kBACZ,KAAK,EAAE,SAAS,IAAI,IAAI,CAAC,cAAc,CAAC,sBAIpD,CAAC,WAAW,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;oBACxD,SAAS,EAEX,SAAS,EAAC,qBAAqB,GAC/B,EACF,eAAM,SAAS,EAAC,yBAAyB,iBAAa,MAAM,YAC1D,eAAM,SAAS,EAAC,oBAAoB,YACjC,eAAe,CAAC,CAAC,CAAC,KAAC,QAAQ,KAAG,CAAC,CAAC,CAAC,KAAC,SAAS,KAAG,GAC1C,GACF,EACN,QAAQ,IAAI,eAAM,SAAS,EAAC,qBAAqB,YAAE,QAAQ,GAAQ,IAC9D,CACT,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,QAAQ,CAAC,WAAW,GAAG,UAAU,CAAC;AAiClC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAGrC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACf,MAAM,EACJ,KAAK,EAAE,eAAe,EACtB,YAAY,EACZ,QAAQ,EACR,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,UAAU,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,GAAG,IAAI,EACR,GAAG,KAAK,CAAC;IAEV,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAC9C,YAAY,IAAI,EAAE,CACnB,CAAC;IACF,MAAM,QAAQ,GAAG,eAAe,IAAI,YAAY,CAAC;IAEjD,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,UAAmB,EAAE,EAAE;QACpD,MAAM,IAAI,GAAG,UAAU;YACrB,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACxB,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;gBACf,CAAC,CAAC,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC;YACxB,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC;QACxC,IAAI,eAAe,KAAK,SAAS;YAAE,eAAe,CAAC,IAAI,CAAC,CAAC;QACzD,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC,CAAC;IAEF,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,iBAAiB,CAC5C,WAAW,EACX,YAAY,EACZ,IAAI,CAAC,SAAS,CACf,CAAC;IAEF,OAAO,CACL,KAAC,oBAAoB,CAAC,QAAQ,IAC5B,KAAK,EAAE;YACL,IAAI;YACJ,QAAQ;YACR,MAAM;YACN,IAAI;YACJ,MAAM;YACN,UAAU;YACV,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,UAAU;YACV,QAAQ;SACT,YAED,KAAC,aAAa,OACR,IAAI,EACR,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,UAAU,EACpB,aAAa,QACb,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,GAClB,GAC4B,CACjC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,aAAa,CAAC,WAAW,GAAG,eAAe,CAAC"}
@@ -0,0 +1,62 @@
1
+ import React from 'react';
2
+ export type FieldsetOrientation = 'vertical' | 'horizontal';
3
+ export interface FieldsetProps extends Omit<React.FieldsetHTMLAttributes<HTMLFieldSetElement>, 'disabled'> {
4
+ /** The question the fields answer. Renders as the `<legend>`. */
5
+ label?: React.ReactNode;
6
+ /** Help text beneath the fields. Replaced by `errorMessage` while invalid. */
7
+ description?: React.ReactNode;
8
+ /** Shown in the description's place while `isInvalid` is set. */
9
+ errorMessage?: React.ReactNode;
10
+ /** Whether the group as a whole fails validation. */
11
+ isInvalid?: boolean;
12
+ /** How the fields flow. Horizontal wraps rather than overflowing. */
13
+ orientation?: FieldsetOrientation;
14
+ children?: React.ReactNode;
15
+ }
16
+ /**
17
+ * The ids a group hands down to its own controls. Kept separate from the
18
+ * rendering so CheckboxGroup and RadioGroup can give every checkbox and radio
19
+ * the same `aria-describedby` the fieldset carries — see FieldsetShell.
20
+ */
21
+ export declare function useFieldsetHelper(description: React.ReactNode, errorMessage: React.ReactNode, isInvalid: boolean | undefined): {
22
+ helper: React.ReactNode;
23
+ helperId: string | undefined;
24
+ };
25
+ interface FieldsetShellProps extends Omit<FieldsetProps, 'description' | 'errorMessage'> {
26
+ /** Only the choice groups may disable natively — see Fieldset. */
27
+ disabled?: boolean;
28
+ /** Choice groups space their options at 8, not a form's 16. */
29
+ isChoiceGroup?: boolean;
30
+ /** The description or the error, whichever shows — see useFieldsetHelper. */
31
+ helper: React.ReactNode;
32
+ helperId: string | undefined;
33
+ }
34
+ /**
35
+ * The rendering shared by Fieldset, CheckboxGroup and RadioGroup.
36
+ *
37
+ * A real `<fieldset>`: the legend names the group for assistive technology and
38
+ * the inputs stay grouped for form submission, neither of which a div with
39
+ * `role="group"` gets for free.
40
+ *
41
+ * The fieldset is `display: block` on purpose. A rendered `<legend>` is not a
42
+ * flex item — browsers lay it out in the fieldset's border, outside the flex
43
+ * container — so a flex column here would put `gap` everywhere but under the
44
+ * legend. The fields get a flex wrapper of their own instead.
45
+ */
46
+ export declare const FieldsetShell: React.ForwardRefExoticComponent<FieldsetShellProps & React.RefAttributes<HTMLFieldSetElement>>;
47
+ /**
48
+ * Groups related fields under one label, with one description and one error —
49
+ * an address, a date range typed as two fields, a set of limits.
50
+ *
51
+ * For checkboxes use CheckboxGroup and for radios RadioGroup: both render this
52
+ * same shell, and add the selection state it deliberately does not own.
53
+ *
54
+ * There is no `isDisabled`. A native `disabled` fieldset does disable every
55
+ * control inside, but Input, Select and the rest draw their disabled state from
56
+ * their own prop, so the fields would stop working while still looking live.
57
+ * Disable the fields themselves; the choice groups can cascade because their
58
+ * checkboxes and radios style off `:disabled`.
59
+ */
60
+ export declare const Fieldset: React.ForwardRefExoticComponent<FieldsetProps & React.RefAttributes<HTMLFieldSetElement>>;
61
+ export {};
62
+ //# sourceMappingURL=Fieldset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Fieldset.d.ts","sourceRoot":"","sources":["../../src/components/Fieldset.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAEjD,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,YAAY,CAAC;AAE5D,MAAM,WAAW,aAAc,SAAQ,IAAI,CACzC,KAAK,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,EACjD,UAAU,CACX;IACC,iEAAiE;IACjE,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,iEAAiE;IACjE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,qDAAqD;IACrD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,qEAAqE;IACrE,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,KAAK,CAAC,SAAS,EAC5B,YAAY,EAAE,KAAK,CAAC,SAAS,EAC7B,SAAS,EAAE,OAAO,GAAG,SAAS;;;EAM/B;AAED,UAAU,kBAAmB,SAAQ,IAAI,CACvC,aAAa,EACb,aAAa,GAAG,cAAc,CAC/B;IACC,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,6EAA6E;IAC7E,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,gGA4CxB,CAAC;AAIH;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,QAAQ,2FAYpB,CAAC"}
@@ -0,0 +1,58 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef, useId } from 'react';
3
+ /**
4
+ * The ids a group hands down to its own controls. Kept separate from the
5
+ * rendering so CheckboxGroup and RadioGroup can give every checkbox and radio
6
+ * the same `aria-describedby` the fieldset carries — see FieldsetShell.
7
+ */
8
+ export function useFieldsetHelper(description, errorMessage, isInvalid) {
9
+ const helperId = useId();
10
+ // Input's convention: the error takes the helper's slot, it does not stack.
11
+ const helper = isInvalid && errorMessage ? errorMessage : description;
12
+ return { helper, helperId: helper ? helperId : undefined };
13
+ }
14
+ /**
15
+ * The rendering shared by Fieldset, CheckboxGroup and RadioGroup.
16
+ *
17
+ * A real `<fieldset>`: the legend names the group for assistive technology and
18
+ * the inputs stay grouped for form submission, neither of which a div with
19
+ * `role="group"` gets for free.
20
+ *
21
+ * The fieldset is `display: block` on purpose. A rendered `<legend>` is not a
22
+ * flex item — browsers lay it out in the fieldset's border, outside the flex
23
+ * container — so a flex column here would put `gap` everywhere but under the
24
+ * legend. The fields get a flex wrapper of their own instead.
25
+ */
26
+ export const FieldsetShell = forwardRef((props, ref) => {
27
+ const { label, isInvalid, orientation = 'vertical', isChoiceGroup = false, helper, helperId, className, children, 'aria-describedby': describedBy, ...rest } = props;
28
+ return (_jsxs("fieldset", { ...rest, ref: ref, "aria-describedby": [describedBy, helperId].filter(Boolean).join(' ') || undefined, "data-invalid": isInvalid || undefined, className: [
29
+ 'ion-fieldset',
30
+ isChoiceGroup ? 'ion-fieldset--choices' : '',
31
+ orientation === 'horizontal' ? 'ion-fieldset--horizontal' : '',
32
+ isInvalid ? 'ion-fieldset--error' : '',
33
+ className || '',
34
+ ]
35
+ .filter(Boolean)
36
+ .join(' '), children: [label && _jsx("legend", { className: "ion-fieldset__legend", children: label }), _jsx("div", { className: "ion-fieldset__content", children: children }), helper && (_jsx("span", { id: helperId, className: "ion-fieldset__helper", children: helper }))] }));
37
+ });
38
+ FieldsetShell.displayName = 'FieldsetShell';
39
+ /**
40
+ * Groups related fields under one label, with one description and one error —
41
+ * an address, a date range typed as two fields, a set of limits.
42
+ *
43
+ * For checkboxes use CheckboxGroup and for radios RadioGroup: both render this
44
+ * same shell, and add the selection state it deliberately does not own.
45
+ *
46
+ * There is no `isDisabled`. A native `disabled` fieldset does disable every
47
+ * control inside, but Input, Select and the rest draw their disabled state from
48
+ * their own prop, so the fields would stop working while still looking live.
49
+ * Disable the fields themselves; the choice groups can cascade because their
50
+ * checkboxes and radios style off `:disabled`.
51
+ */
52
+ export const Fieldset = forwardRef((props, ref) => {
53
+ const { description, errorMessage, ...rest } = props;
54
+ const { helper, helperId } = useFieldsetHelper(description, errorMessage, rest.isInvalid);
55
+ return (_jsx(FieldsetShell, { ...rest, ref: ref, helper: helper, helperId: helperId }));
56
+ });
57
+ Fieldset.displayName = 'Fieldset';
58
+ //# sourceMappingURL=Fieldset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Fieldset.js","sourceRoot":"","sources":["../../src/components/Fieldset.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAqBjD;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,WAA4B,EAC5B,YAA6B,EAC7B,SAA8B;IAE9B,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAC;IACzB,4EAA4E;IAC5E,MAAM,MAAM,GAAG,SAAS,IAAI,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC;IACtE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;AAC7D,CAAC;AAeD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAGrC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACf,MAAM,EACJ,KAAK,EACL,SAAS,EACT,WAAW,GAAG,UAAU,EACxB,aAAa,GAAG,KAAK,EACrB,MAAM,EACN,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,kBAAkB,EAAE,WAAW,EAC/B,GAAG,IAAI,EACR,GAAG,KAAK,CAAC;IAEV,OAAO,CACL,uBACM,IAAI,EACR,GAAG,EAAE,GAAG,sBAEN,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,kBAElD,SAAS,IAAI,SAAS,EACpC,SAAS,EAAE;YACT,cAAc;YACd,aAAa,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE;YAC5C,WAAW,KAAK,YAAY,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,EAAE;YAC9D,SAAS,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE;YACtC,SAAS,IAAI,EAAE;SAChB;aACE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,GAAG,CAAC,aAEX,KAAK,IAAI,iBAAQ,SAAS,EAAC,sBAAsB,YAAE,KAAK,GAAU,EACnE,cAAK,SAAS,EAAC,uBAAuB,YAAE,QAAQ,GAAO,EACtD,MAAM,IAAI,CACT,eAAM,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAC,sBAAsB,YACjD,MAAM,GACF,CACR,IACQ,CACZ,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,aAAa,CAAC,WAAW,GAAG,eAAe,CAAC;AAE5C;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAChC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACb,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IACrD,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,iBAAiB,CAC5C,WAAW,EACX,YAAY,EACZ,IAAI,CAAC,SAAS,CACf,CAAC;IACF,OAAO,CACL,KAAC,aAAa,OAAK,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAI,CAC1E,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,QAAQ,CAAC,WAAW,GAAG,UAAU,CAAC"}
@@ -0,0 +1,90 @@
1
+ import React from 'react';
2
+ import type { ComboboxOption } from './Combobox.js';
3
+ export type MultiSelectSize = 'sm' | 'md' | 'lg';
4
+ /** The same shape as Combobox's option, so a list moves between the two. */
5
+ export type MultiSelectOption = ComboboxOption;
6
+ export interface MultiSelectProps {
7
+ /** The full option list. Filtering happens here, against what is typed. */
8
+ options: readonly MultiSelectOption[];
9
+ /** Field label. Required for a usable control — see `a11y.requires`. */
10
+ label?: React.ReactNode;
11
+ /** Names the field, and its tags, when there is no visible `label`. */
12
+ 'aria-label'?: string;
13
+ /** Helper text below the field. */
14
+ description?: React.ReactNode;
15
+ /** Replaces the helper text when `isInvalid` is set. */
16
+ errorMessage?: React.ReactNode;
17
+ isInvalid?: boolean;
18
+ isDisabled?: boolean;
19
+ isReadOnly?: boolean;
20
+ /** At least one value must be chosen. */
21
+ isRequired?: boolean;
22
+ /** Matches Input's `Size` variant: Small, Medium, Large. */
23
+ size?: MultiSelectSize;
24
+ placeholder?: string;
25
+ /** The selected values (controlled), in the order they were chosen. */
26
+ value?: readonly string[];
27
+ /** The initially selected values (uncontrolled). */
28
+ defaultValue?: readonly string[];
29
+ /** Receives the whole new selection. */
30
+ onChange?: (value: string[]) => void;
31
+ /** Controlled filter text. Usually only needed for remote filtering. */
32
+ inputValue?: string;
33
+ onInputChange?: (value: string) => void;
34
+ /**
35
+ * Leave the tags out, when the chosen values are already on screen as
36
+ * removable tags — a table's active-filters row. The values are still read
37
+ * with the field, and still marked in the list.
38
+ */
39
+ hideTags?: boolean;
40
+ /** Shown in place of the list when nothing matches. */
41
+ emptyLabel?: React.ReactNode;
42
+ /** Accessible label for the disclosure button. */
43
+ buttonLabel?: string;
44
+ /** Posts every selected value under this name, for an uncontrolled form. */
45
+ name?: string;
46
+ /** Class names for the field box (`.ion-input`). */
47
+ className?: string;
48
+ /** Class names for the `.ion-field` wrapper. */
49
+ wrapperClassName?: string;
50
+ id?: string;
51
+ }
52
+ /**
53
+ * MultiSelect — a text field that filters a list, with any number of selected
54
+ * values shown as removable tags beneath it.
55
+ *
56
+ * WHY IT IS ITS OWN COMPONENT, NOT `Combobox selectionMode="multiple"`
57
+ *
58
+ * The two differ in what the field holds. Combobox's input shows the chosen
59
+ * label — typing edits the value. Here the input only ever holds the filter
60
+ * text, the value lives in the tags, and choosing an option leaves the list
61
+ * open for the next one. One prop switching the meaning of the text in the
62
+ * box is the kind of contract agents get wrong in generated code.
63
+ *
64
+ * WHAT REACT ARIA GIVES IT
65
+ *
66
+ * `useComboBoxState` and `useComboBox` in `selectionMode: 'multiple'`: the
67
+ * listbox is `aria-multiselectable`, Enter and click toggle an option without
68
+ * closing the list, the filter text clears after each pick, and native
69
+ * `required` is set only while nothing is chosen — "at least one", the same
70
+ * rule CheckboxGroup enforces.
71
+ *
72
+ * WHAT IT ADDS
73
+ *
74
+ * - The tags. A TagGroup under the field, named by the field's label, one
75
+ * tab stop, Delete or the × to remove. The selection must be visible with
76
+ * the list closed, and "3 selected" hides which three.
77
+ * - The value is announced with the field. React Aria points the input's
78
+ * `aria-describedby` at a value element; this fills it with the chosen
79
+ * labels joined by `Intl.ListFormat`, so "Billing, Legal and Ops" is read
80
+ * in the user's language with no string shipped for it.
81
+ * - Backspace in an empty field removes the last value, which is what
82
+ * every tag input on the web has taught people to expect.
83
+ * - Focus lands back in the field when the last tag is removed, instead of
84
+ * falling to <body> with the TagGroup that held it.
85
+ */
86
+ export declare function MultiSelect({ options, label, 'aria-label': ariaLabel, description, errorMessage, isInvalid, isDisabled, isReadOnly, isRequired, size, placeholder, value, defaultValue, onChange, inputValue, onInputChange, hideTags, emptyLabel, buttonLabel, name, className, wrapperClassName, id, }: MultiSelectProps): React.JSX.Element;
87
+ export declare namespace MultiSelect {
88
+ var displayName: string;
89
+ }
90
+ //# sourceMappingURL=MultiSelect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MultiSelect.d.ts","sourceRoot":"","sources":["../../src/components/MultiSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAoC,MAAM,OAAO,CAAC;AAiBzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAIjD,4EAA4E;AAC5E,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAE/C,MAAM,WAAW,gBAAgB;IAC/B,2EAA2E;IAC3E,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACtC,wEAAwE;IACxE,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mCAAmC;IACnC,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,wDAAwD;IACxD,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yCAAyC;IACzC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,oDAAoD;IACpD,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,wCAAwC;IACxC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uDAAuD;IACvD,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAgKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,KAAK,EACL,YAAY,EAAE,SAAS,EACvB,WAAW,EACX,YAAY,EACZ,SAAS,EACT,UAAU,EACV,UAAU,EACV,UAAU,EACV,IAAW,EACX,WAAW,EACX,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,aAAa,EACb,QAAgB,EAChB,UAAyB,EACzB,WAA4B,EAC5B,IAAI,EACJ,SAAS,EACT,gBAAgB,EAChB,EAAE,GACH,EAAE,gBAAgB,qBAoOlB;yBA5Pe,WAAW"}
@@ -0,0 +1,189 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useMemo, useRef, useState } from 'react';
4
+ import { DismissButton, Overlay, useButton, useComboBox, useFilter, useListBox, useLocale, useOption, usePopover, } from 'react-aria';
5
+ import { Item, useComboBoxState } from 'react-stately';
6
+ import { Tag, TagGroup } from './TagGroup.js';
7
+ const ChevronDown = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", focusable: "false", children: _jsx("path", { d: "m6 9 6 6 6-6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }));
8
+ const CheckMark = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", focusable: "false", children: _jsx("path", { d: "m5 13 4 4L19 7", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round" }) }));
9
+ /* ------------------------------------------------------------------ option */
10
+ function MultiSelectOptionRow({ item, state, }) {
11
+ const ref = useRef(null);
12
+ const { optionProps, isSelected, isFocused, isDisabled } = useOption({ key: item.key }, state, ref);
13
+ const option = item.value;
14
+ return (_jsxs("li", { ...optionProps, ref: ref, className: "ion-combobox-menu__option ion-multi-select-menu__option", "data-focused": isFocused || undefined, "data-selected": isSelected || undefined, "data-disabled": isDisabled || undefined, children: [_jsx("span", { className: "ion-multi-select-menu__check", "aria-hidden": "true", children: _jsx(CheckMark, {}) }), _jsxs("span", { className: "ion-multi-select-menu__text", children: [_jsx("span", { className: "ion-combobox-menu__label", children: item.rendered }), option?.description && (_jsx("span", { className: "ion-combobox-menu__description", children: option.description }))] })] }));
15
+ }
16
+ /** Breathing room kept between the menu and the viewport edge, in px. */
17
+ const GUTTER = 8;
18
+ /* ----------------------------------------------------------------- listbox */
19
+ /**
20
+ * Mounted only while open, for the reason Combobox's is: `usePopover`
21
+ * positions in an effect of the component that calls it. The width is read
22
+ * during render for the reason given there, too — a ResizeObserver feeding a
23
+ * width back into a positioned popover closes it.
24
+ */
25
+ function MultiSelectListBox({ state, listBoxRef, popoverRef, triggerRef, listBoxProps, emptyLabel, }) {
26
+ const { popoverProps } = usePopover({
27
+ triggerRef,
28
+ popoverRef,
29
+ placement: 'bottom start',
30
+ offset: 4,
31
+ // Non-modal: focus stays in the input — see Combobox.
32
+ isNonModal: true,
33
+ }, state);
34
+ const { listBoxProps: innerListBoxProps } = useListBox(listBoxProps, state, listBoxRef);
35
+ const rect = triggerRef.current?.getBoundingClientRect();
36
+ const width = rect
37
+ ? Math.min(rect.width, document.documentElement.clientWidth - rect.left - GUTTER)
38
+ : undefined;
39
+ return (_jsx(Overlay, { children: _jsxs("div", { ...popoverProps, ref: popoverRef, className: "ion-combobox-menu", style: { ...popoverProps.style, width }, children: [_jsx(DismissButton, { onDismiss: () => state.close() }), _jsx("ul", { ...innerListBoxProps, ref: listBoxRef, className: "ion-combobox-menu__list", children: [...state.collection].map((item) => (_jsx(MultiSelectOptionRow, { item: item, state: state }, item.key))) }), state.collection.size === 0 && (_jsx("div", { className: "ion-combobox-menu__empty", role: "presentation", children: emptyLabel })), _jsx(DismissButton, { onDismiss: () => state.close() })] }) }));
40
+ }
41
+ /* ------------------------------------------------------------- multiselect */
42
+ /**
43
+ * MultiSelect — a text field that filters a list, with any number of selected
44
+ * values shown as removable tags beneath it.
45
+ *
46
+ * WHY IT IS ITS OWN COMPONENT, NOT `Combobox selectionMode="multiple"`
47
+ *
48
+ * The two differ in what the field holds. Combobox's input shows the chosen
49
+ * label — typing edits the value. Here the input only ever holds the filter
50
+ * text, the value lives in the tags, and choosing an option leaves the list
51
+ * open for the next one. One prop switching the meaning of the text in the
52
+ * box is the kind of contract agents get wrong in generated code.
53
+ *
54
+ * WHAT REACT ARIA GIVES IT
55
+ *
56
+ * `useComboBoxState` and `useComboBox` in `selectionMode: 'multiple'`: the
57
+ * listbox is `aria-multiselectable`, Enter and click toggle an option without
58
+ * closing the list, the filter text clears after each pick, and native
59
+ * `required` is set only while nothing is chosen — "at least one", the same
60
+ * rule CheckboxGroup enforces.
61
+ *
62
+ * WHAT IT ADDS
63
+ *
64
+ * - The tags. A TagGroup under the field, named by the field's label, one
65
+ * tab stop, Delete or the × to remove. The selection must be visible with
66
+ * the list closed, and "3 selected" hides which three.
67
+ * - The value is announced with the field. React Aria points the input's
68
+ * `aria-describedby` at a value element; this fills it with the chosen
69
+ * labels joined by `Intl.ListFormat`, so "Billing, Legal and Ops" is read
70
+ * in the user's language with no string shipped for it.
71
+ * - Backspace in an empty field removes the last value, which is what
72
+ * every tag input on the web has taught people to expect.
73
+ * - Focus lands back in the field when the last tag is removed, instead of
74
+ * falling to <body> with the TagGroup that held it.
75
+ */
76
+ export function MultiSelect({ options, label, 'aria-label': ariaLabel, description, errorMessage, isInvalid, isDisabled, isReadOnly, isRequired, size = 'md', placeholder, value, defaultValue, onChange, inputValue, onInputChange, hideTags = false, emptyLabel = 'No matches', buttonLabel = 'Show options', name, className, wrapperClassName, id, }) {
77
+ const { contains } = useFilter({ sensitivity: 'base' });
78
+ const { locale } = useLocale();
79
+ const [uncontrolled, setUncontrolled] = useState(defaultValue ?? []);
80
+ const selected = value ?? uncontrolled;
81
+ const setSelected = (next) => {
82
+ if (value === undefined)
83
+ setUncontrolled(next);
84
+ onChange?.(next);
85
+ };
86
+ const byValue = useMemo(() => new Map(options.map((o) => [o.value, o])), [options]);
87
+ // Filtered here, against label and description, for the reasons Combobox
88
+ // gives: `items` bypasses react-stately's filter, and `textValue` must stay
89
+ // the bare label.
90
+ const [typed, setTyped] = useState('');
91
+ const text = inputValue ?? typed;
92
+ const filtered = useMemo(() => {
93
+ if (!text)
94
+ return options;
95
+ return options.filter((o) => contains([o.label, o.description].filter(Boolean).join(' '), text));
96
+ }, [contains, options, text]);
97
+ const disabledKeys = useMemo(() => options.filter((o) => o.isDisabled).map((o) => o.value), [options]);
98
+ const state = useComboBoxState({
99
+ label: typeof label === 'string' ? label : undefined,
100
+ items: filtered,
101
+ children: (item) => (_jsx(Item, { textValue: item.label, children: item.label }, item.value)),
102
+ selectionMode: 'multiple',
103
+ disabledKeys,
104
+ allowsEmptyCollection: true,
105
+ isDisabled,
106
+ isReadOnly,
107
+ isRequired,
108
+ value: selected,
109
+ // The selection keeps insertion order — the order the tags appear in, and
110
+ // the order `onChange` reports. PickingKeepsTheListOpen pins it.
111
+ onChange: (keys) => setSelected([...keys].map(String)),
112
+ inputValue,
113
+ onInputChange: (v) => {
114
+ setTyped(v);
115
+ onInputChange?.(v);
116
+ },
117
+ });
118
+ const inputRef = useRef(null);
119
+ const listBoxRef = useRef(null);
120
+ const popoverRef = useRef(null);
121
+ const buttonRef = useRef(null);
122
+ const boxRef = useRef(null);
123
+ const remove = (keys) => {
124
+ const gone = new Set([...keys].map(String));
125
+ const next = selected.filter((v) => !gone.has(v));
126
+ setSelected(next);
127
+ // The TagGroup unmounts with its last tag; focus goes back to the field.
128
+ if (next.length === 0)
129
+ inputRef.current?.focus();
130
+ };
131
+ const { buttonProps: triggerProps, inputProps, listBoxProps, labelProps, descriptionProps, errorMessageProps, valueProps, } = useComboBox({
132
+ id,
133
+ label: typeof label === 'string' ? label : undefined,
134
+ 'aria-label': ariaLabel,
135
+ placeholder,
136
+ isDisabled,
137
+ isReadOnly,
138
+ isInvalid,
139
+ isRequired,
140
+ selectionMode: 'multiple',
141
+ inputRef,
142
+ listBoxRef,
143
+ popoverRef,
144
+ buttonRef,
145
+ onKeyDown: (e) => {
146
+ if (e.key === 'Backspace' &&
147
+ state.inputValue === '' &&
148
+ selected.length > 0 &&
149
+ !isReadOnly) {
150
+ remove([selected[selected.length - 1]]);
151
+ }
152
+ else {
153
+ e.continuePropagation();
154
+ }
155
+ },
156
+ }, state);
157
+ const { buttonProps } = useButton({ ...triggerProps, 'aria-label': buttonLabel }, buttonRef);
158
+ const labels = selected.map((v) => byValue.get(v)?.label ?? v);
159
+ const spoken = new Intl.ListFormat(locale, { type: 'conjunction' }).format(labels);
160
+ const helper = isInvalid && errorMessage ? errorMessage : description;
161
+ const boxClassNames = [
162
+ 'ion-input',
163
+ 'ion-combobox',
164
+ 'ion-multi-select',
165
+ size !== 'md' ? `ion-input--${size}` : '',
166
+ isInvalid ? 'ion-input--invalid' : '',
167
+ isDisabled ? 'ion-input--disabled' : '',
168
+ className || '',
169
+ ]
170
+ .filter(Boolean)
171
+ .join(' ');
172
+ return (_jsxs("div", { className: [
173
+ 'ion-field',
174
+ isInvalid ? 'ion-field--error' : '',
175
+ wrapperClassName || '',
176
+ ]
177
+ .filter(Boolean)
178
+ .join(' '), children: [label && (_jsx("label", { ...labelProps, className: "ion-field__label", children: label })), _jsxs("div", { ref: boxRef, className: boxClassNames, "data-open": state.isOpen || undefined, "data-invalid": isInvalid || undefined, "data-disabled": isDisabled || undefined, children: [_jsx("input", { ...inputProps, ref: inputRef, className: "ion-input__field" }), name &&
179
+ selected.map((v) => (_jsx("input", { type: "hidden", name: name, value: v }, v))), _jsx("button", { ...buttonProps, "aria-labelledby": undefined, "aria-label": buttonLabel,
180
+ // Pressing it must not take focus from the input — see Combobox.
181
+ onMouseDown: (e) => {
182
+ e.preventDefault();
183
+ inputRef.current?.focus();
184
+ }, ref: buttonRef, type: "button", tabIndex: -1, className: "ion-combobox__button", children: _jsx(ChevronDown, {}) })] }), _jsx("span", { ...valueProps, className: "ion-visually-hidden", children: spoken }), selected.length > 0 && !hideTags && (_jsx(TagGroup, { "aria-labelledby": label ? labelProps.id : undefined, "aria-label": label ? undefined : ariaLabel, size: size === 'lg' ? 'md' : 'sm', onRemove: isDisabled || isReadOnly ? undefined : remove, className: "ion-multi-select__tags", children: selected.map((v) => (_jsx(Tag, { textValue: byValue.get(v)?.label ?? v, children: byValue.get(v)?.label ?? v }, v))) })), state.isOpen && (_jsx(MultiSelectListBox, { state: state, listBoxRef: listBoxRef, popoverRef: popoverRef, triggerRef: boxRef, listBoxProps: listBoxProps, emptyLabel: emptyLabel })), helper && (_jsx("span", { ...(isInvalid && errorMessage
185
+ ? errorMessageProps
186
+ : descriptionProps), className: "ion-field__helper", children: helper }))] }));
187
+ }
188
+ MultiSelect.displayName = 'MultiSelect';
189
+ //# sourceMappingURL=MultiSelect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MultiSelect.js","sourceRoot":"","sources":["../../src/components/MultiSelect.tsx"],"names":[],"mappings":"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"}