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.
- package/LICENSE +21 -0
- package/dist/components/Accordion.d.ts +54 -0
- package/dist/components/Accordion.d.ts.map +1 -0
- package/dist/components/Accordion.js +68 -0
- package/dist/components/Accordion.js.map +1 -0
- package/dist/components/Breadcrumb.d.ts +45 -0
- package/dist/components/Breadcrumb.d.ts.map +1 -0
- package/dist/components/Breadcrumb.js +31 -0
- package/dist/components/Breadcrumb.js.map +1 -0
- package/dist/components/Checkbox.d.ts +2 -1
- package/dist/components/Checkbox.d.ts.map +1 -1
- package/dist/components/Checkbox.js +4 -2
- package/dist/components/Checkbox.js.map +1 -1
- package/dist/components/Combobox.d.ts +86 -0
- package/dist/components/Combobox.d.ts.map +1 -0
- package/dist/components/Combobox.js +261 -0
- package/dist/components/Combobox.js.map +1 -0
- package/dist/components/Drawer.d.ts +52 -0
- package/dist/components/Drawer.d.ts.map +1 -0
- package/dist/components/Drawer.js +66 -0
- package/dist/components/Drawer.js.map +1 -0
- package/dist/components/FileUpload.d.ts +79 -0
- package/dist/components/FileUpload.d.ts.map +1 -0
- package/dist/components/FileUpload.js +218 -0
- package/dist/components/FileUpload.js.map +1 -0
- package/dist/components/ProgressBar.d.ts +46 -0
- package/dist/components/ProgressBar.d.ts.map +1 -0
- package/dist/components/ProgressBar.js +52 -0
- package/dist/components/ProgressBar.js.map +1 -0
- package/dist/components/Select.d.ts +9 -2
- package/dist/components/Select.d.ts.map +1 -1
- package/dist/components/Select.js.map +1 -1
- package/dist/components/Skeleton.d.ts +39 -0
- package/dist/components/Skeleton.d.ts.map +1 -0
- package/dist/components/Skeleton.js +50 -0
- package/dist/components/Skeleton.js.map +1 -0
- package/dist/components/Spinner.d.ts +45 -0
- package/dist/components/Spinner.d.ts.map +1 -0
- package/dist/components/Spinner.js +44 -0
- package/dist/components/Spinner.js.map +1 -0
- package/dist/components/Textarea.d.ts +50 -0
- package/dist/components/Textarea.d.ts.map +1 -0
- package/dist/components/Textarea.js +48 -0
- package/dist/components/Textarea.js.map +1 -0
- package/dist/components/Toggle.d.ts +2 -1
- package/dist/components/Toggle.d.ts.map +1 -1
- package/dist/components/Toggle.js +4 -2
- package/dist/components/Toggle.js.map +1 -1
- package/dist/components/index.d.ts +18 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +9 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/resolve-selection.d.ts +36 -0
- package/dist/components/resolve-selection.d.ts.map +1 -0
- package/dist/components/resolve-selection.js +14 -0
- package/dist/components/resolve-selection.js.map +1 -0
- package/dist/figma-descriptions.json +204 -144
- package/dist/figma-map.json +2311 -1643
- package/dist/meta/Accordion.json +123 -0
- package/dist/meta/AccordionItem.json +90 -0
- package/dist/meta/Breadcrumb.json +87 -0
- package/dist/meta/BreadcrumbItem.json +78 -0
- package/dist/meta/Checkbox.json +18 -1
- package/dist/meta/Combobox.json +265 -0
- package/dist/meta/Drawer.json +234 -0
- package/dist/meta/EmptyState.json +1 -1
- package/dist/meta/FileUpload.json +246 -0
- package/dist/meta/Input.json +0 -1
- package/dist/meta/PhoneInput.json +39 -39
- package/dist/meta/Popover.json +3 -3
- package/dist/meta/ProgressBar.json +166 -0
- package/dist/meta/Select.json +4 -3
- package/dist/meta/Skeleton.json +120 -0
- package/dist/meta/Spinner.json +123 -0
- package/dist/meta/Textarea.json +520 -0
- package/dist/meta/Toggle.json +18 -1
- package/dist/meta/Tooltip.json +3 -3
- package/dist/meta/components.json +2447 -361
- package/dist/meta/contrast.json +3130 -227
- package/dist/meta/index.json +149 -7
- package/dist/meta/patterns/index.json +1 -1
- package/dist/styles/accordion.css +102 -0
- package/dist/styles/breadcrumb.css +72 -0
- package/dist/styles/combobox.css +154 -0
- package/dist/styles/drawer.css +181 -0
- package/dist/styles/empty-state.css +16 -4
- package/dist/styles/file-upload.css +236 -0
- package/dist/styles/index.css +9 -0
- package/dist/styles/input.css +34 -15
- package/dist/styles/progress-bar.css +107 -0
- package/dist/styles/skeleton.css +76 -0
- package/dist/styles/spinner.css +70 -0
- package/dist/styles/textarea.css +178 -0
- package/dist/styles/tokens/base.css +0 -1
- package/dist/styles/tokens/theme-dark.css +0 -1
- package/dist/tokens/index.d.ts +0 -6
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +0 -5
- package/dist/tokens/index.js.map +1 -1
- package/llms.txt +2 -2
- 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;
|
|
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;
|
|
1
|
+
{"version":3,"file":"Checkbox.js","sourceRoot":"","sources":["../../src/components/Checkbox.tsx"],"names":[],"mappings":"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"}
|
|
@@ -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"}
|