@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.
Files changed (179) hide show
  1. package/LICENSE +115 -0
  2. package/README.md +2786 -0
  3. package/dist/components/Accordion.d.ts +12 -0
  4. package/dist/components/Accordion.d.ts.map +1 -0
  5. package/dist/components/Accordion.js +80 -0
  6. package/dist/components/Accordion.js.map +1 -0
  7. package/dist/components/Alert.d.ts +26 -0
  8. package/dist/components/Alert.d.ts.map +1 -0
  9. package/dist/components/Alert.js +53 -0
  10. package/dist/components/Alert.js.map +1 -0
  11. package/dist/components/AuthGuard.d.ts +66 -0
  12. package/dist/components/AuthGuard.d.ts.map +1 -0
  13. package/dist/components/AuthGuard.js +42 -0
  14. package/dist/components/AuthGuard.js.map +1 -0
  15. package/dist/components/Avatar.d.ts +12 -0
  16. package/dist/components/Avatar.d.ts.map +1 -0
  17. package/dist/components/Avatar.js +25 -0
  18. package/dist/components/Avatar.js.map +1 -0
  19. package/dist/components/Badge.d.ts +12 -0
  20. package/dist/components/Badge.d.ts.map +1 -0
  21. package/dist/components/Badge.js +18 -0
  22. package/dist/components/Badge.js.map +1 -0
  23. package/dist/components/Button.d.ts +12 -0
  24. package/dist/components/Button.d.ts.map +1 -0
  25. package/dist/components/Button.js +19 -0
  26. package/dist/components/Button.js.map +1 -0
  27. package/dist/components/Card.d.ts +34 -0
  28. package/dist/components/Card.d.ts.map +1 -0
  29. package/dist/components/Card.js +71 -0
  30. package/dist/components/Card.js.map +1 -0
  31. package/dist/components/Checkbox.d.ts +12 -0
  32. package/dist/components/Checkbox.d.ts.map +1 -0
  33. package/dist/components/Checkbox.js +41 -0
  34. package/dist/components/Checkbox.js.map +1 -0
  35. package/dist/components/Dropdown.d.ts +38 -0
  36. package/dist/components/Dropdown.d.ts.map +1 -0
  37. package/dist/components/Dropdown.js +352 -0
  38. package/dist/components/Dropdown.js.map +1 -0
  39. package/dist/components/EmptyState.d.ts +15 -0
  40. package/dist/components/EmptyState.d.ts.map +1 -0
  41. package/dist/components/EmptyState.js +20 -0
  42. package/dist/components/EmptyState.js.map +1 -0
  43. package/dist/components/FloatingInput.d.ts +22 -0
  44. package/dist/components/FloatingInput.d.ts.map +1 -0
  45. package/dist/components/FloatingInput.js +38 -0
  46. package/dist/components/FloatingInput.js.map +1 -0
  47. package/dist/components/Form.d.ts +22 -0
  48. package/dist/components/Form.d.ts.map +1 -0
  49. package/dist/components/Form.js +81 -0
  50. package/dist/components/Form.js.map +1 -0
  51. package/dist/components/Icon.d.ts +48 -0
  52. package/dist/components/Icon.d.ts.map +1 -0
  53. package/dist/components/Icon.js +46 -0
  54. package/dist/components/Icon.js.map +1 -0
  55. package/dist/components/Input.d.ts +12 -0
  56. package/dist/components/Input.d.ts.map +1 -0
  57. package/dist/components/Input.js +25 -0
  58. package/dist/components/Input.js.map +1 -0
  59. package/dist/components/LanguagePicker.d.ts +60 -0
  60. package/dist/components/LanguagePicker.d.ts.map +1 -0
  61. package/dist/components/LanguagePicker.js +45 -0
  62. package/dist/components/LanguagePicker.js.map +1 -0
  63. package/dist/components/Layout.d.ts +24 -0
  64. package/dist/components/Layout.d.ts.map +1 -0
  65. package/dist/components/Layout.js +104 -0
  66. package/dist/components/Layout.js.map +1 -0
  67. package/dist/components/Modal.d.ts +32 -0
  68. package/dist/components/Modal.d.ts.map +1 -0
  69. package/dist/components/Modal.js +235 -0
  70. package/dist/components/Modal.js.map +1 -0
  71. package/dist/components/PageHeader.d.ts +15 -0
  72. package/dist/components/PageHeader.d.ts.map +1 -0
  73. package/dist/components/PageHeader.js +20 -0
  74. package/dist/components/PageHeader.js.map +1 -0
  75. package/dist/components/PageShell.d.ts +15 -0
  76. package/dist/components/PageShell.d.ts.map +1 -0
  77. package/dist/components/PageShell.js +20 -0
  78. package/dist/components/PageShell.js.map +1 -0
  79. package/dist/components/Pagination.d.ts +12 -0
  80. package/dist/components/Pagination.d.ts.map +1 -0
  81. package/dist/components/Pagination.js +78 -0
  82. package/dist/components/Pagination.js.map +1 -0
  83. package/dist/components/PanelClose.d.ts +40 -0
  84. package/dist/components/PanelClose.d.ts.map +1 -0
  85. package/dist/components/PanelClose.js +32 -0
  86. package/dist/components/PanelClose.js.map +1 -0
  87. package/dist/components/Progress.d.ts +45 -0
  88. package/dist/components/Progress.d.ts.map +1 -0
  89. package/dist/components/Progress.js +21 -0
  90. package/dist/components/Progress.js.map +1 -0
  91. package/dist/components/RadioGroup.d.ts +12 -0
  92. package/dist/components/RadioGroup.d.ts.map +1 -0
  93. package/dist/components/RadioGroup.js +34 -0
  94. package/dist/components/RadioGroup.js.map +1 -0
  95. package/dist/components/Select.d.ts +12 -0
  96. package/dist/components/Select.d.ts.map +1 -0
  97. package/dist/components/Select.js +57 -0
  98. package/dist/components/Select.js.map +1 -0
  99. package/dist/components/Separator.d.ts +25 -0
  100. package/dist/components/Separator.d.ts.map +1 -0
  101. package/dist/components/Separator.js +18 -0
  102. package/dist/components/Separator.js.map +1 -0
  103. package/dist/components/SidebarUserCard.d.ts +60 -0
  104. package/dist/components/SidebarUserCard.d.ts.map +1 -0
  105. package/dist/components/SidebarUserCard.js +45 -0
  106. package/dist/components/SidebarUserCard.js.map +1 -0
  107. package/dist/components/Skeleton.d.ts +26 -0
  108. package/dist/components/Skeleton.d.ts.map +1 -0
  109. package/dist/components/Skeleton.js +45 -0
  110. package/dist/components/Skeleton.js.map +1 -0
  111. package/dist/components/Spinner.d.ts +17 -0
  112. package/dist/components/Spinner.d.ts.map +1 -0
  113. package/dist/components/Spinner.js +32 -0
  114. package/dist/components/Spinner.js.map +1 -0
  115. package/dist/components/Switch.d.ts +12 -0
  116. package/dist/components/Switch.d.ts.map +1 -0
  117. package/dist/components/Switch.js +52 -0
  118. package/dist/components/Switch.js.map +1 -0
  119. package/dist/components/Table.d.ts +12 -0
  120. package/dist/components/Table.d.ts.map +1 -0
  121. package/dist/components/Table.js +53 -0
  122. package/dist/components/Table.js.map +1 -0
  123. package/dist/components/Tabs.d.ts +12 -0
  124. package/dist/components/Tabs.d.ts.map +1 -0
  125. package/dist/components/Tabs.js +72 -0
  126. package/dist/components/Tabs.js.map +1 -0
  127. package/dist/components/Textarea.d.ts +12 -0
  128. package/dist/components/Textarea.d.ts.map +1 -0
  129. package/dist/components/Textarea.js +66 -0
  130. package/dist/components/Textarea.js.map +1 -0
  131. package/dist/components/ThemeToggle.d.ts +43 -0
  132. package/dist/components/ThemeToggle.d.ts.map +1 -0
  133. package/dist/components/ThemeToggle.js +30 -0
  134. package/dist/components/ThemeToggle.js.map +1 -0
  135. package/dist/components/Toast.d.ts +61 -0
  136. package/dist/components/Toast.d.ts.map +1 -0
  137. package/dist/components/Toast.js +159 -0
  138. package/dist/components/Toast.js.map +1 -0
  139. package/dist/components/Tooltip.d.ts +21 -0
  140. package/dist/components/Tooltip.d.ts.map +1 -0
  141. package/dist/components/Tooltip.js +245 -0
  142. package/dist/components/Tooltip.js.map +1 -0
  143. package/dist/components/UserMenu.d.ts +59 -0
  144. package/dist/components/UserMenu.d.ts.map +1 -0
  145. package/dist/components/UserMenu.js +34 -0
  146. package/dist/components/UserMenu.js.map +1 -0
  147. package/dist/components/UserMenuPopover.d.ts +139 -0
  148. package/dist/components/UserMenuPopover.d.ts.map +1 -0
  149. package/dist/components/UserMenuPopover.js +173 -0
  150. package/dist/components/UserMenuPopover.js.map +1 -0
  151. package/dist/components/index.d.ts +43 -0
  152. package/dist/components/index.d.ts.map +1 -0
  153. package/dist/components/index.js +43 -0
  154. package/dist/components/index.js.map +1 -0
  155. package/dist/index.d.ts +131 -0
  156. package/dist/index.d.ts.map +1 -0
  157. package/dist/index.js +131 -0
  158. package/dist/index.js.map +1 -0
  159. package/dist/types.d.ts +7 -0
  160. package/dist/types.d.ts.map +1 -0
  161. package/dist/types.js +7 -0
  162. package/dist/types.js.map +1 -0
  163. package/dist/utilities/index.d.ts +8 -0
  164. package/dist/utilities/index.d.ts.map +1 -0
  165. package/dist/utilities/index.js +8 -0
  166. package/dist/utilities/index.js.map +1 -0
  167. package/dist/utilities/initials.d.ts +13 -0
  168. package/dist/utilities/initials.d.ts.map +1 -0
  169. package/dist/utilities/initials.js +23 -0
  170. package/dist/utilities/initials.js.map +1 -0
  171. package/dist/utilities/renderIcon.d.ts +21 -0
  172. package/dist/utilities/renderIcon.d.ts.map +1 -0
  173. package/dist/utilities/renderIcon.js +40 -0
  174. package/dist/utilities/renderIcon.js.map +1 -0
  175. package/dist/utilities.d.ts +12 -0
  176. package/dist/utilities.d.ts.map +1 -0
  177. package/dist/utilities.js +14 -0
  178. package/dist/utilities.js.map +1 -0
  179. 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"}