@ttoss/fsl-ui 0.2.4
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 +76 -0
- package/dist/_virtual/_rolldown/runtime.cjs +30 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.cjs +129 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.d.cts +61 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.d.mts +61 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.mjs +126 -0
- package/dist/components/Button/Button.cjs +80 -0
- package/dist/components/Button/Button.d.cts +68 -0
- package/dist/components/Button/Button.d.mts +68 -0
- package/dist/components/Button/Button.mjs +79 -0
- package/dist/components/Checkbox/Checkbox.cjs +183 -0
- package/dist/components/Checkbox/Checkbox.d.cts +45 -0
- package/dist/components/Checkbox/Checkbox.d.mts +45 -0
- package/dist/components/Checkbox/Checkbox.mjs +182 -0
- package/dist/components/CheckboxGroup/CheckboxGroup.cjs +97 -0
- package/dist/components/CheckboxGroup/CheckboxGroup.d.cts +56 -0
- package/dist/components/CheckboxGroup/CheckboxGroup.d.mts +56 -0
- package/dist/components/CheckboxGroup/CheckboxGroup.mjs +96 -0
- package/dist/components/FileTrigger/FileTrigger.cjs +51 -0
- package/dist/components/FileTrigger/FileTrigger.d.cts +52 -0
- package/dist/components/FileTrigger/FileTrigger.d.mts +52 -0
- package/dist/components/FileTrigger/FileTrigger.mjs +50 -0
- package/dist/components/GridList/GridList.cjs +220 -0
- package/dist/components/GridList/GridList.d.cts +72 -0
- package/dist/components/GridList/GridList.d.mts +72 -0
- package/dist/components/GridList/GridList.mjs +217 -0
- package/dist/components/Group/Group.cjs +77 -0
- package/dist/components/Group/Group.d.cts +61 -0
- package/dist/components/Group/Group.d.mts +61 -0
- package/dist/components/Group/Group.mjs +74 -0
- package/dist/components/Icon/Icon.cjs +52 -0
- package/dist/components/Icon/Icon.mjs +52 -0
- package/dist/components/Icon/glyphs.cjs +72 -0
- package/dist/components/Icon/glyphs.mjs +63 -0
- package/dist/components/Link/Link.cjs +62 -0
- package/dist/components/Link/Link.d.cts +38 -0
- package/dist/components/Link/Link.d.mts +38 -0
- package/dist/components/Link/Link.mjs +61 -0
- package/dist/components/ListBox/ListBox.cjs +126 -0
- package/dist/components/ListBox/ListBox.d.cts +63 -0
- package/dist/components/ListBox/ListBox.d.mts +63 -0
- package/dist/components/ListBox/ListBox.mjs +123 -0
- package/dist/components/Meter/Meter.cjs +126 -0
- package/dist/components/Meter/Meter.d.cts +63 -0
- package/dist/components/Meter/Meter.d.mts +63 -0
- package/dist/components/Meter/Meter.mjs +125 -0
- package/dist/components/NumberField/NumberField.cjs +221 -0
- package/dist/components/NumberField/NumberField.d.cts +68 -0
- package/dist/components/NumberField/NumberField.d.mts +68 -0
- package/dist/components/NumberField/NumberField.mjs +220 -0
- package/dist/components/ProgressBar/ProgressBar.cjs +132 -0
- package/dist/components/ProgressBar/ProgressBar.d.cts +56 -0
- package/dist/components/ProgressBar/ProgressBar.d.mts +56 -0
- package/dist/components/ProgressBar/ProgressBar.mjs +129 -0
- package/dist/components/RadioGroup/RadioGroup.cjs +218 -0
- package/dist/components/RadioGroup/RadioGroup.d.cts +82 -0
- package/dist/components/RadioGroup/RadioGroup.d.mts +82 -0
- package/dist/components/RadioGroup/RadioGroup.mjs +215 -0
- package/dist/components/Select/Select.cjs +253 -0
- package/dist/components/Select/Select.d.cts +86 -0
- package/dist/components/Select/Select.d.mts +86 -0
- package/dist/components/Select/Select.mjs +250 -0
- package/dist/components/Separator/Separator.cjs +64 -0
- package/dist/components/Separator/Separator.d.cts +44 -0
- package/dist/components/Separator/Separator.d.mts +44 -0
- package/dist/components/Separator/Separator.mjs +63 -0
- package/dist/components/Slider/Slider.cjs +160 -0
- package/dist/components/Slider/Slider.d.cts +45 -0
- package/dist/components/Slider/Slider.d.mts +45 -0
- package/dist/components/Slider/Slider.mjs +159 -0
- package/dist/components/Switch/Switch.cjs +176 -0
- package/dist/components/Switch/Switch.d.cts +43 -0
- package/dist/components/Switch/Switch.d.mts +43 -0
- package/dist/components/Switch/Switch.mjs +175 -0
- package/dist/components/Tabs/Tabs.cjs +180 -0
- package/dist/components/Tabs/Tabs.d.cts +85 -0
- package/dist/components/Tabs/Tabs.d.mts +85 -0
- package/dist/components/Tabs/Tabs.mjs +173 -0
- package/dist/components/Toast/Toast.cjs +218 -0
- package/dist/components/Toast/Toast.d.cts +96 -0
- package/dist/components/Toast/Toast.d.mts +96 -0
- package/dist/components/Toast/Toast.mjs +214 -0
- package/dist/components/ToggleButton/ToggleButton.cjs +125 -0
- package/dist/components/ToggleButton/ToggleButton.d.cts +43 -0
- package/dist/components/ToggleButton/ToggleButton.d.mts +43 -0
- package/dist/components/ToggleButton/ToggleButton.mjs +124 -0
- package/dist/components/ToggleButtonGroup/ToggleButtonGroup.cjs +48 -0
- package/dist/components/ToggleButtonGroup/ToggleButtonGroup.d.cts +41 -0
- package/dist/components/ToggleButtonGroup/ToggleButtonGroup.d.mts +41 -0
- package/dist/components/ToggleButtonGroup/ToggleButtonGroup.mjs +47 -0
- package/dist/components/Toolbar/Toolbar.cjs +67 -0
- package/dist/components/Toolbar/Toolbar.d.cts +60 -0
- package/dist/components/Toolbar/Toolbar.d.mts +60 -0
- package/dist/components/Toolbar/Toolbar.mjs +66 -0
- package/dist/composites/Accordion/Accordion.cjs +279 -0
- package/dist/composites/Accordion/Accordion.d.cts +176 -0
- package/dist/composites/Accordion/Accordion.d.mts +176 -0
- package/dist/composites/Accordion/Accordion.mjs +270 -0
- package/dist/composites/ConfirmationDialog/ConfirmationDialog.cjs +206 -0
- package/dist/composites/ConfirmationDialog/ConfirmationDialog.d.cts +166 -0
- package/dist/composites/ConfirmationDialog/ConfirmationDialog.d.mts +166 -0
- package/dist/composites/ConfirmationDialog/ConfirmationDialog.mjs +203 -0
- package/dist/composites/Dialog/Dialog.cjs +372 -0
- package/dist/composites/Dialog/Dialog.d.cts +234 -0
- package/dist/composites/Dialog/Dialog.d.mts +234 -0
- package/dist/composites/Dialog/Dialog.mjs +360 -0
- package/dist/composites/Disclosure/Disclosure.cjs +214 -0
- package/dist/composites/Disclosure/Disclosure.d.cts +118 -0
- package/dist/composites/Disclosure/Disclosure.d.mts +118 -0
- package/dist/composites/Disclosure/Disclosure.mjs +207 -0
- package/dist/composites/Form/Form.cjs +161 -0
- package/dist/composites/Form/Form.d.cts +176 -0
- package/dist/composites/Form/Form.d.mts +176 -0
- package/dist/composites/Form/Form.mjs +156 -0
- package/dist/composites/Menu/Menu.cjs +190 -0
- package/dist/composites/Menu/Menu.d.cts +158 -0
- package/dist/composites/Menu/Menu.d.mts +158 -0
- package/dist/composites/Menu/Menu.mjs +186 -0
- package/dist/composites/Popover/Popover.cjs +80 -0
- package/dist/composites/Popover/Popover.d.cts +56 -0
- package/dist/composites/Popover/Popover.d.mts +56 -0
- package/dist/composites/Popover/Popover.mjs +78 -0
- package/dist/composites/SearchField/SearchField.cjs +194 -0
- package/dist/composites/SearchField/SearchField.d.cts +81 -0
- package/dist/composites/SearchField/SearchField.d.mts +81 -0
- package/dist/composites/SearchField/SearchField.mjs +189 -0
- package/dist/composites/TagGroup/TagGroup.cjs +212 -0
- package/dist/composites/TagGroup/TagGroup.d.cts +84 -0
- package/dist/composites/TagGroup/TagGroup.d.mts +84 -0
- package/dist/composites/TagGroup/TagGroup.mjs +209 -0
- package/dist/composites/TextArea/TextArea.cjs +190 -0
- package/dist/composites/TextArea/TextArea.d.cts +95 -0
- package/dist/composites/TextArea/TextArea.d.mts +95 -0
- package/dist/composites/TextArea/TextArea.mjs +181 -0
- package/dist/composites/TextField/TextField.cjs +200 -0
- package/dist/composites/TextField/TextField.d.cts +111 -0
- package/dist/composites/TextField/TextField.d.mts +111 -0
- package/dist/composites/TextField/TextField.mjs +191 -0
- package/dist/composites/Tooltip/Tooltip.cjs +79 -0
- package/dist/composites/Tooltip/Tooltip.d.cts +53 -0
- package/dist/composites/Tooltip/Tooltip.d.mts +53 -0
- package/dist/composites/Tooltip/Tooltip.mjs +77 -0
- package/dist/composites/Wizard/Wizard.cjs +333 -0
- package/dist/composites/Wizard/Wizard.d.cts +206 -0
- package/dist/composites/Wizard/Wizard.d.mts +206 -0
- package/dist/composites/Wizard/Wizard.mjs +324 -0
- package/dist/composites/scope.cjs +124 -0
- package/dist/composites/scope.mjs +121 -0
- package/dist/index.cjs +186 -0
- package/dist/index.d.cts +37 -0
- package/dist/index.d.mts +37 -0
- package/dist/index.mjs +39 -0
- package/dist/semantics/componentMeta.d.cts +37 -0
- package/dist/semantics/componentMeta.d.mts +37 -0
- package/dist/semantics/index.cjs +16 -0
- package/dist/semantics/index.d.cts +4 -0
- package/dist/semantics/index.d.mts +4 -0
- package/dist/semantics/index.mjs +3 -0
- package/dist/semantics/taxonomy.cjs +150 -0
- package/dist/semantics/taxonomy.d.cts +153 -0
- package/dist/semantics/taxonomy.d.mts +153 -0
- package/dist/semantics/taxonomy.mjs +140 -0
- package/dist/tokens/escapeHatch.cjs +13 -0
- package/dist/tokens/escapeHatch.mjs +13 -0
- package/dist/tokens/focusRing.cjs +28 -0
- package/dist/tokens/focusRing.mjs +28 -0
- package/dist/tokens/keyframes.cjs +76 -0
- package/dist/tokens/keyframes.mjs +75 -0
- package/dist/tokens/resolveInteractiveStyle.cjs +41 -0
- package/dist/tokens/resolveInteractiveStyle.mjs +41 -0
- package/llms.txt +142 -0
- package/package.json +70 -0
- package/src/tokens/CONTRACT.md +505 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
|
|
2
|
+
import { EvaluationsFor } from "../../semantics/taxonomy.mjs";
|
|
3
|
+
import { ButtonProps, DisclosureGroupProps, DisclosurePanelProps, DisclosureProps } from "react-aria-components";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
|
|
6
|
+
//#region src/composites/Accordion/Accordion.d.ts
|
|
7
|
+
/** Formal semantic identity — Accordion root (Disclosure entity, group host). */
|
|
8
|
+
declare const accordionMeta: {
|
|
9
|
+
readonly displayName: "Accordion";
|
|
10
|
+
readonly entity: "Disclosure";
|
|
11
|
+
readonly structure: "root";
|
|
12
|
+
};
|
|
13
|
+
/** Formal semantic identity — AccordionItem (Disclosure entity, single item).
|
|
14
|
+
*
|
|
15
|
+
* Intentionally has no `composition` field. Per the §2.3 evidence rule,
|
|
16
|
+
* `composition` is declared only when a runtime dispatches on it (DOM
|
|
17
|
+
* reorder, behavior selection, or coloring). The Accordion host does not
|
|
18
|
+
* dispatch on composition — items are not reordered, selected, or styled
|
|
19
|
+
* by it — so attaching a value here would be dead weight. The disclosure's
|
|
20
|
+
* interactive `'control'` is the trigger button, not the item container,
|
|
21
|
+
* and even on `accordionTriggerMeta` the value would be unused today; if
|
|
22
|
+
* a future runtime starts dispatching on it, declare it then.
|
|
23
|
+
*/
|
|
24
|
+
declare const accordionItemMeta: {
|
|
25
|
+
readonly displayName: "AccordionItem";
|
|
26
|
+
readonly entity: "Disclosure";
|
|
27
|
+
readonly structure: "root";
|
|
28
|
+
};
|
|
29
|
+
/** Formal semantic identity — AccordionTrigger (header button). */
|
|
30
|
+
declare const accordionTriggerMeta: {
|
|
31
|
+
readonly displayName: "AccordionTrigger";
|
|
32
|
+
readonly entity: "Disclosure";
|
|
33
|
+
readonly structure: "trigger";
|
|
34
|
+
};
|
|
35
|
+
/** Formal semantic identity — AccordionPanel (collapsible content region). */
|
|
36
|
+
declare const accordionPanelMeta: {
|
|
37
|
+
readonly displayName: "AccordionPanel";
|
|
38
|
+
readonly entity: "Disclosure";
|
|
39
|
+
readonly structure: "content";
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Props for the Accordion component.
|
|
43
|
+
*
|
|
44
|
+
* The composite owns its layout; pass `style`/`className` on a wrapping
|
|
45
|
+
* element rather than on the composite root. See CONTRIBUTING §4.
|
|
46
|
+
*/
|
|
47
|
+
interface AccordionProps extends Omit<DisclosureGroupProps, 'style' | 'children' | 'className'> {
|
|
48
|
+
/**
|
|
49
|
+
* Authorial emphasis. `primary` is the standard accordion chrome;
|
|
50
|
+
* `muted` is a subdued variant for sidebars and dense lists.
|
|
51
|
+
* @default 'primary'
|
|
52
|
+
*/
|
|
53
|
+
evaluation?: EvaluationsFor<'Disclosure'>;
|
|
54
|
+
/** `AccordionItem` children. */
|
|
55
|
+
children?: React.ReactNode;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A semantic accordion built on React Aria's `DisclosureGroup`.
|
|
59
|
+
*
|
|
60
|
+
* Entity = Disclosure, interaction = `disclose.toggle`. Reads from
|
|
61
|
+
* `vars.colors.navigation.{primary|muted}` and animates with
|
|
62
|
+
* `vars.motion.transition.{enter,exit}` — never with `vars.motion.feedback`,
|
|
63
|
+
* which is reserved for micro-interactions on Action and Input controls.
|
|
64
|
+
*
|
|
65
|
+
* Supports single-expand (default) or `allowsMultipleExpanded` for multiple
|
|
66
|
+
* concurrently open panels.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```tsx
|
|
70
|
+
* <Accordion>
|
|
71
|
+
* <AccordionItem id="terms">
|
|
72
|
+
* <AccordionTrigger>Terms of service</AccordionTrigger>
|
|
73
|
+
* <AccordionPanel>You agree not to misuse the service.</AccordionPanel>
|
|
74
|
+
* </AccordionItem>
|
|
75
|
+
* <AccordionItem id="privacy">
|
|
76
|
+
* <AccordionTrigger>Privacy policy</AccordionTrigger>
|
|
77
|
+
* <AccordionPanel>We collect minimal personal data.</AccordionPanel>
|
|
78
|
+
* </AccordionItem>
|
|
79
|
+
* </Accordion>
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
declare const Accordion: {
|
|
83
|
+
({
|
|
84
|
+
evaluation,
|
|
85
|
+
children,
|
|
86
|
+
...props
|
|
87
|
+
}: AccordionProps): import("react/jsx-runtime").JSX.Element;
|
|
88
|
+
displayName: "Accordion";
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Props for the AccordionItem component.
|
|
92
|
+
*/
|
|
93
|
+
interface AccordionItemProps extends Omit<DisclosureProps, 'style' | 'children' | 'className'> {
|
|
94
|
+
/** `AccordionTrigger` and `AccordionPanel` children, in that order. */
|
|
95
|
+
children?: React.ReactNode;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* A single collapsible item — must be used inside an `Accordion`.
|
|
99
|
+
*
|
|
100
|
+
* Wraps React Aria's `Disclosure`. Adjacent items are separated by a divider
|
|
101
|
+
* border; the last item's bottom border is suppressed by the parent `overflow:
|
|
102
|
+
* hidden` + the rounded surface radius.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```tsx
|
|
106
|
+
* <AccordionItem id="terms">
|
|
107
|
+
* <AccordionTrigger>Terms of service</AccordionTrigger>
|
|
108
|
+
* <AccordionPanel>You agree not to misuse the service.</AccordionPanel>
|
|
109
|
+
* </AccordionItem>
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
declare const AccordionItem: {
|
|
113
|
+
({
|
|
114
|
+
children,
|
|
115
|
+
...props
|
|
116
|
+
}: AccordionItemProps): import("react/jsx-runtime").JSX.Element;
|
|
117
|
+
displayName: "AccordionItem";
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Props for the AccordionTrigger component.
|
|
121
|
+
*
|
|
122
|
+
* Extends the full React Aria `Button` API (minus `style`/`className` and
|
|
123
|
+
* the reserved `slot`) so behavior props — `isDisabled`, `onPress`, `id`,
|
|
124
|
+
* `aria-*` — flow through to the underlying trigger button.
|
|
125
|
+
*/
|
|
126
|
+
interface AccordionTriggerProps extends Omit<ButtonProps, 'style' | 'className' | 'children' | 'slot'> {
|
|
127
|
+
/**
|
|
128
|
+
* HTML heading level of the wrapping heading element. Pick the level
|
|
129
|
+
* that fits the host page's document outline.
|
|
130
|
+
* @default 3
|
|
131
|
+
*/
|
|
132
|
+
headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
133
|
+
/** Visible label content of the trigger row. */
|
|
134
|
+
children?: React.ReactNode;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* The clickable header of an `AccordionItem`. Renders inside a heading
|
|
138
|
+
* element (level via `headingLevel`, default `<h3>` per RAC's recommended
|
|
139
|
+
* structure) and exposes `aria-expanded` / a controlled chevron icon.
|
|
140
|
+
*
|
|
141
|
+
* Reads `isExpanded`, `isHovered`, `isFocusVisible`, `isDisabled` from RAC's
|
|
142
|
+
* `Button` render-props and resolves them through the canonical state
|
|
143
|
+
* cascade in [`resolveInteractiveStyle`](../../tokens/resolveInteractiveStyle.ts).
|
|
144
|
+
*/
|
|
145
|
+
declare const AccordionTrigger: {
|
|
146
|
+
({
|
|
147
|
+
headingLevel,
|
|
148
|
+
children,
|
|
149
|
+
...props
|
|
150
|
+
}: AccordionTriggerProps): import("react/jsx-runtime").JSX.Element;
|
|
151
|
+
displayName: "AccordionTrigger";
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Props for the AccordionPanel component.
|
|
155
|
+
*/
|
|
156
|
+
type AccordionPanelProps = Omit<DisclosurePanelProps, 'style' | 'className'>;
|
|
157
|
+
/**
|
|
158
|
+
* The collapsible content region of an `AccordionItem`. RAC handles the
|
|
159
|
+
* show/hide via the parent Disclosure state; we apply the
|
|
160
|
+
* `vars.motion.transition.{enter,exit}` semantics for the chrome's
|
|
161
|
+
* appearance change.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```tsx
|
|
165
|
+
* <AccordionPanel>You agree not to misuse the service.</AccordionPanel>
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
declare const AccordionPanel: {
|
|
169
|
+
({
|
|
170
|
+
children,
|
|
171
|
+
...props
|
|
172
|
+
}: AccordionPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
173
|
+
displayName: "AccordionPanel";
|
|
174
|
+
};
|
|
175
|
+
//#endregion
|
|
176
|
+
export { Accordion, AccordionItem, AccordionItemProps, AccordionPanel, AccordionPanelProps, AccordionProps, AccordionTrigger, AccordionTriggerProps, accordionItemMeta, accordionMeta, accordionPanelMeta, accordionTriggerMeta };
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
|
|
2
|
+
import { focusRingOutline } from "../../tokens/focusRing.mjs";
|
|
3
|
+
import { resolveInteractiveStyle } from "../../tokens/resolveInteractiveStyle.mjs";
|
|
4
|
+
import { Icon } from "../../components/Icon/Icon.mjs";
|
|
5
|
+
import { createCompositeScope } from "../scope.mjs";
|
|
6
|
+
import { vars } from "@ttoss/fsl-theme/vars";
|
|
7
|
+
import { Button, Disclosure, DisclosureGroup, DisclosurePanel, DisclosureStateContext, Heading } from "react-aria-components";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import * as React from "react";
|
|
10
|
+
|
|
11
|
+
//#region src/composites/Accordion/Accordion.tsx
|
|
12
|
+
var accordionScope = createCompositeScope("Accordion");
|
|
13
|
+
/** Formal semantic identity — Accordion root (Disclosure entity, group host). */
|
|
14
|
+
var accordionMeta = {
|
|
15
|
+
displayName: "Accordion",
|
|
16
|
+
entity: "Disclosure",
|
|
17
|
+
structure: "root"
|
|
18
|
+
};
|
|
19
|
+
/** Formal semantic identity — AccordionItem (Disclosure entity, single item).
|
|
20
|
+
*
|
|
21
|
+
* Intentionally has no `composition` field. Per the §2.3 evidence rule,
|
|
22
|
+
* `composition` is declared only when a runtime dispatches on it (DOM
|
|
23
|
+
* reorder, behavior selection, or coloring). The Accordion host does not
|
|
24
|
+
* dispatch on composition — items are not reordered, selected, or styled
|
|
25
|
+
* by it — so attaching a value here would be dead weight. The disclosure's
|
|
26
|
+
* interactive `'control'` is the trigger button, not the item container,
|
|
27
|
+
* and even on `accordionTriggerMeta` the value would be unused today; if
|
|
28
|
+
* a future runtime starts dispatching on it, declare it then.
|
|
29
|
+
*/
|
|
30
|
+
var accordionItemMeta = {
|
|
31
|
+
displayName: "AccordionItem",
|
|
32
|
+
entity: "Disclosure",
|
|
33
|
+
structure: "root"
|
|
34
|
+
};
|
|
35
|
+
/** Formal semantic identity — AccordionTrigger (header button). */
|
|
36
|
+
var accordionTriggerMeta = {
|
|
37
|
+
displayName: "AccordionTrigger",
|
|
38
|
+
entity: "Disclosure",
|
|
39
|
+
structure: "trigger"
|
|
40
|
+
};
|
|
41
|
+
/** Formal semantic identity — AccordionPanel (collapsible content region). */
|
|
42
|
+
var accordionPanelMeta = {
|
|
43
|
+
displayName: "AccordionPanel",
|
|
44
|
+
entity: "Disclosure",
|
|
45
|
+
structure: "content"
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* A semantic accordion built on React Aria's `DisclosureGroup`.
|
|
49
|
+
*
|
|
50
|
+
* Entity = Disclosure, interaction = `disclose.toggle`. Reads from
|
|
51
|
+
* `vars.colors.navigation.{primary|muted}` and animates with
|
|
52
|
+
* `vars.motion.transition.{enter,exit}` — never with `vars.motion.feedback`,
|
|
53
|
+
* which is reserved for micro-interactions on Action and Input controls.
|
|
54
|
+
*
|
|
55
|
+
* Supports single-expand (default) or `allowsMultipleExpanded` for multiple
|
|
56
|
+
* concurrently open panels.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```tsx
|
|
60
|
+
* <Accordion>
|
|
61
|
+
* <AccordionItem id="terms">
|
|
62
|
+
* <AccordionTrigger>Terms of service</AccordionTrigger>
|
|
63
|
+
* <AccordionPanel>You agree not to misuse the service.</AccordionPanel>
|
|
64
|
+
* </AccordionItem>
|
|
65
|
+
* <AccordionItem id="privacy">
|
|
66
|
+
* <AccordionTrigger>Privacy policy</AccordionTrigger>
|
|
67
|
+
* <AccordionPanel>We collect minimal personal data.</AccordionPanel>
|
|
68
|
+
* </AccordionItem>
|
|
69
|
+
* </Accordion>
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
var Accordion = ({
|
|
73
|
+
evaluation = "primary",
|
|
74
|
+
children,
|
|
75
|
+
...props
|
|
76
|
+
}) => {
|
|
77
|
+
return /* @__PURE__ */jsx(accordionScope.Provider, {
|
|
78
|
+
value: {
|
|
79
|
+
evaluation
|
|
80
|
+
},
|
|
81
|
+
children: /* @__PURE__ */jsx(DisclosureGroup, {
|
|
82
|
+
...props,
|
|
83
|
+
"data-scope": "accordion",
|
|
84
|
+
"data-part": "root",
|
|
85
|
+
"data-evaluation": evaluation,
|
|
86
|
+
style: {
|
|
87
|
+
boxSizing: "border-box",
|
|
88
|
+
display: "flex",
|
|
89
|
+
flexDirection: "column",
|
|
90
|
+
borderWidth: vars.border.outline.control.width,
|
|
91
|
+
borderStyle: vars.border.outline.control.style,
|
|
92
|
+
borderColor: vars.colors.navigation[evaluation]?.border?.default ?? "transparent",
|
|
93
|
+
borderRadius: vars.radii.surface,
|
|
94
|
+
overflow: "hidden"
|
|
95
|
+
},
|
|
96
|
+
children
|
|
97
|
+
})
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
Accordion.displayName = accordionMeta.displayName;
|
|
101
|
+
/**
|
|
102
|
+
* A single collapsible item — must be used inside an `Accordion`.
|
|
103
|
+
*
|
|
104
|
+
* Wraps React Aria's `Disclosure`. Adjacent items are separated by a divider
|
|
105
|
+
* border; the last item's bottom border is suppressed by the parent `overflow:
|
|
106
|
+
* hidden` + the rounded surface radius.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```tsx
|
|
110
|
+
* <AccordionItem id="terms">
|
|
111
|
+
* <AccordionTrigger>Terms of service</AccordionTrigger>
|
|
112
|
+
* <AccordionPanel>You agree not to misuse the service.</AccordionPanel>
|
|
113
|
+
* </AccordionItem>
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
var AccordionItem = ({
|
|
117
|
+
children,
|
|
118
|
+
...props
|
|
119
|
+
}) => {
|
|
120
|
+
const {
|
|
121
|
+
evaluation
|
|
122
|
+
} = accordionScope.use(accordionItemMeta.displayName);
|
|
123
|
+
return /* @__PURE__ */jsx(Disclosure, {
|
|
124
|
+
...props,
|
|
125
|
+
"data-scope": "accordion",
|
|
126
|
+
"data-part": "item",
|
|
127
|
+
style: {
|
|
128
|
+
boxSizing: "border-box",
|
|
129
|
+
borderBlockStartWidth: vars.border.divider.width,
|
|
130
|
+
borderBlockStartStyle: vars.border.divider.style,
|
|
131
|
+
borderBlockStartColor: vars.colors.navigation[evaluation]?.border?.default ?? "transparent"
|
|
132
|
+
},
|
|
133
|
+
children
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
AccordionItem.displayName = accordionItemMeta.displayName;
|
|
137
|
+
/**
|
|
138
|
+
* The clickable header of an `AccordionItem`. Renders inside a heading
|
|
139
|
+
* element (level via `headingLevel`, default `<h3>` per RAC's recommended
|
|
140
|
+
* structure) and exposes `aria-expanded` / a controlled chevron icon.
|
|
141
|
+
*
|
|
142
|
+
* Reads `isExpanded`, `isHovered`, `isFocusVisible`, `isDisabled` from RAC's
|
|
143
|
+
* `Button` render-props and resolves them through the canonical state
|
|
144
|
+
* cascade in [`resolveInteractiveStyle`](../../tokens/resolveInteractiveStyle.ts).
|
|
145
|
+
*/
|
|
146
|
+
var AccordionTrigger = ({
|
|
147
|
+
headingLevel = 3,
|
|
148
|
+
children,
|
|
149
|
+
...props
|
|
150
|
+
}) => {
|
|
151
|
+
const {
|
|
152
|
+
evaluation
|
|
153
|
+
} = accordionScope.use(accordionTriggerMeta.displayName);
|
|
154
|
+
const c = vars.colors.navigation[evaluation];
|
|
155
|
+
const isExpanded = React.useContext(DisclosureStateContext)?.isExpanded ?? false;
|
|
156
|
+
return /* @__PURE__ */jsx(Heading, {
|
|
157
|
+
level: headingLevel,
|
|
158
|
+
"data-scope": "accordion",
|
|
159
|
+
"data-part": "header",
|
|
160
|
+
style: {
|
|
161
|
+
margin: 0
|
|
162
|
+
},
|
|
163
|
+
children: /* @__PURE__ */jsxs(Button, {
|
|
164
|
+
...props,
|
|
165
|
+
slot: "trigger",
|
|
166
|
+
"data-scope": "accordion",
|
|
167
|
+
"data-part": "trigger",
|
|
168
|
+
style: ({
|
|
169
|
+
isHovered,
|
|
170
|
+
isPressed,
|
|
171
|
+
isDisabled,
|
|
172
|
+
isFocusVisible
|
|
173
|
+
}) => {
|
|
174
|
+
const flags = {
|
|
175
|
+
isHovered,
|
|
176
|
+
isPressed,
|
|
177
|
+
isDisabled,
|
|
178
|
+
isFocusVisible,
|
|
179
|
+
isExpanded
|
|
180
|
+
};
|
|
181
|
+
return {
|
|
182
|
+
boxSizing: "border-box",
|
|
183
|
+
width: "100%",
|
|
184
|
+
display: "inline-flex",
|
|
185
|
+
alignItems: "center",
|
|
186
|
+
justifyContent: "space-between",
|
|
187
|
+
gap: vars.spacing.gap.inline.sm,
|
|
188
|
+
minHeight: vars.sizing.hit.base,
|
|
189
|
+
paddingBlock: vars.spacing.inset.control.md,
|
|
190
|
+
paddingInline: vars.spacing.inset.control.md,
|
|
191
|
+
border: "none",
|
|
192
|
+
background: "none",
|
|
193
|
+
backgroundColor: resolveInteractiveStyle(c?.background, flags),
|
|
194
|
+
color: resolveInteractiveStyle(c?.text, flags) ?? c?.text?.default,
|
|
195
|
+
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
196
|
+
opacity: isDisabled ? vars.opacity.disabled : void 0,
|
|
197
|
+
...vars.text.label.md,
|
|
198
|
+
textAlign: "start",
|
|
199
|
+
transitionProperty: "background-color, color",
|
|
200
|
+
transitionDuration: vars.motion.transition.enter.duration,
|
|
201
|
+
transitionTimingFunction: vars.motion.transition.enter.easing,
|
|
202
|
+
outline: focusRingOutline(isFocusVisible),
|
|
203
|
+
outlineOffset: "-2px"
|
|
204
|
+
};
|
|
205
|
+
},
|
|
206
|
+
children: [/* @__PURE__ */jsx("span", {
|
|
207
|
+
"data-scope": "accordion",
|
|
208
|
+
"data-part": "label",
|
|
209
|
+
style: {
|
|
210
|
+
flex: 1
|
|
211
|
+
},
|
|
212
|
+
children
|
|
213
|
+
}), /* @__PURE__ */jsx("span", {
|
|
214
|
+
"data-scope": "accordion",
|
|
215
|
+
"data-part": "indicator",
|
|
216
|
+
"aria-hidden": true,
|
|
217
|
+
style: {
|
|
218
|
+
flexShrink: 0,
|
|
219
|
+
display: "inline-block",
|
|
220
|
+
transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)",
|
|
221
|
+
transitionProperty: "transform",
|
|
222
|
+
transitionDuration: isExpanded ? vars.motion.transition.enter.duration : vars.motion.transition.exit.duration,
|
|
223
|
+
transitionTimingFunction: isExpanded ? vars.motion.transition.enter.easing : vars.motion.transition.exit.easing
|
|
224
|
+
},
|
|
225
|
+
children: /* @__PURE__ */jsx(Icon, {
|
|
226
|
+
intent: "disclosure.collapse"
|
|
227
|
+
})
|
|
228
|
+
})]
|
|
229
|
+
})
|
|
230
|
+
});
|
|
231
|
+
};
|
|
232
|
+
AccordionTrigger.displayName = accordionTriggerMeta.displayName;
|
|
233
|
+
/**
|
|
234
|
+
* The collapsible content region of an `AccordionItem`. RAC handles the
|
|
235
|
+
* show/hide via the parent Disclosure state; we apply the
|
|
236
|
+
* `vars.motion.transition.{enter,exit}` semantics for the chrome's
|
|
237
|
+
* appearance change.
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* ```tsx
|
|
241
|
+
* <AccordionPanel>You agree not to misuse the service.</AccordionPanel>
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
var AccordionPanel = ({
|
|
245
|
+
children,
|
|
246
|
+
...props
|
|
247
|
+
}) => {
|
|
248
|
+
const {
|
|
249
|
+
evaluation
|
|
250
|
+
} = accordionScope.use(accordionPanelMeta.displayName);
|
|
251
|
+
const c = vars.colors.navigation[evaluation];
|
|
252
|
+
return /* @__PURE__ */jsx(DisclosurePanel, {
|
|
253
|
+
...props,
|
|
254
|
+
"data-scope": "accordion",
|
|
255
|
+
"data-part": "content",
|
|
256
|
+
style: {
|
|
257
|
+
boxSizing: "border-box",
|
|
258
|
+
paddingBlock: vars.spacing.inset.control.md,
|
|
259
|
+
paddingInline: vars.spacing.inset.control.md,
|
|
260
|
+
backgroundColor: c?.background?.default,
|
|
261
|
+
color: c?.text?.default,
|
|
262
|
+
...vars.text.body.md
|
|
263
|
+
},
|
|
264
|
+
children
|
|
265
|
+
});
|
|
266
|
+
};
|
|
267
|
+
AccordionPanel.displayName = accordionPanelMeta.displayName;
|
|
268
|
+
|
|
269
|
+
//#endregion
|
|
270
|
+
export { Accordion, AccordionItem, AccordionPanel, AccordionTrigger, accordionItemMeta, accordionMeta, accordionPanelMeta, accordionTriggerMeta };
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
|
|
2
|
+
const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_Button = require('../../components/Button/Button.cjs');
|
|
4
|
+
const require_Dialog = require('../Dialog/Dialog.cjs');
|
|
5
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
6
|
+
let react = require("react");
|
|
7
|
+
react = require_runtime.__toESM(react);
|
|
8
|
+
|
|
9
|
+
//#region src/composites/ConfirmationDialog/ConfirmationDialog.tsx
|
|
10
|
+
/**
|
|
11
|
+
* Formal semantic identity — ConfirmationDialog root (Overlay entity).
|
|
12
|
+
*/
|
|
13
|
+
var confirmationDialogMeta = {
|
|
14
|
+
displayName: "ConfirmationDialog",
|
|
15
|
+
entity: "Overlay",
|
|
16
|
+
structure: "root"
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Owns the consequence-driven confirm mechanism so the component body stays
|
|
20
|
+
* declarative. `destructive` requires a two-click arm→confirm within
|
|
21
|
+
* `armWindowMs`; everything else confirms on the first click. Toggling
|
|
22
|
+
* `consequence` mid-lifetime resets arming via the render-phase adjustment
|
|
23
|
+
* pattern (no extra commit).
|
|
24
|
+
*/
|
|
25
|
+
var useArmedConfirm = ({
|
|
26
|
+
consequence,
|
|
27
|
+
onConfirm,
|
|
28
|
+
armWindowMs
|
|
29
|
+
}) => {
|
|
30
|
+
const requiresArming = consequence === "destructive";
|
|
31
|
+
const [isArmed, setIsArmed] = react.useState(false);
|
|
32
|
+
const armTimerRef = react.useRef(null);
|
|
33
|
+
const clearArmTimer = react.useCallback(() => {
|
|
34
|
+
if (armTimerRef.current !== null) {
|
|
35
|
+
clearTimeout(armTimerRef.current);
|
|
36
|
+
armTimerRef.current = null;
|
|
37
|
+
}
|
|
38
|
+
}, []);
|
|
39
|
+
const [prevConsequence, setPrevConsequence] = react.useState(consequence);
|
|
40
|
+
if (prevConsequence !== consequence) {
|
|
41
|
+
setPrevConsequence(consequence);
|
|
42
|
+
setIsArmed(false);
|
|
43
|
+
}
|
|
44
|
+
react.useEffect(() => {
|
|
45
|
+
return () => {
|
|
46
|
+
clearArmTimer();
|
|
47
|
+
};
|
|
48
|
+
}, [clearArmTimer]);
|
|
49
|
+
const reset = react.useCallback(() => {
|
|
50
|
+
clearArmTimer();
|
|
51
|
+
setIsArmed(false);
|
|
52
|
+
}, [clearArmTimer]);
|
|
53
|
+
const arm = react.useCallback(() => {
|
|
54
|
+
setIsArmed(true);
|
|
55
|
+
clearArmTimer();
|
|
56
|
+
armTimerRef.current = setTimeout(() => {
|
|
57
|
+
armTimerRef.current = null;
|
|
58
|
+
setIsArmed(false);
|
|
59
|
+
}, armWindowMs);
|
|
60
|
+
}, [armWindowMs, clearArmTimer]);
|
|
61
|
+
const confirm = close => {
|
|
62
|
+
if (!(!requiresArming || isArmed)) {
|
|
63
|
+
arm();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
reset();
|
|
67
|
+
onConfirm();
|
|
68
|
+
close();
|
|
69
|
+
};
|
|
70
|
+
return {
|
|
71
|
+
isArmed,
|
|
72
|
+
confirm,
|
|
73
|
+
reset
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* A Dialog composite that demands confirmation before invoking a side effect.
|
|
78
|
+
*
|
|
79
|
+
* Reads its `consequence` prop at runtime to select the confirm mechanism —
|
|
80
|
+
* this is what makes `Consequence` a behavior-driving FSL dimension and not
|
|
81
|
+
* decoration. For `destructive`, the confirm button emits
|
|
82
|
+
* `data-arming="true"` while awaiting the second click. (`data-pending` is
|
|
83
|
+
* reserved by React Aria for `isPending`, which also toggles
|
|
84
|
+
* `aria-disabled` — unsuitable here because the armed button must remain
|
|
85
|
+
* clickable for the second press.)
|
|
86
|
+
*
|
|
87
|
+
* @example Single-click commit
|
|
88
|
+
* ```tsx
|
|
89
|
+
* <ConfirmationDialog
|
|
90
|
+
* trigger={<Button>Publish</Button>}
|
|
91
|
+
* title="Publish post?"
|
|
92
|
+
* confirmLabel="Publish"
|
|
93
|
+
* cancelLabel="Cancel"
|
|
94
|
+
* consequence="committing"
|
|
95
|
+
* onConfirm={publish}
|
|
96
|
+
* >
|
|
97
|
+
* Your post will become visible to everyone.
|
|
98
|
+
* </ConfirmationDialog>
|
|
99
|
+
* ```
|
|
100
|
+
*
|
|
101
|
+
* @example Two-click destructive confirm
|
|
102
|
+
* ```tsx
|
|
103
|
+
* <ConfirmationDialog
|
|
104
|
+
* trigger={<Button evaluation="negative">Delete account</Button>}
|
|
105
|
+
* title="Delete account?"
|
|
106
|
+
* confirmLabel="Delete"
|
|
107
|
+
* armedLabel="Click again to confirm"
|
|
108
|
+
* cancelLabel="Cancel"
|
|
109
|
+
* consequence="destructive"
|
|
110
|
+
* evaluation="negative"
|
|
111
|
+
* onConfirm={deleteAccount}
|
|
112
|
+
* >
|
|
113
|
+
* This action cannot be undone.
|
|
114
|
+
* </ConfirmationDialog>
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* @example Visually destructive but single-click (escape-hatch pattern)
|
|
118
|
+
*
|
|
119
|
+
* Use `consequence="committing"` with `evaluation="negative"` when the
|
|
120
|
+
* action is irreversible-looking but does **not** warrant two-click arming
|
|
121
|
+
* (e.g. "Remove from list", "Unsubscribe"). The confirm button renders in
|
|
122
|
+
* the negative color without engaging the arming protocol.
|
|
123
|
+
*
|
|
124
|
+
* ```tsx
|
|
125
|
+
* <ConfirmationDialog
|
|
126
|
+
* trigger={<Button evaluation="negative">Unsubscribe</Button>}
|
|
127
|
+
* title="Unsubscribe?"
|
|
128
|
+
* confirmLabel="Unsubscribe"
|
|
129
|
+
* cancelLabel="Cancel"
|
|
130
|
+
* consequence="committing"
|
|
131
|
+
* evaluation="negative"
|
|
132
|
+
* onConfirm={unsubscribe}
|
|
133
|
+
* />
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
var ConfirmationDialog = ({
|
|
137
|
+
trigger,
|
|
138
|
+
title,
|
|
139
|
+
children,
|
|
140
|
+
confirmLabel,
|
|
141
|
+
armedLabel,
|
|
142
|
+
cancelLabel,
|
|
143
|
+
consequence = "neutral",
|
|
144
|
+
evaluation = "primary",
|
|
145
|
+
onConfirm,
|
|
146
|
+
armWindowMs = 2e3,
|
|
147
|
+
platform = "ios"
|
|
148
|
+
}) => {
|
|
149
|
+
const {
|
|
150
|
+
isArmed,
|
|
151
|
+
confirm,
|
|
152
|
+
reset
|
|
153
|
+
} = useArmedConfirm({
|
|
154
|
+
consequence,
|
|
155
|
+
onConfirm,
|
|
156
|
+
armWindowMs
|
|
157
|
+
});
|
|
158
|
+
const currentConfirmLabel = consequence === "destructive" && isArmed ? armedLabel : confirmLabel;
|
|
159
|
+
return /* @__PURE__ */(0, react_jsx_runtime.jsxs)(require_Dialog.DialogTrigger, {
|
|
160
|
+
onOpenChange: open => {
|
|
161
|
+
if (!open) reset();
|
|
162
|
+
},
|
|
163
|
+
children: [trigger, /* @__PURE__ */(0, react_jsx_runtime.jsx)(require_Dialog.DialogModal, {
|
|
164
|
+
children: /* @__PURE__ */(0, react_jsx_runtime.jsx)(require_Dialog.Dialog, {
|
|
165
|
+
"data-scope": "confirmation-dialog",
|
|
166
|
+
"data-consequence": consequence,
|
|
167
|
+
children: ({
|
|
168
|
+
close
|
|
169
|
+
}) => {
|
|
170
|
+
return /* @__PURE__ */(0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, {
|
|
171
|
+
children: [/* @__PURE__ */(0, react_jsx_runtime.jsx)(require_Dialog.DialogHeading, {
|
|
172
|
+
children: title
|
|
173
|
+
}), children !== void 0 && /* @__PURE__ */(0, react_jsx_runtime.jsx)(require_Dialog.DialogBody, {
|
|
174
|
+
children
|
|
175
|
+
}), /* @__PURE__ */(0, react_jsx_runtime.jsxs)(require_Dialog.DialogActions, {
|
|
176
|
+
platform,
|
|
177
|
+
children: [/* @__PURE__ */(0, react_jsx_runtime.jsx)(require_Button.Button, {
|
|
178
|
+
slot: "close",
|
|
179
|
+
composition: "dismissAction",
|
|
180
|
+
evaluation: "muted",
|
|
181
|
+
onPress: () => {
|
|
182
|
+
return reset();
|
|
183
|
+
},
|
|
184
|
+
children: cancelLabel
|
|
185
|
+
}), /* @__PURE__ */(0, react_jsx_runtime.jsx)(require_Button.Button, {
|
|
186
|
+
composition: "primaryAction",
|
|
187
|
+
consequence,
|
|
188
|
+
evaluation,
|
|
189
|
+
"data-arming": isArmed ? "true" : void 0,
|
|
190
|
+
onPress: () => {
|
|
191
|
+
return confirm(close);
|
|
192
|
+
},
|
|
193
|
+
children: currentConfirmLabel
|
|
194
|
+
})]
|
|
195
|
+
})]
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
})
|
|
199
|
+
})]
|
|
200
|
+
});
|
|
201
|
+
};
|
|
202
|
+
ConfirmationDialog.displayName = confirmationDialogMeta.displayName;
|
|
203
|
+
|
|
204
|
+
//#endregion
|
|
205
|
+
exports.ConfirmationDialog = ConfirmationDialog;
|
|
206
|
+
exports.confirmationDialogMeta = confirmationDialogMeta;
|