ionbase-ui 0.84.0 → 0.86.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 (43) 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/Radio.d.ts +14 -0
  10. package/dist/components/Radio.d.ts.map +1 -1
  11. package/dist/components/Radio.js +15 -4
  12. package/dist/components/Radio.js.map +1 -1
  13. package/dist/components/SearchField.d.ts +36 -0
  14. package/dist/components/SearchField.d.ts.map +1 -0
  15. package/dist/components/SearchField.js +76 -0
  16. package/dist/components/SearchField.js.map +1 -0
  17. package/dist/components/index.d.ts +6 -2
  18. package/dist/components/index.d.ts.map +1 -1
  19. package/dist/components/index.js +3 -1
  20. package/dist/components/index.js.map +1 -1
  21. package/dist/figma-descriptions.json +87 -77
  22. package/dist/figma-map.json +132 -3
  23. package/dist/meta/Checkbox.json +8 -6
  24. package/dist/meta/CheckboxGroup.json +268 -0
  25. package/dist/meta/Divider.json +2 -2
  26. package/dist/meta/Fieldset.json +162 -0
  27. package/dist/meta/Radio.json +0 -1
  28. package/dist/meta/RadioGroup.json +59 -7
  29. package/dist/meta/SearchField.json +487 -0
  30. package/dist/meta/Stepper.json +2 -2
  31. package/dist/meta/Tabs.json +3 -3
  32. package/dist/meta/components.json +1015 -45
  33. package/dist/meta/contrast.json +370 -74
  34. package/dist/meta/index.json +59 -8
  35. package/dist/meta/patterns/DataTable.json +14 -6
  36. package/dist/meta/patterns/Form.json +27 -2
  37. package/dist/meta/patterns/index.json +4 -2
  38. package/dist/styles/fieldset.css +65 -0
  39. package/dist/styles/index.css +2 -0
  40. package/dist/styles/radio.css +0 -20
  41. package/dist/styles/search-field.css +70 -0
  42. package/llms.txt +2 -2
  43. 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":"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"}
1
+ {"version":3,"file":"Checkbox.js","sourceRoot":"","sources":["../../src/components/Checkbox.tsx"],"names":[],"mappings":"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"}
@@ -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"}
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { type FieldsetOrientation } from './Fieldset.js';
2
3
  export type RadioSize = 'sm' | 'md' | 'lg';
3
4
  export type RadioIntent = 'brand' | 'neutral' | 'danger';
4
5
  export interface RadioProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'type' | 'value'> {
@@ -20,7 +21,17 @@ export interface RadioGroupProps extends Omit<React.FieldsetHTMLAttributes<HTMLF
20
21
  value?: string;
21
22
  defaultValue?: string;
22
23
  onChange?: (value: string) => void;
24
+ /** The question the options answer. Renders as the `<legend>`. */
23
25
  label?: React.ReactNode;
26
+ /** Help text beneath the options. Replaced by `errorMessage` while invalid. */
27
+ description?: React.ReactNode;
28
+ /** Shown in the description's place while `isInvalid` is set. */
29
+ errorMessage?: React.ReactNode;
30
+ /** Shows `errorMessage` in the description's place. */
31
+ isInvalid?: boolean;
32
+ /** One option must be chosen before the form submits. */
33
+ isRequired?: boolean;
34
+ orientation?: FieldsetOrientation;
24
35
  size?: RadioSize;
25
36
  intent?: RadioIntent;
26
37
  /** Whether every radio in the group is disabled. */
@@ -36,6 +47,9 @@ export interface RadioGroupProps extends Omit<React.FieldsetHTMLAttributes<HTMLF
36
47
  * `role="radiogroup"`. Both are announced correctly, but a fieldset also groups
37
48
  * the inputs for form submission and native validation, which the ARIA version
38
49
  * does not.
50
+ *
51
+ * The fieldset itself is Fieldset's shell, shared with CheckboxGroup, so the
52
+ * two choice groups take the same label, help, error and orientation props.
39
53
  */
40
54
  export declare const RadioGroup: React.ForwardRefExoticComponent<RadioGroupProps & React.RefAttributes<HTMLFieldSetElement>>;
41
55
  //# sourceMappingURL=Radio.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Radio.d.ts","sourceRoot":"","sources":["../../src/components/Radio.tsx"],"names":[],"mappings":"AAEA,OAAO,KAON,MAAM,OAAO,CAAC;AAGf,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC3C,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAoBzD,MAAM,WAAW,UAAW,SAAQ,IAAI,CACtC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAC3C,MAAM,GAAG,MAAM,GAAG,OAAO,CAC1B;IACC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED,eAAO,MAAM,KAAK,qFAuEjB,CAAC;AAIF,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,KAAK,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,EACjD,UAAU,CACX;IACC,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;GAKG;AACH,eAAO,MAAM,UAAU,6FA4CtB,CAAC"}
1
+ {"version":3,"file":"Radio.d.ts","sourceRoot":"","sources":["../../src/components/Radio.tsx"],"names":[],"mappings":"AAEA,OAAO,KAON,MAAM,OAAO,CAAC;AACf,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,eAAe,CAAC;AAGvB,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC3C,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAsBzD,MAAM,WAAW,UAAW,SAAQ,IAAI,CACtC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAC3C,MAAM,GAAG,MAAM,GAAG,OAAO,CAC1B;IACC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED,eAAO,MAAM,KAAK,qFAiFjB,CAAC;AAIF,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,KAAK,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,EACjD,UAAU,CACX;IACC,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,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,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,yDAAyD;IACzD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,6FAoDtB,CAAC"}
@@ -1,6 +1,7 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { forwardRef, useRef, useImperativeHandle, useContext, createContext, useId, } from 'react';
4
+ import { FieldsetShell, useFieldsetHelper, } from './Fieldset.js';
4
5
  import { resolveDisabled } from './resolve-disabled.js';
5
6
  /**
6
7
  * A radio is meaningless alone — it needs siblings sharing a `name` and one
@@ -11,7 +12,7 @@ import { resolveDisabled } from './resolve-disabled.js';
11
12
  const RadioGroupContext = createContext(null);
12
13
  export const Radio = forwardRef((props, forwardedRef) => {
13
14
  const group = useContext(RadioGroupContext);
14
- const { value, size = group?.size ?? 'md', intent = group?.intent ?? 'brand', className, children, isDisabled, disabled, name = group?.name, ...rest } = props;
15
+ const { value, size = group?.size ?? 'md', intent = group?.intent ?? 'brand', className, children, isDisabled, disabled, name = group?.name, 'aria-describedby': describedBy, ...rest } = props;
15
16
  const resolvedDisabled = resolveDisabled(isDisabled, disabled) ?? group?.isDisabled;
16
17
  const domRef = useRef(null);
17
18
  useImperativeHandle(forwardedRef, () => domRef.current);
@@ -40,7 +41,11 @@ export const Radio = forwardRef((props, forwardedRef) => {
40
41
  group?.onChange?.(value);
41
42
  rest.onChange?.(e);
42
43
  };
43
- return (_jsxs("label", { className: classNames, children: [_jsx("input", { ...rest, ref: domRef, type: "radio", name: name, value: value, disabled: resolvedDisabled, className: "ion-radio__input", onChange: handleChange, ...(controlled
44
+ return (_jsxs("label", { className: classNames, children: [_jsx("input", { ...rest, ref: domRef, type: "radio", name: name, value: value, disabled: resolvedDisabled,
45
+ // Native `required` on a radio already means "one of this name" —
46
+ // unlike a checkbox, it needs no toggling to say "at least one".
47
+ required: group?.isRequired || rest.required, "aria-describedby": [describedBy, group?.helperId].filter(Boolean).join(' ') ||
48
+ undefined, className: "ion-radio__input", onChange: handleChange, ...(controlled
44
49
  ? { checked: group.value === value }
45
50
  : { defaultChecked: group?.defaultValue === value }) }), _jsx("span", { className: "ion-radio__indicator", "aria-hidden": "true", children: _jsx("span", { className: "ion-radio__dot" }) }), children && _jsx("span", { className: "ion-radio__label", children: children })] }));
46
51
  });
@@ -50,11 +55,15 @@ Radio.displayName = 'Radio';
50
55
  * `role="radiogroup"`. Both are announced correctly, but a fieldset also groups
51
56
  * the inputs for form submission and native validation, which the ARIA version
52
57
  * does not.
58
+ *
59
+ * The fieldset itself is Fieldset's shell, shared with CheckboxGroup, so the
60
+ * two choice groups take the same label, help, error and orientation props.
53
61
  */
54
62
  export const RadioGroup = forwardRef((props, ref) => {
55
- const { name, value, defaultValue, onChange, label, size, intent, isDisabled, disabled, className, children, ...rest } = props;
63
+ const { name, value, defaultValue, onChange, size, intent, isDisabled, disabled, isRequired, description, errorMessage, className, ...rest } = props;
56
64
  const resolvedDisabled = resolveDisabled(isDisabled, disabled);
57
65
  const generated = useId();
66
+ const { helper, helperId } = useFieldsetHelper(description, errorMessage, rest.isInvalid);
58
67
  return (_jsx(RadioGroupContext.Provider, { value: {
59
68
  name: name ?? generated,
60
69
  value,
@@ -63,7 +72,9 @@ export const RadioGroup = forwardRef((props, ref) => {
63
72
  size,
64
73
  intent,
65
74
  isDisabled: resolvedDisabled,
66
- }, children: _jsxs("fieldset", { ...rest, ref: ref, disabled: resolvedDisabled, className: ['ion-radio-group', className].filter(Boolean).join(' '), children: [label && _jsx("legend", { className: "ion-radio-group__label", children: label }), children] }) }));
75
+ isRequired,
76
+ helperId,
77
+ }, children: _jsx(FieldsetShell, { ...rest, ref: ref, disabled: resolvedDisabled, isChoiceGroup: true, helper: helper, helperId: helperId, className: ['ion-radio-group', className].filter(Boolean).join(' ') }) }));
67
78
  });
68
79
  RadioGroup.displayName = 'RadioGroup';
69
80
  //# sourceMappingURL=Radio.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Radio.js","sourceRoot":"","sources":["../../src/components/Radio.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Radio.js","sourceRoot":"","sources":["../../src/components/Radio.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAc,EACZ,UAAU,EACV,MAAM,EACN,mBAAmB,EACnB,UAAU,EACV,aAAa,EACb,KAAK,GACN,MAAM,OAAO,CAAC;AACf,OAAO,EACL,aAAa,EACb,iBAAiB,GAElB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAiBxD;;;;;GAKG;AACH,MAAM,iBAAiB,GAAG,aAAa,CAAgC,IAAI,CAAC,CAAC;AAkB7E,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAC7B,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE;IACtB,MAAM,KAAK,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAC5C,MAAM,EACJ,KAAK,EACL,IAAI,GAAG,KAAK,EAAE,IAAI,IAAI,IAAI,EAC1B,MAAM,GAAG,KAAK,EAAE,MAAM,IAAI,OAAO,EACjC,SAAS,EACT,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,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;IAE7D,MAAM,MAAM,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;IAC9C,mBAAmB,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAQ,CAAC,CAAC;IAEzD,MAAM,UAAU,GAAG;QACjB,WAAW;QACX,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;QACzC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,cAAc,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE;QAChD,gBAAgB,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE;QAC7C,SAAS,IAAI,EAAE;KAChB;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,sEAAsE;IACtE,sEAAsE;IACtE,MAAM,UAAU,GAAG,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC;IAEtD;;;;;;;;OAQG;IACH,MAAM,YAAY,GAAG,CAAC,CAAsC,EAAE,EAAE;QAC9D,KAAK,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC,CAAC;IAEF,OAAO,CACL,iBAAO,SAAS,EAAE,UAAU,aAC1B,mBACM,IAAI,EACR,GAAG,EAAE,MAAM,EACX,IAAI,EAAC,OAAO,EACZ,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,gBAAgB;gBAC1B,kEAAkE;gBAClE,iEAAiE;gBACjE,QAAQ,EAAE,KAAK,EAAE,UAAU,IAAI,IAAI,CAAC,QAAQ,sBAI1C,CAAC,WAAW,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;oBACxD,SAAS,EAEX,SAAS,EAAC,kBAAkB,EAC5B,QAAQ,EAAE,YAAY,KAClB,CAAC,UAAU;oBACb,CAAC,CAAC,EAAE,OAAO,EAAE,KAAM,CAAC,KAAK,KAAK,KAAK,EAAE;oBACrC,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,KAAK,EAAE,CAAC,GACtD,EACF,eAAM,SAAS,EAAC,sBAAsB,iBAAa,MAAM,YACvD,eAAM,SAAS,EAAC,gBAAgB,GAAG,GAC9B,EACN,QAAQ,IAAI,eAAM,SAAS,EAAC,kBAAkB,YAAE,QAAQ,GAAQ,IAC3D,CACT,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC;AAiC5B;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAClC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IACb,MAAM,EACJ,IAAI,EACJ,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,UAAU,EACV,QAAQ,EACR,UAAU,EACV,WAAW,EACX,YAAY,EACZ,SAAS,EACT,GAAG,IAAI,EACR,GAAG,KAAK,CAAC;IAEV,MAAM,gBAAgB,GAAG,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,KAAK,EAAE,CAAC;IAC1B,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,iBAAiB,CAC5C,WAAW,EACX,YAAY,EACZ,IAAI,CAAC,SAAS,CACf,CAAC;IAEF,OAAO,CACL,KAAC,iBAAiB,CAAC,QAAQ,IACzB,KAAK,EAAE;YACL,IAAI,EAAE,IAAI,IAAI,SAAS;YACvB,KAAK;YACL,YAAY;YACZ,QAAQ;YACR,IAAI;YACJ,MAAM;YACN,UAAU,EAAE,gBAAgB;YAC5B,UAAU;YACV,QAAQ;SACT,YAED,KAAC,aAAa,OACR,IAAI,EACR,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,gBAAgB,EAC1B,aAAa,QACb,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GACnE,GACyB,CAC9B,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,UAAU,CAAC,WAAW,GAAG,YAAY,CAAC"}
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import type { AriaSearchFieldProps } from 'react-aria';
3
+ export type SearchFieldSize = 'sm' | 'md' | 'lg';
4
+ type SearchFieldDOMProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, keyof AriaSearchFieldProps | 'size' | 'type' | 'disabled' | 'autoCapitalize'>;
5
+ export interface SearchFieldProps extends AriaSearchFieldProps, SearchFieldDOMProps {
6
+ /** Input's sizes: Small, Medium, Large. */
7
+ size?: SearchFieldSize;
8
+ /** Class names for the control box (`.ion-input`). */
9
+ className?: string;
10
+ /** Class names for the `.ion-field` wrapper when a label or helper is shown. */
11
+ wrapperClassName?: string;
12
+ }
13
+ /**
14
+ * SearchField — a text field for a search query.
15
+ *
16
+ * NOT `<Input type="search">`. That gets the right input type and nothing
17
+ * else. `useSearchField` adds what a search box owes its user:
18
+ *
19
+ * `role="searchbox"`, so a screen reader announces a search field, not a
20
+ * text field. Enter calls `onSubmit` with the query. Escape clears it — a
21
+ * second Escape then reaches whatever the field sits in, so a search inside
22
+ * a dialog clears first and closes second. A clear button appears once there
23
+ * is something to clear, named in the user's language by React Aria.
24
+ *
25
+ * The clear button is out of the tab order on purpose, as React Aria sets it:
26
+ * Escape is the keyboard's way to clear, and an extra tab stop in every search
27
+ * box costs every keyboard user a keystroke. Pressing it puts focus back in the
28
+ * field.
29
+ *
30
+ * The box IS Input's — the component renders `.ion-input` and its size and
31
+ * state classes, so a search field beside an Input in a toolbar matches it
32
+ * exactly and cannot drift. Same arrangement as NumberInput.
33
+ */
34
+ export declare const SearchField: React.ForwardRefExoticComponent<SearchFieldProps & React.RefAttributes<HTMLInputElement>>;
35
+ export {};
36
+ //# sourceMappingURL=SearchField.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchField.d.ts","sourceRoot":"","sources":["../../src/components/SearchField.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAkD,MAAM,OAAO,CAAC;AAQvE,OAAO,KAAK,EAAmB,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAIxE,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEjD,KAAK,mBAAmB,GAAG,IAAI,CAC7B,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAC3C,MAAM,oBAAoB,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,gBAAgB,CAC7E,CAAC;AAEF,MAAM,WAAW,gBACf,SAAQ,oBAAoB,EAAE,mBAAmB;IACjD,2CAA2C;IAC3C,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA0CD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,WAAW,2FAqGvB,CAAC"}
@@ -0,0 +1,76 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef, useImperativeHandle, useRef } from 'react';
4
+ import { mergeProps, useButton, useFocusRing, useHover, useSearchField, } from 'react-aria';
5
+ import { useSearchFieldState } from 'react-stately';
6
+ import { ARIA_TEXT_FIELD_NON_DOM_PROPS, omitProps } from './dom-props.js';
7
+ /** `onSubmit` and `onClear` are React Aria's, not the DOM's — never spread. */
8
+ const SEARCH_FIELD_NON_DOM_PROPS = [
9
+ ...ARIA_TEXT_FIELD_NON_DOM_PROPS,
10
+ 'onSubmit',
11
+ 'onClear',
12
+ ];
13
+ const Magnifier = () => (_jsxs("svg", { viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", focusable: "false", children: [_jsx("circle", { cx: "11", cy: "11", r: "7", stroke: "currentColor", strokeWidth: "2" }), _jsx("path", { d: "m20 20-3.5-3.5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })] }));
14
+ const Cross = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", focusable: "false", children: _jsx("path", { d: "M18 6 6 18M6 6l12 12", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }));
15
+ function ClearButton(props) {
16
+ const ref = useRef(null);
17
+ const { buttonProps } = useButton(props, ref);
18
+ return (_jsx("button", { ...buttonProps, ref: ref, className: "ion-search-field__clear", children: _jsx(Cross, {}) }));
19
+ }
20
+ /**
21
+ * SearchField — a text field for a search query.
22
+ *
23
+ * NOT `<Input type="search">`. That gets the right input type and nothing
24
+ * else. `useSearchField` adds what a search box owes its user:
25
+ *
26
+ * `role="searchbox"`, so a screen reader announces a search field, not a
27
+ * text field. Enter calls `onSubmit` with the query. Escape clears it — a
28
+ * second Escape then reaches whatever the field sits in, so a search inside
29
+ * a dialog clears first and closes second. A clear button appears once there
30
+ * is something to clear, named in the user's language by React Aria.
31
+ *
32
+ * The clear button is out of the tab order on purpose, as React Aria sets it:
33
+ * Escape is the keyboard's way to clear, and an extra tab stop in every search
34
+ * box costs every keyboard user a keystroke. Pressing it puts focus back in the
35
+ * field.
36
+ *
37
+ * The box IS Input's — the component renders `.ion-input` and its size and
38
+ * state classes, so a search field beside an Input in a toolbar matches it
39
+ * exactly and cannot drift. Same arrangement as NumberInput.
40
+ */
41
+ export const SearchField = forwardRef((props, forwardedRef) => {
42
+ const { size = 'md', label, description, errorMessage, isDisabled, isReadOnly, isInvalid, className, wrapperClassName, ...rest } = props;
43
+ const state = useSearchFieldState(props);
44
+ const ref = useRef(null);
45
+ useImperativeHandle(forwardedRef, () => ref.current);
46
+ const { labelProps, inputProps, clearButtonProps, descriptionProps, errorMessageProps, } = useSearchField(props, state, ref);
47
+ const { hoverProps, isHovered } = useHover({ isDisabled });
48
+ const { focusProps, isFocusVisible } = useFocusRing({ isTextInput: true });
49
+ const domProps = omitProps(rest, SEARCH_FIELD_NON_DOM_PROPS);
50
+ const canClear = state.value !== '' && !isDisabled && !isReadOnly;
51
+ const box = (_jsxs("div", { ...hoverProps, "data-hovered": isHovered || undefined, "data-focused": isFocusVisible || undefined, "data-invalid": isInvalid || undefined, "data-readonly": isReadOnly || undefined, "data-disabled": isDisabled || undefined, className: [
52
+ 'ion-input',
53
+ 'ion-search-field',
54
+ size !== 'md' ? `ion-input--${size}` : '',
55
+ canClear ? 'ion-search-field--clearable' : '',
56
+ isInvalid ? 'ion-input--invalid' : '',
57
+ isReadOnly ? 'ion-input--readonly' : '',
58
+ isDisabled ? 'ion-input--disabled' : '',
59
+ className || '',
60
+ ]
61
+ .filter(Boolean)
62
+ .join(' '), children: [_jsx("span", { className: "ion-input__icon-start", "aria-hidden": "true", children: _jsx(Magnifier, {}) }), _jsx("input", { ...domProps, ...mergeProps(inputProps, focusProps), ref: ref, className: "ion-input__field ion-search-field__field" }), canClear && _jsx(ClearButton, { ...clearButtonProps })] }));
63
+ const helper = isInvalid && errorMessage ? errorMessage : description;
64
+ const helperProps = isInvalid && errorMessage ? errorMessageProps : descriptionProps;
65
+ if (!label && !helper)
66
+ return box;
67
+ return (_jsxs("div", { className: [
68
+ 'ion-field',
69
+ isInvalid ? 'ion-field--error' : '',
70
+ wrapperClassName || '',
71
+ ]
72
+ .filter(Boolean)
73
+ .join(' '), children: [label && (_jsx("label", { ...labelProps, className: "ion-field__label", children: label })), box, helper && (_jsx("span", { ...helperProps, className: "ion-field__helper", children: helper }))] }));
74
+ });
75
+ SearchField.displayName = 'SearchField';
76
+ //# sourceMappingURL=SearchField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchField.js","sourceRoot":"","sources":["../../src/components/SearchField.tsx"],"names":[],"mappings":"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"}
@@ -16,8 +16,10 @@ export { PhoneInput } from './PhoneInput.js';
16
16
  export type { PhoneInputProps } from './PhoneInput.js';
17
17
  export { Select } from './Select.js';
18
18
  export type { SelectProps, SelectSize, SelectOption } from './Select.js';
19
- export { Checkbox } from './Checkbox.js';
20
- export type { CheckboxProps, CheckboxSize, CheckboxIntent, } from './Checkbox.js';
19
+ export { Checkbox, CheckboxGroup } from './Checkbox.js';
20
+ export type { CheckboxProps, CheckboxGroupProps, CheckboxSize, CheckboxIntent, } from './Checkbox.js';
21
+ export { Fieldset } from './Fieldset.js';
22
+ export type { FieldsetProps, FieldsetOrientation } from './Fieldset.js';
21
23
  export { Radio, RadioGroup } from './Radio.js';
22
24
  export type { RadioProps, RadioGroupProps, RadioSize, RadioIntent, } from './Radio.js';
23
25
  export { Toggle } from './Toggle.js';
@@ -87,6 +89,8 @@ export { SegmentedControl, SegmentedControlItem } from './SegmentedControl.js';
87
89
  export type { SegmentedControlProps, SegmentedControlItemProps, SegmentedControlSize, } from './SegmentedControl.js';
88
90
  export { NumberInput } from './NumberInput.js';
89
91
  export type { NumberInputProps, NumberInputSize } from './NumberInput.js';
92
+ export { SearchField } from './SearchField.js';
93
+ export type { SearchFieldProps, SearchFieldSize } from './SearchField.js';
90
94
  export { ToolCall } from './ToolCall.js';
91
95
  export type { ToolCallProps } from './ToolCall.js';
92
96
  export { PromptInput } from './PromptInput.js';