ionbase-ui 0.48.0 → 0.59.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 (101) hide show
  1. package/LICENSE +21 -0
  2. package/dist/components/Accordion.d.ts +54 -0
  3. package/dist/components/Accordion.d.ts.map +1 -0
  4. package/dist/components/Accordion.js +68 -0
  5. package/dist/components/Accordion.js.map +1 -0
  6. package/dist/components/Breadcrumb.d.ts +45 -0
  7. package/dist/components/Breadcrumb.d.ts.map +1 -0
  8. package/dist/components/Breadcrumb.js +31 -0
  9. package/dist/components/Breadcrumb.js.map +1 -0
  10. package/dist/components/Checkbox.d.ts +2 -1
  11. package/dist/components/Checkbox.d.ts.map +1 -1
  12. package/dist/components/Checkbox.js +4 -2
  13. package/dist/components/Checkbox.js.map +1 -1
  14. package/dist/components/Combobox.d.ts +86 -0
  15. package/dist/components/Combobox.d.ts.map +1 -0
  16. package/dist/components/Combobox.js +261 -0
  17. package/dist/components/Combobox.js.map +1 -0
  18. package/dist/components/Drawer.d.ts +52 -0
  19. package/dist/components/Drawer.d.ts.map +1 -0
  20. package/dist/components/Drawer.js +66 -0
  21. package/dist/components/Drawer.js.map +1 -0
  22. package/dist/components/FileUpload.d.ts +79 -0
  23. package/dist/components/FileUpload.d.ts.map +1 -0
  24. package/dist/components/FileUpload.js +218 -0
  25. package/dist/components/FileUpload.js.map +1 -0
  26. package/dist/components/ProgressBar.d.ts +46 -0
  27. package/dist/components/ProgressBar.d.ts.map +1 -0
  28. package/dist/components/ProgressBar.js +52 -0
  29. package/dist/components/ProgressBar.js.map +1 -0
  30. package/dist/components/Select.d.ts +9 -2
  31. package/dist/components/Select.d.ts.map +1 -1
  32. package/dist/components/Select.js.map +1 -1
  33. package/dist/components/Skeleton.d.ts +39 -0
  34. package/dist/components/Skeleton.d.ts.map +1 -0
  35. package/dist/components/Skeleton.js +50 -0
  36. package/dist/components/Skeleton.js.map +1 -0
  37. package/dist/components/Spinner.d.ts +45 -0
  38. package/dist/components/Spinner.d.ts.map +1 -0
  39. package/dist/components/Spinner.js +44 -0
  40. package/dist/components/Spinner.js.map +1 -0
  41. package/dist/components/Textarea.d.ts +50 -0
  42. package/dist/components/Textarea.d.ts.map +1 -0
  43. package/dist/components/Textarea.js +48 -0
  44. package/dist/components/Textarea.js.map +1 -0
  45. package/dist/components/Toggle.d.ts +2 -1
  46. package/dist/components/Toggle.d.ts.map +1 -1
  47. package/dist/components/Toggle.js +4 -2
  48. package/dist/components/Toggle.js.map +1 -1
  49. package/dist/components/index.d.ts +18 -0
  50. package/dist/components/index.d.ts.map +1 -1
  51. package/dist/components/index.js +9 -0
  52. package/dist/components/index.js.map +1 -1
  53. package/dist/components/resolve-selection.d.ts +36 -0
  54. package/dist/components/resolve-selection.d.ts.map +1 -0
  55. package/dist/components/resolve-selection.js +14 -0
  56. package/dist/components/resolve-selection.js.map +1 -0
  57. package/dist/figma-descriptions.json +204 -144
  58. package/dist/figma-map.json +2311 -1643
  59. package/dist/meta/Accordion.json +123 -0
  60. package/dist/meta/AccordionItem.json +90 -0
  61. package/dist/meta/Breadcrumb.json +87 -0
  62. package/dist/meta/BreadcrumbItem.json +78 -0
  63. package/dist/meta/Checkbox.json +18 -1
  64. package/dist/meta/Combobox.json +265 -0
  65. package/dist/meta/Drawer.json +234 -0
  66. package/dist/meta/EmptyState.json +1 -1
  67. package/dist/meta/FileUpload.json +246 -0
  68. package/dist/meta/Input.json +0 -1
  69. package/dist/meta/PhoneInput.json +39 -39
  70. package/dist/meta/Popover.json +3 -3
  71. package/dist/meta/ProgressBar.json +166 -0
  72. package/dist/meta/Select.json +4 -3
  73. package/dist/meta/Skeleton.json +120 -0
  74. package/dist/meta/Spinner.json +123 -0
  75. package/dist/meta/Textarea.json +520 -0
  76. package/dist/meta/Toggle.json +18 -1
  77. package/dist/meta/Tooltip.json +3 -3
  78. package/dist/meta/components.json +2447 -361
  79. package/dist/meta/contrast.json +3130 -227
  80. package/dist/meta/index.json +149 -7
  81. package/dist/meta/patterns/index.json +1 -1
  82. package/dist/styles/accordion.css +102 -0
  83. package/dist/styles/breadcrumb.css +72 -0
  84. package/dist/styles/combobox.css +154 -0
  85. package/dist/styles/drawer.css +181 -0
  86. package/dist/styles/empty-state.css +16 -4
  87. package/dist/styles/file-upload.css +236 -0
  88. package/dist/styles/index.css +9 -0
  89. package/dist/styles/input.css +34 -15
  90. package/dist/styles/progress-bar.css +107 -0
  91. package/dist/styles/skeleton.css +76 -0
  92. package/dist/styles/spinner.css +70 -0
  93. package/dist/styles/textarea.css +178 -0
  94. package/dist/styles/tokens/base.css +0 -1
  95. package/dist/styles/tokens/theme-dark.css +0 -1
  96. package/dist/tokens/index.d.ts +0 -6
  97. package/dist/tokens/index.d.ts.map +1 -1
  98. package/dist/tokens/index.js +0 -5
  99. package/dist/tokens/index.js.map +1 -1
  100. package/llms.txt +2 -2
  101. package/package.json +19 -19
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 IonBase
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,54 @@
1
+ import React from 'react';
2
+ export type AccordionHeadingLevel = 2 | 3 | 4 | 5 | 6;
3
+ export interface AccordionProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {
4
+ /** Let more than one section be open at once. */
5
+ allowsMultiple?: boolean;
6
+ /** Uncontrolled: which sections start open. */
7
+ defaultExpandedKeys?: string[];
8
+ /** Controlled: which sections are open. Pass `onExpandedChange` with it. */
9
+ expandedKeys?: string[];
10
+ onExpandedChange?: (keys: string[]) => void;
11
+ /**
12
+ * The level each section's heading renders at. Must fit the surrounding
13
+ * document — a panel inside an `h2` section wants `3`.
14
+ */
15
+ headingLevel?: AccordionHeadingLevel;
16
+ children?: React.ReactNode;
17
+ }
18
+ export interface AccordionItemProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title' | 'id'> {
19
+ /** Stable identity for the open set. Required. */
20
+ id: string;
21
+ /** The always-visible label. */
22
+ title: React.ReactNode;
23
+ isDisabled?: boolean;
24
+ children?: React.ReactNode;
25
+ }
26
+ /**
27
+ * Accordion — sections that collapse, with the heading structure intact.
28
+ *
29
+ * WHY THE TRIGGER IS A BUTTON INSIDE A HEADING
30
+ *
31
+ * Both parts are load-bearing and the obvious implementations drop one of them.
32
+ * The heading is how a screen-reader user navigates a long page — pressing `h`
33
+ * moves between sections, and an accordion built from `div`s removes every one
34
+ * of those stops. The button is what makes the section operable by keyboard and
35
+ * announced as expandable; a heading with a click handler is neither.
36
+ *
37
+ * So the shape is `<h3><button aria-expanded aria-controls>`, which is the only
38
+ * arrangement that keeps document structure AND operability.
39
+ *
40
+ * `headingLevel` is a prop with no safe default beyond 3, because the right
41
+ * level depends on the document around it and nothing here can see that. Two
42
+ * accordions at the wrong level produce a page whose outline is nonsense while
43
+ * looking perfectly fine.
44
+ *
45
+ * THE PANEL IS NOT UNMOUNTED
46
+ *
47
+ * Collapsed sections keep their DOM and are hidden with `hidden`. Unmounting
48
+ * would lose form state in a collapsed section — the classic multi-step-form
49
+ * bug where answers vanish when a section is folded away — and would break
50
+ * in-page search, which cannot find text that is not there.
51
+ */
52
+ export declare const Accordion: React.ForwardRefExoticComponent<AccordionProps & React.RefAttributes<HTMLDivElement>>;
53
+ export declare const AccordionItem: React.ForwardRefExoticComponent<AccordionItemProps & React.RefAttributes<HTMLDivElement>>;
54
+ //# sourceMappingURL=Accordion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Accordion.d.ts","sourceRoot":"","sources":["../../src/components/Accordion.tsx"],"names":[],"mappings":"AAEA,OAAO,KAMN,MAAM,OAAO,CAAC;AAEf,MAAM,MAAM,qBAAqB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAUtD,MAAM,WAAW,cAAe,SAAQ,IAAI,CAC1C,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EACpC,UAAU,CACX;IACC,iDAAiD;IACjD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,+CAA+C;IAC/C,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC5C;;;OAGG;IACH,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAC9C,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EACpC,OAAO,GAAG,IAAI,CACf;IACC,kDAAkD;IAClD,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAcD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,SAAS,uFA+CrB,CAAC;AAIF,eAAO,MAAM,aAAa,2FAsDzB,CAAC"}
@@ -0,0 +1,68 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { createContext, forwardRef, useContext, useId, useState, } from 'react';
4
+ const AccordionContext = createContext(null);
5
+ const Chevron = () => (_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" }) }));
6
+ /**
7
+ * Accordion — sections that collapse, with the heading structure intact.
8
+ *
9
+ * WHY THE TRIGGER IS A BUTTON INSIDE A HEADING
10
+ *
11
+ * Both parts are load-bearing and the obvious implementations drop one of them.
12
+ * The heading is how a screen-reader user navigates a long page — pressing `h`
13
+ * moves between sections, and an accordion built from `div`s removes every one
14
+ * of those stops. The button is what makes the section operable by keyboard and
15
+ * announced as expandable; a heading with a click handler is neither.
16
+ *
17
+ * So the shape is `<h3><button aria-expanded aria-controls>`, which is the only
18
+ * arrangement that keeps document structure AND operability.
19
+ *
20
+ * `headingLevel` is a prop with no safe default beyond 3, because the right
21
+ * level depends on the document around it and nothing here can see that. Two
22
+ * accordions at the wrong level produce a page whose outline is nonsense while
23
+ * looking perfectly fine.
24
+ *
25
+ * THE PANEL IS NOT UNMOUNTED
26
+ *
27
+ * Collapsed sections keep their DOM and are hidden with `hidden`. Unmounting
28
+ * would lose form state in a collapsed section — the classic multi-step-form
29
+ * bug where answers vanish when a section is folded away — and would break
30
+ * in-page search, which cannot find text that is not there.
31
+ */
32
+ export const Accordion = forwardRef(({ allowsMultiple = false, defaultExpandedKeys, expandedKeys, onExpandedChange, headingLevel = 3, children, className, ...rest }, ref) => {
33
+ const [internal, setInternal] = useState(defaultExpandedKeys ?? []);
34
+ const isControlled = expandedKeys !== undefined;
35
+ const current = isControlled ? expandedKeys : internal;
36
+ const toggle = (id) => {
37
+ const open = current.includes(id);
38
+ const next = open
39
+ ? current.filter((k) => k !== id)
40
+ : allowsMultiple
41
+ ? [...current, id]
42
+ : [id];
43
+ if (!isControlled)
44
+ setInternal(next);
45
+ onExpandedChange?.(next);
46
+ };
47
+ return (_jsx(AccordionContext.Provider, { value: { expanded: new Set(current), toggle, headingLevel }, children: _jsx("div", { ...rest, ref: ref, className: ['ion-accordion', className || '']
48
+ .filter(Boolean)
49
+ .join(' '), children: children }) }));
50
+ });
51
+ Accordion.displayName = 'Accordion';
52
+ export const AccordionItem = forwardRef(({ id, title, isDisabled = false, children, className, ...rest }, ref) => {
53
+ const ctx = useContext(AccordionContext);
54
+ if (!ctx) {
55
+ throw new Error('AccordionItem must be rendered inside an Accordion');
56
+ }
57
+ const { expanded, toggle, headingLevel } = ctx;
58
+ const reactId = useId();
59
+ const buttonId = `${reactId}-trigger`;
60
+ const panelId = `${reactId}-panel`;
61
+ const isExpanded = expanded.has(id);
62
+ const Heading = `h${headingLevel}`;
63
+ return (_jsxs("div", { ...rest, ref: ref, "data-expanded": isExpanded || undefined, className: ['ion-accordion__item', className || '']
64
+ .filter(Boolean)
65
+ .join(' '), children: [_jsx(Heading, { className: "ion-accordion__heading", children: _jsxs("button", { type: "button", id: buttonId, className: "ion-accordion__trigger", "aria-expanded": isExpanded, "aria-controls": panelId, disabled: isDisabled, onClick: () => toggle(id), children: [_jsx("span", { className: "ion-accordion__title", children: title }), _jsx("span", { className: "ion-accordion__indicator", "aria-hidden": "true", children: _jsx(Chevron, {}) })] }) }), _jsx("div", { id: panelId, role: "region", "aria-labelledby": buttonId, hidden: !isExpanded, className: "ion-accordion__panel", children: _jsx("div", { className: "ion-accordion__content", children: children }) })] }));
66
+ });
67
+ AccordionItem.displayName = 'AccordionItem';
68
+ //# sourceMappingURL=Accordion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Accordion.js","sourceRoot":"","sources":["../../src/components/Accordion.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import React from 'react';
2
+ export interface BreadcrumbProps extends React.HTMLAttributes<HTMLElement> {
3
+ /**
4
+ * Names the landmark. A page with more than one `nav` needs them told apart,
5
+ * and "Breadcrumb" is what screen-reader users are listening for.
6
+ */
7
+ label?: string;
8
+ /** `BreadcrumbItem` elements, ancestor first. */
9
+ children?: React.ReactNode;
10
+ }
11
+ export interface BreadcrumbItemProps extends Omit<React.LiHTMLAttributes<HTMLLIElement>, 'onClick'> {
12
+ /** Omit on the current page — the last crumb is not a link. */
13
+ href?: string;
14
+ /**
15
+ * The page the user is on. Marked `aria-current="page"` and rendered as text
16
+ * rather than a link.
17
+ */
18
+ isCurrent?: boolean;
19
+ children?: React.ReactNode;
20
+ }
21
+ /**
22
+ * Breadcrumb — where this page sits, and how to get back up.
23
+ *
24
+ * WHY AN ORDERED LIST INSIDE A NAMED LANDMARK
25
+ *
26
+ * The trail is a sequence, and `ol` is what says so: a screen reader announces
27
+ * "list, 4 items" and the position within it, which is the entire content of a
28
+ * breadcrumb. A row of `div`s with slashes conveys none of that, and the
29
+ * slashes themselves get read out as punctuation.
30
+ *
31
+ * The separator here is drawn by CSS `::before` on each item after the first,
32
+ * so it is decoration that never enters the accessibility tree. Putting a "/"
33
+ * in the markup is the usual version of this component and the usual defect.
34
+ *
35
+ * THE LAST CRUMB IS NOT A LINK
36
+ *
37
+ * `isCurrent` renders text with `aria-current="page"`. A link to the page you
38
+ * are already on is a dead control: it announces as a link, invites a click,
39
+ * and does nothing. This is the most common breadcrumb bug and the reason the
40
+ * prop exists rather than being inferred from position — a trail whose last
41
+ * crumb IS a link to somewhere else is legitimate, and inferring would break it.
42
+ */
43
+ export declare const Breadcrumb: React.ForwardRefExoticComponent<BreadcrumbProps & React.RefAttributes<HTMLElement>>;
44
+ export declare const BreadcrumbItem: React.ForwardRefExoticComponent<BreadcrumbItemProps & React.RefAttributes<HTMLLIElement>>;
45
+ //# sourceMappingURL=Breadcrumb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Breadcrumb.d.ts","sourceRoot":"","sources":["../../src/components/Breadcrumb.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAE1C,MAAM,WAAW,eAAgB,SAAQ,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC;IACxE;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAC/C,KAAK,CAAC,gBAAgB,CAAC,aAAa,CAAC,EACrC,SAAS,CACV;IACC,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,UAAU,qFAWtB,CAAC;AAIF,eAAO,MAAM,cAAc,2FAuB1B,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ /**
4
+ * Breadcrumb — where this page sits, and how to get back up.
5
+ *
6
+ * WHY AN ORDERED LIST INSIDE A NAMED LANDMARK
7
+ *
8
+ * The trail is a sequence, and `ol` is what says so: a screen reader announces
9
+ * "list, 4 items" and the position within it, which is the entire content of a
10
+ * breadcrumb. A row of `div`s with slashes conveys none of that, and the
11
+ * slashes themselves get read out as punctuation.
12
+ *
13
+ * The separator here is drawn by CSS `::before` on each item after the first,
14
+ * so it is decoration that never enters the accessibility tree. Putting a "/"
15
+ * in the markup is the usual version of this component and the usual defect.
16
+ *
17
+ * THE LAST CRUMB IS NOT A LINK
18
+ *
19
+ * `isCurrent` renders text with `aria-current="page"`. A link to the page you
20
+ * are already on is a dead control: it announces as a link, invites a click,
21
+ * and does nothing. This is the most common breadcrumb bug and the reason the
22
+ * prop exists rather than being inferred from position — a trail whose last
23
+ * crumb IS a link to somewhere else is legitimate, and inferring would break it.
24
+ */
25
+ export const Breadcrumb = forwardRef(({ label = 'Breadcrumb', children, className, ...rest }, ref) => (_jsx("nav", { ...rest, ref: ref, "aria-label": label, className: ['ion-breadcrumb', className || ''].filter(Boolean).join(' '), children: _jsx("ol", { className: "ion-breadcrumb__list", children: children }) })));
26
+ Breadcrumb.displayName = 'Breadcrumb';
27
+ export const BreadcrumbItem = forwardRef(({ href, isCurrent = false, children, className, ...rest }, ref) => (_jsx("li", { ...rest, ref: ref, className: ['ion-breadcrumb__item', className || '']
28
+ .filter(Boolean)
29
+ .join(' '), children: isCurrent || !href ? (_jsx("span", { className: "ion-breadcrumb__current", ...(isCurrent ? { 'aria-current': 'page' } : {}), children: children })) : (_jsx("a", { href: href, className: "ion-breadcrumb__link", children: children })) })));
30
+ BreadcrumbItem.displayName = 'BreadcrumbItem';
31
+ //# sourceMappingURL=Breadcrumb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Breadcrumb.js","sourceRoot":"","sources":["../../src/components/Breadcrumb.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AA0B1C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAClC,CAAC,EAAE,KAAK,GAAG,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAC/D,iBACM,IAAI,EACR,GAAG,EAAE,GAAG,gBACI,KAAK,EACjB,SAAS,EAAE,CAAC,gBAAgB,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,YAExE,aAAI,SAAS,EAAC,sBAAsB,YAAE,QAAQ,GAAM,GAChD,CACP,CACF,CAAC;AAEF,UAAU,CAAC,WAAW,GAAG,YAAY,CAAC;AAEtC,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CACtC,CAAC,EAAE,IAAI,EAAE,SAAS,GAAG,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClE,gBACM,IAAI,EACR,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,CAAC,sBAAsB,EAAE,SAAS,IAAI,EAAE,CAAC;SACjD,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,YAEX,SAAS,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CACpB,eACE,SAAS,EAAC,yBAAyB,KAC/B,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,YAEhD,QAAQ,GACJ,CACR,CAAC,CAAC,CAAC,CACF,YAAG,IAAI,EAAE,IAAI,EAAE,SAAS,EAAC,sBAAsB,YAC5C,QAAQ,GACP,CACL,GACE,CACN,CACF,CAAC;AAEF,cAAc,CAAC,WAAW,GAAG,gBAAgB,CAAC"}
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
+ import { type SelectionProps } from './resolve-selection.js';
2
3
  export type CheckboxSize = 'sm' | 'md' | 'lg';
3
4
  export type CheckboxIntent = 'brand' | 'neutral' | 'danger';
4
- export interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {
5
+ export interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'>, SelectionProps {
5
6
  /** Matches the Figma `Size` variant: Small, Medium, Large. */
6
7
  size?: CheckboxSize;
7
8
  /** Matches the Figma `Color` variant: Brand, Neutral, Danger. */
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../../src/components/Checkbox.tsx"],"names":[],"mappings":"AAEA,OAAO,KAKN,MAAM,OAAO,CAAC;AAGf,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC9C,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE5D,MAAM,WAAW,aAAc,SAAQ,IAAI,CACzC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAC3C,MAAM,GAAG,MAAM,CAChB;IACC,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,wFAkDpB,CAAC"}
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"}
@@ -2,6 +2,7 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { forwardRef, useRef, useImperativeHandle, useEffect, } from 'react';
4
4
  import { resolveDisabled } from './resolve-disabled.js';
5
+ import { resolveSelection } from './resolve-selection.js';
5
6
  /** Figma's check glyph. Inlined for the same reason as Select's chevron: it is
6
7
  * part of the control, not a slot a caller fills. */
7
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" }) }));
@@ -19,8 +20,9 @@ const DashMark = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", "aria-
19
20
  * declaratively and it must be written after every render.
20
21
  */
21
22
  export const Checkbox = forwardRef((props, forwardedRef) => {
22
- const { size = 'md', intent = 'brand', isIndeterminate = false, className, children, isDisabled, disabled, ...rest } = props;
23
+ const { size = 'md', intent = 'brand', isIndeterminate = false, className, children, isDisabled, disabled, isSelected, checked, onChange, onSelectionChange, ...rest } = props;
23
24
  const resolvedDisabled = resolveDisabled(isDisabled, disabled);
25
+ const selection = resolveSelection(isSelected, checked, onChange, onSelectionChange);
24
26
  const domRef = useRef(null);
25
27
  useImperativeHandle(forwardedRef, () => domRef.current);
26
28
  useEffect(() => {
@@ -36,7 +38,7 @@ export const Checkbox = forwardRef((props, forwardedRef) => {
36
38
  ]
37
39
  .filter(Boolean)
38
40
  .join(' ');
39
- return (_jsxs("label", { className: classNames, children: [_jsx("input", { ...rest, ref: domRef, type: "checkbox", 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 })] }));
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 })] }));
40
42
  });
41
43
  Checkbox.displayName = 'Checkbox';
42
44
  //# 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;AA4BxD;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,GAAG,IAAI,EACR,GAAG,KAAK,CAAC;IAEV,MAAM,gBAAgB,GAAG,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAE/D,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,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,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"}
@@ -0,0 +1,86 @@
1
+ import React from 'react';
2
+ export type ComboboxSize = 'sm' | 'md' | 'lg';
3
+ export interface ComboboxOption {
4
+ value: string;
5
+ label: string;
6
+ /** Second line in the row. Part of the option's name, so it is searchable. */
7
+ description?: string;
8
+ isDisabled?: boolean;
9
+ }
10
+ export interface ComboboxProps {
11
+ /** The full option list. Filtering happens here, against what is typed. */
12
+ options: readonly ComboboxOption[];
13
+ /** Field label. Required for a usable control — see `a11y.requires`. */
14
+ label?: React.ReactNode;
15
+ /** Helper text below the field. */
16
+ description?: React.ReactNode;
17
+ /** Replaces the helper text when `isInvalid` is set. */
18
+ errorMessage?: React.ReactNode;
19
+ isInvalid?: boolean;
20
+ isDisabled?: boolean;
21
+ isReadOnly?: boolean;
22
+ /** Matches Input's `Size` variant: Small, Medium, Large. */
23
+ size?: ComboboxSize;
24
+ placeholder?: string;
25
+ /** Controlled selection. `null` means nothing is selected. */
26
+ selectedKey?: string | null;
27
+ defaultSelectedKey?: string;
28
+ onSelectionChange?: (key: string | null) => void;
29
+ /** Controlled text. Usually only needed for async/remote filtering. */
30
+ inputValue?: string;
31
+ defaultInputValue?: string;
32
+ onInputChange?: (value: string) => void;
33
+ /**
34
+ * Accept text that matches no option. Off by default: a combobox whose value
35
+ * is a free string is a text field with suggestions, and the caller should
36
+ * have to say that is what they want.
37
+ */
38
+ allowsCustomValue?: boolean;
39
+ /**
40
+ * What opens the list. `input` — react-aria's default and this one — opens it
41
+ * on the first keystroke; the chevron opens it on demand. `focus` opens it
42
+ * the moment the field is tabbed into, which is loud in a long form.
43
+ */
44
+ menuTrigger?: 'focus' | 'input' | 'manual';
45
+ /** Shown in place of the list when nothing matches. */
46
+ emptyLabel?: React.ReactNode;
47
+ /** Accessible label for the disclosure button. */
48
+ buttonLabel?: string;
49
+ /** Posts the selected value under this name, for an uncontrolled form. */
50
+ name?: string;
51
+ className?: string;
52
+ wrapperClassName?: string;
53
+ id?: string;
54
+ }
55
+ /**
56
+ * Combobox — a text field that filters a list, with one selected value.
57
+ *
58
+ * Drawn in Figma as `Combobox` (1370:2359) — three sizes by seven states, the
59
+ * same axes `Input` carries, because the field IS Input's box. The open list is
60
+ * a second Figma component, `Combobox Menu`, with no React export behind it.
61
+ *
62
+ * WHY THIS IS NOT `Select` WITH A SEARCH BOX
63
+ *
64
+ * `Select` wraps a native `<select>`, whose list the browser owns: it cannot be
65
+ * filtered, and its rows can only hold text. Everything above about twenty
66
+ * options needs filtering, and `Select`'s own contract has pointed at "a
67
+ * combobox — not yet in this system" since it was written. This is it.
68
+ *
69
+ * The cost is that everything the native control gave away for free — keyboard
70
+ * handling, the mobile picker, screen-reader semantics — now has to be built.
71
+ * React Aria's `useComboBox` builds it: `role="combobox"` with `aria-expanded`,
72
+ * `aria-controls` and `aria-activedescendant`, arrow keys that move a virtual
73
+ * focus while the real focus stays in the input, and Escape that reverts.
74
+ *
75
+ * FILTERING IS LOCALE-AWARE, NOT `toLowerCase().includes()`
76
+ *
77
+ * `useFilter({ sensitivity: 'base' })` is `Intl.Collator` underneath, so
78
+ * "resume" matches "résumé" and Turkish dotted/dotless I behave the way a
79
+ * Turkish reader expects. The lowercase-and-includes version fails both, and
80
+ * fails them silently in exactly the locales least likely to be tested.
81
+ */
82
+ export declare function Combobox({ options, label, description, errorMessage, isInvalid, isDisabled, isReadOnly, size, placeholder, selectedKey, defaultSelectedKey, onSelectionChange, inputValue, defaultInputValue, onInputChange, allowsCustomValue, menuTrigger, emptyLabel, buttonLabel, name, className, wrapperClassName, id, }: ComboboxProps): React.JSX.Element;
83
+ export declare namespace Combobox {
84
+ var displayName: string;
85
+ }
86
+ //# sourceMappingURL=Combobox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Combobox.d.ts","sourceRoot":"","sources":["../../src/components/Combobox.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAoC,MAAM,OAAO,CAAC;AAiBzD,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE9C,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,2EAA2E;IAC3E,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IACnC,wEAAwE;IACxE,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,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,4DAA4D;IAC5D,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC3C,uDAAuD;IACvD,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAyMD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EACP,KAAK,EACL,WAAW,EACX,YAAY,EACZ,SAAS,EACT,UAAU,EACV,UAAU,EACV,IAAW,EACX,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,WAAqB,EACrB,UAAyB,EACzB,WAAgC,EAChC,IAAI,EACJ,SAAS,EACT,gBAAgB,EAChB,EAAE,GACH,EAAE,aAAa,qBAyPf;yBAjRe,QAAQ"}