ionbase-ui 0.1.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/README.md +74 -0
- package/dist/Icon.d.ts +72 -0
- package/dist/Icon.d.ts.map +1 -0
- package/dist/Icon.js +50 -0
- package/dist/Icon.js.map +1 -0
- package/dist/components/Avatar.d.ts +52 -0
- package/dist/components/Avatar.d.ts.map +1 -0
- package/dist/components/Avatar.js +59 -0
- package/dist/components/Avatar.js.map +1 -0
- package/dist/components/Badge.d.ts +26 -0
- package/dist/components/Badge.d.ts.map +1 -0
- package/dist/components/Badge.js +17 -0
- package/dist/components/Badge.js.map +1 -0
- package/dist/components/Button.d.ts +18 -0
- package/dist/components/Button.d.ts.map +1 -0
- package/dist/components/Button.js +43 -0
- package/dist/components/Button.js.map +1 -0
- package/dist/components/Checkbox.d.ts +30 -0
- package/dist/components/Checkbox.d.ts.map +1 -0
- package/dist/components/Checkbox.js +39 -0
- package/dist/components/Checkbox.js.map +1 -0
- package/dist/components/Divider.d.ts +17 -0
- package/dist/components/Divider.d.ts.map +1 -0
- package/dist/components/Divider.js +16 -0
- package/dist/components/Divider.js.map +1 -0
- package/dist/components/Header.d.ts +25 -0
- package/dist/components/Header.d.ts.map +1 -0
- package/dist/components/Header.js +18 -0
- package/dist/components/Header.js.map +1 -0
- package/dist/components/Input.d.ts +32 -0
- package/dist/components/Input.d.ts.map +1 -0
- package/dist/components/Input.js +66 -0
- package/dist/components/Input.js.map +1 -0
- package/dist/components/Logo.d.ts +41 -0
- package/dist/components/Logo.d.ts.map +1 -0
- package/dist/components/Logo.js +70 -0
- package/dist/components/Logo.js.map +1 -0
- package/dist/components/Menu.d.ts +29 -0
- package/dist/components/Menu.d.ts.map +1 -0
- package/dist/components/Menu.js +31 -0
- package/dist/components/Menu.js.map +1 -0
- package/dist/components/NavItem.d.ts +30 -0
- package/dist/components/NavItem.d.ts.map +1 -0
- package/dist/components/NavItem.js +45 -0
- package/dist/components/NavItem.js.map +1 -0
- package/dist/components/Radio.d.ts +30 -0
- package/dist/components/Radio.d.ts.map +1 -0
- package/dist/components/Radio.js +61 -0
- package/dist/components/Radio.js.map +1 -0
- package/dist/components/ScrollProgress.d.ts +33 -0
- package/dist/components/ScrollProgress.d.ts.map +1 -0
- package/dist/components/ScrollProgress.js +115 -0
- package/dist/components/ScrollProgress.js.map +1 -0
- package/dist/components/Select.d.ts +43 -0
- package/dist/components/Select.d.ts.map +1 -0
- package/dist/components/Select.js +80 -0
- package/dist/components/Select.js.map +1 -0
- package/dist/components/Table.d.ts +71 -0
- package/dist/components/Table.d.ts.map +1 -0
- package/dist/components/Table.js +60 -0
- package/dist/components/Table.js.map +1 -0
- package/dist/components/Tabs.d.ts +23 -0
- package/dist/components/Tabs.d.ts.map +1 -0
- package/dist/components/Tabs.js +47 -0
- package/dist/components/Tabs.js.map +1 -0
- package/dist/components/Toggle.d.ts +25 -0
- package/dist/components/Toggle.d.ts.map +1 -0
- package/dist/components/Toggle.js +32 -0
- package/dist/components/Toggle.js.map +1 -0
- package/dist/components/index.d.ts +33 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +17 -0
- package/dist/components/index.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/styles/avatar.css +138 -0
- package/dist/styles/badge.css +125 -0
- package/dist/styles/button.css +331 -0
- package/dist/styles/checkbox.css +229 -0
- package/dist/styles/divider.css +31 -0
- package/dist/styles/header.css +95 -0
- package/dist/styles/index.css +44 -0
- package/dist/styles/input.css +264 -0
- package/dist/styles/logo.css +63 -0
- package/dist/styles/menu.css +150 -0
- package/dist/styles/nav-item.css +120 -0
- package/dist/styles/radio.css +200 -0
- package/dist/styles/scroll-progress.css +171 -0
- package/dist/styles/select.css +162 -0
- package/dist/styles/table.css +192 -0
- package/dist/styles/tabs.css +219 -0
- package/dist/styles/toggle.css +184 -0
- package/dist/styles/tokens/base.css +386 -0
- package/dist/styles/tokens/breakpoint-mobile.css +34 -0
- package/dist/styles/tokens/breakpoint-tablet.css +25 -0
- package/dist/styles/tokens/elevation.css +112 -0
- package/dist/styles/tokens/index.css +6 -0
- package/dist/styles/tokens/theme-dark.css +106 -0
- package/dist/styles/tokens/typography.css +124 -0
- package/dist/tokens/index.d.ts +2097 -0
- package/dist/tokens/index.d.ts.map +1 -0
- package/dist/tokens/index.js +1702 -0
- package/dist/tokens/index.js.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useState, useRef, useId, useEffect, useImperativeHandle, } from 'react';
|
|
3
|
+
import { useHover } from 'react-aria';
|
|
4
|
+
/**
|
|
5
|
+
* The compact rail is the disclosure trigger. It is a real `<button>`, so a
|
|
6
|
+
* keyboard user reaches it by Tab and opens it the same way as any button —
|
|
7
|
+
* Enter or Space — no `:focus-within` trick required; a mouse user can also
|
|
8
|
+
* just hover it. Built as a WAI-ARIA Disclosure (`aria-expanded` +
|
|
9
|
+
* `aria-controls`) rather than a menu: see the CSS header for why
|
|
10
|
+
* `role="menu"` is deliberately not used here.
|
|
11
|
+
*
|
|
12
|
+
* Closes on outside pointerdown and on Escape — the minimum a disclosure
|
|
13
|
+
* needs to not trap the page once opened, not a full popover/focus-trap
|
|
14
|
+
* implementation.
|
|
15
|
+
*/
|
|
16
|
+
export const ScrollProgress = forwardRef(({ progress, sections, activeId, onSelect, className, ...rest }, forwardedRef) => {
|
|
17
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
18
|
+
const isTriggerHovered = useRef(false);
|
|
19
|
+
const isPanelHovered = useRef(false);
|
|
20
|
+
const closeTimeoutRef = useRef(undefined);
|
|
21
|
+
const panelId = useId();
|
|
22
|
+
const containerRef = useRef(null);
|
|
23
|
+
useImperativeHandle(forwardedRef, () => containerRef.current);
|
|
24
|
+
/*
|
|
25
|
+
* Two separate hover regions, not one on the outer container: the panel
|
|
26
|
+
* is `position: absolute` and doesn't expand the container's own layout
|
|
27
|
+
* box, so a single hover region sized to the trigger would see the
|
|
28
|
+
* pointer leave (and close the panel) the moment it travels from the
|
|
29
|
+
* trigger into the panel to click a row. The panel stays open as long as
|
|
30
|
+
* either region is hovered.
|
|
31
|
+
*
|
|
32
|
+
* Closing is debounced by 100ms: the trigger and the panel don't touch,
|
|
33
|
+
* so the cursor crosses a dead zone between them on the way from one to
|
|
34
|
+
* the other, briefly leaving both. Closing instantly on that gap, rather
|
|
35
|
+
* than giving the pointer a moment to arrive somewhere that counts, is
|
|
36
|
+
* the same "safe triangle" problem every hoverable popover has.
|
|
37
|
+
*/
|
|
38
|
+
const scheduleClose = () => {
|
|
39
|
+
clearTimeout(closeTimeoutRef.current);
|
|
40
|
+
closeTimeoutRef.current = setTimeout(() => {
|
|
41
|
+
if (!isTriggerHovered.current && !isPanelHovered.current) {
|
|
42
|
+
setIsOpen(false);
|
|
43
|
+
}
|
|
44
|
+
}, 100);
|
|
45
|
+
};
|
|
46
|
+
useEffect(() => () => clearTimeout(closeTimeoutRef.current), []);
|
|
47
|
+
const { hoverProps: triggerHoverProps, isHovered } = useHover({
|
|
48
|
+
onHoverChange: (hovered) => {
|
|
49
|
+
isTriggerHovered.current = hovered;
|
|
50
|
+
if (hovered) {
|
|
51
|
+
clearTimeout(closeTimeoutRef.current);
|
|
52
|
+
setIsOpen(true);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
scheduleClose();
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
const { hoverProps: panelHoverProps } = useHover({
|
|
60
|
+
onHoverChange: (hovered) => {
|
|
61
|
+
isPanelHovered.current = hovered;
|
|
62
|
+
if (hovered) {
|
|
63
|
+
clearTimeout(closeTimeoutRef.current);
|
|
64
|
+
setIsOpen(true);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
scheduleClose();
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (!isOpen)
|
|
73
|
+
return;
|
|
74
|
+
function handlePointerDown(e) {
|
|
75
|
+
if (containerRef.current &&
|
|
76
|
+
!containerRef.current.contains(e.target)) {
|
|
77
|
+
setIsOpen(false);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function handleKeyDown(e) {
|
|
81
|
+
if (e.key === 'Escape')
|
|
82
|
+
setIsOpen(false);
|
|
83
|
+
}
|
|
84
|
+
document.addEventListener('pointerdown', handlePointerDown);
|
|
85
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
86
|
+
return () => {
|
|
87
|
+
document.removeEventListener('pointerdown', handlePointerDown);
|
|
88
|
+
document.removeEventListener('keydown', handleKeyDown);
|
|
89
|
+
};
|
|
90
|
+
}, [isOpen]);
|
|
91
|
+
const roundedProgress = Math.round(progress);
|
|
92
|
+
const activeSection = sections.find((s) => s.id === activeId);
|
|
93
|
+
return (_jsxs("div", { ...rest, ref: containerRef, className: ['ion-scroll-progress', className].filter(Boolean).join(' '), children: [_jsxs("button", { ...triggerHoverProps, type: "button", className: "ion-scroll-progress__trigger", "data-hovered": isHovered || undefined, "aria-expanded": isOpen, "aria-controls": panelId, "aria-label": `Reading progress: ${roundedProgress}%` +
|
|
94
|
+
(activeSection ? `. Currently in ${activeSection.label}.` : '') +
|
|
95
|
+
' Activate to jump to a section.', onClick: () => setIsOpen((v) => !v), children: [_jsxs("span", { className: "ion-scroll-progress__percent", "aria-hidden": "true", children: [roundedProgress, "%"] }), _jsx("span", { className: "ion-scroll-progress__rail", "aria-hidden": "true", children: sections.map((section) => (_jsx("span", { className: [
|
|
96
|
+
'ion-scroll-progress__tick',
|
|
97
|
+
section.id === activeId
|
|
98
|
+
? 'ion-scroll-progress__tick--active'
|
|
99
|
+
: '',
|
|
100
|
+
]
|
|
101
|
+
.filter(Boolean)
|
|
102
|
+
.join(' ') }, section.id))) })] }), _jsx("div", { ...panelHoverProps, id: panelId, className: "ion-scroll-progress__panel", "data-open": isOpen || undefined, children: sections.map((section) => (_jsx("button", { type: "button", className: [
|
|
103
|
+
'ion-scroll-progress__heading',
|
|
104
|
+
section.id === activeId
|
|
105
|
+
? 'ion-scroll-progress__heading--selected'
|
|
106
|
+
: '',
|
|
107
|
+
]
|
|
108
|
+
.filter(Boolean)
|
|
109
|
+
.join(' '), "aria-current": section.id === activeId ? 'true' : undefined, onClick: () => {
|
|
110
|
+
onSelect?.(section.id);
|
|
111
|
+
setIsOpen(false);
|
|
112
|
+
}, children: section.label }, section.id))) })] }));
|
|
113
|
+
});
|
|
114
|
+
ScrollProgress.displayName = 'ScrollProgress';
|
|
115
|
+
//# sourceMappingURL=ScrollProgress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScrollProgress.js","sourceRoot":"","sources":["../../src/components/ScrollProgress.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export type SelectSize = 'sm' | 'md' | 'lg';
|
|
3
|
+
export interface SelectOption {
|
|
4
|
+
value: string;
|
|
5
|
+
label: string;
|
|
6
|
+
isDisabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface SelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'size'> {
|
|
9
|
+
/** Matches the Figma `Size` variant: Small, Medium, Large. */
|
|
10
|
+
size?: SelectSize;
|
|
11
|
+
/** The options to render. Omit and pass `children` for grouped options. */
|
|
12
|
+
options?: SelectOption[];
|
|
13
|
+
/**
|
|
14
|
+
* Text shown when nothing is selected. Renders as a disabled option so the
|
|
15
|
+
* field can start empty without that being a valid choice.
|
|
16
|
+
*/
|
|
17
|
+
placeholder?: string;
|
|
18
|
+
/** Field label. Renders the Figma `Form Field` wrapper around the control. */
|
|
19
|
+
label?: React.ReactNode;
|
|
20
|
+
/** Helper text below the field. */
|
|
21
|
+
description?: React.ReactNode;
|
|
22
|
+
/** Replaces the helper text when `isInvalid` is set. */
|
|
23
|
+
errorMessage?: React.ReactNode;
|
|
24
|
+
isInvalid?: boolean;
|
|
25
|
+
isDisabled?: boolean;
|
|
26
|
+
/** Additional CSS class names, applied to the outermost element. */
|
|
27
|
+
className?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Select wraps a native `<select>` rather than rebuilding one.
|
|
31
|
+
*
|
|
32
|
+
* React Aria's `useSelect` builds a listbox in a popover, which is the right
|
|
33
|
+
* answer when the menu needs custom rows — but Figma models only the trigger
|
|
34
|
+
* here, and the dropdown list is a separate component on the Menu page. Until
|
|
35
|
+
* that is built, the native control is the honest match: it brings keyboard
|
|
36
|
+
* handling, type-ahead and the platform picker on mobile for free, and it is
|
|
37
|
+
* accessible without any of it being reimplemented.
|
|
38
|
+
*
|
|
39
|
+
* Figma's six states map the same way Input's do — Hover and Focus from
|
|
40
|
+
* interaction, Filled from whether a value is set, the rest from props.
|
|
41
|
+
*/
|
|
42
|
+
export declare const Select: React.ForwardRefExoticComponent<SelectProps & React.RefAttributes<HTMLSelectElement>>;
|
|
43
|
+
//# sourceMappingURL=Select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../src/components/Select.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyD,MAAM,OAAO,CAAC;AAG9E,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,WAAY,SAAQ,IAAI,CACvC,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAC7C,MAAM,CACP;IACC,8DAA8D;IAC9D,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,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,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAuBD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,MAAM,uFA6HlB,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useRef, useImperativeHandle, useId } from 'react';
|
|
3
|
+
import { useHover, useFocusRing, mergeProps } from 'react-aria';
|
|
4
|
+
/**
|
|
5
|
+
* The chevron from Figma's `Chevron` slot, inlined.
|
|
6
|
+
*
|
|
7
|
+
* Inlined rather than taken from `@ionbase-ui/icons` because the chevron is part
|
|
8
|
+
* of the component rather than a slot a consumer fills — Select would otherwise
|
|
9
|
+
* be the only thing in this package that depends on the icon library, to draw a
|
|
10
|
+
* shape that never varies. Sizing comes from the CSS, so it tracks the size
|
|
11
|
+
* modifier without a prop.
|
|
12
|
+
*/
|
|
13
|
+
const ChevronDown = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", focusable: "false", children: _jsx("path", { d: "m6 9 6 6 6-6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }));
|
|
14
|
+
/**
|
|
15
|
+
* Select wraps a native `<select>` rather than rebuilding one.
|
|
16
|
+
*
|
|
17
|
+
* React Aria's `useSelect` builds a listbox in a popover, which is the right
|
|
18
|
+
* answer when the menu needs custom rows — but Figma models only the trigger
|
|
19
|
+
* here, and the dropdown list is a separate component on the Menu page. Until
|
|
20
|
+
* that is built, the native control is the honest match: it brings keyboard
|
|
21
|
+
* handling, type-ahead and the platform picker on mobile for free, and it is
|
|
22
|
+
* accessible without any of it being reimplemented.
|
|
23
|
+
*
|
|
24
|
+
* Figma's six states map the same way Input's do — Hover and Focus from
|
|
25
|
+
* interaction, Filled from whether a value is set, the rest from props.
|
|
26
|
+
*/
|
|
27
|
+
export const Select = forwardRef((props, forwardedRef) => {
|
|
28
|
+
const { size = 'md', options, placeholder, label, description, errorMessage, isInvalid, isDisabled, className: customClassName, value, defaultValue, children, id: providedId, ...rest } = props;
|
|
29
|
+
const domRef = useRef(null);
|
|
30
|
+
useImperativeHandle(forwardedRef, () => domRef.current);
|
|
31
|
+
const generatedId = useId();
|
|
32
|
+
const id = providedId ?? generatedId;
|
|
33
|
+
const helperId = `${id}-helper`;
|
|
34
|
+
const { hoverProps, isHovered } = useHover({ isDisabled });
|
|
35
|
+
const { focusProps, isFocusVisible } = useFocusRing();
|
|
36
|
+
/*
|
|
37
|
+
* A browser will not auto-select a disabled <option>, so an uncontrolled
|
|
38
|
+
* Select with a placeholder skips past it and lands on the first real
|
|
39
|
+
* option — the field claims a value the user never chose. Seeding
|
|
40
|
+
* `defaultValue=""` selects the placeholder explicitly, which is allowed:
|
|
41
|
+
* `disabled` stops the user picking it, not the code.
|
|
42
|
+
*
|
|
43
|
+
* Only when uncontrolled and no defaultValue was given, so a controlled
|
|
44
|
+
* Select keeps sole ownership of its value.
|
|
45
|
+
*/
|
|
46
|
+
const seeded = defaultValue === undefined && value === undefined && placeholder
|
|
47
|
+
? ''
|
|
48
|
+
: defaultValue;
|
|
49
|
+
const current = value ?? seeded;
|
|
50
|
+
const isPlaceholder = Boolean(placeholder) && (current === undefined || current === '');
|
|
51
|
+
const helper = isInvalid && errorMessage ? errorMessage : description;
|
|
52
|
+
const boxClassNames = [
|
|
53
|
+
'ion-select',
|
|
54
|
+
size !== 'md' ? `ion-select--${size}` : '',
|
|
55
|
+
isPlaceholder ? 'ion-select--placeholder' : '',
|
|
56
|
+
isInvalid ? 'ion-select--invalid' : '',
|
|
57
|
+
isDisabled ? 'ion-select--disabled' : '',
|
|
58
|
+
!label && !helper ? customClassName || '' : '',
|
|
59
|
+
]
|
|
60
|
+
.filter(Boolean)
|
|
61
|
+
.join(' ');
|
|
62
|
+
const stateAttributes = {
|
|
63
|
+
'data-hovered': isHovered || undefined,
|
|
64
|
+
'data-focused': isFocusVisible || undefined,
|
|
65
|
+
'data-invalid': isInvalid || undefined,
|
|
66
|
+
'data-disabled': isDisabled || undefined,
|
|
67
|
+
};
|
|
68
|
+
const box = (_jsxs("div", { ...hoverProps, ...stateAttributes, className: boxClassNames, children: [_jsxs("select", { ...mergeProps(rest, focusProps), ref: domRef, id: id, className: "ion-select__field", disabled: isDisabled, value: value, defaultValue: seeded, "aria-invalid": isInvalid || undefined, "aria-describedby": helper ? helperId : undefined, children: [placeholder && (_jsx("option", { value: "", disabled: true, children: placeholder })), options?.map((o) => (_jsx("option", { value: o.value, disabled: o.isDisabled, children: o.label }, o.value))), children] }), _jsx("span", { className: "ion-select__chevron", children: _jsx(ChevronDown, {}) })] }));
|
|
69
|
+
if (!label && !helper)
|
|
70
|
+
return box;
|
|
71
|
+
return (_jsxs("div", { className: [
|
|
72
|
+
'ion-field',
|
|
73
|
+
isInvalid ? 'ion-field--error' : '',
|
|
74
|
+
customClassName || '',
|
|
75
|
+
]
|
|
76
|
+
.filter(Boolean)
|
|
77
|
+
.join(' '), children: [label && (_jsx("label", { htmlFor: id, className: "ion-field__label", children: label })), box, helper && (_jsx("span", { id: helperId, className: "ion-field__helper", children: helper }))] }));
|
|
78
|
+
});
|
|
79
|
+
Select.displayName = 'Select';
|
|
80
|
+
//# sourceMappingURL=Select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.js","sourceRoot":"","sources":["../../src/components/Select.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Checkbox } from './Checkbox.js';
|
|
3
|
+
export type TableDensity = 'compact' | 'default' | 'relaxed';
|
|
4
|
+
export interface TableProps extends React.TableHTMLAttributes<HTMLTableElement> {
|
|
5
|
+
/** Matches Figma's `Density` variant on `Table Cell` / `Table Row`. */
|
|
6
|
+
density?: TableDensity;
|
|
7
|
+
/** Alternating row background, read from the row's position, not a prop
|
|
8
|
+
* repeated on every `TableRow`. */
|
|
9
|
+
isStriped?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* `Table` owns the scroll container and the density class; everything else
|
|
13
|
+
* is composed from `TableHead` / `TableBody` / `TableRow` / `TableCell`,
|
|
14
|
+
* matching how Figma actually layers `Table Row` > `Table Cell` > `Cell Text`
|
|
15
|
+
* rather than one component with a wall of props.
|
|
16
|
+
*
|
|
17
|
+
* Density has no React state to thread: it only ever changes vertical cell
|
|
18
|
+
* padding, which `.ion-table--compact td` and friends apply through the CSS
|
|
19
|
+
* cascade from this one class. A context provider for a value nothing in JS
|
|
20
|
+
* ever reads would be infrastructure with no consumer.
|
|
21
|
+
*/
|
|
22
|
+
export declare const Table: React.ForwardRefExoticComponent<TableProps & React.RefAttributes<HTMLTableElement>>;
|
|
23
|
+
export declare const TableHead: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
|
|
24
|
+
export declare const TableBody: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
|
|
25
|
+
export interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {
|
|
26
|
+
isSelected?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Renders a leading `Checkbox` cell — Figma's `Show Selection`. Takes the
|
|
29
|
+
* checkbox's own props directly rather than a boolean, since a selectable
|
|
30
|
+
* row needs `checked`/`onChange` wiring, not just a decorative box.
|
|
31
|
+
*/
|
|
32
|
+
selection?: React.ComponentProps<typeof Checkbox>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A plain `<tr>`. Hover is CSS-only (`:hover` plus a `data-hovered` escape
|
|
36
|
+
* hatch, matching the rest of the system) rather than React Aria's
|
|
37
|
+
* `useHover`: a row is not itself an interactive element — nothing about it
|
|
38
|
+
* takes focus or fires a click — so there is no keyboard-vs-pointer
|
|
39
|
+
* distinction to track. A clickable row is a link or button inside a cell,
|
|
40
|
+
* the same accessible pattern Menu and Table Cell's own link variant use;
|
|
41
|
+
* nesting an interactive role on `<tr>` itself is not valid HTML.
|
|
42
|
+
*/
|
|
43
|
+
export declare const TableRow: React.ForwardRefExoticComponent<TableRowProps & React.RefAttributes<HTMLTableRowElement>>;
|
|
44
|
+
export type TableCellAlign = 'leading' | 'trailing' | 'center';
|
|
45
|
+
export interface TableCellProps extends Omit<React.TdHTMLAttributes<HTMLTableCellElement>, 'align'> {
|
|
46
|
+
/** Renders `<th>` instead of `<td>` — Figma's header cell, `surface/page`
|
|
47
|
+
* fill included. */
|
|
48
|
+
header?: boolean;
|
|
49
|
+
align?: TableCellAlign;
|
|
50
|
+
/** Figma's `Type=Link` — recolours the content to `text/link` /
|
|
51
|
+
* `icon/primary` rather than the body defaults. */
|
|
52
|
+
variant?: 'default' | 'link';
|
|
53
|
+
/** Figma's per-cell `Show Divider` — a column rule, not a row rule. */
|
|
54
|
+
showDivider?: boolean;
|
|
55
|
+
/** Figma's `Leading Icon` / `Trailing Icon` slots on `Cell Text`. */
|
|
56
|
+
icon?: React.ReactNode;
|
|
57
|
+
trailingIcon?: React.ReactNode;
|
|
58
|
+
children?: React.ReactNode;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* One component covers Figma's `Table Cell` + `Cell Text`: the two are never
|
|
62
|
+
* used apart in the design (`Table Cell` always wraps exactly one `Cell
|
|
63
|
+
* Text`), so splitting them into two exported components would only add API
|
|
64
|
+
* surface for a composition nothing ever varies independently.
|
|
65
|
+
*
|
|
66
|
+
* `header` decides `<th>` vs `<td>` directly rather than a `type` prop that
|
|
67
|
+
* could disagree with where the cell actually sits — a `<th>` rendered inside
|
|
68
|
+
* `<tbody>` is still a header cell to the browser and to CSS either way.
|
|
69
|
+
*/
|
|
70
|
+
export declare const TableCell: React.ForwardRefExoticComponent<TableCellProps & React.RefAttributes<HTMLTableCellElement>>;
|
|
71
|
+
//# sourceMappingURL=Table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../src/components/Table.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAE7D,MAAM,WAAW,UAAW,SAAQ,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC;IAC7E,uEAAuE;IACvE,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB;wCACoC;IACpC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,KAAK,qFAmBjB,CAAC;AAGF,eAAO,MAAM,SAAS,+HAG2B,CAAC;AAGlD,eAAO,MAAM,SAAS,+HAG2B,CAAC;AAGlD,MAAM,WAAW,aAAc,SAAQ,KAAK,CAAC,cAAc,CAAC,mBAAmB,CAAC;IAC9E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,QAAQ,CAAC,CAAC;CACnD;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ,2FAgBpB,CAAC;AAGF,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE/D,MAAM,WAAW,cAAe,SAAQ,IAAI,CAC1C,KAAK,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,EAC5C,OAAO,CACR;IACC;yBACqB;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB;wDACoD;IACpD,OAAO,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC7B,uEAAuE;IACvE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qEAAqE;IACrE,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,6FAkDrB,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
import { Checkbox } from './Checkbox.js';
|
|
4
|
+
/**
|
|
5
|
+
* `Table` owns the scroll container and the density class; everything else
|
|
6
|
+
* is composed from `TableHead` / `TableBody` / `TableRow` / `TableCell`,
|
|
7
|
+
* matching how Figma actually layers `Table Row` > `Table Cell` > `Cell Text`
|
|
8
|
+
* rather than one component with a wall of props.
|
|
9
|
+
*
|
|
10
|
+
* Density has no React state to thread: it only ever changes vertical cell
|
|
11
|
+
* padding, which `.ion-table--compact td` and friends apply through the CSS
|
|
12
|
+
* cascade from this one class. A context provider for a value nothing in JS
|
|
13
|
+
* ever reads would be infrastructure with no consumer.
|
|
14
|
+
*/
|
|
15
|
+
export const Table = forwardRef(({ density = 'default', isStriped, className, children, ...rest }, ref) => (_jsx("div", { className: "ion-table-container", children: _jsx("table", { ...rest, ref: ref, className: [
|
|
16
|
+
'ion-table',
|
|
17
|
+
density !== 'default' ? `ion-table--${density}` : '',
|
|
18
|
+
isStriped ? 'ion-table--striped' : '',
|
|
19
|
+
className,
|
|
20
|
+
]
|
|
21
|
+
.filter(Boolean)
|
|
22
|
+
.join(' '), children: children }) })));
|
|
23
|
+
Table.displayName = 'Table';
|
|
24
|
+
export const TableHead = forwardRef((props, ref) => _jsx("thead", { ...props, ref: ref }));
|
|
25
|
+
TableHead.displayName = 'TableHead';
|
|
26
|
+
export const TableBody = forwardRef((props, ref) => _jsx("tbody", { ...props, ref: ref }));
|
|
27
|
+
TableBody.displayName = 'TableBody';
|
|
28
|
+
/**
|
|
29
|
+
* A plain `<tr>`. Hover is CSS-only (`:hover` plus a `data-hovered` escape
|
|
30
|
+
* hatch, matching the rest of the system) rather than React Aria's
|
|
31
|
+
* `useHover`: a row is not itself an interactive element — nothing about it
|
|
32
|
+
* takes focus or fires a click — so there is no keyboard-vs-pointer
|
|
33
|
+
* distinction to track. A clickable row is a link or button inside a cell,
|
|
34
|
+
* the same accessible pattern Menu and Table Cell's own link variant use;
|
|
35
|
+
* nesting an interactive role on `<tr>` itself is not valid HTML.
|
|
36
|
+
*/
|
|
37
|
+
export const TableRow = forwardRef(({ isSelected, selection, className, children, ...rest }, ref) => (_jsxs("tr", { ...rest, ref: ref, "data-selected": isSelected || undefined, className: ['ion-table__row', className].filter(Boolean).join(' '), children: [selection && (_jsx("td", { children: _jsx(Checkbox, { ...selection }) })), children] })));
|
|
38
|
+
TableRow.displayName = 'TableRow';
|
|
39
|
+
/**
|
|
40
|
+
* One component covers Figma's `Table Cell` + `Cell Text`: the two are never
|
|
41
|
+
* used apart in the design (`Table Cell` always wraps exactly one `Cell
|
|
42
|
+
* Text`), so splitting them into two exported components would only add API
|
|
43
|
+
* surface for a composition nothing ever varies independently.
|
|
44
|
+
*
|
|
45
|
+
* `header` decides `<th>` vs `<td>` directly rather than a `type` prop that
|
|
46
|
+
* could disagree with where the cell actually sits — a `<th>` rendered inside
|
|
47
|
+
* `<tbody>` is still a header cell to the browser and to CSS either way.
|
|
48
|
+
*/
|
|
49
|
+
export const TableCell = forwardRef(({ header, align = 'leading', variant = 'default', showDivider, icon, trailingIcon, className, children, ...rest }, ref) => {
|
|
50
|
+
const Tag = header ? 'th' : 'td';
|
|
51
|
+
const contentClassNames = [
|
|
52
|
+
'ion-table__cell-content',
|
|
53
|
+
variant === 'link' ? 'ion-table__cell-content--link' : '',
|
|
54
|
+
]
|
|
55
|
+
.filter(Boolean)
|
|
56
|
+
.join(' ');
|
|
57
|
+
return (_jsx(Tag, { ...rest, ref: ref, "data-align": align !== 'leading' ? align : undefined, "data-divider": showDivider || undefined, className: className, children: _jsxs("span", { className: contentClassNames, children: [icon && (_jsx("span", { className: "ion-table__cell-icon", "aria-hidden": "true", children: icon })), children, trailingIcon && (_jsx("span", { className: "ion-table__cell-icon ion-table__cell-icon--trailing", "aria-hidden": "true", children: trailingIcon }))] }) }));
|
|
58
|
+
});
|
|
59
|
+
TableCell.displayName = 'TableCell';
|
|
60
|
+
//# sourceMappingURL=Table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Table.js","sourceRoot":"","sources":["../../src/components/Table.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAYzC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAC7B,CAAC,EAAE,OAAO,GAAG,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CACzE,cAAK,SAAS,EAAC,qBAAqB,YAClC,mBACM,IAAI,EACR,GAAG,EAAE,GAAG,EACR,SAAS,EAAE;YACT,WAAW;YACX,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE;YACpD,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE;YACrC,SAAS;SACV;aACE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,GAAG,CAAC,YAEX,QAAQ,GACH,GACJ,CACP,CACF,CAAC;AACF,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC;AAE5B,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CAGjC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,mBAAW,KAAK,EAAE,GAAG,EAAE,GAAG,GAAI,CAAC,CAAC;AAClD,SAAS,CAAC,WAAW,GAAG,WAAW,CAAC;AAEpC,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CAGjC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,mBAAW,KAAK,EAAE,GAAG,EAAE,GAAG,GAAI,CAAC,CAAC;AAClD,SAAS,CAAC,WAAW,GAAG,WAAW,CAAC;AAYpC;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAChC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAChE,iBACM,IAAI,EACR,GAAG,EAAE,GAAG,mBACO,UAAU,IAAI,SAAS,EACtC,SAAS,EAAE,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,aAEjE,SAAS,IAAI,CACZ,uBACE,KAAC,QAAQ,OAAK,SAAS,GAAI,GACxB,CACN,EACA,QAAQ,IACN,CACN,CACF,CAAC;AACF,QAAQ,CAAC,WAAW,GAAG,UAAU,CAAC;AAuBlC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CACjC,CACE,EACE,MAAM,EACN,KAAK,GAAG,SAAS,EACjB,OAAO,GAAG,SAAS,EACnB,WAAW,EACX,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,GAAG,IAAI,EACR,EACD,GAAG,EACH,EAAE;IACF,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACjC,MAAM,iBAAiB,GAAG;QACxB,yBAAyB;QACzB,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,EAAE;KAC1D;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,OAAO,CACL,KAAC,GAAG,OACE,IAAI,EACR,GAAG,EAAE,GAAG,gBACI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,kBACrC,WAAW,IAAI,SAAS,EACtC,SAAS,EAAE,SAAS,YAEpB,gBAAM,SAAS,EAAE,iBAAiB,aAC/B,IAAI,IAAI,CACP,eAAM,SAAS,EAAC,sBAAsB,iBAAa,MAAM,YACtD,IAAI,GACA,CACR,EACA,QAAQ,EACR,YAAY,IAAI,CACf,eACE,SAAS,EAAC,qDAAqD,iBACnD,MAAM,YAEjB,YAAY,GACR,CACR,IACI,GACH,CACP,CAAC;AACJ,CAAC,CACF,CAAC;AACF,SAAS,CAAC,WAAW,GAAG,WAAW,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type AriaTabListProps } from 'react-aria';
|
|
3
|
+
import { Item } from '@react-stately/collections';
|
|
4
|
+
export type TabsType = 'pill' | 'underline';
|
|
5
|
+
export type TabsSize = 'sm' | 'md' | 'lg';
|
|
6
|
+
export interface TabsProps<T extends object> extends AriaTabListProps<T> {
|
|
7
|
+
/** Visual style. Matches the Figma `Type` variant. */
|
|
8
|
+
type?: TabsType;
|
|
9
|
+
/** Matches the Figma `Size` variant. */
|
|
10
|
+
size?: TabsSize;
|
|
11
|
+
/**
|
|
12
|
+
* Only `horizontal` is implemented. Figma also defines vertical; the prop
|
|
13
|
+
* exists so adding it later is additive rather than a breaking rename.
|
|
14
|
+
*/
|
|
15
|
+
orientation?: 'horizontal';
|
|
16
|
+
className?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare const Tabs: <T extends object>(props: TabsProps<T> & {
|
|
19
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
20
|
+
}) => React.ReactElement;
|
|
21
|
+
/** A tab and its panel content. `title` is the tab label; children are the panel. */
|
|
22
|
+
export { Item as TabItem };
|
|
23
|
+
//# sourceMappingURL=Tabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../src/components/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6B,MAAM,OAAO,CAAC;AAClD,OAAO,EAOL,KAAK,gBAAgB,EACtB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAGlD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAC5C,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE1C,MAAM,WAAW,SAAS,CAAC,CAAC,SAAS,MAAM,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IACtE,sDAAsD;IACtD,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,wCAAwC;IACxC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAwED,eAAO,MAAM,IAAI,EAyCX,CAAC,CAAC,SAAS,MAAM,EACrB,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;CAAE,KACtD,KAAK,CAAC,YAAY,CAAC;AAExB,qFAAqF;AACrF,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useRef } from 'react';
|
|
3
|
+
import { useTabList, useTab, useTabPanel, useHover, useFocusRing, mergeProps, } from 'react-aria';
|
|
4
|
+
import { useTabListState } from 'react-stately';
|
|
5
|
+
import { Item } from '@react-stately/collections';
|
|
6
|
+
/**
|
|
7
|
+
* A single tab. `useTab` supplies roving tabindex, arrow-key navigation and the
|
|
8
|
+
* aria-controls/aria-labelledby pairing with the panel.
|
|
9
|
+
*/
|
|
10
|
+
function Tab({ item, state, type, size, }) {
|
|
11
|
+
const ref = useRef(null);
|
|
12
|
+
const { key, rendered } = item;
|
|
13
|
+
const isDisabled = state.disabledKeys.has(key);
|
|
14
|
+
const { tabProps, isSelected } = useTab({ key }, state, ref);
|
|
15
|
+
// Same pattern as Button: native :hover latches on touch, and focus-visible
|
|
16
|
+
// must distinguish keyboard from pointer.
|
|
17
|
+
const { hoverProps, isHovered } = useHover({ isDisabled });
|
|
18
|
+
const { focusProps, isFocusVisible } = useFocusRing();
|
|
19
|
+
const className = [
|
|
20
|
+
'ion-tabs__item',
|
|
21
|
+
`ion-tabs__item--${type}`,
|
|
22
|
+
size !== 'md' ? `ion-tabs__item--${size}` : '',
|
|
23
|
+
]
|
|
24
|
+
.filter(Boolean)
|
|
25
|
+
.join(' ');
|
|
26
|
+
return (_jsx("div", { ...mergeProps(tabProps, hoverProps, focusProps), ref: ref, className: className, "data-selected": isSelected || undefined, "data-hovered": isHovered || undefined, "data-focused": isFocusVisible || undefined, "data-disabled": isDisabled || undefined, children: rendered }));
|
|
27
|
+
}
|
|
28
|
+
function TabPanel({ state, className, ...rest }) {
|
|
29
|
+
const ref = useRef(null);
|
|
30
|
+
const { tabPanelProps } = useTabPanel(rest, state, ref);
|
|
31
|
+
return (_jsx("div", { ...tabPanelProps, ref: ref, className: ['ion-tabs__panel', className].filter(Boolean).join(' '), children: state.selectedItem?.props.children }));
|
|
32
|
+
}
|
|
33
|
+
export const Tabs = forwardRef(function Tabs(props, forwardedRef) {
|
|
34
|
+
const { type = 'pill', size = 'md', orientation = 'horizontal', className: customClassName, ...ariaProps } = props;
|
|
35
|
+
const state = useTabListState(ariaProps);
|
|
36
|
+
const listRef = useRef(null);
|
|
37
|
+
const { tabListProps } = useTabList(ariaProps, state, listRef);
|
|
38
|
+
const trackClassName = [
|
|
39
|
+
'ion-tabs__track',
|
|
40
|
+
`ion-tabs__track--${type}`,
|
|
41
|
+
`ion-tabs__track--${orientation}`,
|
|
42
|
+
].join(' ');
|
|
43
|
+
return (_jsxs("div", { ref: forwardedRef, className: ['ion-tabs', customClassName].filter(Boolean).join(' '), children: [_jsx("div", { ...tabListProps, ref: listRef, className: trackClassName, children: [...state.collection].map((item) => (_jsx(Tab, { item: item, state: state, type: type, size: size }, item.key))) }), _jsx(TabPanel, { state: state }, state.selectedItem?.key)] }));
|
|
44
|
+
});
|
|
45
|
+
/** A tab and its panel content. `title` is the tab label; children are the panel. */
|
|
46
|
+
export { Item as TabItem };
|
|
47
|
+
//# sourceMappingURL=Tabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tabs.js","sourceRoot":"","sources":["../../src/components/Tabs.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export type ToggleSize = 'sm' | 'md' | 'lg';
|
|
3
|
+
export type ToggleIntent = 'brand' | 'neutral' | 'danger';
|
|
4
|
+
export interface ToggleProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {
|
|
5
|
+
/** Matches the Figma `Size` variant: Small, Medium, Large. */
|
|
6
|
+
size?: ToggleSize;
|
|
7
|
+
/** Matches the Figma `Color` variant: Brand, Neutral, Danger. */
|
|
8
|
+
intent?: ToggleIntent;
|
|
9
|
+
children?: React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Toggle is a checkbox with `role="switch"`.
|
|
13
|
+
*
|
|
14
|
+
* Not a button with aria-pressed: a switch is a form value, and the checkbox
|
|
15
|
+
* gives form association and `:checked` for free. `role="switch"` changes only
|
|
16
|
+
* how it is announced — "on/off" rather than "checked/unchecked" — which is
|
|
17
|
+
* what Figma's On/Off states describe.
|
|
18
|
+
*
|
|
19
|
+
* The visual difference from Checkbox is entirely in CSS; this component and
|
|
20
|
+
* Checkbox are near-identical by design rather than by accident, and are kept
|
|
21
|
+
* apart because Figma models them as separate components with separate size
|
|
22
|
+
* ramps.
|
|
23
|
+
*/
|
|
24
|
+
export declare const Toggle: React.ForwardRefExoticComponent<ToggleProps & React.RefAttributes<HTMLInputElement>>;
|
|
25
|
+
//# sourceMappingURL=Toggle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toggle.d.ts","sourceRoot":"","sources":["../../src/components/Toggle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkD,MAAM,OAAO,CAAC;AAEvE,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC5C,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE1D,MAAM,WAAW,WAAY,SAAQ,IAAI,CACvC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAC3C,MAAM,GAAG,MAAM,CAChB;IACC,8DAA8D;IAC9D,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,iEAAiE;IACjE,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,MAAM,sFAyClB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useRef, useImperativeHandle } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Toggle is a checkbox with `role="switch"`.
|
|
5
|
+
*
|
|
6
|
+
* Not a button with aria-pressed: a switch is a form value, and the checkbox
|
|
7
|
+
* gives form association and `:checked` for free. `role="switch"` changes only
|
|
8
|
+
* how it is announced — "on/off" rather than "checked/unchecked" — which is
|
|
9
|
+
* what Figma's On/Off states describe.
|
|
10
|
+
*
|
|
11
|
+
* The visual difference from Checkbox is entirely in CSS; this component and
|
|
12
|
+
* Checkbox are near-identical by design rather than by accident, and are kept
|
|
13
|
+
* apart because Figma models them as separate components with separate size
|
|
14
|
+
* ramps.
|
|
15
|
+
*/
|
|
16
|
+
export const Toggle = forwardRef((props, forwardedRef) => {
|
|
17
|
+
const { size = 'md', intent = 'brand', className, children, disabled, ...rest } = props;
|
|
18
|
+
const domRef = useRef(null);
|
|
19
|
+
useImperativeHandle(forwardedRef, () => domRef.current);
|
|
20
|
+
const classNames = [
|
|
21
|
+
'ion-toggle',
|
|
22
|
+
size !== 'md' ? `ion-toggle--${size}` : '',
|
|
23
|
+
intent !== 'brand' ? `ion-toggle--${intent}` : '',
|
|
24
|
+
disabled ? 'ion-toggle--disabled' : '',
|
|
25
|
+
className || '',
|
|
26
|
+
]
|
|
27
|
+
.filter(Boolean)
|
|
28
|
+
.join(' ');
|
|
29
|
+
return (_jsxs("label", { className: classNames, children: [_jsx("input", { ...rest, ref: domRef, type: "checkbox", role: "switch", disabled: disabled, className: "ion-toggle__input" }), _jsx("span", { className: "ion-toggle__track", "aria-hidden": "true", children: _jsx("span", { className: "ion-toggle__thumb" }) }), children && _jsx("span", { className: "ion-toggle__label", children: children })] }));
|
|
30
|
+
});
|
|
31
|
+
Toggle.displayName = 'Toggle';
|
|
32
|
+
//# sourceMappingURL=Toggle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toggle.js","sourceRoot":"","sources":["../../src/components/Toggle.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,UAAU,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAgBvE;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAC9B,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE;IACtB,MAAM,EACJ,IAAI,GAAG,IAAI,EACX,MAAM,GAAG,OAAO,EAChB,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,GAAG,IAAI,EACR,GAAG,KAAK,CAAC;IAEV,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,YAAY;QACZ,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;QAC1C,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,eAAe,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE;QACjD,QAAQ,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE;QACtC,SAAS,IAAI,EAAE;KAChB;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,OAAO,CACL,iBAAO,SAAS,EAAE,UAAU,aAC1B,mBACM,IAAI,EACR,GAAG,EAAE,MAAM,EACX,IAAI,EAAC,UAAU,EACf,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAC,mBAAmB,GAC7B,EACF,eAAM,SAAS,EAAC,mBAAmB,iBAAa,MAAM,YACpD,eAAM,SAAS,EAAC,mBAAmB,GAAG,GACjC,EACN,QAAQ,IAAI,eAAM,SAAS,EAAC,mBAAmB,YAAE,QAAQ,GAAQ,IAC5D,CACT,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export { Button } from './Button.js';
|
|
2
|
+
export type { ButtonProps } from './Button.js';
|
|
3
|
+
export { Tabs, TabItem } from './Tabs.js';
|
|
4
|
+
export type { TabsProps, TabsType, TabsSize } from './Tabs.js';
|
|
5
|
+
export { Badge } from './Badge.js';
|
|
6
|
+
export type { BadgeProps, BadgeIntent } from './Badge.js';
|
|
7
|
+
export { Input } from './Input.js';
|
|
8
|
+
export type { InputProps, InputSize } from './Input.js';
|
|
9
|
+
export { Select } from './Select.js';
|
|
10
|
+
export type { SelectProps, SelectSize, SelectOption } from './Select.js';
|
|
11
|
+
export { Checkbox } from './Checkbox.js';
|
|
12
|
+
export type { CheckboxProps, CheckboxSize, CheckboxIntent, } from './Checkbox.js';
|
|
13
|
+
export { Radio, RadioGroup } from './Radio.js';
|
|
14
|
+
export type { RadioProps, RadioGroupProps, RadioSize, RadioIntent, } from './Radio.js';
|
|
15
|
+
export { Toggle } from './Toggle.js';
|
|
16
|
+
export type { ToggleProps, ToggleSize, ToggleIntent } from './Toggle.js';
|
|
17
|
+
export { Menu, MenuItem } from './Menu.js';
|
|
18
|
+
export type { MenuProps, MenuItemProps } from './Menu.js';
|
|
19
|
+
export { Avatar, AvatarGroup } from './Avatar.js';
|
|
20
|
+
export type { AvatarProps, AvatarGroupProps, AvatarSize, AvatarShape, } from './Avatar.js';
|
|
21
|
+
export { Header } from './Header.js';
|
|
22
|
+
export type { HeaderProps } from './Header.js';
|
|
23
|
+
export { Logo, LogoMark } from './Logo.js';
|
|
24
|
+
export type { LogoProps, LogoMarkProps, LogoSize, LogoWordmark, } from './Logo.js';
|
|
25
|
+
export { Divider } from './Divider.js';
|
|
26
|
+
export type { DividerProps, DividerOrientation } from './Divider.js';
|
|
27
|
+
export { NavItem } from './NavItem.js';
|
|
28
|
+
export type { NavItemProps } from './NavItem.js';
|
|
29
|
+
export { Table, TableHead, TableBody, TableRow, TableCell } from './Table.js';
|
|
30
|
+
export type { TableProps, TableDensity, TableRowProps, TableCellProps, TableCellAlign, } from './Table.js';
|
|
31
|
+
export { ScrollProgress } from './ScrollProgress.js';
|
|
32
|
+
export type { ScrollProgressProps, ScrollProgressSection, } from './ScrollProgress.js';
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EACV,aAAa,EACb,YAAY,EACZ,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC/C,YAAY,EACV,UAAU,EACV,eAAe,EACf,SAAS,EACT,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAClD,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,UAAU,EACV,WAAW,GACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,YAAY,EACV,SAAS,EACT,aAAa,EACb,QAAQ,EACR,YAAY,GACb,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC9E,YAAY,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,cAAc,EACd,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EACV,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export { Button } from './Button.js';
|
|
2
|
+
export { Tabs, TabItem } from './Tabs.js';
|
|
3
|
+
export { Badge } from './Badge.js';
|
|
4
|
+
export { Input } from './Input.js';
|
|
5
|
+
export { Select } from './Select.js';
|
|
6
|
+
export { Checkbox } from './Checkbox.js';
|
|
7
|
+
export { Radio, RadioGroup } from './Radio.js';
|
|
8
|
+
export { Toggle } from './Toggle.js';
|
|
9
|
+
export { Menu, MenuItem } from './Menu.js';
|
|
10
|
+
export { Avatar, AvatarGroup } from './Avatar.js';
|
|
11
|
+
export { Header } from './Header.js';
|
|
12
|
+
export { Logo, LogoMark } from './Logo.js';
|
|
13
|
+
export { Divider } from './Divider.js';
|
|
14
|
+
export { NavItem } from './NavItem.js';
|
|
15
|
+
export { Table, TableHead, TableBody, TableRow, TableCell } from './Table.js';
|
|
16
|
+
export { ScrollProgress } from './ScrollProgress.js';
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAMzC,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAO/C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAOlD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAO3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAQ9E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|