@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,173 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * UserMenuPopover — an inline (non-modal) popover account menu.
4
+ *
5
+ * Unlike `UserMenu` / `SidebarUserCard` (which open their panel in a
6
+ * `<Modal>` drawer), this family renders the panel inline as an
7
+ * absolutely-positioned popover. It auto-dismisses on route change, raw
8
+ * `popstate`, outside click, and `Escape` — so an SPA navigation never
9
+ * leaves the menu hovering over the next page.
10
+ *
11
+ * Compose it:
12
+ *
13
+ * ```tsx
14
+ * <UserMenuPopover guestName={t('userMenu.guestName', {}, { defaultValue: 'Analyst' })}>
15
+ * <UserMenuPopoverTrigger />
16
+ * <UserMenuPopoverPanel>
17
+ * <Link to="/settings">Settings</Link>
18
+ * <Link to="/datasets">My datasets</Link>
19
+ * <UserMenuPopoverSignOut />
20
+ * </UserMenuPopoverPanel>
21
+ * </UserMenuPopover>
22
+ * ```
23
+ *
24
+ * @module
25
+ */
26
+ import { createContext, useContext, useEffect, useId, useRef, useState, } from 'react';
27
+ import { useLocation } from 'react-router';
28
+ import { useAuth, useTranslation } from '@molecule/app-react';
29
+ import { getClassMap } from '@molecule/app-ui';
30
+ import { getInitials } from '../utilities/initials.js';
31
+ const UserMenuPopoverContext = createContext(null);
32
+ /**
33
+ * Returns the nearest `UserMenuPopoverContext` value, throwing if not inside a `UserMenuPopover`.
34
+ */
35
+ function usePopoverContext(component) {
36
+ const ctx = useContext(UserMenuPopoverContext);
37
+ if (!ctx) {
38
+ throw new Error(`<${component}> must be rendered inside <UserMenuPopover>`);
39
+ }
40
+ return ctx;
41
+ }
42
+ /**
43
+ * Container for the inline popover account menu. Owns the open state and
44
+ * the auto-dismiss behaviour (route change, `popstate`, outside click,
45
+ * `Escape`), and provides the resolved account identity to its
46
+ * sub-components via context.
47
+ *
48
+ * @param props - The popover children, optional guest label, and className.
49
+ * @returns The relative-positioned popover container.
50
+ */
51
+ export function UserMenuPopover({ children, guestName, className, }) {
52
+ const cm = getClassMap();
53
+ const { t } = useTranslation();
54
+ const auth = useAuth();
55
+ const user = auth.user;
56
+ const location = useLocation();
57
+ const [open, setOpen] = useState(false);
58
+ const containerRef = useRef(null);
59
+ const panelId = useId();
60
+ // Close on route change so the panel never sticks across navigations.
61
+ useEffect(() => {
62
+ setOpen(false);
63
+ }, [location.pathname, location.search, location.hash]);
64
+ // Also close on a raw `popstate` — `useLocation()` only fires when a
65
+ // URL part changes, but a same-route SPA navigation still pops.
66
+ useEffect(() => {
67
+ const onPopState = () => setOpen(false);
68
+ window.addEventListener('popstate', onPopState);
69
+ return () => window.removeEventListener('popstate', onPopState);
70
+ }, []);
71
+ // Close on outside click and Escape while the panel is open.
72
+ useEffect(() => {
73
+ if (!open)
74
+ return;
75
+ const onMouseDown = (event) => {
76
+ if (containerRef.current && !containerRef.current.contains(event.target)) {
77
+ setOpen(false);
78
+ }
79
+ };
80
+ const onKeyDown = (event) => {
81
+ if (event.key === 'Escape')
82
+ setOpen(false);
83
+ };
84
+ document.addEventListener('mousedown', onMouseDown);
85
+ document.addEventListener('keydown', onKeyDown);
86
+ return () => {
87
+ document.removeEventListener('mousedown', onMouseDown);
88
+ document.removeEventListener('keydown', onKeyDown);
89
+ };
90
+ }, [open]);
91
+ const resolvedGuest = guestName ?? t('userMenuPopover.guest', {}, { defaultValue: 'Account' });
92
+ const displayName = user?.name ?? user?.email ?? resolvedGuest;
93
+ const email = user?.email ?? undefined;
94
+ return (_jsx("div", { ref: containerRef, className: cm.cn(cm.position('relative'), className), children: _jsx(UserMenuPopoverContext.Provider, { value: { open, setOpen, displayName, email, panelId }, children: children }) }));
95
+ }
96
+ /**
97
+ * The trigger button: an initials avatar plus the account name and email,
98
+ * styled as a full-width sidebar card. Toggles the popover panel.
99
+ *
100
+ * @param props - aria-label overrides, `data-mol-id`, and className.
101
+ * @returns The popover trigger button.
102
+ */
103
+ export function UserMenuPopoverTrigger({ ariaLabelKey = 'userMenu.open', ariaLabelDefault = 'Open user menu', dataMolId = 'user-menu', className, }) {
104
+ const cm = getClassMap();
105
+ const { t } = useTranslation();
106
+ const { open, setOpen, displayName, email, panelId } = usePopoverContext('UserMenuPopoverTrigger');
107
+ return (_jsxs("button", { type: "button", onClick: () => setOpen(!open), "aria-expanded": open, "aria-controls": panelId, "aria-label": t(ariaLabelKey, {}, { defaultValue: ariaLabelDefault }), "data-mol-id": dataMolId, className: cm.cn(cm.flex({ align: 'center', gap: 'sm' }), cm.sp('px', 3), cm.sp('py', 3), 'w-full text-left rounded-xl bg-surface-container-low hover:bg-surface-container transition-colors', className), children: [_jsx("span", { "aria-hidden": "true", className: cm.cn(cm.w(10), cm.h(10), cm.roundedFull, cm.flex({ align: 'center', justify: 'center' }), cm.textSize('sm'), cm.fontWeight('bold'), cm.shrink0), style: {
108
+ backgroundColor: 'var(--color-primary)',
109
+ color: 'var(--color-on-primary, #ffffff)',
110
+ }, children: getInitials(displayName) }), _jsxs("span", { className: cm.cn(cm.flex1, 'min-w-0'), children: [_jsx("span", { className: cm.cn(cm.textSize('sm'), cm.fontWeight('semibold'), cm.displayBlock, 'truncate'), children: displayName }), email ? (_jsx("span", { className: cm.cn(cm.textSize('xs'), cm.displayBlock, 'truncate', cm.textMuted), children: email })) : null] })] }));
111
+ }
112
+ /**
113
+ * The popover panel: an absolutely-positioned card with a built-in
114
+ * identity header (name + email) and a `<nav>` wrapping the caller's nav
115
+ * items. Renders nothing while the popover is closed.
116
+ *
117
+ * Provides only the structural concerns (absolute positioning above the
118
+ * trigger, `rounded-xl` border frame, the header/nav layout). Cosmetic
119
+ * choices — width, background, padding, shadow — are per-app: pass them
120
+ * via `className`. `cn()` concatenates (it does not tailwind-merge), so
121
+ * the panel never bakes a width/background the caller would have to
122
+ * fight.
123
+ *
124
+ * @param props - The nav children, className, and aria-label overrides.
125
+ * @returns The popover panel, or `null` when closed.
126
+ */
127
+ export function UserMenuPopoverPanel({ children, className, ariaLabelKey = 'userMenu.panelLabel', ariaLabelDefault = 'Account menu', dataMolId = 'user-menu-panel', }) {
128
+ const cm = getClassMap();
129
+ const { t } = useTranslation();
130
+ const { open, displayName, email, panelId } = usePopoverContext('UserMenuPopoverPanel');
131
+ if (!open)
132
+ return null;
133
+ return (_jsxs("div", { id: panelId, "data-mol-id": dataMolId, className: cm.cn('absolute bottom-full mb-2 z-50 rounded-xl border border-outline-variant', className), children: [_jsxs("header", { className: cm.cn(cm.sp('pb', 4), 'border-b border-outline-variant'), children: [_jsx("p", { className: cm.cn(cm.textSize('sm'), cm.fontWeight('semibold')), children: displayName }), email ? _jsx("p", { className: cm.cn(cm.textSize('xs'), cm.textMuted), children: email }) : null] }), _jsx("nav", { className: cm.cn(cm.sp('mt', 4), cm.stack(1)), "aria-label": t(ariaLabelKey, {}, { defaultValue: ariaLabelDefault }), children: children })] }));
134
+ }
135
+ /**
136
+ * Returns a callback that closes the enclosing `UserMenuPopover`. Useful
137
+ * for nav-item `onClick` handlers that should dismiss the popover even
138
+ * when they don't change the route. Returns a no-op when called outside
139
+ * a `UserMenuPopover`.
140
+ *
141
+ * @returns A function that closes the popover.
142
+ */
143
+ export function useUserMenuPopoverClose() {
144
+ const ctx = useContext(UserMenuPopoverContext);
145
+ if (!ctx)
146
+ return () => { };
147
+ return () => ctx.setOpen(false);
148
+ }
149
+ /**
150
+ * The sign-out nav item — closes the popover and calls `auth.logout()`.
151
+ * Drop it in as the last child of `<UserMenuPopoverPanel>`.
152
+ *
153
+ * @param props - Label overrides, `data-mol-id`, and className.
154
+ * @returns The sign-out button.
155
+ */
156
+ export function UserMenuPopoverSignOut({ labelKey = 'userMenu.signOut', labelDefault = 'Sign out', dataMolId = 'user-menu-sign-out', className, }) {
157
+ const cm = getClassMap();
158
+ const { t } = useTranslation();
159
+ const auth = useAuth();
160
+ const { setOpen } = usePopoverContext('UserMenuPopoverSignOut');
161
+ return (_jsx("button", { type: "button", "data-mol-id": dataMolId, onClick: async () => {
162
+ setOpen(false);
163
+ try {
164
+ await auth.logout();
165
+ }
166
+ catch (_error) {
167
+ // A logout failure should not crash the panel — the user is already
168
+ // treated as signed-out from the UI perspective; the provider may
169
+ // clean up asynchronously or retry on the next request.
170
+ }
171
+ }, className: cm.cn(cm.sp('px', 3), cm.sp('py', 2), cm.textSize('sm'), cm.fontWeight('semibold'), cm.displayBlock, cm.w('full'), cm.textError, 'text-left rounded-md hover:bg-error/10 transition-colors', className), children: t(labelKey, {}, { defaultValue: labelDefault }) }));
172
+ }
173
+ //# sourceMappingURL=UserMenuPopover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserMenuPopover.js","sourceRoot":"","sources":["../../src/components/UserMenuPopover.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAc,EACZ,aAAa,EAEb,UAAU,EACV,SAAS,EACT,KAAK,EACL,MAAM,EACN,QAAQ,GACT,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAyBtD,MAAM,sBAAsB,GAAG,aAAa,CAAqC,IAAI,CAAC,CAAA;AAEtF;;GAEG;AACH,SAAS,iBAAiB,CAAC,SAAiB;IAC1C,MAAM,GAAG,GAAG,UAAU,CAAC,sBAAsB,CAAC,CAAA;IAC9C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,IAAI,SAAS,6CAA6C,CAAC,CAAA;IAC7E,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAoBD;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,QAAQ,EACR,SAAS,EACT,SAAS,GACY;IACrB,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IACxB,MAAM,EAAE,CAAC,EAAE,GAAG,cAAc,EAAE,CAAA;IAC9B,MAAM,IAAI,GAAG,OAAO,EAAe,CAAA;IACnC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;IACtB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACvC,MAAM,YAAY,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAA;IACjD,MAAM,OAAO,GAAG,KAAK,EAAE,CAAA;IAEvB,sEAAsE;IACtE,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,CAAC,KAAK,CAAC,CAAA;IAChB,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;IAEvD,qEAAqE;IACrE,gEAAgE;IAChE,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,UAAU,GAAG,GAAS,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC7C,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAA;QAC/C,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAA;IACjE,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,6DAA6D;IAC7D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,IAAI;YAAE,OAAM;QACjB,MAAM,WAAW,GAAG,CAAC,KAAiB,EAAQ,EAAE;YAC9C,IAAI,YAAY,CAAC,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAc,CAAC,EAAE,CAAC;gBACjF,OAAO,CAAC,KAAK,CAAC,CAAA;YAChB,CAAC;QACH,CAAC,CAAA;QACD,MAAM,SAAS,GAAG,CAAC,KAAoB,EAAQ,EAAE;YAC/C,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ;gBAAE,OAAO,CAAC,KAAK,CAAC,CAAA;QAC5C,CAAC,CAAA;QACD,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;QACnD,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;QAC/C,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;YACtD,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;QACpD,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEV,MAAM,aAAa,GAAG,SAAS,IAAI,CAAC,CAAC,uBAAuB,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,CAAA;IAC9F,MAAM,WAAW,GAAG,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,KAAK,IAAI,aAAa,CAAA;IAC9D,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,SAAS,CAAA;IAEtC,OAAO,CACL,cAAK,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,YAC1E,KAAC,sBAAsB,CAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,YACnF,QAAQ,GACuB,GAC9B,CACP,CAAA;AACH,CAAC;AAgBD;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,EACrC,YAAY,GAAG,eAAe,EAC9B,gBAAgB,GAAG,gBAAgB,EACnC,SAAS,GAAG,WAAW,EACvB,SAAS,GACmB;IAC5B,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IACxB,MAAM,EAAE,CAAC,EAAE,GAAG,cAAc,EAAE,CAAA;IAC9B,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,iBAAiB,CAAC,wBAAwB,CAAC,CAAA;IAClG,OAAO,CACL,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,mBAOd,IAAI,mBACJ,OAAO,gBACV,CAAC,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,gBAAgB,EAAE,CAAC,iBACtD,SAAS,EACtB,SAAS,EAAE,EAAE,CAAC,EAAE,CACd,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EACvC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EACd,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EACd,mGAAmG,EACnG,SAAS,CACV,aAED,8BACc,MAAM,EAClB,SAAS,EAAE,EAAE,CAAC,EAAE,CACd,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EACR,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EACR,EAAE,CAAC,WAAW,EACd,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAC/C,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EACjB,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EACrB,EAAE,CAAC,OAAO,CACX,EACD,KAAK,EAAE;oBACL,eAAe,EAAE,sBAAsB;oBACvC,KAAK,EAAE,kCAAkC;iBAC1C,YAEA,WAAW,CAAC,WAAW,CAAC,GACpB,EACP,gBAAM,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,aACzC,eACE,SAAS,EAAE,EAAE,CAAC,EAAE,CACd,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EACjB,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EACzB,EAAE,CAAC,YAAY,EACf,UAAU,CACX,YAEA,WAAW,GACP,EACN,KAAK,CAAC,CAAC,CAAC,CACP,eAAM,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,YAAY,EAAE,UAAU,EAAE,EAAE,CAAC,SAAS,CAAC,YACjF,KAAK,GACD,CACR,CAAC,CAAC,CAAC,IAAI,IACH,IACA,CACV,CAAA;AACH,CAAC;AAsBD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,oBAAoB,CAAC,EACnC,QAAQ,EACR,SAAS,EACT,YAAY,GAAG,qBAAqB,EACpC,gBAAgB,GAAG,cAAc,EACjC,SAAS,GAAG,iBAAiB,GACH;IAC1B,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IACxB,MAAM,EAAE,CAAC,EAAE,GAAG,cAAc,EAAE,CAAA;IAC9B,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,iBAAiB,CAAC,sBAAsB,CAAC,CAAA;IACvF,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAA;IACtB,OAAO,CASL,eACE,EAAE,EAAE,OAAO,iBACE,SAAS,EACtB,SAAS,EAAE,EAAE,CAAC,EAAE,CACd,yEAAyE,EACzE,SAAS,CACV,aAED,kBAAQ,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,iCAAiC,CAAC,aACzE,YAAG,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,YAAG,WAAW,GAAK,EACnF,KAAK,CAAC,CAAC,CAAC,YAAG,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,YAAG,KAAK,GAAK,CAAC,CAAC,CAAC,IAAI,IAC1E,EACT,cACE,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,gBACjC,CAAC,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,gBAAgB,EAAE,CAAC,YAElE,QAAQ,GACL,IACF,CACP,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB;IACrC,MAAM,GAAG,GAAG,UAAU,CAAC,sBAAsB,CAAC,CAAA;IAC9C,IAAI,CAAC,GAAG;QAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAA;IACzB,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AACjC,CAAC;AAgBD;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,EACrC,QAAQ,GAAG,kBAAkB,EAC7B,YAAY,GAAG,UAAU,EACzB,SAAS,GAAG,oBAAoB,EAChC,SAAS,GACmB;IAC5B,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IACxB,MAAM,EAAE,CAAC,EAAE,GAAG,cAAc,EAAE,CAAA;IAC9B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;IACtB,MAAM,EAAE,OAAO,EAAE,GAAG,iBAAiB,CAAC,wBAAwB,CAAC,CAAA;IAC/D,OAAO,CACL,iBACE,IAAI,EAAC,QAAQ,iBACA,SAAS,EACtB,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,OAAO,CAAC,KAAK,CAAC,CAAA;YACd,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,MAAM,EAAE,CAAA;YACrB,CAAC;YAAC,OAAO,MAAM,EAAE,CAAC;gBAChB,oEAAoE;gBACpE,kEAAkE;gBAClE,wDAAwD;YAC1D,CAAC;QACH,CAAC,EACD,SAAS,EAAE,EAAE,CAAC,EAAE,CACd,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EACd,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EACd,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EACjB,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EACzB,EAAE,CAAC,YAAY,EACf,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EACZ,EAAE,CAAC,SAAS,EACZ,0DAA0D,EAC1D,SAAS,CACV,YAEA,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC,GACzC,CACV,CAAA;AACH,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Component exports.
3
+ *
4
+ * @module
5
+ */
6
+ export * from './Accordion.js';
7
+ export * from './Alert.js';
8
+ export * from './AuthGuard.js';
9
+ export * from './Avatar.js';
10
+ export * from './Badge.js';
11
+ export * from './Button.js';
12
+ export * from './Card.js';
13
+ export * from './Checkbox.js';
14
+ export * from './Dropdown.js';
15
+ export * from './EmptyState.js';
16
+ export * from './FloatingInput.js';
17
+ export * from './Form.js';
18
+ export * from './Icon.js';
19
+ export * from './Input.js';
20
+ export * from './LanguagePicker.js';
21
+ export * from './Layout.js';
22
+ export * from './Modal.js';
23
+ export * from './PageHeader.js';
24
+ export * from './PageShell.js';
25
+ export * from './Pagination.js';
26
+ export * from './PanelClose.js';
27
+ export * from './Progress.js';
28
+ export * from './RadioGroup.js';
29
+ export * from './Select.js';
30
+ export * from './Separator.js';
31
+ export * from './SidebarUserCard.js';
32
+ export * from './Skeleton.js';
33
+ export * from './Spinner.js';
34
+ export * from './Switch.js';
35
+ export * from './Table.js';
36
+ export * from './Tabs.js';
37
+ export * from './Textarea.js';
38
+ export * from './ThemeToggle.js';
39
+ export * from './Toast.js';
40
+ export * from './Tooltip.js';
41
+ export * from './UserMenu.js';
42
+ export * from './UserMenuPopover.js';
43
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA;AAC7B,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,YAAY,CAAA;AAC1B,cAAc,qBAAqB,CAAA;AACnC,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,sBAAsB,CAAA;AACpC,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA;AAC7B,cAAc,kBAAkB,CAAA;AAChC,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Component exports.
3
+ *
4
+ * @module
5
+ */
6
+ export * from './Accordion.js';
7
+ export * from './Alert.js';
8
+ export * from './AuthGuard.js';
9
+ export * from './Avatar.js';
10
+ export * from './Badge.js';
11
+ export * from './Button.js';
12
+ export * from './Card.js';
13
+ export * from './Checkbox.js';
14
+ export * from './Dropdown.js';
15
+ export * from './EmptyState.js';
16
+ export * from './FloatingInput.js';
17
+ export * from './Form.js';
18
+ export * from './Icon.js';
19
+ export * from './Input.js';
20
+ export * from './LanguagePicker.js';
21
+ export * from './Layout.js';
22
+ export * from './Modal.js';
23
+ export * from './PageHeader.js';
24
+ export * from './PageShell.js';
25
+ export * from './Pagination.js';
26
+ export * from './PanelClose.js';
27
+ export * from './Progress.js';
28
+ export * from './RadioGroup.js';
29
+ export * from './Select.js';
30
+ export * from './Separator.js';
31
+ export * from './SidebarUserCard.js';
32
+ export * from './Skeleton.js';
33
+ export * from './Spinner.js';
34
+ export * from './Switch.js';
35
+ export * from './Table.js';
36
+ export * from './Tabs.js';
37
+ export * from './Textarea.js';
38
+ export * from './ThemeToggle.js';
39
+ export * from './Toast.js';
40
+ export * from './Tooltip.js';
41
+ export * from './UserMenu.js';
42
+ export * from './UserMenuPopover.js';
43
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA;AAC7B,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,YAAY,CAAA;AAC1B,cAAc,qBAAqB,CAAA;AACnC,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,sBAAsB,CAAA;AACpC,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA;AAC7B,cAAc,kBAAkB,CAAA;AAChC,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * React UI components for molecule.dev.
3
+ *
4
+ * Provides React implementations of the `@molecule/app-ui` component
5
+ * interfaces using the UIClassMap abstraction from `@molecule/app-ui`.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { setClassMap } from '@molecule/app-ui'
10
+ * import { classMap } from '@molecule/app-ui-tailwind'
11
+ * import { Button, Modal, Icon, EmptyState } from '@molecule/app-ui-react'
12
+ * import { useState } from 'react'
13
+ *
14
+ * // Once at startup, before first render — components throw without it:
15
+ * setClassMap(classMap)
16
+ *
17
+ * function ConfirmDelete({ onConfirm }: { onConfirm: () => void }) {
18
+ * const [open, setOpen] = useState(false)
19
+ * return (
20
+ * <>
21
+ * <Button color="error" onClick={() => setOpen(true)}>
22
+ * <Icon name="trash" size={16} /> Delete
23
+ * </Button>
24
+ * <Modal open={open} onClose={() => setOpen(false)} title="Delete item?" data-mol-id="confirm-delete">
25
+ * <EmptyState title="This cannot be undone" />
26
+ * <Button color="error" onClick={onConfirm}>Confirm</Button>
27
+ * </Modal>
28
+ * </>
29
+ * )
30
+ * }
31
+ * ```
32
+ *
33
+ * @remarks
34
+ * Wiring prerequisites — get these right before debugging anything else:
35
+ *
36
+ * - **A ClassMap bond must be set before first render.** Every component resolves styling via
37
+ * `getClassMap()` from `@molecule/app-ui`, which THROWS ("No UIClassMap has been set") until
38
+ * `setClassMap(...)` runs with a bond like `@molecule/app-ui-tailwind`. Scaffolded apps do
39
+ * this in `bonds/index.ts` — keep that import first in `main.tsx`.
40
+ * - **Some components require molecule providers from `@molecule/app-react`** and throw without
41
+ * them: `UserMenu`, `UserMenuPopover`, `LanguagePicker`, `SidebarUserCard`, `AuthGuard`, and
42
+ * `ThemeToggle` need `I18nProvider` (via `MoleculeProvider i18n={...}`); `ThemeToggle` also
43
+ * needs `ThemeProvider`; `AuthGuard` also needs `AuthProvider`. The primitive components
44
+ * (Button, Modal, Input, …) need only the ClassMap.
45
+ * - **Router-linked components** (`UserMenu`, `UserMenuPopover`, `SidebarUserCard`, `Dropdown`
46
+ * item `href`s, `AuthGuard` redirects) render react-router `<Link>`/navigation — they need a
47
+ * react-router context (`<BrowserRouter>`) and, in workspace dev setups, the Vite
48
+ * `resolve.dedupe: ['react', 'react-dom', 'react-router', 'react-router']` entry; a
49
+ * duplicate copy surfaces as "useHref may be used only in the context of a <Router>".
50
+ * - **`UserMenu` panel content is `children`** (rendered inside the popover, with
51
+ * `PanelClose`/`usePanelClose` available) — there is no `renderPanel` prop.
52
+ * - **`Icon` names are kebab-case `IconName`s from `@molecule/app-icons`** — an unknown name is
53
+ * a runtime error, not a blank. Extend via `CustomIconNames` augmentation, never raw SVG.
54
+ * - **Name collisions with feature packages** — several feature packages export a
55
+ * same-named component; import from the package whose props/behavior you want:
56
+ * - `EmptyState` — also `@molecule/app-empty-state-react` (adds an icon badge,
57
+ * per-brand `className`/`dataMolId`, and a companion `<CtaCard>`). THIS one is the
58
+ * primitive icon/title/description/action variant.
59
+ * - `PageHeader` — also `@molecule/app-page-chrome-react` (adds `subtitle`, `icon`,
60
+ * `meta`, `emphasis` + a `<HeroSection>`). THIS one takes
61
+ * `title`/`description`/`actions`/`breadcrumbs`.
62
+ * - `Pagination` — the low-level page-window control (no "showing X of Y" text, no
63
+ * page-size selector); for those use `<PaginationBar>` from
64
+ * `@molecule/app-pagination-bar-react`.
65
+ *
66
+ * A11y contracts worth knowing before you debug "it doesn't look like it's
67
+ * doing anything" on these components:
68
+ *
69
+ * - **`Modal`** implements the WAI-ARIA APG dialog pattern: opening moves
70
+ * focus to the first focusable element inside the dialog (or the dialog
71
+ * itself when it has none); Tab/Shift+Tab are trapped inside; closing
72
+ * restores focus to whatever opened it. Stacked dialogs (a confirm above a
73
+ * drawer) register on a module-level stack — Escape and the Tab trap only
74
+ * act for the TOPMOST dialog, and the body scroll lock is
75
+ * reference-counted, so closing one of several open dialogs never unlocks
76
+ * scroll behind the ones still open. `centered={false}` top-anchors the
77
+ * dialog instead of vertically centering it (an inline-style exception —
78
+ * `UIClassMap` has no `dialogWrapper({ centered })` resolver yet).
79
+ * - **`Dropdown`** implements the WAI-ARIA APG menu-button pattern: the
80
+ * `trigger` is made a real, keyboard-operable control (cloned with
81
+ * `aria-haspopup`/`aria-expanded`/`aria-controls` when it's a single
82
+ * element; wrapped in a `role="button" tabIndex={0}` container otherwise).
83
+ * Enter/Space/ArrowDown open the menu and focus the first item (ArrowUp
84
+ * opens to the last); once open, ArrowUp/Down/Home/End roving-navigate the
85
+ * `menuitem`s, Escape closes and returns focus to the trigger, and Tab
86
+ * closes the menu in sync with focus leaving it (native menus don't trap
87
+ * Tab). `width="trigger"` never renders literal `width: 'trigger'` CSS on
88
+ * the not-yet-measurable first-open frame — it renders unset instead.
89
+ * - **`Tooltip`** requires a single element as `children` for its content to
90
+ * be programmatically associated (`aria-describedby`, injected via
91
+ * `cloneElement`) with the actually-focused/hovered control — a non-element
92
+ * `children` still shows visually but without that association.
93
+ * `hasArrow` renders a small themed pointer at the resolved `placement`.
94
+ * - **`Toast`** pauses its auto-dismiss countdown on hover AND focus (WCAG
95
+ * 2.2.1) and resumes with whatever time was left. The announced role
96
+ * follows `status`: `warning`/`error` get the assertive `role="alert"`;
97
+ * every other status gets the polite `role="status"` so a routine
98
+ * confirmation doesn't interrupt a screen reader mid-sentence.
99
+ * - **`Alert`** takes a `live` prop (default `true`, matching the previous
100
+ * unconditional behavior): `live={false}` switches it from the assertive
101
+ * `role="alert"` to the polite `role="status"` for a banner that's part of
102
+ * the page's normal (not dynamically-appearing) content.
103
+ * - **`UserMenuPopover*`**: `UserMenuPopoverPanel` is a disclosure region
104
+ * (`aria-expanded` + `aria-controls` on the trigger, no role on the panel
105
+ * itself), NOT `role="menu"` — it renders a header plus a `<nav>` of
106
+ * arbitrary links, which is invalid content for `role="menu"` (that role
107
+ * may contain ONLY `menuitem` descendants).
108
+ * - **`Switch`** dispatches a REAL native `change` Event through its hidden
109
+ * checkbox — `event.preventDefault()`, `event.currentTarget`, and
110
+ * `event.stopPropagation()` all behave like they do for any native input
111
+ * (previously the handler received a synthesized `{ target: { checked } }`
112
+ * object that crashed on any of those).
113
+ * - **`Tabs`** implements the WAI-ARIA APG tabs pattern: roving tabindex
114
+ * (only the active tab is in the Tab order) with ArrowLeft/ArrowRight/
115
+ * Home/End moving focus and selection.
116
+ * - **`FormField`** wires `aria-describedby` from its error paragraph onto
117
+ * the child input automatically (falling back to a `useId()`-derived id
118
+ * when no `name` prop is given) — don't duplicate the association by hand.
119
+ * - **`Progress`** clamps `aria-valuenow` into `[0, max]` to match the
120
+ * clamped visual bar, so out-of-range values never announce impossible
121
+ * percentages.
122
+ * - **`Textarea`** `autoResize` also works uncontrolled (`defaultValue` +
123
+ * user typing): it listens to `input` events rather than only reacting to
124
+ * the controlled `value` prop.
125
+ *
126
+ * @module
127
+ */
128
+ export * from './components/index.js';
129
+ export * from './types.js';
130
+ export * from './utilities.js';
131
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8HG;AAEH,cAAc,uBAAuB,CAAA;AACrC,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,131 @@
1
+ /**
2
+ * React UI components for molecule.dev.
3
+ *
4
+ * Provides React implementations of the `@molecule/app-ui` component
5
+ * interfaces using the UIClassMap abstraction from `@molecule/app-ui`.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { setClassMap } from '@molecule/app-ui'
10
+ * import { classMap } from '@molecule/app-ui-tailwind'
11
+ * import { Button, Modal, Icon, EmptyState } from '@molecule/app-ui-react'
12
+ * import { useState } from 'react'
13
+ *
14
+ * // Once at startup, before first render — components throw without it:
15
+ * setClassMap(classMap)
16
+ *
17
+ * function ConfirmDelete({ onConfirm }: { onConfirm: () => void }) {
18
+ * const [open, setOpen] = useState(false)
19
+ * return (
20
+ * <>
21
+ * <Button color="error" onClick={() => setOpen(true)}>
22
+ * <Icon name="trash" size={16} /> Delete
23
+ * </Button>
24
+ * <Modal open={open} onClose={() => setOpen(false)} title="Delete item?" data-mol-id="confirm-delete">
25
+ * <EmptyState title="This cannot be undone" />
26
+ * <Button color="error" onClick={onConfirm}>Confirm</Button>
27
+ * </Modal>
28
+ * </>
29
+ * )
30
+ * }
31
+ * ```
32
+ *
33
+ * @remarks
34
+ * Wiring prerequisites — get these right before debugging anything else:
35
+ *
36
+ * - **A ClassMap bond must be set before first render.** Every component resolves styling via
37
+ * `getClassMap()` from `@molecule/app-ui`, which THROWS ("No UIClassMap has been set") until
38
+ * `setClassMap(...)` runs with a bond like `@molecule/app-ui-tailwind`. Scaffolded apps do
39
+ * this in `bonds/index.ts` — keep that import first in `main.tsx`.
40
+ * - **Some components require molecule providers from `@molecule/app-react`** and throw without
41
+ * them: `UserMenu`, `UserMenuPopover`, `LanguagePicker`, `SidebarUserCard`, `AuthGuard`, and
42
+ * `ThemeToggle` need `I18nProvider` (via `MoleculeProvider i18n={...}`); `ThemeToggle` also
43
+ * needs `ThemeProvider`; `AuthGuard` also needs `AuthProvider`. The primitive components
44
+ * (Button, Modal, Input, …) need only the ClassMap.
45
+ * - **Router-linked components** (`UserMenu`, `UserMenuPopover`, `SidebarUserCard`, `Dropdown`
46
+ * item `href`s, `AuthGuard` redirects) render react-router `<Link>`/navigation — they need a
47
+ * react-router context (`<BrowserRouter>`) and, in workspace dev setups, the Vite
48
+ * `resolve.dedupe: ['react', 'react-dom', 'react-router', 'react-router']` entry; a
49
+ * duplicate copy surfaces as "useHref may be used only in the context of a <Router>".
50
+ * - **`UserMenu` panel content is `children`** (rendered inside the popover, with
51
+ * `PanelClose`/`usePanelClose` available) — there is no `renderPanel` prop.
52
+ * - **`Icon` names are kebab-case `IconName`s from `@molecule/app-icons`** — an unknown name is
53
+ * a runtime error, not a blank. Extend via `CustomIconNames` augmentation, never raw SVG.
54
+ * - **Name collisions with feature packages** — several feature packages export a
55
+ * same-named component; import from the package whose props/behavior you want:
56
+ * - `EmptyState` — also `@molecule/app-empty-state-react` (adds an icon badge,
57
+ * per-brand `className`/`dataMolId`, and a companion `<CtaCard>`). THIS one is the
58
+ * primitive icon/title/description/action variant.
59
+ * - `PageHeader` — also `@molecule/app-page-chrome-react` (adds `subtitle`, `icon`,
60
+ * `meta`, `emphasis` + a `<HeroSection>`). THIS one takes
61
+ * `title`/`description`/`actions`/`breadcrumbs`.
62
+ * - `Pagination` — the low-level page-window control (no "showing X of Y" text, no
63
+ * page-size selector); for those use `<PaginationBar>` from
64
+ * `@molecule/app-pagination-bar-react`.
65
+ *
66
+ * A11y contracts worth knowing before you debug "it doesn't look like it's
67
+ * doing anything" on these components:
68
+ *
69
+ * - **`Modal`** implements the WAI-ARIA APG dialog pattern: opening moves
70
+ * focus to the first focusable element inside the dialog (or the dialog
71
+ * itself when it has none); Tab/Shift+Tab are trapped inside; closing
72
+ * restores focus to whatever opened it. Stacked dialogs (a confirm above a
73
+ * drawer) register on a module-level stack — Escape and the Tab trap only
74
+ * act for the TOPMOST dialog, and the body scroll lock is
75
+ * reference-counted, so closing one of several open dialogs never unlocks
76
+ * scroll behind the ones still open. `centered={false}` top-anchors the
77
+ * dialog instead of vertically centering it (an inline-style exception —
78
+ * `UIClassMap` has no `dialogWrapper({ centered })` resolver yet).
79
+ * - **`Dropdown`** implements the WAI-ARIA APG menu-button pattern: the
80
+ * `trigger` is made a real, keyboard-operable control (cloned with
81
+ * `aria-haspopup`/`aria-expanded`/`aria-controls` when it's a single
82
+ * element; wrapped in a `role="button" tabIndex={0}` container otherwise).
83
+ * Enter/Space/ArrowDown open the menu and focus the first item (ArrowUp
84
+ * opens to the last); once open, ArrowUp/Down/Home/End roving-navigate the
85
+ * `menuitem`s, Escape closes and returns focus to the trigger, and Tab
86
+ * closes the menu in sync with focus leaving it (native menus don't trap
87
+ * Tab). `width="trigger"` never renders literal `width: 'trigger'` CSS on
88
+ * the not-yet-measurable first-open frame — it renders unset instead.
89
+ * - **`Tooltip`** requires a single element as `children` for its content to
90
+ * be programmatically associated (`aria-describedby`, injected via
91
+ * `cloneElement`) with the actually-focused/hovered control — a non-element
92
+ * `children` still shows visually but without that association.
93
+ * `hasArrow` renders a small themed pointer at the resolved `placement`.
94
+ * - **`Toast`** pauses its auto-dismiss countdown on hover AND focus (WCAG
95
+ * 2.2.1) and resumes with whatever time was left. The announced role
96
+ * follows `status`: `warning`/`error` get the assertive `role="alert"`;
97
+ * every other status gets the polite `role="status"` so a routine
98
+ * confirmation doesn't interrupt a screen reader mid-sentence.
99
+ * - **`Alert`** takes a `live` prop (default `true`, matching the previous
100
+ * unconditional behavior): `live={false}` switches it from the assertive
101
+ * `role="alert"` to the polite `role="status"` for a banner that's part of
102
+ * the page's normal (not dynamically-appearing) content.
103
+ * - **`UserMenuPopover*`**: `UserMenuPopoverPanel` is a disclosure region
104
+ * (`aria-expanded` + `aria-controls` on the trigger, no role on the panel
105
+ * itself), NOT `role="menu"` — it renders a header plus a `<nav>` of
106
+ * arbitrary links, which is invalid content for `role="menu"` (that role
107
+ * may contain ONLY `menuitem` descendants).
108
+ * - **`Switch`** dispatches a REAL native `change` Event through its hidden
109
+ * checkbox — `event.preventDefault()`, `event.currentTarget`, and
110
+ * `event.stopPropagation()` all behave like they do for any native input
111
+ * (previously the handler received a synthesized `{ target: { checked } }`
112
+ * object that crashed on any of those).
113
+ * - **`Tabs`** implements the WAI-ARIA APG tabs pattern: roving tabindex
114
+ * (only the active tab is in the Tab order) with ArrowLeft/ArrowRight/
115
+ * Home/End moving focus and selection.
116
+ * - **`FormField`** wires `aria-describedby` from its error paragraph onto
117
+ * the child input automatically (falling back to a `useId()`-derived id
118
+ * when no `name` prop is given) — don't duplicate the association by hand.
119
+ * - **`Progress`** clamps `aria-valuenow` into `[0, max]` to match the
120
+ * clamped visual bar, so out-of-range values never announce impossible
121
+ * percentages.
122
+ * - **`Textarea`** `autoResize` also works uncontrolled (`defaultValue` +
123
+ * user typing): it listens to `input` events rather than only reacting to
124
+ * the controlled `value` prop.
125
+ *
126
+ * @module
127
+ */
128
+ export * from './components/index.js';
129
+ export * from './types.js';
130
+ export * from './utilities.js';
131
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8HG;AAEH,cAAc,uBAAuB,CAAA;AACrC,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Type re-exports for `@molecule/app-ui-react`.
3
+ *
4
+ * @module
5
+ */
6
+ export type { AccordionItem, AccordionProps, AlertProps, AvatarProps, BadgeProps, BaseProps, ButtonElementProps, ButtonProps, ButtonVariant, CardProps, ChangeEventHandler, CheckboxProps, Children, ColorVariant, ContainerProps, CSSProperties, EventHandler, FlexProps, FocusEventHandler, FormElementProps, FormEventHandler, FormFieldProps, FormProps, GridProps, HTMLElementProps, InputElementProps, InputProps, InputType, KeyboardEventHandler, ModalProps, ModalSize, MouseEventHandler, PaginationProps, RadioGroupProps, RadioOption, SelectElementProps, SelectOption, SelectProps, Size, SkeletonProps, SpacerProps, SpinnerProps, SwitchProps, TabItem, TableColumn, TableProps, TabsProps, TextareaElementProps, TextareaProps, ToastProps, TooltipPlacement, TooltipProps, } from '@molecule/app-ui';
7
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EAEV,aAAa,EACb,cAAc,EAEd,UAAU,EAEV,WAAW,EAEX,UAAU,EACV,SAAS,EACT,kBAAkB,EAClB,WAAW,EAEX,aAAa,EAEb,SAAS,EACT,kBAAkB,EAElB,aAAa,EACb,QAAQ,EACR,YAAY,EAEZ,cAAc,EAEd,aAAa,EACb,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EAEd,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EAEV,SAAS,EACT,oBAAoB,EACpB,UAAU,EAEV,SAAS,EACT,iBAAiB,EAEjB,eAAe,EACf,eAAe,EAEf,WAAW,EACX,kBAAkB,EAElB,YAAY,EACZ,WAAW,EACX,IAAI,EAEJ,aAAa,EACb,WAAW,EAEX,YAAY,EAEZ,WAAW,EAEX,OAAO,EAEP,WAAW,EACX,UAAU,EACV,SAAS,EACT,oBAAoB,EAEpB,aAAa,EACb,UAAU,EAEV,gBAAgB,EAChB,YAAY,GACb,MAAM,kBAAkB,CAAA"}
package/dist/types.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Type re-exports for `@molecule/app-ui-react`.
3
+ *
4
+ * @module
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Utility functions for React UI components.
3
+ *
4
+ * @module
5
+ */
6
+ export * from './initials.js';
7
+ export * from './renderIcon.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utilities/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Utility functions for React UI components.
3
+ *
4
+ * @module
5
+ */
6
+ export * from './initials.js';
7
+ export * from './renderIcon.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utilities/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Initials derivation for avatar fallbacks.
3
+ *
4
+ * @module
5
+ */
6
+ /**
7
+ * Compute up-to-two-letter initials from a display name or email.
8
+ *
9
+ * @param value - The name or email to derive initials from.
10
+ * @returns The uppercased initials, or `'?'` when no usable input is given.
11
+ */
12
+ export declare function getInitials(value: string | null | undefined): string;
13
+ //# sourceMappingURL=initials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"initials.d.ts","sourceRoot":"","sources":["../../src/utilities/initials.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAQpE"}