@molecule/app-ui-react 1.0.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 +115 -0
- package/README.md +2786 -0
- package/dist/components/Accordion.d.ts +12 -0
- package/dist/components/Accordion.d.ts.map +1 -0
- package/dist/components/Accordion.js +80 -0
- package/dist/components/Accordion.js.map +1 -0
- package/dist/components/Alert.d.ts +26 -0
- package/dist/components/Alert.d.ts.map +1 -0
- package/dist/components/Alert.js +53 -0
- package/dist/components/Alert.js.map +1 -0
- package/dist/components/AuthGuard.d.ts +66 -0
- package/dist/components/AuthGuard.d.ts.map +1 -0
- package/dist/components/AuthGuard.js +42 -0
- package/dist/components/AuthGuard.js.map +1 -0
- package/dist/components/Avatar.d.ts +12 -0
- package/dist/components/Avatar.d.ts.map +1 -0
- package/dist/components/Avatar.js +25 -0
- package/dist/components/Avatar.js.map +1 -0
- package/dist/components/Badge.d.ts +12 -0
- package/dist/components/Badge.d.ts.map +1 -0
- package/dist/components/Badge.js +18 -0
- package/dist/components/Badge.js.map +1 -0
- package/dist/components/Button.d.ts +12 -0
- package/dist/components/Button.d.ts.map +1 -0
- package/dist/components/Button.js +19 -0
- package/dist/components/Button.js.map +1 -0
- package/dist/components/Card.d.ts +34 -0
- package/dist/components/Card.d.ts.map +1 -0
- package/dist/components/Card.js +71 -0
- package/dist/components/Card.js.map +1 -0
- package/dist/components/Checkbox.d.ts +12 -0
- package/dist/components/Checkbox.d.ts.map +1 -0
- package/dist/components/Checkbox.js +41 -0
- package/dist/components/Checkbox.js.map +1 -0
- package/dist/components/Dropdown.d.ts +38 -0
- package/dist/components/Dropdown.d.ts.map +1 -0
- package/dist/components/Dropdown.js +352 -0
- package/dist/components/Dropdown.js.map +1 -0
- package/dist/components/EmptyState.d.ts +15 -0
- package/dist/components/EmptyState.d.ts.map +1 -0
- package/dist/components/EmptyState.js +20 -0
- package/dist/components/EmptyState.js.map +1 -0
- package/dist/components/FloatingInput.d.ts +22 -0
- package/dist/components/FloatingInput.d.ts.map +1 -0
- package/dist/components/FloatingInput.js +38 -0
- package/dist/components/FloatingInput.js.map +1 -0
- package/dist/components/Form.d.ts +22 -0
- package/dist/components/Form.d.ts.map +1 -0
- package/dist/components/Form.js +81 -0
- package/dist/components/Form.js.map +1 -0
- package/dist/components/Icon.d.ts +48 -0
- package/dist/components/Icon.d.ts.map +1 -0
- package/dist/components/Icon.js +46 -0
- package/dist/components/Icon.js.map +1 -0
- package/dist/components/Input.d.ts +12 -0
- package/dist/components/Input.d.ts.map +1 -0
- package/dist/components/Input.js +25 -0
- package/dist/components/Input.js.map +1 -0
- package/dist/components/LanguagePicker.d.ts +60 -0
- package/dist/components/LanguagePicker.d.ts.map +1 -0
- package/dist/components/LanguagePicker.js +45 -0
- package/dist/components/LanguagePicker.js.map +1 -0
- package/dist/components/Layout.d.ts +24 -0
- package/dist/components/Layout.d.ts.map +1 -0
- package/dist/components/Layout.js +104 -0
- package/dist/components/Layout.js.map +1 -0
- package/dist/components/Modal.d.ts +32 -0
- package/dist/components/Modal.d.ts.map +1 -0
- package/dist/components/Modal.js +235 -0
- package/dist/components/Modal.js.map +1 -0
- package/dist/components/PageHeader.d.ts +15 -0
- package/dist/components/PageHeader.d.ts.map +1 -0
- package/dist/components/PageHeader.js +20 -0
- package/dist/components/PageHeader.js.map +1 -0
- package/dist/components/PageShell.d.ts +15 -0
- package/dist/components/PageShell.d.ts.map +1 -0
- package/dist/components/PageShell.js +20 -0
- package/dist/components/PageShell.js.map +1 -0
- package/dist/components/Pagination.d.ts +12 -0
- package/dist/components/Pagination.d.ts.map +1 -0
- package/dist/components/Pagination.js +78 -0
- package/dist/components/Pagination.js.map +1 -0
- package/dist/components/PanelClose.d.ts +40 -0
- package/dist/components/PanelClose.d.ts.map +1 -0
- package/dist/components/PanelClose.js +32 -0
- package/dist/components/PanelClose.js.map +1 -0
- package/dist/components/Progress.d.ts +45 -0
- package/dist/components/Progress.d.ts.map +1 -0
- package/dist/components/Progress.js +21 -0
- package/dist/components/Progress.js.map +1 -0
- package/dist/components/RadioGroup.d.ts +12 -0
- package/dist/components/RadioGroup.d.ts.map +1 -0
- package/dist/components/RadioGroup.js +34 -0
- package/dist/components/RadioGroup.js.map +1 -0
- package/dist/components/Select.d.ts +12 -0
- package/dist/components/Select.d.ts.map +1 -0
- package/dist/components/Select.js +57 -0
- package/dist/components/Select.js.map +1 -0
- package/dist/components/Separator.d.ts +25 -0
- package/dist/components/Separator.d.ts.map +1 -0
- package/dist/components/Separator.js +18 -0
- package/dist/components/Separator.js.map +1 -0
- package/dist/components/SidebarUserCard.d.ts +60 -0
- package/dist/components/SidebarUserCard.d.ts.map +1 -0
- package/dist/components/SidebarUserCard.js +45 -0
- package/dist/components/SidebarUserCard.js.map +1 -0
- package/dist/components/Skeleton.d.ts +26 -0
- package/dist/components/Skeleton.d.ts.map +1 -0
- package/dist/components/Skeleton.js +45 -0
- package/dist/components/Skeleton.js.map +1 -0
- package/dist/components/Spinner.d.ts +17 -0
- package/dist/components/Spinner.d.ts.map +1 -0
- package/dist/components/Spinner.js +32 -0
- package/dist/components/Spinner.js.map +1 -0
- package/dist/components/Switch.d.ts +12 -0
- package/dist/components/Switch.d.ts.map +1 -0
- package/dist/components/Switch.js +52 -0
- package/dist/components/Switch.js.map +1 -0
- package/dist/components/Table.d.ts +12 -0
- package/dist/components/Table.d.ts.map +1 -0
- package/dist/components/Table.js +53 -0
- package/dist/components/Table.js.map +1 -0
- package/dist/components/Tabs.d.ts +12 -0
- package/dist/components/Tabs.d.ts.map +1 -0
- package/dist/components/Tabs.js +72 -0
- package/dist/components/Tabs.js.map +1 -0
- package/dist/components/Textarea.d.ts +12 -0
- package/dist/components/Textarea.d.ts.map +1 -0
- package/dist/components/Textarea.js +66 -0
- package/dist/components/Textarea.js.map +1 -0
- package/dist/components/ThemeToggle.d.ts +43 -0
- package/dist/components/ThemeToggle.d.ts.map +1 -0
- package/dist/components/ThemeToggle.js +30 -0
- package/dist/components/ThemeToggle.js.map +1 -0
- package/dist/components/Toast.d.ts +61 -0
- package/dist/components/Toast.d.ts.map +1 -0
- package/dist/components/Toast.js +159 -0
- package/dist/components/Toast.js.map +1 -0
- package/dist/components/Tooltip.d.ts +21 -0
- package/dist/components/Tooltip.d.ts.map +1 -0
- package/dist/components/Tooltip.js +245 -0
- package/dist/components/Tooltip.js.map +1 -0
- package/dist/components/UserMenu.d.ts +59 -0
- package/dist/components/UserMenu.d.ts.map +1 -0
- package/dist/components/UserMenu.js +34 -0
- package/dist/components/UserMenu.js.map +1 -0
- package/dist/components/UserMenuPopover.d.ts +139 -0
- package/dist/components/UserMenuPopover.d.ts.map +1 -0
- package/dist/components/UserMenuPopover.js +173 -0
- package/dist/components/UserMenuPopover.js.map +1 -0
- package/dist/components/index.d.ts +43 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +43 -0
- package/dist/components/index.js.map +1 -0
- package/dist/index.d.ts +131 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +131 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/utilities/index.d.ts +8 -0
- package/dist/utilities/index.d.ts.map +1 -0
- package/dist/utilities/index.js +8 -0
- package/dist/utilities/index.js.map +1 -0
- package/dist/utilities/initials.d.ts +13 -0
- package/dist/utilities/initials.d.ts.map +1 -0
- package/dist/utilities/initials.js +23 -0
- package/dist/utilities/initials.js.map +1 -0
- package/dist/utilities/renderIcon.d.ts +21 -0
- package/dist/utilities/renderIcon.d.ts.map +1 -0
- package/dist/utilities/renderIcon.js +40 -0
- package/dist/utilities/renderIcon.js.map +1 -0
- package/dist/utilities.d.ts +12 -0
- package/dist/utilities.d.ts.map +1 -0
- package/dist/utilities.js +14 -0
- package/dist/utilities.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Modal component.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { forwardRef, useEffect, useId, useMemo, useRef } from 'react';
|
|
8
|
+
import { createPortal } from 'react-dom';
|
|
9
|
+
import { t } from '@molecule/app-i18n';
|
|
10
|
+
import { getClassMap } from '@molecule/app-ui';
|
|
11
|
+
import { renderIcon } from '../utilities/renderIcon.js';
|
|
12
|
+
/** Elements the WAI-ARIA APG dialog pattern treats as tab-stops for the focus trap. */
|
|
13
|
+
const FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
14
|
+
/**
|
|
15
|
+
* Returns the tab-stop elements inside a container, in DOM (tab) order.
|
|
16
|
+
* @param container - The element to search within.
|
|
17
|
+
* @returns The focusable descendants, in document order.
|
|
18
|
+
*/
|
|
19
|
+
function getFocusableElements(container) {
|
|
20
|
+
return Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Merges multiple refs (object or callback) into a single callback ref, so
|
|
24
|
+
* an internal ref (needed for focus-trap bookkeeping) can coexist with the
|
|
25
|
+
* consumer's own forwarded ref on the same DOM node.
|
|
26
|
+
* @param refs - The refs to merge; `undefined`/`null` entries are skipped.
|
|
27
|
+
* @returns A single callback ref that updates every merged ref.
|
|
28
|
+
*/
|
|
29
|
+
function mergeRefs(...refs) {
|
|
30
|
+
return (node) => {
|
|
31
|
+
for (const r of refs) {
|
|
32
|
+
if (!r)
|
|
33
|
+
continue;
|
|
34
|
+
if (typeof r === 'function') {
|
|
35
|
+
r(node);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
;
|
|
39
|
+
r.current = node;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Module-level open-modal stack. Every open <Modal> instance registers its
|
|
46
|
+
// own `useId()` here. Escape and the Tab focus-trap only act for the TOPMOST
|
|
47
|
+
// entry, so a confirm dialog stacked over a drawer doesn't let one Escape
|
|
48
|
+
// press close both (the user could never tell which action was cancelled).
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
const openModalStack = [];
|
|
51
|
+
/** Pushes a modal instance onto the open-stack (it becomes the topmost). */
|
|
52
|
+
function pushModalStack(id) {
|
|
53
|
+
if (!openModalStack.includes(id))
|
|
54
|
+
openModalStack.push(id);
|
|
55
|
+
}
|
|
56
|
+
/** Removes a modal instance from the open-stack. */
|
|
57
|
+
function popModalStack(id) {
|
|
58
|
+
const index = openModalStack.indexOf(id);
|
|
59
|
+
if (index !== -1)
|
|
60
|
+
openModalStack.splice(index, 1);
|
|
61
|
+
}
|
|
62
|
+
/** Whether the given modal instance is currently the topmost of the stack. */
|
|
63
|
+
function isTopOfModalStack(id) {
|
|
64
|
+
return openModalStack.length > 0 && openModalStack[openModalStack.length - 1] === id;
|
|
65
|
+
}
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
// Reference-counted body scroll lock. Two modals can be open at once (a
|
|
68
|
+
// drawer with a confirm dialog above it); without a shared counter, closing
|
|
69
|
+
// EITHER one reset `overflow` to '', silently unlocking page scroll behind
|
|
70
|
+
// the dialog that is still open.
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
let scrollLockCount = 0;
|
|
73
|
+
let previousBodyOverflow = '';
|
|
74
|
+
/** Locks body scroll on the first caller; later callers just increment the count. */
|
|
75
|
+
function lockBodyScroll() {
|
|
76
|
+
if (scrollLockCount === 0) {
|
|
77
|
+
previousBodyOverflow = document.body.style.overflow;
|
|
78
|
+
document.body.style.overflow = 'hidden';
|
|
79
|
+
}
|
|
80
|
+
scrollLockCount += 1;
|
|
81
|
+
}
|
|
82
|
+
/** Decrements the lock count; restores the ORIGINAL overflow only once it reaches zero. */
|
|
83
|
+
function unlockBodyScroll() {
|
|
84
|
+
scrollLockCount = Math.max(0, scrollLockCount - 1);
|
|
85
|
+
if (scrollLockCount === 0) {
|
|
86
|
+
document.body.style.overflow = previousBodyOverflow;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Modal component.
|
|
91
|
+
*
|
|
92
|
+
* Renders into a `document.body` portal. Forwards any extra `data-*` or
|
|
93
|
+
* `aria-*` props on the rest spread to the inner dialog `<div>` (e.g.
|
|
94
|
+
* callers commonly pass `data-mol-id="some-modal"` for AI-agent / e2e
|
|
95
|
+
* selectors).
|
|
96
|
+
*
|
|
97
|
+
* The internal close button always carries `data-mol-id="modal-close"`
|
|
98
|
+
* as the molecule-convention default for the one fixed interactive
|
|
99
|
+
* element inside the chrome.
|
|
100
|
+
*
|
|
101
|
+
* Implements the WAI-ARIA APG dialog (modal) pattern: on open, focus moves
|
|
102
|
+
* to the first focusable element inside the dialog (or the dialog itself
|
|
103
|
+
* when it has none); Tab/Shift+Tab are trapped inside the dialog; on close,
|
|
104
|
+
* focus returns to whatever was focused before the dialog opened. Stacked
|
|
105
|
+
* dialogs (a confirm above a drawer) each register on a module-level stack —
|
|
106
|
+
* Escape and the Tab trap only act for the TOPMOST dialog, and the body
|
|
107
|
+
* scroll lock is reference-counted so closing one of several open dialogs
|
|
108
|
+
* never unlocks scroll behind the ones still open.
|
|
109
|
+
*/
|
|
110
|
+
export const Modal = forwardRef(({ open, onClose, title, children, size = 'md', showCloseButton = true, closeOnOverlayClick = true, closeOnEscape = true, footer, centered = true, closeLabel, preventScroll = true, className, style, testId, ...rest }, ref) => {
|
|
111
|
+
const cm = getClassMap();
|
|
112
|
+
// Per-instance title id AND stack key. A hardcoded 'modal-title'
|
|
113
|
+
// duplicated the id whenever two modals were mounted (stacked dialogs, a
|
|
114
|
+
// drawer + a confirm) — aria-labelledby then resolved to the FIRST
|
|
115
|
+
// match, so screen readers announced the WRONG dialog title.
|
|
116
|
+
const instanceId = useId();
|
|
117
|
+
const titleId = instanceId;
|
|
118
|
+
const dialogRef = useRef(null);
|
|
119
|
+
// Merges the internal focus-trap ref with the consumer's forwarded ref
|
|
120
|
+
// onto the same dialog node, memoized so it isn't a fresh function
|
|
121
|
+
// identity (and therefore a spurious detach/reattach) on every render.
|
|
122
|
+
const setDialogRef = useMemo(() => mergeRefs(ref, dialogRef), [ref]);
|
|
123
|
+
// The element focused right before this dialog opened — restored on close.
|
|
124
|
+
const previouslyFocusedRef = useRef(null);
|
|
125
|
+
const handleOverlayClick = (e) => {
|
|
126
|
+
if (closeOnOverlayClick && e.target === e.currentTarget) {
|
|
127
|
+
onClose();
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
// Effect A — stack registration + move focus INTO the dialog on open +
|
|
131
|
+
// restore focus to whatever was focused before on close. Deps are
|
|
132
|
+
// intentionally narrow ([open, instanceId] only): this must run exactly
|
|
133
|
+
// once per open/close transition, NOT on every parent re-render that
|
|
134
|
+
// hands down a fresh `onClose` closure — otherwise a busy parent would
|
|
135
|
+
// silently steal focus back to the first control on every re-render,
|
|
136
|
+
// even after the user had already tabbed further into the dialog.
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
if (!open)
|
|
139
|
+
return undefined;
|
|
140
|
+
previouslyFocusedRef.current = document.activeElement;
|
|
141
|
+
pushModalStack(instanceId);
|
|
142
|
+
const dialogEl = dialogRef.current;
|
|
143
|
+
if (dialogEl) {
|
|
144
|
+
const focusables = getFocusableElements(dialogEl);
|
|
145
|
+
(focusables[0] ?? dialogEl).focus();
|
|
146
|
+
}
|
|
147
|
+
return () => {
|
|
148
|
+
popModalStack(instanceId);
|
|
149
|
+
// Restore focus to whatever opened this dialog. Best-effort: if the
|
|
150
|
+
// element was itself removed from the document while the dialog was
|
|
151
|
+
// open, there is nothing sensible to restore focus to.
|
|
152
|
+
const toRestore = previouslyFocusedRef.current;
|
|
153
|
+
if (toRestore && document.contains(toRestore)) {
|
|
154
|
+
toRestore.focus();
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}, [open, instanceId]);
|
|
158
|
+
// Effect B — reference-counted body scroll lock, independent of focus
|
|
159
|
+
// and Escape handling so it can react to `preventScroll` toggling on
|
|
160
|
+
// its own.
|
|
161
|
+
useEffect(() => {
|
|
162
|
+
if (!open || !preventScroll)
|
|
163
|
+
return undefined;
|
|
164
|
+
lockBodyScroll();
|
|
165
|
+
return () => unlockBodyScroll();
|
|
166
|
+
}, [open, preventScroll]);
|
|
167
|
+
// Effect C — Escape + Tab focus-trap. Re-subscribing when `onClose`
|
|
168
|
+
// changes identity is safe (it only swaps which closure the listener
|
|
169
|
+
// calls) and keeps the handler from ever closing over a stale `onClose`.
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
if (!open)
|
|
172
|
+
return undefined;
|
|
173
|
+
const handleKeyDown = (e) => {
|
|
174
|
+
if (e.key === 'Escape') {
|
|
175
|
+
if (closeOnEscape && isTopOfModalStack(instanceId)) {
|
|
176
|
+
onClose();
|
|
177
|
+
}
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (e.key !== 'Tab' || !isTopOfModalStack(instanceId))
|
|
181
|
+
return;
|
|
182
|
+
const el = dialogRef.current;
|
|
183
|
+
if (!el)
|
|
184
|
+
return;
|
|
185
|
+
const focusables = getFocusableElements(el);
|
|
186
|
+
if (focusables.length === 0) {
|
|
187
|
+
e.preventDefault();
|
|
188
|
+
el.focus();
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const first = focusables[0];
|
|
192
|
+
const last = focusables[focusables.length - 1];
|
|
193
|
+
const active = document.activeElement;
|
|
194
|
+
if (e.shiftKey) {
|
|
195
|
+
if (active === first || !el.contains(active)) {
|
|
196
|
+
e.preventDefault();
|
|
197
|
+
last.focus();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
else if (active === last || !el.contains(active)) {
|
|
201
|
+
e.preventDefault();
|
|
202
|
+
first.focus();
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
206
|
+
return () => document.removeEventListener('keydown', handleKeyDown);
|
|
207
|
+
}, [open, closeOnEscape, onClose, instanceId]);
|
|
208
|
+
if (!open) {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
const passthrough = {};
|
|
212
|
+
for (const [k, v] of Object.entries(rest)) {
|
|
213
|
+
if (k.startsWith('data-') || k.startsWith('aria-'))
|
|
214
|
+
passthrough[k] = v;
|
|
215
|
+
}
|
|
216
|
+
const closeButton = (closeClassName) => showCloseButton ? (_jsx("button", { type: "button", onClick: onClose, className: closeClassName, "data-mol-id": "modal-close", "aria-label": closeLabel ?? t('ui.modal.close', undefined, { defaultValue: 'Close' }), children: renderIcon('x-mark', cm.iconMd) })) : null;
|
|
217
|
+
// `centered` has no dedicated ClassMap resolver option (dialogWrapper is
|
|
218
|
+
// a fixed token, not a `{ centered }`-parameterized one) — a top-anchored
|
|
219
|
+
// layout is expressed as the one inline-style exception the workspace
|
|
220
|
+
// styling rule allows for values ClassMap genuinely cannot express.
|
|
221
|
+
// Long-term this belongs in UIClassMap (e.g. `dialogWrapper(opts?: {
|
|
222
|
+
// centered?: boolean })`), which needs @molecule/app-ui + the ClassMap
|
|
223
|
+
// bond, both outside this package.
|
|
224
|
+
const wrapperStyle = centered
|
|
225
|
+
? undefined
|
|
226
|
+
: { alignItems: 'flex-start' };
|
|
227
|
+
const modalContent = (_jsxs(_Fragment, { children: [_jsx("div", { className: cm.dialogOverlay, "aria-hidden": "true" }), _jsx("div", { className: cm.dialogWrapper, style: wrapperStyle, onClick: handleOverlayClick, children: _jsxs("div", { ref: setDialogRef, role: "dialog", "aria-modal": "true", "aria-labelledby": title ? titleId : undefined, tabIndex: -1, className: cm.cn(cm.modal({ size }), className), style: style, "data-testid": testId, onClick: (e) => e.stopPropagation(), ...passthrough, children: [title ? (_jsxs("div", { className: cm.dialogHeader, children: [_jsx("h2", { id: titleId, className: cm.dialogTitle, children: title }), closeButton(cm.dialogClose)] })) : (closeButton(cm.dialogCloseFloating)), _jsx("div", { className: cm.dialogBody, children: children }), !!footer && _jsx("div", { className: cm.dialogFooter, children: footer })] }) })] }));
|
|
228
|
+
// Render into portal
|
|
229
|
+
if (typeof document !== 'undefined') {
|
|
230
|
+
return createPortal(modalContent, document.body);
|
|
231
|
+
}
|
|
232
|
+
return modalContent;
|
|
233
|
+
});
|
|
234
|
+
Modal.displayName = 'Modal';
|
|
235
|
+
//# sourceMappingURL=Modal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Modal.js","sourceRoot":"","sources":["../../src/components/Modal.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PageHeader component — consistent page title area with breadcrumbs and actions.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { PageHeaderProps } from '@molecule/app-ui';
|
|
8
|
+
/**
|
|
9
|
+
* PageHeader component.
|
|
10
|
+
*
|
|
11
|
+
* Renders a page title with optional breadcrumb trail, description, and
|
|
12
|
+
* action buttons for a consistent page heading area.
|
|
13
|
+
*/
|
|
14
|
+
export declare const PageHeader: React.ForwardRefExoticComponent<PageHeaderProps & React.RefAttributes<HTMLDivElement>>;
|
|
15
|
+
//# sourceMappingURL=PageHeader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageHeader.d.ts","sourceRoot":"","sources":["../../src/components/PageHeader.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAqB,MAAM,OAAO,CAAA;AAEzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAGvD;;;;;GAKG;AACH,eAAO,MAAM,UAAU,wFA4CtB,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* PageHeader component — consistent page title area with breadcrumbs and actions.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import React, { forwardRef } from 'react';
|
|
8
|
+
import { getClassMap } from '@molecule/app-ui';
|
|
9
|
+
/**
|
|
10
|
+
* PageHeader component.
|
|
11
|
+
*
|
|
12
|
+
* Renders a page title with optional breadcrumb trail, description, and
|
|
13
|
+
* action buttons for a consistent page heading area.
|
|
14
|
+
*/
|
|
15
|
+
export const PageHeader = forwardRef(({ title, description, actions, breadcrumbs, className, style, testId, automationId }, ref) => {
|
|
16
|
+
const cm = getClassMap();
|
|
17
|
+
return (_jsxs("div", { ref: ref, className: cm.cn(cm.pageHeader, className), style: style, "data-testid": testId, "data-mol-id": automationId, children: [breadcrumbs && breadcrumbs.length > 0 && (_jsx("nav", { className: cm.pageHeaderBreadcrumbs, "aria-label": "Breadcrumb", children: breadcrumbs.map((crumb, index) => (_jsxs(React.Fragment, { children: [index > 0 && (_jsx("span", { className: cm.pageHeaderBreadcrumbSeparator, "aria-hidden": "true", children: "/" })), crumb.href ? (_jsx("a", { href: crumb.href, className: cm.pageHeaderBreadcrumbItem, children: crumb.label })) : (_jsx("span", { className: cm.pageHeaderBreadcrumbItem, children: crumb.label }))] }, index))) })), _jsxs("div", { className: cm.cn(cm.flex({ justify: 'between', align: 'center' })), children: [_jsxs("div", { children: [_jsx("h1", { className: cm.pageHeaderTitle, children: title }), description && _jsx("p", { className: cm.pageHeaderDescription, children: description })] }), actions ? (_jsx("div", { className: cm.pageHeaderActions, children: actions })) : null] })] }));
|
|
18
|
+
});
|
|
19
|
+
PageHeader.displayName = 'PageHeader';
|
|
20
|
+
//# sourceMappingURL=PageHeader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageHeader.js","sourceRoot":"","sources":["../../src/components/PageHeader.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAGzC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAClC,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,GAAG,EAAE,EAAE;IAC5F,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IAExB,OAAO,CACL,eACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,EAC1C,KAAK,EAAE,KAAK,iBACC,MAAM,iBACN,YAAY,aAExB,WAAW,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,CACxC,cAAK,SAAS,EAAE,EAAE,CAAC,qBAAqB,gBAAa,YAAY,YAC9D,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CACjC,MAAC,KAAK,CAAC,QAAQ,eACZ,KAAK,GAAG,CAAC,IAAI,CACZ,eAAM,SAAS,EAAE,EAAE,CAAC,6BAA6B,iBAAc,MAAM,kBAE9D,CACR,EACA,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CACZ,YAAG,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,wBAAwB,YACxD,KAAK,CAAC,KAAK,GACV,CACL,CAAC,CAAC,CAAC,CACF,eAAM,SAAS,EAAE,EAAE,CAAC,wBAAwB,YAAG,KAAK,CAAC,KAAK,GAAQ,CACnE,KAZkB,KAAK,CAaT,CAClB,CAAC,GACE,CACP,EACD,eAAK,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,aACrE,0BACE,aAAI,SAAS,EAAE,EAAE,CAAC,eAAe,YAAG,KAAK,GAAM,EAC9C,WAAW,IAAI,YAAG,SAAS,EAAE,EAAE,CAAC,qBAAqB,YAAG,WAAW,GAAK,IACrE,EACL,OAAO,CAAC,CAAC,CAAC,CACT,cAAK,SAAS,EAAE,EAAE,CAAC,iBAAiB,YAAG,OAA0B,GAAO,CACzE,CAAC,CAAC,CAAC,IAAI,IACJ,IACF,CACP,CAAA;AACH,CAAC,CACF,CAAA;AAED,UAAU,CAAC,WAAW,GAAG,YAAY,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PageShell component — authenticated page wrapper with sidebar and top bar.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { PageShellProps } from '@molecule/app-ui';
|
|
8
|
+
/**
|
|
9
|
+
* PageShell component.
|
|
10
|
+
*
|
|
11
|
+
* Provides the top-level layout for authenticated pages with an optional
|
|
12
|
+
* collapsible sidebar, a top bar, and a scrollable main content area.
|
|
13
|
+
*/
|
|
14
|
+
export declare const PageShell: React.ForwardRefExoticComponent<PageShellProps & React.RefAttributes<HTMLDivElement>>;
|
|
15
|
+
//# sourceMappingURL=PageShell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageShell.d.ts","sourceRoot":"","sources":["../../src/components/PageShell.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAqB,MAAM,OAAO,CAAA;AAEzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAGtD;;;;;GAKG;AACH,eAAO,MAAM,SAAS,uFAmDrB,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* PageShell component — authenticated page wrapper with sidebar and top bar.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { forwardRef } from 'react';
|
|
8
|
+
import { getClassMap } from '@molecule/app-ui';
|
|
9
|
+
/**
|
|
10
|
+
* PageShell component.
|
|
11
|
+
*
|
|
12
|
+
* Provides the top-level layout for authenticated pages with an optional
|
|
13
|
+
* collapsible sidebar, a top bar, and a scrollable main content area.
|
|
14
|
+
*/
|
|
15
|
+
export const PageShell = forwardRef(({ children, sidebar, topbar, sidebarCollapsed, onSidebarToggle, className, style, testId, automationId, }, ref) => {
|
|
16
|
+
const cm = getClassMap();
|
|
17
|
+
return (_jsxs("div", { ref: ref, className: cm.cn(cm.pageShell, className), style: style, "data-testid": testId, "data-mol-id": automationId, children: [sidebar ? (_jsxs("aside", { className: cm.cn(cm.pageShellSidebar, sidebarCollapsed && cm.pageShellSidebarCollapsed), children: [onSidebarToggle ? (_jsx("button", { type: "button", className: cm.pageShellSidebarToggle, onClick: onSidebarToggle, "aria-label": sidebarCollapsed ? 'Expand sidebar' : 'Collapse sidebar', children: sidebarCollapsed ? '\u25B6' : '\u25C0' })) : null, sidebar] })) : null, _jsxs("div", { className: cm.flex1, children: [topbar ? (_jsx("header", { className: cm.pageShellTopbar, children: topbar })) : null, _jsx("main", { className: cm.pageShellContent, children: children })] })] }));
|
|
18
|
+
});
|
|
19
|
+
PageShell.displayName = 'PageShell';
|
|
20
|
+
//# sourceMappingURL=PageShell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageShell.js","sourceRoot":"","sources":["../../src/components/PageShell.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH,OAAc,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAGzC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CACjC,CACE,EACE,QAAQ,EACR,OAAO,EACP,MAAM,EACN,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,KAAK,EACL,MAAM,EACN,YAAY,GACb,EACD,GAAG,EACH,EAAE;IACF,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IAExB,OAAO,CACL,eACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,EACzC,KAAK,EAAE,KAAK,iBACC,MAAM,iBACN,YAAY,aAExB,OAAO,CAAC,CAAC,CAAC,CACT,iBACE,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,EAAE,gBAAgB,IAAI,EAAE,CAAC,yBAAyB,CAAC,aAEtF,eAAe,CAAC,CAAC,CAAC,CACjB,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,EAAE,CAAC,sBAAsB,EACpC,OAAO,EAAE,eAAe,gBACZ,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,kBAAkB,YAEnE,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,GAChC,CACV,CAAC,CAAC,CAAC,IAAI,EACP,OAA0B,IACrB,CACT,CAAC,CAAC,CAAC,IAAI,EACR,eAAK,SAAS,EAAE,EAAE,CAAC,KAAK,aACrB,MAAM,CAAC,CAAC,CAAC,CACR,iBAAQ,SAAS,EAAE,EAAE,CAAC,eAAe,YAAG,MAAyB,GAAU,CAC5E,CAAC,CAAC,CAAC,IAAI,EACR,eAAM,SAAS,EAAE,EAAE,CAAC,gBAAgB,YAAG,QAA2B,GAAQ,IACtE,IACF,CACP,CAAA;AACH,CAAC,CACF,CAAA;AAED,SAAS,CAAC,WAAW,GAAG,WAAW,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pagination component.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { PaginationProps } from '@molecule/app-ui';
|
|
8
|
+
/**
|
|
9
|
+
* Pagination component.
|
|
10
|
+
*/
|
|
11
|
+
export declare const Pagination: React.ForwardRefExoticComponent<PaginationProps & React.RefAttributes<HTMLElement>>;
|
|
12
|
+
//# sourceMappingURL=Pagination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pagination.d.ts","sourceRoot":"","sources":["../../src/components/Pagination.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAA8B,MAAM,OAAO,CAAA;AAGlD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAsEvD;;GAEG;AACH,eAAO,MAAM,UAAU,qFAuJtB,CAAA"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Pagination component.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { forwardRef, useMemo } from 'react';
|
|
8
|
+
import { t } from '@molecule/app-i18n';
|
|
9
|
+
import { getClassMap } from '@molecule/app-ui';
|
|
10
|
+
import { renderIcon } from '../utilities/renderIcon.js';
|
|
11
|
+
/**
|
|
12
|
+
* Generate pagination range with ellipsis.
|
|
13
|
+
* @param currentPage - The currently active page number.
|
|
14
|
+
* @param totalPages - The total number of pages.
|
|
15
|
+
* @param siblings - The number of sibling pages to show around the current page.
|
|
16
|
+
* @param boundaries - The number of boundary pages to always show at start and end.
|
|
17
|
+
* @returns An array of page numbers and ellipsis markers.
|
|
18
|
+
*/
|
|
19
|
+
function generatePaginationRange(currentPage, totalPages, siblings, boundaries) {
|
|
20
|
+
const range = [];
|
|
21
|
+
// Always show first boundary pages
|
|
22
|
+
for (let i = 1; i <= Math.min(boundaries, totalPages); i++) {
|
|
23
|
+
range.push(i);
|
|
24
|
+
}
|
|
25
|
+
// Calculate sibling range
|
|
26
|
+
const siblingStart = Math.max(boundaries + 1, currentPage - siblings);
|
|
27
|
+
const siblingEnd = Math.min(totalPages - boundaries, currentPage + siblings);
|
|
28
|
+
// Add ellipsis after boundary if needed
|
|
29
|
+
if (siblingStart > boundaries + 1) {
|
|
30
|
+
range.push('ellipsis');
|
|
31
|
+
}
|
|
32
|
+
// Add sibling pages
|
|
33
|
+
for (let i = siblingStart; i <= siblingEnd; i++) {
|
|
34
|
+
if (!range.includes(i)) {
|
|
35
|
+
range.push(i);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Add ellipsis before end boundary if needed
|
|
39
|
+
if (siblingEnd < totalPages - boundaries) {
|
|
40
|
+
range.push('ellipsis');
|
|
41
|
+
}
|
|
42
|
+
// Always show last boundary pages
|
|
43
|
+
for (let i = Math.max(totalPages - boundaries + 1, boundaries + 1); i <= totalPages; i++) {
|
|
44
|
+
if (!range.includes(i)) {
|
|
45
|
+
range.push(i);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return range;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Ellipsis indicator.
|
|
52
|
+
* @returns The ellipsis JSX element.
|
|
53
|
+
*/
|
|
54
|
+
const Ellipsis = () => {
|
|
55
|
+
const cm = getClassMap();
|
|
56
|
+
return (_jsx("span", { className: cm.paginationEllipsis, "aria-hidden": "true", children: renderIcon('ellipsis-horizontal', cm.iconSm) }));
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Pagination component.
|
|
60
|
+
*/
|
|
61
|
+
export const Pagination = forwardRef(({ page, totalPages, onChange, siblings = 1, boundaries = 1, size = 'md', showFirstLast = false, showPrevNext = true, labels, className, style, testId, disabled, }, ref) => {
|
|
62
|
+
const cm = getClassMap();
|
|
63
|
+
const range = useMemo(() => generatePaginationRange(page, totalPages, siblings, boundaries), [page, totalPages, siblings, boundaries]);
|
|
64
|
+
const handlePageChange = (newPage) => {
|
|
65
|
+
if (newPage >= 1 && newPage <= totalPages && newPage !== page && !disabled) {
|
|
66
|
+
onChange(newPage);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const buttonClasses = (isActive) => cm.cn(cm.pagination({ active: isActive, size }), cm.paginationInteractive);
|
|
70
|
+
return (_jsx("nav", { ref: ref, role: "navigation", "aria-label": labels?.nav ?? t('ui.pagination.nav', undefined, { defaultValue: 'Pagination' }), className: cm.cn(cm.paginationRoot, className), style: style, "data-testid": testId, children: _jsxs("ul", { className: cm.paginationContent, children: [showFirstLast && (_jsx("li", { children: _jsx("button", { type: "button", className: buttonClasses(false), onClick: () => handlePageChange(1), disabled: page === 1 || disabled, "aria-label": labels?.first ??
|
|
71
|
+
t('ui.pagination.first', undefined, { defaultValue: 'Go to first page' }), children: renderIcon('chevrons-left', cm.iconSm) }) })), showPrevNext && (_jsx("li", { children: _jsx("button", { type: "button", className: buttonClasses(false), onClick: () => handlePageChange(page - 1), disabled: page === 1 || disabled, "aria-label": labels?.previous ??
|
|
72
|
+
t('ui.pagination.previous', undefined, { defaultValue: 'Go to previous page' }), children: renderIcon('chevron-left', cm.iconSm) }) })), range.map((item, index) => item === 'ellipsis' ? (_jsx("li", { children: _jsx(Ellipsis, {}) }, `ellipsis-${index}`)) : (_jsx("li", { children: _jsx("button", { type: "button", className: buttonClasses(item === page), onClick: () => handlePageChange(item), disabled: disabled, "aria-label": labels?.goToPage?.(item) ??
|
|
73
|
+
t('ui.pagination.goToPage', { page: item }, { defaultValue: 'Go to page {{page}}' }), "aria-current": item === page ? 'page' : undefined, children: item }) }, item))), showPrevNext && (_jsx("li", { children: _jsx("button", { type: "button", className: buttonClasses(false), onClick: () => handlePageChange(page + 1), disabled: page === totalPages || disabled, "aria-label": labels?.next ??
|
|
74
|
+
t('ui.pagination.next', undefined, { defaultValue: 'Go to next page' }), children: renderIcon('chevron-right', cm.iconSm) }) })), showFirstLast && (_jsx("li", { children: _jsx("button", { type: "button", className: buttonClasses(false), onClick: () => handlePageChange(totalPages), disabled: page === totalPages || disabled, "aria-label": labels?.last ??
|
|
75
|
+
t('ui.pagination.last', undefined, { defaultValue: 'Go to last page' }), children: renderIcon('chevrons-right', cm.iconSm) }) }))] }) }));
|
|
76
|
+
});
|
|
77
|
+
Pagination.displayName = 'Pagination';
|
|
78
|
+
//# sourceMappingURL=Pagination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pagination.js","sourceRoot":"","sources":["../../src/components/Pagination.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Panel-close context shared by `UserMenu` and `SidebarUserCard`.
|
|
3
|
+
*
|
|
4
|
+
* Both components mount caller-supplied `children` (typically an app's
|
|
5
|
+
* `SettingsPanel`) inside a drawer. The panel needs a way to dismiss
|
|
6
|
+
* that drawer — historically passed down via a `renderPanel` render
|
|
7
|
+
* prop. This context replaces that render prop: the component provides
|
|
8
|
+
* the close callback, and panel content reads it with `usePanelClose()`.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import type { JSX, ReactNode } from 'react';
|
|
13
|
+
/**
|
|
14
|
+
* Props for {@link PanelCloseProvider}.
|
|
15
|
+
*/
|
|
16
|
+
export interface PanelCloseProviderProps {
|
|
17
|
+
/** Callback that dismisses the enclosing drawer/modal. */
|
|
18
|
+
close: () => void;
|
|
19
|
+
/** Panel content that may call {@link usePanelClose}. */
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Provides the panel-close callback to descendants. Rendered internally
|
|
24
|
+
* by `UserMenu` and `SidebarUserCard` around their `children`; apps do
|
|
25
|
+
* not normally render this directly.
|
|
26
|
+
*
|
|
27
|
+
* @param props - The close callback and the panel content.
|
|
28
|
+
* @returns The children wrapped in the close-context provider.
|
|
29
|
+
*/
|
|
30
|
+
export declare function PanelCloseProvider({ close, children }: PanelCloseProviderProps): JSX.Element;
|
|
31
|
+
/**
|
|
32
|
+
* Returns the callback that dismisses the drawer the current panel is
|
|
33
|
+
* mounted in. Safe to call anywhere — returns a no-op when no enclosing
|
|
34
|
+
* `UserMenu` / `SidebarUserCard` provides one (e.g. a `SettingsPanel`
|
|
35
|
+
* rendered as a standalone page).
|
|
36
|
+
*
|
|
37
|
+
* @returns A function that closes the enclosing drawer, or a no-op.
|
|
38
|
+
*/
|
|
39
|
+
export declare function usePanelClose(): () => void;
|
|
40
|
+
//# sourceMappingURL=PanelClose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PanelClose.d.ts","sourceRoot":"","sources":["../../src/components/PanelClose.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAW3C;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,0DAA0D;IAC1D,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,yDAAyD;IACzD,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,uBAAuB,GAAG,GAAG,CAAC,OAAO,CAE5F;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,IAAI,MAAM,IAAI,CAE1C"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Carries the close callback for the drawer a panel is mounted in.
|
|
5
|
+
* Defaults to a no-op so `usePanelClose()` is always safe to call —
|
|
6
|
+
* panel content rendered outside a drawer simply gets a close callback
|
|
7
|
+
* that does nothing.
|
|
8
|
+
*/
|
|
9
|
+
const PanelCloseContext = createContext(() => { });
|
|
10
|
+
/**
|
|
11
|
+
* Provides the panel-close callback to descendants. Rendered internally
|
|
12
|
+
* by `UserMenu` and `SidebarUserCard` around their `children`; apps do
|
|
13
|
+
* not normally render this directly.
|
|
14
|
+
*
|
|
15
|
+
* @param props - The close callback and the panel content.
|
|
16
|
+
* @returns The children wrapped in the close-context provider.
|
|
17
|
+
*/
|
|
18
|
+
export function PanelCloseProvider({ close, children }) {
|
|
19
|
+
return _jsx(PanelCloseContext.Provider, { value: close, children: children });
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Returns the callback that dismisses the drawer the current panel is
|
|
23
|
+
* mounted in. Safe to call anywhere — returns a no-op when no enclosing
|
|
24
|
+
* `UserMenu` / `SidebarUserCard` provides one (e.g. a `SettingsPanel`
|
|
25
|
+
* rendered as a standalone page).
|
|
26
|
+
*
|
|
27
|
+
* @returns A function that closes the enclosing drawer, or a no-op.
|
|
28
|
+
*/
|
|
29
|
+
export function usePanelClose() {
|
|
30
|
+
return useContext(PanelCloseContext);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=PanelClose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PanelClose.js","sourceRoot":"","sources":["../../src/components/PanelClose.tsx"],"names":[],"mappings":";AAaA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAEjD;;;;;GAKG;AACH,MAAM,iBAAiB,GAAG,aAAa,CAAa,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;AAY7D;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAA2B;IAC7E,OAAO,KAAC,iBAAiB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAA8B,CAAA;AAC1F,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,UAAU,CAAC,iBAAiB,CAAC,CAAA;AACtC,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress component.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { BaseProps, ColorVariant, Size } from '@molecule/app-ui';
|
|
8
|
+
/**
|
|
9
|
+
* Props for the Progress component.
|
|
10
|
+
*/
|
|
11
|
+
export interface ProgressProps extends BaseProps {
|
|
12
|
+
/**
|
|
13
|
+
* Progress value (0-100).
|
|
14
|
+
*/
|
|
15
|
+
value: number;
|
|
16
|
+
/**
|
|
17
|
+
* Maximum value.
|
|
18
|
+
*/
|
|
19
|
+
max?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Progress size.
|
|
22
|
+
*/
|
|
23
|
+
size?: Size;
|
|
24
|
+
/**
|
|
25
|
+
* Progress color.
|
|
26
|
+
*/
|
|
27
|
+
color?: ColorVariant;
|
|
28
|
+
/**
|
|
29
|
+
* Whether to show the value label.
|
|
30
|
+
*/
|
|
31
|
+
showValue?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Accessible label.
|
|
34
|
+
*/
|
|
35
|
+
label?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Whether the progress is indeterminate.
|
|
38
|
+
*/
|
|
39
|
+
indeterminate?: boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Progress component.
|
|
43
|
+
*/
|
|
44
|
+
export declare const Progress: React.ForwardRefExoticComponent<ProgressProps & React.RefAttributes<HTMLDivElement>>;
|
|
45
|
+
//# sourceMappingURL=Progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Progress.d.ts","sourceRoot":"","sources":["../../src/components/Progress.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAqB,MAAM,OAAO,CAAA;AAGzC,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAGrE;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,SAAS;IAC9C;;OAEG;IACH,KAAK,EAAE,MAAM,CAAA;IAEb;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ;;OAEG;IACH,IAAI,CAAC,EAAE,IAAI,CAAA;IAEX;;OAEG;IACH,KAAK,CAAC,EAAE,YAAY,CAAA;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAKD;;GAEG;AACH,eAAO,MAAM,QAAQ,sFAuDpB,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Progress component.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { forwardRef } from 'react';
|
|
8
|
+
import { t } from '@molecule/app-i18n';
|
|
9
|
+
import { getClassMap } from '@molecule/app-ui';
|
|
10
|
+
// sizeHeightMap removed — use cm.progressHeight(size) instead
|
|
11
|
+
// colorMap removed — use cm.progressColor(color) instead
|
|
12
|
+
/**
|
|
13
|
+
* Progress component.
|
|
14
|
+
*/
|
|
15
|
+
export const Progress = forwardRef(({ value, max = 100, size = 'md', color = 'primary', showValue, label, indeterminate, className, style, testId, }, ref) => {
|
|
16
|
+
const cm = getClassMap();
|
|
17
|
+
const percentage = Math.min(Math.max((value / max) * 100, 0), 100);
|
|
18
|
+
return (_jsxs("div", { ref: ref, className: cm.cn(cm.progressWrapper, className), style: style, "data-testid": testId, children: [(label || showValue) && (_jsxs("div", { className: cm.progressLabelContainer, children: [label && _jsx("span", { className: cm.progressLabelText, children: label }), showValue && _jsxs("span", { className: cm.progressLabelText, children: [Math.round(percentage), "%"] })] })), _jsx("div", { className: cm.cn(cm.progress(), cm.progressHeight(size)), role: "progressbar", "aria-valuenow": indeterminate ? undefined : Math.min(Math.max(value, 0), max), "aria-valuemin": 0, "aria-valuemax": max, "aria-label": label ?? t('ui.progress.label', undefined, { defaultValue: 'Progress' }), children: _jsx("div", { className: cm.cn(cm.progressBar(), cm.progressColor(color), indeterminate && cm.progressIndeterminate), style: indeterminate ? undefined : { transform: `translateX(-${100 - percentage}%)` } }) })] }));
|
|
19
|
+
});
|
|
20
|
+
Progress.displayName = 'Progress';
|
|
21
|
+
//# sourceMappingURL=Progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Progress.js","sourceRoot":"","sources":["../../src/components/Progress.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH,OAAc,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAEzC,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAA;AAEtC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AA0C9C,8DAA8D;AAC9D,yDAAyD;AAEzD;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAChC,CACE,EACE,KAAK,EACL,GAAG,GAAG,GAAG,EACT,IAAI,GAAG,IAAI,EACX,KAAK,GAAG,SAAS,EACjB,SAAS,EACT,KAAK,EACL,aAAa,EACb,SAAS,EACT,KAAK,EACL,MAAM,GACP,EACD,GAAG,EACH,EAAE;IACF,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IACxB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IAElE,OAAO,CACL,eACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,SAAS,CAAC,EAC/C,KAAK,EAAE,KAAK,iBACC,MAAM,aAElB,CAAC,KAAK,IAAI,SAAS,CAAC,IAAI,CACvB,eAAK,SAAS,EAAE,EAAE,CAAC,sBAAsB,aACtC,KAAK,IAAI,eAAM,SAAS,EAAE,EAAE,CAAC,iBAAiB,YAAG,KAAK,GAAQ,EAC9D,SAAS,IAAI,gBAAM,SAAS,EAAE,EAAE,CAAC,iBAAiB,aAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,IACjF,CACP,EACD,cACE,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EACxD,IAAI,EAAC,aAAa,mBAIH,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,mBAC7D,CAAC,mBACD,GAAG,gBACN,KAAK,IAAI,CAAC,CAAC,mBAAmB,EAAE,SAAS,EAAE,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,YAEpF,cACE,SAAS,EAAE,EAAE,CAAC,EAAE,CACd,EAAE,CAAC,WAAW,EAAE,EAChB,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,EACvB,aAAa,IAAI,EAAE,CAAC,qBAAqB,CAC1C,EACD,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,eAAe,GAAG,GAAG,UAAU,IAAI,EAAE,GACrF,GACE,IACF,CACP,CAAA;AACH,CAAC,CACF,CAAA;AAED,QAAQ,CAAC,WAAW,GAAG,UAAU,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RadioGroup component.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { RadioGroupProps } from '@molecule/app-ui';
|
|
8
|
+
/**
|
|
9
|
+
* RadioGroup component.
|
|
10
|
+
*/
|
|
11
|
+
export declare const RadioGroup: React.ForwardRefExoticComponent<RadioGroupProps<string> & React.RefAttributes<HTMLDivElement>>;
|
|
12
|
+
//# sourceMappingURL=RadioGroup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RadioGroup.d.ts","sourceRoot":"","sources":["../../src/components/RadioGroup.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAA4B,MAAM,OAAO,CAAA;AAGhD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAGvD;;GAEG;AACH,eAAO,MAAM,UAAU,gGAgFtB,CAAA"}
|