@raydenui/ui 0.9.7 → 0.10.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 (308) hide show
  1. package/dist/Table-DCNSxua1.d.cts +31 -0
  2. package/dist/Table-DCNSxua1.d.ts +31 -0
  3. package/dist/blocks/ApplicationShellBlock.cjs +157 -0
  4. package/dist/blocks/ApplicationShellBlock.js +154 -0
  5. package/dist/blocks/CheckoutReviewBlock.cjs +16 -0
  6. package/dist/blocks/CheckoutReviewBlock.js +13 -0
  7. package/dist/blocks/CommandPaletteBlock.cjs +334 -0
  8. package/dist/blocks/CommandPaletteBlock.js +331 -0
  9. package/dist/blocks/CreateAccountBlock.cjs +147 -0
  10. package/dist/blocks/CreateAccountBlock.js +143 -0
  11. package/dist/blocks/EmptyStateBlock.cjs +19 -0
  12. package/dist/blocks/EmptyStateBlock.js +16 -0
  13. package/dist/blocks/FeatureOverviewBlock.cjs +54 -0
  14. package/dist/blocks/FeatureOverviewBlock.js +51 -0
  15. package/dist/blocks/HeaderBlock.cjs +230 -0
  16. package/dist/blocks/HeaderBlock.js +227 -0
  17. package/dist/blocks/KpiOverviewBlock.cjs +63 -0
  18. package/dist/blocks/KpiOverviewBlock.js +60 -0
  19. package/dist/blocks/LoginBlock.cjs +66 -0
  20. package/dist/blocks/LoginBlock.js +63 -0
  21. package/dist/blocks/NotificationsBlock.cjs +17 -0
  22. package/dist/blocks/NotificationsBlock.js +14 -0
  23. package/dist/blocks/PageHeaderBlock.cjs +121 -0
  24. package/dist/blocks/PageHeaderBlock.js +118 -0
  25. package/dist/blocks/PricingPlansBlock.cjs +146 -0
  26. package/dist/blocks/PricingPlansBlock.js +143 -0
  27. package/dist/blocks/ProductCollectionBlock.cjs +37 -0
  28. package/dist/blocks/ProductCollectionBlock.js +34 -0
  29. package/dist/blocks/ProductDetailBlock.cjs +30 -0
  30. package/dist/blocks/ProductDetailBlock.js +27 -0
  31. package/dist/blocks/ProductHeroBlock.cjs +83 -0
  32. package/dist/blocks/ProductHeroBlock.js +80 -0
  33. package/dist/blocks/ProfileSettingsBlock.cjs +130 -0
  34. package/dist/blocks/ProfileSettingsBlock.js +126 -0
  35. package/dist/blocks/QuickSendBlock.cjs +11 -0
  36. package/dist/blocks/QuickSendBlock.js +8 -0
  37. package/dist/blocks/RecentTransactionsBlock.cjs +13 -0
  38. package/dist/blocks/RecentTransactionsBlock.js +10 -0
  39. package/dist/blocks/SearchableTableBlock.cjs +91 -0
  40. package/dist/blocks/SearchableTableBlock.js +88 -0
  41. package/dist/blocks/ShoppingCartBlock.cjs +16 -0
  42. package/dist/blocks/ShoppingCartBlock.js +13 -0
  43. package/dist/blocks/SiteFooterBlock.cjs +69 -0
  44. package/dist/blocks/SiteFooterBlock.js +66 -0
  45. package/dist/blocks/TableBlock.cjs +20 -0
  46. package/dist/blocks/TableBlock.js +17 -0
  47. package/dist/blocks/TaskListBlock.cjs +198 -0
  48. package/dist/blocks/TaskListBlock.js +195 -0
  49. package/dist/blocks/WorkspaceSwitcherBlock.cjs +291 -0
  50. package/dist/blocks/WorkspaceSwitcherBlock.js +288 -0
  51. package/dist/blocks/commerce.cjs +44 -0
  52. package/dist/blocks/commerce.js +35 -0
  53. package/dist/blocks/index.cjs +53 -0
  54. package/dist/blocks/index.js +24 -0
  55. package/dist/blocks.d.cts +1820 -0
  56. package/dist/blocks.d.ts +1820 -0
  57. package/dist/chart.cjs +13 -0
  58. package/dist/chart.d.cts +59 -0
  59. package/dist/chart.d.ts +59 -0
  60. package/dist/chart.js +5 -0
  61. package/dist/components/Accordion/Accordion.cjs +94 -0
  62. package/dist/components/Accordion/Accordion.js +91 -0
  63. package/dist/components/Accordion/index.cjs +8 -0
  64. package/dist/components/Accordion/index.js +1 -0
  65. package/dist/components/ActivityFeed/ActivityContent.cjs +40 -0
  66. package/dist/components/ActivityFeed/ActivityContent.js +37 -0
  67. package/dist/components/ActivityFeed/ActivityItem.cjs +19 -0
  68. package/dist/components/ActivityFeed/ActivityItem.js +16 -0
  69. package/dist/components/ActivityFeed/index.cjs +7 -0
  70. package/dist/components/ActivityFeed/index.js +2 -0
  71. package/dist/components/Alert/Alert.cjs +42 -0
  72. package/dist/components/Alert/Alert.js +39 -0
  73. package/dist/components/Alert/index.cjs +5 -0
  74. package/dist/components/Alert/index.js +1 -0
  75. package/dist/components/Avatar/Avatar.cjs +101 -0
  76. package/dist/components/Avatar/Avatar.js +98 -0
  77. package/dist/components/Avatar/index.cjs +6 -0
  78. package/dist/components/Avatar/index.js +1 -0
  79. package/dist/components/Badge/Badge.cjs +53 -0
  80. package/dist/components/Badge/Badge.js +50 -0
  81. package/dist/components/Badge/index.cjs +5 -0
  82. package/dist/components/Badge/index.js +1 -0
  83. package/dist/components/Banner/Banner.cjs +83 -0
  84. package/dist/components/Banner/Banner.js +80 -0
  85. package/dist/components/Banner/index.cjs +5 -0
  86. package/dist/components/Banner/index.js +1 -0
  87. package/dist/components/Breadcrumb/Breadcrumb.cjs +31 -0
  88. package/dist/components/Breadcrumb/Breadcrumb.js +28 -0
  89. package/dist/components/Breadcrumb/index.cjs +5 -0
  90. package/dist/components/Breadcrumb/index.js +1 -0
  91. package/dist/components/Button/Button.cjs +88 -0
  92. package/dist/components/Button/Button.js +85 -0
  93. package/dist/components/Button/index.cjs +5 -0
  94. package/dist/components/Button/index.js +1 -0
  95. package/dist/components/ButtonGroup/ButtonGroup.cjs +8 -0
  96. package/dist/components/ButtonGroup/ButtonGroup.js +5 -0
  97. package/dist/components/ButtonGroup/ButtonGroupItem.cjs +15 -0
  98. package/dist/components/ButtonGroup/ButtonGroupItem.js +12 -0
  99. package/dist/components/ButtonGroup/index.cjs +7 -0
  100. package/dist/components/ButtonGroup/index.js +2 -0
  101. package/dist/components/Card/Card.cjs +94 -0
  102. package/dist/components/Card/Card.js +91 -0
  103. package/dist/components/Card/index.cjs +9 -0
  104. package/dist/components/Card/index.js +1 -0
  105. package/dist/components/Chart/Chart.cjs +160 -0
  106. package/dist/components/Chart/Chart.js +153 -0
  107. package/dist/components/Chart/index.cjs +10 -0
  108. package/dist/components/Chart/index.js +2 -0
  109. package/dist/components/Chart/theme.cjs +67 -0
  110. package/dist/components/Chart/theme.js +62 -0
  111. package/dist/components/Chip/Chip.cjs +18 -0
  112. package/dist/components/Chip/Chip.js +15 -0
  113. package/dist/components/Chip/index.cjs +5 -0
  114. package/dist/components/Chip/index.js +1 -0
  115. package/dist/components/Counter/Counter.cjs +74 -0
  116. package/dist/components/Counter/Counter.js +71 -0
  117. package/dist/components/Counter/index.cjs +6 -0
  118. package/dist/components/Counter/index.js +1 -0
  119. package/dist/components/DatePicker/DatePicker.cjs +343 -0
  120. package/dist/components/DatePicker/DatePicker.js +340 -0
  121. package/dist/components/DatePicker/index.cjs +5 -0
  122. package/dist/components/DatePicker/index.js +1 -0
  123. package/dist/components/Divider/Divider.cjs +31 -0
  124. package/dist/components/Divider/Divider.js +28 -0
  125. package/dist/components/Divider/index.cjs +5 -0
  126. package/dist/components/Divider/index.js +1 -0
  127. package/dist/components/DropdownMenu/DropdownMenu.cjs +108 -0
  128. package/dist/components/DropdownMenu/DropdownMenu.js +105 -0
  129. package/dist/components/DropdownMenu/index.cjs +11 -0
  130. package/dist/components/DropdownMenu/index.js +1 -0
  131. package/dist/components/EmptyStateIllustration/EmptyStateIllustration.cjs +42 -0
  132. package/dist/components/EmptyStateIllustration/EmptyStateIllustration.js +39 -0
  133. package/dist/components/EmptyStateIllustration/illustrations.cjs +3322 -0
  134. package/dist/components/EmptyStateIllustration/illustrations.js +3319 -0
  135. package/dist/components/EmptyStateIllustration/index.cjs +7 -0
  136. package/dist/components/EmptyStateIllustration/index.js +2 -0
  137. package/dist/components/FileUpload/FileUpload.cjs +116 -0
  138. package/dist/components/FileUpload/FileUpload.js +113 -0
  139. package/dist/components/FileUpload/FileUploadDropZone.cjs +58 -0
  140. package/dist/components/FileUpload/FileUploadDropZone.js +55 -0
  141. package/dist/components/FileUpload/FileUploadIcons.cjs +55 -0
  142. package/dist/components/FileUpload/FileUploadIcons.js +50 -0
  143. package/dist/components/FileUpload/FileUploadItem.cjs +34 -0
  144. package/dist/components/FileUpload/FileUploadItem.js +31 -0
  145. package/dist/components/FileUpload/index.cjs +9 -0
  146. package/dist/components/FileUpload/index.js +3 -0
  147. package/dist/components/FormControl/Checkbox.cjs +27 -0
  148. package/dist/components/FormControl/Checkbox.js +24 -0
  149. package/dist/components/FormControl/Radio.cjs +15 -0
  150. package/dist/components/FormControl/Radio.js +12 -0
  151. package/dist/components/FormControl/Toggle.cjs +15 -0
  152. package/dist/components/FormControl/Toggle.js +12 -0
  153. package/dist/components/FormControl/index.cjs +9 -0
  154. package/dist/components/FormControl/index.js +3 -0
  155. package/dist/components/Icon/Icon.cjs +70 -0
  156. package/dist/components/Icon/Icon.js +34 -0
  157. package/dist/components/Icon/catalog.cjs +1672 -0
  158. package/dist/components/Icon/catalog.js +1669 -0
  159. package/dist/components/Icon/icons.cjs +5621 -0
  160. package/dist/components/Icon/icons.js +5610 -0
  161. package/dist/components/Icon/index.cjs +8 -0
  162. package/dist/components/Icon/index.js +2 -0
  163. package/dist/components/Input/Input.cjs +64 -0
  164. package/dist/components/Input/Input.js +61 -0
  165. package/dist/components/Input/index.cjs +5 -0
  166. package/dist/components/Input/index.js +1 -0
  167. package/dist/components/MetricsCard/MetricsCard.cjs +107 -0
  168. package/dist/components/MetricsCard/MetricsCard.js +104 -0
  169. package/dist/components/MetricsCard/index.cjs +5 -0
  170. package/dist/components/MetricsCard/index.js +1 -0
  171. package/dist/components/Modal/Modal.cjs +126 -0
  172. package/dist/components/Modal/Modal.js +123 -0
  173. package/dist/components/Modal/index.cjs +5 -0
  174. package/dist/components/Modal/index.js +1 -0
  175. package/dist/components/Pagination/Pagination.cjs +42 -0
  176. package/dist/components/Pagination/Pagination.js +39 -0
  177. package/dist/components/Pagination/index.cjs +5 -0
  178. package/dist/components/Pagination/index.js +1 -0
  179. package/dist/components/ProgressBar/ProgressBar.cjs +34 -0
  180. package/dist/components/ProgressBar/ProgressBar.js +31 -0
  181. package/dist/components/ProgressBar/index.cjs +5 -0
  182. package/dist/components/ProgressBar/index.js +1 -0
  183. package/dist/components/ProgressCircle/ProgressCircle.cjs +34 -0
  184. package/dist/components/ProgressCircle/ProgressCircle.js +31 -0
  185. package/dist/components/ProgressCircle/index.cjs +5 -0
  186. package/dist/components/ProgressCircle/index.js +1 -0
  187. package/dist/components/Select/Select.cjs +84 -0
  188. package/dist/components/Select/Select.js +80 -0
  189. package/dist/components/Select/SelectOption.cjs +26 -0
  190. package/dist/components/Select/SelectOption.js +23 -0
  191. package/dist/components/Select/index.cjs +7 -0
  192. package/dist/components/Select/index.js +2 -0
  193. package/dist/components/SidebarMenu/SidebarMenu.cjs +85 -0
  194. package/dist/components/SidebarMenu/SidebarMenu.js +81 -0
  195. package/dist/components/SidebarMenu/SidebarMenuItem.cjs +126 -0
  196. package/dist/components/SidebarMenu/SidebarMenuItem.js +122 -0
  197. package/dist/components/SidebarMenu/SidebarMenuSection.cjs +14 -0
  198. package/dist/components/SidebarMenu/SidebarMenuSection.js +11 -0
  199. package/dist/components/SidebarMenu/index.cjs +12 -0
  200. package/dist/components/SidebarMenu/index.js +4 -0
  201. package/dist/components/Slider/Slider.cjs +161 -0
  202. package/dist/components/Slider/Slider.js +158 -0
  203. package/dist/components/Slider/index.cjs +6 -0
  204. package/dist/components/Slider/index.js +1 -0
  205. package/dist/components/Spinner/Spinner.cjs +93 -0
  206. package/dist/components/Spinner/Spinner.js +90 -0
  207. package/dist/components/Spinner/index.cjs +5 -0
  208. package/dist/components/Spinner/index.js +1 -0
  209. package/dist/components/Stepper/Stepper.cjs +82 -0
  210. package/dist/components/Stepper/Stepper.js +79 -0
  211. package/dist/components/Stepper/index.cjs +7 -0
  212. package/dist/components/Stepper/index.js +1 -0
  213. package/dist/components/Table/Table.cjs +25 -0
  214. package/dist/components/Table/Table.js +22 -0
  215. package/dist/components/Table/index.cjs +10 -0
  216. package/dist/components/Table/index.js +1 -0
  217. package/dist/components/Table/useTableSelection.cjs +60 -0
  218. package/dist/components/Table/useTableSelection.js +57 -0
  219. package/dist/components/Tabs/Tab.cjs +70 -0
  220. package/dist/components/Tabs/Tab.js +67 -0
  221. package/dist/components/Tabs/Tabs.cjs +133 -0
  222. package/dist/components/Tabs/Tabs.js +129 -0
  223. package/dist/components/Tabs/index.cjs +7 -0
  224. package/dist/components/Tabs/index.js +2 -0
  225. package/dist/components/Tooltip/Tooltip.cjs +101 -0
  226. package/dist/components/Tooltip/Tooltip.js +98 -0
  227. package/dist/components/Tooltip/index.cjs +5 -0
  228. package/dist/components/Tooltip/index.js +1 -0
  229. package/dist/context/ThemeContext.cjs +97 -0
  230. package/dist/context/ThemeContext.js +92 -0
  231. package/dist/fonts/README.md +13 -0
  232. package/dist/fonts/hanken-grotesk-cyrillic-ext-italic.woff2 +0 -0
  233. package/dist/fonts/hanken-grotesk-cyrillic-ext-normal.woff2 +0 -0
  234. package/dist/fonts/hanken-grotesk-latin-ext-italic.woff2 +0 -0
  235. package/dist/fonts/hanken-grotesk-latin-ext-normal.woff2 +0 -0
  236. package/dist/fonts/hanken-grotesk-latin-italic.woff2 +0 -0
  237. package/dist/fonts/hanken-grotesk-latin-normal.woff2 +0 -0
  238. package/dist/fonts/hanken-grotesk-vietnamese-italic.woff2 +0 -0
  239. package/dist/fonts/hanken-grotesk-vietnamese-normal.woff2 +0 -0
  240. package/dist/fonts/hankengrotesk-LICENSE.txt +94 -0
  241. package/dist/fonts/manrope-LICENSE.txt +93 -0
  242. package/dist/fonts/manrope-cyrillic-ext-normal.woff2 +0 -0
  243. package/dist/fonts/manrope-cyrillic-normal.woff2 +0 -0
  244. package/dist/fonts/manrope-greek-normal.woff2 +0 -0
  245. package/dist/fonts/manrope-latin-ext-normal.woff2 +0 -0
  246. package/dist/fonts/manrope-latin-normal.woff2 +0 -0
  247. package/dist/fonts/manrope-vietnamese-normal.woff2 +0 -0
  248. package/dist/fonts.css +148 -0
  249. package/dist/hooks/form/index.cjs +11 -0
  250. package/dist/hooks/form/index.js +3 -0
  251. package/dist/hooks/form/useRaydenFormControl.cjs +81 -0
  252. package/dist/hooks/form/useRaydenFormControl.js +76 -0
  253. package/dist/hooks/form/useRaydenInput.cjs +38 -0
  254. package/dist/hooks/form/useRaydenInput.js +35 -0
  255. package/dist/hooks/form/useRaydenSelect.cjs +45 -0
  256. package/dist/hooks/form/useRaydenSelect.js +42 -0
  257. package/dist/hooks/index.cjs +17 -0
  258. package/dist/hooks/index.js +1 -0
  259. package/dist/hooks/useBodyScrollLock.cjs +24 -0
  260. package/dist/hooks/useBodyScrollLock.js +21 -0
  261. package/dist/hooks/useCollisionAwareSide.cjs +72 -0
  262. package/dist/hooks/useCollisionAwareSide.js +69 -0
  263. package/dist/hooks/useControllableValue.cjs +16 -0
  264. package/dist/hooks/useControllableValue.js +13 -0
  265. package/dist/hooks/useDismissableLayer.cjs +100 -0
  266. package/dist/hooks/useDismissableLayer.js +97 -0
  267. package/dist/hooks/usePopupList.cjs +101 -0
  268. package/dist/hooks/usePopupList.js +98 -0
  269. package/dist/icons-8yD7I5jO.d.cts +430 -0
  270. package/dist/icons-8yD7I5jO.d.ts +430 -0
  271. package/dist/icons.cjs +2111 -418
  272. package/dist/icons.d.cts +1256 -429
  273. package/dist/icons.d.ts +1256 -429
  274. package/dist/icons.js +2089 -1
  275. package/dist/index.cjs +128 -15046
  276. package/dist/index.d.cts +697 -662
  277. package/dist/index.d.ts +697 -662
  278. package/dist/index.js +43 -14962
  279. package/dist/motion/Collapse.cjs +28 -0
  280. package/dist/motion/Collapse.js +25 -0
  281. package/dist/motion/MotionProvider.cjs +43 -0
  282. package/dist/motion/MotionProvider.js +38 -0
  283. package/dist/motion/Pressable.cjs +46 -0
  284. package/dist/motion/Pressable.js +43 -0
  285. package/dist/motion/Reveal.cjs +19 -0
  286. package/dist/motion/Reveal.js +16 -0
  287. package/dist/motion/SharedLayout.cjs +46 -0
  288. package/dist/motion/SharedLayout.js +43 -0
  289. package/dist/motion/index.cjs +19 -0
  290. package/dist/motion/index.js +6 -0
  291. package/dist/motion/presence.cjs +58 -0
  292. package/dist/motion/presence.js +55 -0
  293. package/dist/motion/presets.cjs +88 -0
  294. package/dist/motion/presets.js +84 -0
  295. package/dist/motion.d.cts +51 -0
  296. package/dist/motion.d.ts +51 -0
  297. package/dist/preset.cjs +356 -195
  298. package/dist/preset.d.cts +111 -32
  299. package/dist/preset.d.ts +111 -32
  300. package/dist/preset.js +353 -187
  301. package/dist/presets-Ba5QndHg.d.cts +144 -0
  302. package/dist/presets-Ba5QndHg.d.ts +144 -0
  303. package/dist/styles.css +1 -1
  304. package/dist/utils/cn.cjs +38 -0
  305. package/dist/utils/cn.js +35 -0
  306. package/dist/utils/resolveIcon.cjs +18 -0
  307. package/dist/utils/resolveIcon.js +15 -0
  308. package/package.json +79 -21
@@ -0,0 +1,31 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, TdHTMLAttributes, ThHTMLAttributes } from 'react';
3
+
4
+ declare const illustrationNames: readonly ["calendar", "chat", "contacts", "dashboard", "favorites", "file-manager", "forms", "gallery", "inbox", "invoice", "notifications", "product-catalog", "project-list", "search", "shopping-cart", "subscriptions", "survey", "task-templates", "team"];
5
+ type IllustrationName = (typeof illustrationNames)[number];
6
+
7
+ type TableProps = HTMLAttributes<HTMLTableElement>;
8
+ declare const Table: react.ForwardRefExoticComponent<TableProps & react.RefAttributes<HTMLTableElement>>;
9
+ type TableHeaderProps = HTMLAttributes<HTMLTableSectionElement>;
10
+ declare const TableHeader: react.ForwardRefExoticComponent<TableHeaderProps & react.RefAttributes<HTMLTableSectionElement>>;
11
+ type TableBodyProps = HTMLAttributes<HTMLTableSectionElement>;
12
+ declare const TableBody: react.ForwardRefExoticComponent<TableBodyProps & react.RefAttributes<HTMLTableSectionElement>>;
13
+ interface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {
14
+ /** Whether this row is selected */
15
+ selected?: boolean;
16
+ }
17
+ declare const TableRow: react.ForwardRefExoticComponent<TableRowProps & react.RefAttributes<HTMLTableRowElement>>;
18
+ type SortDirection = "asc" | "desc" | null;
19
+ interface TableHeadProps extends ThHTMLAttributes<HTMLTableCellElement> {
20
+ /** Enable sort indicator and click-to-sort behavior */
21
+ sortable?: boolean;
22
+ /** Current sort direction for this column */
23
+ sortDirection?: SortDirection;
24
+ /** Called when the sort indicator is clicked */
25
+ onSort?: () => void;
26
+ }
27
+ declare const TableHead: react.ForwardRefExoticComponent<TableHeadProps & react.RefAttributes<HTMLTableCellElement>>;
28
+ type TableCellProps = TdHTMLAttributes<HTMLTableCellElement>;
29
+ declare const TableCell: react.ForwardRefExoticComponent<TableCellProps & react.RefAttributes<HTMLTableCellElement>>;
30
+
31
+ export { type IllustrationName as I, type SortDirection as S, Table as T, TableBody as a, type TableBodyProps as b, TableCell as c, type TableCellProps as d, TableHead as e, type TableHeadProps as f, TableHeader as g, type TableHeaderProps as h, type TableProps as i, TableRow as j, type TableRowProps as k, illustrationNames as l };
@@ -0,0 +1,31 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, TdHTMLAttributes, ThHTMLAttributes } from 'react';
3
+
4
+ declare const illustrationNames: readonly ["calendar", "chat", "contacts", "dashboard", "favorites", "file-manager", "forms", "gallery", "inbox", "invoice", "notifications", "product-catalog", "project-list", "search", "shopping-cart", "subscriptions", "survey", "task-templates", "team"];
5
+ type IllustrationName = (typeof illustrationNames)[number];
6
+
7
+ type TableProps = HTMLAttributes<HTMLTableElement>;
8
+ declare const Table: react.ForwardRefExoticComponent<TableProps & react.RefAttributes<HTMLTableElement>>;
9
+ type TableHeaderProps = HTMLAttributes<HTMLTableSectionElement>;
10
+ declare const TableHeader: react.ForwardRefExoticComponent<TableHeaderProps & react.RefAttributes<HTMLTableSectionElement>>;
11
+ type TableBodyProps = HTMLAttributes<HTMLTableSectionElement>;
12
+ declare const TableBody: react.ForwardRefExoticComponent<TableBodyProps & react.RefAttributes<HTMLTableSectionElement>>;
13
+ interface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {
14
+ /** Whether this row is selected */
15
+ selected?: boolean;
16
+ }
17
+ declare const TableRow: react.ForwardRefExoticComponent<TableRowProps & react.RefAttributes<HTMLTableRowElement>>;
18
+ type SortDirection = "asc" | "desc" | null;
19
+ interface TableHeadProps extends ThHTMLAttributes<HTMLTableCellElement> {
20
+ /** Enable sort indicator and click-to-sort behavior */
21
+ sortable?: boolean;
22
+ /** Current sort direction for this column */
23
+ sortDirection?: SortDirection;
24
+ /** Called when the sort indicator is clicked */
25
+ onSort?: () => void;
26
+ }
27
+ declare const TableHead: react.ForwardRefExoticComponent<TableHeadProps & react.RefAttributes<HTMLTableCellElement>>;
28
+ type TableCellProps = TdHTMLAttributes<HTMLTableCellElement>;
29
+ declare const TableCell: react.ForwardRefExoticComponent<TableCellProps & react.RefAttributes<HTMLTableCellElement>>;
30
+
31
+ export { type IllustrationName as I, type SortDirection as S, Table as T, TableBody as a, type TableBodyProps as b, TableCell as c, type TableCellProps as d, TableHead as e, type TableHeadProps as f, TableHeader as g, type TableHeaderProps as h, type TableProps as i, TableRow as j, type TableRowProps as k, illustrationNames as l };
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApplicationShellBlock = ApplicationShellBlock;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const cn_1 = require("../utils/cn.cjs");
7
+ const Icon_1 = require("../components/Icon/index.cjs");
8
+ const Spinner_1 = require("../components/Spinner/index.cjs");
9
+ const TIER = {
10
+ sm: {
11
+ expandedFlex: "hidden @min-[720px]:flex",
12
+ collapsed: "@min-[720px]:hidden",
13
+ row: "@min-[720px]:flex-row",
14
+ sidebarWidth: "@min-[720px]:w-[248px]",
15
+ pad: "@min-[720px]:px-6",
16
+ },
17
+ md: {
18
+ expandedFlex: "hidden @min-[900px]:flex",
19
+ collapsed: "@min-[900px]:hidden",
20
+ row: "@min-[900px]:flex-row",
21
+ sidebarWidth: "@min-[900px]:w-[264px]",
22
+ pad: "@min-[900px]:px-6",
23
+ },
24
+ lg: {
25
+ expandedFlex: "hidden @min-[1080px]:flex",
26
+ collapsed: "@min-[1080px]:hidden",
27
+ row: "@min-[1080px]:flex-row",
28
+ sidebarWidth: "@min-[1080px]:w-[280px]",
29
+ pad: "@min-[1080px]:px-6",
30
+ },
31
+ };
32
+ /* ─── Shared recipes ─────────────────────────────────────────────────── */
33
+ const FOCUS_RING = "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-action-primary-text";
34
+ const NAV_ITEM_BASE = (0, cn_1.cn)("group flex min-h-11 w-full min-w-0 items-start gap-3 rounded-lg px-3 py-2 text-left text-body-sm font-medium transition-colors", FOCUS_RING);
35
+ /* ─── Navigation item ────────────────────────────────────────────────── */
36
+ function NavBadge({ badge, badgeDescription, }) {
37
+ return ((0, jsx_runtime_1.jsxs)("span", { className: "ml-auto inline-flex shrink-0 items-center rounded-full bg-grey-100 px-2 py-0.5 text-body-xs font-semibold text-grey-700", children: [(0, jsx_runtime_1.jsx)("span", { "aria-hidden": badgeDescription ? true : undefined, children: badge }), badgeDescription && (0, jsx_runtime_1.jsx)("span", { className: "sr-only", children: badgeDescription })] }));
38
+ }
39
+ /**
40
+ * One element for both arrangements. The collapsed panel used to rebuild
41
+ * destinations as buttons, which dropped the href and sent them nowhere
42
+ * (audit B01); rendering an anchor whenever there is an href makes that
43
+ * impossible to reintroduce.
44
+ */
45
+ function ShellNavItem({ item, showDescription, onNavigate, reasonIdPrefix, }) {
46
+ const unavailable = "unavailableReason" in item ? item.unavailableReason : undefined;
47
+ const reasonId = `${reasonIdPrefix}-${item.id}-reason`;
48
+ const body = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [item.icon && ((0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: item.icon, size: "md", className: (0, cn_1.cn)("mt-0.5 shrink-0", item.current ? "text-action-primary-text" : "text-grey-500") })), (0, jsx_runtime_1.jsxs)("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [(0, jsx_runtime_1.jsx)("span", { className: "break-words", children: item.label }), showDescription && item.description && ((0, jsx_runtime_1.jsx)("span", { className: "text-body-xs font-normal break-words text-grey-500", children: item.description }))] }), item.badge && (0, jsx_runtime_1.jsx)(NavBadge, { badge: item.badge, badgeDescription: item.badgeDescription })] }));
49
+ if (unavailable) {
50
+ return ((0, jsx_runtime_1.jsxs)("li", { children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", disabled: true, "aria-describedby": reasonId, className: (0, cn_1.cn)(NAV_ITEM_BASE, "cursor-not-allowed text-grey-500"), children: [(0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "lock", size: "md", className: "mt-0.5 shrink-0 text-grey-500", "aria-hidden": "true" }), (0, jsx_runtime_1.jsx)("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: (0, jsx_runtime_1.jsx)("span", { className: "break-words", children: item.label }) })] }), (0, jsx_runtime_1.jsx)("p", { id: reasonId, className: "px-3 pb-1 text-body-xs break-words text-grey-500", children: unavailable })] }));
51
+ }
52
+ const tone = item.current
53
+ ? "bg-primary-50 text-grey-900"
54
+ : "text-grey-700 hover:bg-surface-muted hover:text-grey-900";
55
+ if (item.href) {
56
+ return ((0, jsx_runtime_1.jsx)("li", { children: (0, jsx_runtime_1.jsx)("a", { href: item.href, "aria-current": item.current ? "page" : undefined, onClick: () => {
57
+ item.onClick?.();
58
+ onNavigate?.();
59
+ }, ...(item.external ? { target: "_blank", rel: "noreferrer" } : {}), className: (0, cn_1.cn)(NAV_ITEM_BASE, tone), children: body }) }));
60
+ }
61
+ return ((0, jsx_runtime_1.jsx)("li", { children: (0, jsx_runtime_1.jsx)("button", { type: "button", "aria-current": item.current ? "page" : undefined, onClick: () => {
62
+ item.onClick?.();
63
+ onNavigate?.();
64
+ }, className: (0, cn_1.cn)(NAV_ITEM_BASE, "cursor-pointer", tone), children: body }) }));
65
+ }
66
+ /* ─── Component ──────────────────────────────────────────────────────── */
67
+ function ApplicationShellBlock({ brand, brandHref, onBrandClick, navSections = [], navLabel = "Main", sectionHeadingLevel = "h2", navStatus = "idle", navErrorMessage = "Navigation could not be loaded.", onRetryNav, navLoadingMessage = "Loading navigation", navEmptyMessage, search, switcher, actions = [], actionsLabel = "Account and tools", sidebarFooter, openMenuLabel = "Open navigation", closeMenuLabel = "Close navigation", skipLinkLabel = "Skip to main content", skipNavLabel = "Skip links", expandAt = "md", mainScroll = "page", stickyTopBar = true, mainLabel = "Workspace", children, className, }) {
68
+ const uid = (0, react_1.useId)();
69
+ const mainId = `${uid}-main`;
70
+ const panelId = `${uid}-nav-panel`;
71
+ const [menuOpen, setMenuOpen] = (0, react_1.useState)(false);
72
+ const toggleRef = (0, react_1.useRef)(null);
73
+ const tier = TIER[expandAt];
74
+ const SectionHeading = sectionHeadingLevel;
75
+ const itemCount = navSections.reduce((total, section) => total + section.items.length, 0);
76
+ /**
77
+ * A shell with nothing to navigate to renders no rail and no toggle, rather
78
+ * than an empty rail and a control that opens nothing. Supplying
79
+ * `navEmptyMessage` is how a consumer asks for the empty rail instead.
80
+ */
81
+ const hasNav = navStatus !== "idle" || itemCount > 0 || Boolean(navEmptyMessage);
82
+ const regionScroll = mainScroll === "region";
83
+ function closeMenu() {
84
+ setMenuOpen(false);
85
+ }
86
+ function handleKeyDown(event) {
87
+ if (event.defaultPrevented || event.key !== "Escape" || !menuOpen)
88
+ return;
89
+ setMenuOpen(false);
90
+ toggleRef.current?.focus();
91
+ }
92
+ /* ── Navigation body, rendered in the sidebar and in the collapsed panel ── */
93
+ function renderNav(placement) {
94
+ if (navStatus === "loading") {
95
+ return ((0, jsx_runtime_1.jsxs)("div", { role: "status", className: "flex items-center gap-2 px-3 py-4 text-body-sm text-grey-500", children: [(0, jsx_runtime_1.jsx)(Spinner_1.Spinner, { size: "sm" }), (0, jsx_runtime_1.jsx)("span", { children: navLoadingMessage })] }));
96
+ }
97
+ if (navStatus === "error") {
98
+ return ((0, jsx_runtime_1.jsxs)("div", { role: "alert", className: "mx-1 rounded-lg border border-error-200 bg-error-50 px-3 py-3 text-body-sm text-error-700", children: [(0, jsx_runtime_1.jsx)("p", { className: "break-words", children: navErrorMessage }), onRetryNav && ((0, jsx_runtime_1.jsxs)("button", { type: "button", onClick: onRetryNav, className: (0, cn_1.cn)("mt-2 inline-flex min-h-9 cursor-pointer items-center gap-2 rounded-lg border-[1.5px] border-current px-3 py-1.5 font-semibold", FOCUS_RING), children: [(0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "refresh", size: "sm", "aria-hidden": "true" }), "Try again"] }))] }));
99
+ }
100
+ if (itemCount === 0) {
101
+ return navEmptyMessage ? ((0, jsx_runtime_1.jsx)("p", { className: "px-3 py-4 text-body-sm break-words text-grey-500", children: navEmptyMessage })) : null;
102
+ }
103
+ return ((0, jsx_runtime_1.jsx)("div", { className: "flex flex-col gap-5", children: navSections.map((section) => {
104
+ const headingId = `${uid}-${placement}-${section.id}`;
105
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-1", children: [section.label && ((0, jsx_runtime_1.jsx)(SectionHeading, { id: headingId, className: "px-3 pb-1 text-caption-sm font-semibold break-words text-grey-500 uppercase", children: section.label })), (0, jsx_runtime_1.jsx)("ul", { className: "flex list-none flex-col gap-0.5", ...(section.label ? { "aria-labelledby": headingId } : {}), children: section.items.map((item) => ((0, jsx_runtime_1.jsx)(ShellNavItem, { item: item, showDescription: placement === "panel", onNavigate: placement === "panel" ? closeMenu : undefined, reasonIdPrefix: `${uid}-${placement}` }, item.id))) })] }, section.id));
106
+ }) }));
107
+ }
108
+ /* ── Brand ── */
109
+ function renderBrand(extraClassName) {
110
+ if (!brand)
111
+ return null;
112
+ const content = (0, jsx_runtime_1.jsx)("span", { className: "flex min-w-0 items-center gap-2 break-words", children: brand });
113
+ if (brandHref) {
114
+ return ((0, jsx_runtime_1.jsx)("a", { href: brandHref, onClick: onBrandClick, className: (0, cn_1.cn)("rounded", FOCUS_RING, extraClassName), children: content }));
115
+ }
116
+ if (onBrandClick) {
117
+ return ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onBrandClick, className: (0, cn_1.cn)("cursor-pointer rounded text-left", FOCUS_RING, extraClassName), children: content }));
118
+ }
119
+ return (0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("min-w-0", extraClassName), children: content });
120
+ }
121
+ /* ── Top-bar actions ── */
122
+ function renderAction(action) {
123
+ const iconOnly = Boolean(action.icon);
124
+ const inner = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [action.icon ? ((0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: action.icon, size: "md", "aria-hidden": "true" })) : ((0, jsx_runtime_1.jsx)("span", { className: "break-words", children: action.label })), iconOnly && (0, jsx_runtime_1.jsx)("span", { className: "sr-only", children: action.label }), action.badge && ((0, jsx_runtime_1.jsxs)("span", { className: "absolute top-0.5 right-0.5 inline-flex min-w-4 items-center justify-center rounded-full bg-action-primary px-1 text-[10px] leading-4 font-semibold text-white", children: [(0, jsx_runtime_1.jsx)("span", { "aria-hidden": action.badgeDescription ? true : undefined, children: action.badge }), action.badgeDescription && (0, jsx_runtime_1.jsx)("span", { className: "sr-only", children: action.badgeDescription })] }))] }));
125
+ const classes = (0, cn_1.cn)("relative inline-flex min-h-11 min-w-11 items-center justify-center gap-2 rounded-lg px-2 text-body-sm font-medium text-grey-700 transition-colors hover:bg-surface-muted hover:text-grey-900", FOCUS_RING);
126
+ if (action.href) {
127
+ return ((0, jsx_runtime_1.jsx)("a", { href: action.href, onClick: action.onClick, ...(action.external ? { target: "_blank", rel: "noreferrer" } : {}), className: classes, children: inner }, action.id));
128
+ }
129
+ return ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: action.onClick, className: (0, cn_1.cn)(classes, "cursor-pointer"), children: inner }, action.id));
130
+ }
131
+ const sidebarInner = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [brand && (0, jsx_runtime_1.jsx)("div", { className: "px-3 pb-4", children: renderBrand("inline-flex min-h-10 items-center") }), (0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("flex-1", regionScroll && "min-h-0 overflow-y-auto"), children: renderNav("sidebar") }), sidebarFooter && ((0, jsx_runtime_1.jsx)("div", { className: "mt-4 border-t border-surface-border px-3 pt-4", children: sidebarFooter }))] }));
132
+ return ((0, jsx_runtime_1.jsxs)("div", { onKeyDown: handleKeyDown, className: (0, cn_1.cn)(
133
+ // `@container` sits on the outermost element, outside the padded
134
+ // surfaces, so `@min-[…]` padding inside resolves against the shell's
135
+ // real width. `relative` keeps the skip link's positioned box inside
136
+ // the shell instead of widening the document (audit B03).
137
+ "@container relative flex w-full flex-col bg-surface-muted", regionScroll && "h-full max-h-full overflow-hidden", className), children: [(0, jsx_runtime_1.jsx)("nav", { "aria-label": skipNavLabel, children: (0, jsx_runtime_1.jsx)("a", { href: `#${mainId}`, className: (0, cn_1.cn)("sr-only rounded-lg bg-surface px-4 py-2 text-body-sm font-semibold text-action-primary-text shadow-soft-sm", "focus:not-sr-only focus:absolute focus:top-3 focus:left-3 focus:z-40", FOCUS_RING), children: skipLinkLabel }) }), (0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("flex min-h-0 w-full flex-1 flex-col", tier.row), children: [hasNav && (
138
+ // The landmark wraps the brand, the destinations, and the sidebar
139
+ // footer. With the landmark on an inner element the brand and footer
140
+ // were page content outside every landmark, which axe's `region` rule
141
+ // reported and a screen-reader user would meet as stray text.
142
+ (0, jsx_runtime_1.jsx)("nav", { "aria-label": navLabel, className: (0, cn_1.cn)("w-full shrink-0 flex-col border-r border-surface-border bg-surface px-3 py-5", tier.sidebarWidth, regionScroll && "min-h-0", tier.expandedFlex), children: sidebarInner })), (0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("flex min-w-0 min-h-0 flex-1 flex-col"), children: [(0, jsx_runtime_1.jsxs)("header", { className: (0, cn_1.cn)("flex w-full flex-wrap items-center gap-2 border-b border-surface-border bg-surface px-4 py-2", tier.pad, stickyTopBar && !regionScroll && "sticky top-0 z-20"), children: [hasNav && ((0, jsx_runtime_1.jsxs)("button", { ref: toggleRef, type: "button", onClick: () => setMenuOpen((open) => !open), "aria-expanded": menuOpen, "aria-controls": panelId, className: (0, cn_1.cn)("inline-flex min-h-11 min-w-11 shrink-0 cursor-pointer items-center justify-center rounded-lg text-grey-700 hover:bg-surface-muted hover:text-grey-900", FOCUS_RING, tier.collapsed), children: [(0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: menuOpen ? "multiply" : "list", size: "md", "aria-hidden": "true" }), (0, jsx_runtime_1.jsx)("span", { className: "sr-only", children: menuOpen ? closeMenuLabel : openMenuLabel })] })), brand && !(hasNav && switcher) && ((0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("min-w-0", hasNav ? tier.collapsed : undefined), children: renderBrand("inline-flex min-h-10 items-center") })), switcher && (
143
+ // A floor, not a fixed width: the switcher is a feature, and a
144
+ // feature squeezed to nothing has been dropped. It wraps onto the
145
+ // next row before it shrinks below this.
146
+ (0, jsx_runtime_1.jsx)("div", { className: "flex min-w-0 flex-1 @min-[640px]:min-w-[168px] @min-[640px]:flex-none", children: switcher })), search && ((0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)(
147
+ // Wraps onto its own row while the shell is narrow rather
148
+ // than being removed. One instance, so its state is stable.
149
+ "order-last w-full min-w-0 basis-full", "@min-[640px]:order-none @min-[640px]:w-auto @min-[640px]:max-w-[420px] @min-[640px]:flex-1 @min-[640px]:basis-auto"), children: search })), actions.length > 0 && ((0, jsx_runtime_1.jsx)("div", { role: "group", "aria-label": actionsLabel, className: "ml-auto flex shrink-0 items-center gap-1", children: actions.map((action) => renderAction(action)) }))] }), hasNav && ((0, jsx_runtime_1.jsxs)("nav", { id: panelId, "aria-label": navLabel, className: (0, cn_1.cn)("border-b border-surface-border bg-surface px-3 py-4", tier.collapsed, !menuOpen && "hidden"), children: [brand && switcher && ((0, jsx_runtime_1.jsx)("div", { className: "px-3 pb-4", children: renderBrand("inline-flex min-h-11 items-center") })), renderNav("panel"), sidebarFooter && ((0, jsx_runtime_1.jsx)("div", { className: "mt-4 border-t border-surface-border px-3 pt-4", children: sidebarFooter }))] })), (0, jsx_runtime_1.jsx)("main", { id: mainId,
150
+ /**
151
+ * In `region` mode the workspace is its own scroll container, so it
152
+ * has to be reachable from the keyboard even when the content it
153
+ * holds is not focusable (WCAG 2.1.1). In `page` mode it is only a
154
+ * skip-link target and should not be a tab stop.
155
+ */
156
+ tabIndex: regionScroll ? 0 : -1, "aria-label": mainLabel, className: (0, cn_1.cn)("min-w-0 flex-1 px-4 py-6", tier.pad, regionScroll && "min-h-0 overflow-y-auto"), children: children })] })] })] }));
157
+ }
@@ -0,0 +1,154 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useId, useRef, useState, } from "react";
3
+ import { cn } from "../utils/cn.js";
4
+ import { Icon } from "../components/Icon/index.js";
5
+ import { Spinner } from "../components/Spinner/index.js";
6
+ const TIER = {
7
+ sm: {
8
+ expandedFlex: "hidden @min-[720px]:flex",
9
+ collapsed: "@min-[720px]:hidden",
10
+ row: "@min-[720px]:flex-row",
11
+ sidebarWidth: "@min-[720px]:w-[248px]",
12
+ pad: "@min-[720px]:px-6",
13
+ },
14
+ md: {
15
+ expandedFlex: "hidden @min-[900px]:flex",
16
+ collapsed: "@min-[900px]:hidden",
17
+ row: "@min-[900px]:flex-row",
18
+ sidebarWidth: "@min-[900px]:w-[264px]",
19
+ pad: "@min-[900px]:px-6",
20
+ },
21
+ lg: {
22
+ expandedFlex: "hidden @min-[1080px]:flex",
23
+ collapsed: "@min-[1080px]:hidden",
24
+ row: "@min-[1080px]:flex-row",
25
+ sidebarWidth: "@min-[1080px]:w-[280px]",
26
+ pad: "@min-[1080px]:px-6",
27
+ },
28
+ };
29
+ /* ─── Shared recipes ─────────────────────────────────────────────────── */
30
+ const FOCUS_RING = "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-action-primary-text";
31
+ const NAV_ITEM_BASE = cn("group flex min-h-11 w-full min-w-0 items-start gap-3 rounded-lg px-3 py-2 text-left text-body-sm font-medium transition-colors", FOCUS_RING);
32
+ /* ─── Navigation item ────────────────────────────────────────────────── */
33
+ function NavBadge({ badge, badgeDescription, }) {
34
+ return (_jsxs("span", { className: "ml-auto inline-flex shrink-0 items-center rounded-full bg-grey-100 px-2 py-0.5 text-body-xs font-semibold text-grey-700", children: [_jsx("span", { "aria-hidden": badgeDescription ? true : undefined, children: badge }), badgeDescription && _jsx("span", { className: "sr-only", children: badgeDescription })] }));
35
+ }
36
+ /**
37
+ * One element for both arrangements. The collapsed panel used to rebuild
38
+ * destinations as buttons, which dropped the href and sent them nowhere
39
+ * (audit B01); rendering an anchor whenever there is an href makes that
40
+ * impossible to reintroduce.
41
+ */
42
+ function ShellNavItem({ item, showDescription, onNavigate, reasonIdPrefix, }) {
43
+ const unavailable = "unavailableReason" in item ? item.unavailableReason : undefined;
44
+ const reasonId = `${reasonIdPrefix}-${item.id}-reason`;
45
+ const body = (_jsxs(_Fragment, { children: [item.icon && (_jsx(Icon, { name: item.icon, size: "md", className: cn("mt-0.5 shrink-0", item.current ? "text-action-primary-text" : "text-grey-500") })), _jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [_jsx("span", { className: "break-words", children: item.label }), showDescription && item.description && (_jsx("span", { className: "text-body-xs font-normal break-words text-grey-500", children: item.description }))] }), item.badge && _jsx(NavBadge, { badge: item.badge, badgeDescription: item.badgeDescription })] }));
46
+ if (unavailable) {
47
+ return (_jsxs("li", { children: [_jsxs("button", { type: "button", disabled: true, "aria-describedby": reasonId, className: cn(NAV_ITEM_BASE, "cursor-not-allowed text-grey-500"), children: [_jsx(Icon, { name: "lock", size: "md", className: "mt-0.5 shrink-0 text-grey-500", "aria-hidden": "true" }), _jsx("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: _jsx("span", { className: "break-words", children: item.label }) })] }), _jsx("p", { id: reasonId, className: "px-3 pb-1 text-body-xs break-words text-grey-500", children: unavailable })] }));
48
+ }
49
+ const tone = item.current
50
+ ? "bg-primary-50 text-grey-900"
51
+ : "text-grey-700 hover:bg-surface-muted hover:text-grey-900";
52
+ if (item.href) {
53
+ return (_jsx("li", { children: _jsx("a", { href: item.href, "aria-current": item.current ? "page" : undefined, onClick: () => {
54
+ item.onClick?.();
55
+ onNavigate?.();
56
+ }, ...(item.external ? { target: "_blank", rel: "noreferrer" } : {}), className: cn(NAV_ITEM_BASE, tone), children: body }) }));
57
+ }
58
+ return (_jsx("li", { children: _jsx("button", { type: "button", "aria-current": item.current ? "page" : undefined, onClick: () => {
59
+ item.onClick?.();
60
+ onNavigate?.();
61
+ }, className: cn(NAV_ITEM_BASE, "cursor-pointer", tone), children: body }) }));
62
+ }
63
+ /* ─── Component ──────────────────────────────────────────────────────── */
64
+ export function ApplicationShellBlock({ brand, brandHref, onBrandClick, navSections = [], navLabel = "Main", sectionHeadingLevel = "h2", navStatus = "idle", navErrorMessage = "Navigation could not be loaded.", onRetryNav, navLoadingMessage = "Loading navigation", navEmptyMessage, search, switcher, actions = [], actionsLabel = "Account and tools", sidebarFooter, openMenuLabel = "Open navigation", closeMenuLabel = "Close navigation", skipLinkLabel = "Skip to main content", skipNavLabel = "Skip links", expandAt = "md", mainScroll = "page", stickyTopBar = true, mainLabel = "Workspace", children, className, }) {
65
+ const uid = useId();
66
+ const mainId = `${uid}-main`;
67
+ const panelId = `${uid}-nav-panel`;
68
+ const [menuOpen, setMenuOpen] = useState(false);
69
+ const toggleRef = useRef(null);
70
+ const tier = TIER[expandAt];
71
+ const SectionHeading = sectionHeadingLevel;
72
+ const itemCount = navSections.reduce((total, section) => total + section.items.length, 0);
73
+ /**
74
+ * A shell with nothing to navigate to renders no rail and no toggle, rather
75
+ * than an empty rail and a control that opens nothing. Supplying
76
+ * `navEmptyMessage` is how a consumer asks for the empty rail instead.
77
+ */
78
+ const hasNav = navStatus !== "idle" || itemCount > 0 || Boolean(navEmptyMessage);
79
+ const regionScroll = mainScroll === "region";
80
+ function closeMenu() {
81
+ setMenuOpen(false);
82
+ }
83
+ function handleKeyDown(event) {
84
+ if (event.defaultPrevented || event.key !== "Escape" || !menuOpen)
85
+ return;
86
+ setMenuOpen(false);
87
+ toggleRef.current?.focus();
88
+ }
89
+ /* ── Navigation body, rendered in the sidebar and in the collapsed panel ── */
90
+ function renderNav(placement) {
91
+ if (navStatus === "loading") {
92
+ return (_jsxs("div", { role: "status", className: "flex items-center gap-2 px-3 py-4 text-body-sm text-grey-500", children: [_jsx(Spinner, { size: "sm" }), _jsx("span", { children: navLoadingMessage })] }));
93
+ }
94
+ if (navStatus === "error") {
95
+ return (_jsxs("div", { role: "alert", className: "mx-1 rounded-lg border border-error-200 bg-error-50 px-3 py-3 text-body-sm text-error-700", children: [_jsx("p", { className: "break-words", children: navErrorMessage }), onRetryNav && (_jsxs("button", { type: "button", onClick: onRetryNav, className: cn("mt-2 inline-flex min-h-9 cursor-pointer items-center gap-2 rounded-lg border-[1.5px] border-current px-3 py-1.5 font-semibold", FOCUS_RING), children: [_jsx(Icon, { name: "refresh", size: "sm", "aria-hidden": "true" }), "Try again"] }))] }));
96
+ }
97
+ if (itemCount === 0) {
98
+ return navEmptyMessage ? (_jsx("p", { className: "px-3 py-4 text-body-sm break-words text-grey-500", children: navEmptyMessage })) : null;
99
+ }
100
+ return (_jsx("div", { className: "flex flex-col gap-5", children: navSections.map((section) => {
101
+ const headingId = `${uid}-${placement}-${section.id}`;
102
+ return (_jsxs("div", { className: "flex flex-col gap-1", children: [section.label && (_jsx(SectionHeading, { id: headingId, className: "px-3 pb-1 text-caption-sm font-semibold break-words text-grey-500 uppercase", children: section.label })), _jsx("ul", { className: "flex list-none flex-col gap-0.5", ...(section.label ? { "aria-labelledby": headingId } : {}), children: section.items.map((item) => (_jsx(ShellNavItem, { item: item, showDescription: placement === "panel", onNavigate: placement === "panel" ? closeMenu : undefined, reasonIdPrefix: `${uid}-${placement}` }, item.id))) })] }, section.id));
103
+ }) }));
104
+ }
105
+ /* ── Brand ── */
106
+ function renderBrand(extraClassName) {
107
+ if (!brand)
108
+ return null;
109
+ const content = _jsx("span", { className: "flex min-w-0 items-center gap-2 break-words", children: brand });
110
+ if (brandHref) {
111
+ return (_jsx("a", { href: brandHref, onClick: onBrandClick, className: cn("rounded", FOCUS_RING, extraClassName), children: content }));
112
+ }
113
+ if (onBrandClick) {
114
+ return (_jsx("button", { type: "button", onClick: onBrandClick, className: cn("cursor-pointer rounded text-left", FOCUS_RING, extraClassName), children: content }));
115
+ }
116
+ return _jsx("div", { className: cn("min-w-0", extraClassName), children: content });
117
+ }
118
+ /* ── Top-bar actions ── */
119
+ function renderAction(action) {
120
+ const iconOnly = Boolean(action.icon);
121
+ const inner = (_jsxs(_Fragment, { children: [action.icon ? (_jsx(Icon, { name: action.icon, size: "md", "aria-hidden": "true" })) : (_jsx("span", { className: "break-words", children: action.label })), iconOnly && _jsx("span", { className: "sr-only", children: action.label }), action.badge && (_jsxs("span", { className: "absolute top-0.5 right-0.5 inline-flex min-w-4 items-center justify-center rounded-full bg-action-primary px-1 text-[10px] leading-4 font-semibold text-white", children: [_jsx("span", { "aria-hidden": action.badgeDescription ? true : undefined, children: action.badge }), action.badgeDescription && _jsx("span", { className: "sr-only", children: action.badgeDescription })] }))] }));
122
+ const classes = cn("relative inline-flex min-h-11 min-w-11 items-center justify-center gap-2 rounded-lg px-2 text-body-sm font-medium text-grey-700 transition-colors hover:bg-surface-muted hover:text-grey-900", FOCUS_RING);
123
+ if (action.href) {
124
+ return (_jsx("a", { href: action.href, onClick: action.onClick, ...(action.external ? { target: "_blank", rel: "noreferrer" } : {}), className: classes, children: inner }, action.id));
125
+ }
126
+ return (_jsx("button", { type: "button", onClick: action.onClick, className: cn(classes, "cursor-pointer"), children: inner }, action.id));
127
+ }
128
+ const sidebarInner = (_jsxs(_Fragment, { children: [brand && _jsx("div", { className: "px-3 pb-4", children: renderBrand("inline-flex min-h-10 items-center") }), _jsx("div", { className: cn("flex-1", regionScroll && "min-h-0 overflow-y-auto"), children: renderNav("sidebar") }), sidebarFooter && (_jsx("div", { className: "mt-4 border-t border-surface-border px-3 pt-4", children: sidebarFooter }))] }));
129
+ return (_jsxs("div", { onKeyDown: handleKeyDown, className: cn(
130
+ // `@container` sits on the outermost element, outside the padded
131
+ // surfaces, so `@min-[…]` padding inside resolves against the shell's
132
+ // real width. `relative` keeps the skip link's positioned box inside
133
+ // the shell instead of widening the document (audit B03).
134
+ "@container relative flex w-full flex-col bg-surface-muted", regionScroll && "h-full max-h-full overflow-hidden", className), children: [_jsx("nav", { "aria-label": skipNavLabel, children: _jsx("a", { href: `#${mainId}`, className: cn("sr-only rounded-lg bg-surface px-4 py-2 text-body-sm font-semibold text-action-primary-text shadow-soft-sm", "focus:not-sr-only focus:absolute focus:top-3 focus:left-3 focus:z-40", FOCUS_RING), children: skipLinkLabel }) }), _jsxs("div", { className: cn("flex min-h-0 w-full flex-1 flex-col", tier.row), children: [hasNav && (
135
+ // The landmark wraps the brand, the destinations, and the sidebar
136
+ // footer. With the landmark on an inner element the brand and footer
137
+ // were page content outside every landmark, which axe's `region` rule
138
+ // reported and a screen-reader user would meet as stray text.
139
+ _jsx("nav", { "aria-label": navLabel, className: cn("w-full shrink-0 flex-col border-r border-surface-border bg-surface px-3 py-5", tier.sidebarWidth, regionScroll && "min-h-0", tier.expandedFlex), children: sidebarInner })), _jsxs("div", { className: cn("flex min-w-0 min-h-0 flex-1 flex-col"), children: [_jsxs("header", { className: cn("flex w-full flex-wrap items-center gap-2 border-b border-surface-border bg-surface px-4 py-2", tier.pad, stickyTopBar && !regionScroll && "sticky top-0 z-20"), children: [hasNav && (_jsxs("button", { ref: toggleRef, type: "button", onClick: () => setMenuOpen((open) => !open), "aria-expanded": menuOpen, "aria-controls": panelId, className: cn("inline-flex min-h-11 min-w-11 shrink-0 cursor-pointer items-center justify-center rounded-lg text-grey-700 hover:bg-surface-muted hover:text-grey-900", FOCUS_RING, tier.collapsed), children: [_jsx(Icon, { name: menuOpen ? "multiply" : "list", size: "md", "aria-hidden": "true" }), _jsx("span", { className: "sr-only", children: menuOpen ? closeMenuLabel : openMenuLabel })] })), brand && !(hasNav && switcher) && (_jsx("div", { className: cn("min-w-0", hasNav ? tier.collapsed : undefined), children: renderBrand("inline-flex min-h-10 items-center") })), switcher && (
140
+ // A floor, not a fixed width: the switcher is a feature, and a
141
+ // feature squeezed to nothing has been dropped. It wraps onto the
142
+ // next row before it shrinks below this.
143
+ _jsx("div", { className: "flex min-w-0 flex-1 @min-[640px]:min-w-[168px] @min-[640px]:flex-none", children: switcher })), search && (_jsx("div", { className: cn(
144
+ // Wraps onto its own row while the shell is narrow rather
145
+ // than being removed. One instance, so its state is stable.
146
+ "order-last w-full min-w-0 basis-full", "@min-[640px]:order-none @min-[640px]:w-auto @min-[640px]:max-w-[420px] @min-[640px]:flex-1 @min-[640px]:basis-auto"), children: search })), actions.length > 0 && (_jsx("div", { role: "group", "aria-label": actionsLabel, className: "ml-auto flex shrink-0 items-center gap-1", children: actions.map((action) => renderAction(action)) }))] }), hasNav && (_jsxs("nav", { id: panelId, "aria-label": navLabel, className: cn("border-b border-surface-border bg-surface px-3 py-4", tier.collapsed, !menuOpen && "hidden"), children: [brand && switcher && (_jsx("div", { className: "px-3 pb-4", children: renderBrand("inline-flex min-h-11 items-center") })), renderNav("panel"), sidebarFooter && (_jsx("div", { className: "mt-4 border-t border-surface-border px-3 pt-4", children: sidebarFooter }))] })), _jsx("main", { id: mainId,
147
+ /**
148
+ * In `region` mode the workspace is its own scroll container, so it
149
+ * has to be reachable from the keyboard even when the content it
150
+ * holds is not focusable (WCAG 2.1.1). In `page` mode it is only a
151
+ * skip-link target and should not be a tab stop.
152
+ */
153
+ tabIndex: regionScroll ? 0 : -1, "aria-label": mainLabel, className: cn("min-w-0 flex-1 px-4 py-6", tier.pad, regionScroll && "min-h-0 overflow-y-auto"), children: children })] })] })] }));
154
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CheckoutReviewBlock = CheckoutReviewBlock;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const Button_1 = require("../components/Button/index.cjs");
6
+ const commerce_1 = require("./commerce.cjs");
7
+ function CheckoutReviewBlock({ title = "Review your order", description = "Check the details before placing your order.", items, deliveryAddress, deliveryMethod, paymentSummary, onEditDelivery, onEditPayment, onEditCart, onConfirm, confirmLabel = "Place order", pending = false, errorMessage, confirmation, terms, totalsNote, shipping, tax, discount, currency, locale, ...frame }) {
8
+ const canConfirm = items.length > 0 &&
9
+ deliveryAddress.some((line) => line.trim()) &&
10
+ deliveryMethod.trim() &&
11
+ paymentSummary.trim() &&
12
+ items.every((item) => Number.isInteger(item.quantity) &&
13
+ item.quantity > 0 &&
14
+ item.quantity <= (item.stock ?? Infinity));
15
+ return ((0, jsx_runtime_1.jsx)(commerce_1.CommerceFrame, { ...frame, title: confirmation?.title ?? title, description: confirmation ? confirmation.description : description, busy: pending, children: confirmation ? ((0, jsx_runtime_1.jsxs)("div", { role: "status", className: "rounded-2xl bg-surface-muted p-6", children: [(0, jsx_runtime_1.jsx)("p", { className: "font-medium", children: confirmation.title }), confirmation.reference && ((0, jsx_runtime_1.jsxs)("p", { className: "mt-2 text-sm text-grey-600", children: ["Order reference: ", confirmation.reference] }))] })) : ((0, jsx_runtime_1.jsxs)("div", { className: "grid items-start gap-8 @min-[760px]:grid-cols-[minmax(0,1.3fr)_minmax(0,1fr)] @min-[960px]:gap-14", children: [(0, jsx_runtime_1.jsxs)("div", { className: "min-w-0 space-y-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "border-b border-surface-border pb-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-lg font-semibold tracking-tight", children: "Delivery details" }), onEditDelivery && ((0, jsx_runtime_1.jsx)("button", { type: "button", disabled: pending, className: `${commerce_1.commerceControl} border-transparent bg-transparent px-2 text-sm underline underline-offset-4 hover:border-transparent`, onClick: onEditDelivery, children: "Edit delivery" }))] }), (0, jsx_runtime_1.jsx)("address", { className: "mt-3 text-sm leading-relaxed not-italic text-grey-600", children: deliveryAddress.map((line, i) => ((0, jsx_runtime_1.jsx)("span", { className: "block", children: line }, i))) }), (0, jsx_runtime_1.jsx)("p", { className: "mt-3 text-sm", children: deliveryMethod })] }), (0, jsx_runtime_1.jsxs)("div", { className: "border-b border-surface-border pb-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-lg font-semibold tracking-tight", children: "Payment method" }), onEditPayment && ((0, jsx_runtime_1.jsx)("button", { type: "button", disabled: pending, className: `${commerce_1.commerceControl} border-transparent bg-transparent px-2 text-sm underline underline-offset-4 hover:border-transparent`, onClick: onEditPayment, children: "Edit payment" }))] }), (0, jsx_runtime_1.jsx)("p", { className: "mt-3 text-sm text-grey-600", children: paymentSummary })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "mb-3 flex flex-wrap items-center justify-between gap-3", children: [(0, jsx_runtime_1.jsx)("p", { className: "font-semibold", children: "Items in your order" }), onEditCart && ((0, jsx_runtime_1.jsx)("button", { type: "button", disabled: pending, className: `${commerce_1.commerceControl} border-transparent bg-transparent px-2 text-sm underline underline-offset-4 hover:border-transparent`, onClick: onEditCart, children: "Edit bag" }))] }), (0, jsx_runtime_1.jsx)("ul", { className: "divide-y divide-surface-border", children: items.map((item) => ((0, jsx_runtime_1.jsxs)("li", { className: "grid grid-cols-[48px_minmax(0,1fr)_auto] items-center gap-3 py-4 text-sm", children: [(0, jsx_runtime_1.jsx)(commerce_1.CommercePhoto, { image: item.image, className: "rounded" }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { className: "font-medium", children: item.name }), (0, jsx_runtime_1.jsxs)("p", { className: "mt-1 text-grey-600", children: [item.variant ? `${item.variant} · ` : "", "Quantity: ", item.quantity] })] }), (0, jsx_runtime_1.jsx)("p", { className: "text-right tabular-nums", children: (0, commerce_1.formatCommerceMoney)(item.price * item.quantity, currency, locale) })] }, item.id))) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "rounded-xl border border-surface-border bg-surface-muted p-5 @min-[440px]:p-6", children: [(0, jsx_runtime_1.jsx)("p", { className: "mb-6 text-lg font-semibold tracking-tight", children: "Order total" }), (0, jsx_runtime_1.jsx)(commerce_1.CommerceTotals, { items: items, shipping: shipping, tax: tax, discount: discount, currency: currency, locale: locale }), totalsNote && (0, jsx_runtime_1.jsx)("p", { className: "mt-4 text-sm text-grey-600", children: totalsNote }), terms && (0, jsx_runtime_1.jsx)("div", { className: "mt-5 text-sm leading-relaxed text-grey-600", children: terms }), errorMessage && ((0, jsx_runtime_1.jsx)("p", { role: "alert", className: "mt-4 text-sm text-error-700", children: errorMessage })), !canConfirm && ((0, jsx_runtime_1.jsx)("p", { role: "status", className: "mt-4 text-sm text-error-700", children: "Add available items and complete the delivery and payment details to continue." })), onConfirm && ((0, jsx_runtime_1.jsx)(Button_1.Button, { disabled: pending || !canConfirm, className: "mt-6 h-auto min-h-12 w-full whitespace-normal", onClick: onConfirm, children: pending ? "Placing order…" : confirmLabel }))] })] })) }));
16
+ }
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button } from "../components/Button/index.js";
3
+ import { CommerceFrame, CommerceTotals, CommercePhoto, commerceControl, formatCommerceMoney, } from "./commerce.js";
4
+ export function CheckoutReviewBlock({ title = "Review your order", description = "Check the details before placing your order.", items, deliveryAddress, deliveryMethod, paymentSummary, onEditDelivery, onEditPayment, onEditCart, onConfirm, confirmLabel = "Place order", pending = false, errorMessage, confirmation, terms, totalsNote, shipping, tax, discount, currency, locale, ...frame }) {
5
+ const canConfirm = items.length > 0 &&
6
+ deliveryAddress.some((line) => line.trim()) &&
7
+ deliveryMethod.trim() &&
8
+ paymentSummary.trim() &&
9
+ items.every((item) => Number.isInteger(item.quantity) &&
10
+ item.quantity > 0 &&
11
+ item.quantity <= (item.stock ?? Infinity));
12
+ return (_jsx(CommerceFrame, { ...frame, title: confirmation?.title ?? title, description: confirmation ? confirmation.description : description, busy: pending, children: confirmation ? (_jsxs("div", { role: "status", className: "rounded-2xl bg-surface-muted p-6", children: [_jsx("p", { className: "font-medium", children: confirmation.title }), confirmation.reference && (_jsxs("p", { className: "mt-2 text-sm text-grey-600", children: ["Order reference: ", confirmation.reference] }))] })) : (_jsxs("div", { className: "grid items-start gap-8 @min-[760px]:grid-cols-[minmax(0,1.3fr)_minmax(0,1fr)] @min-[960px]:gap-14", children: [_jsxs("div", { className: "min-w-0 space-y-6", children: [_jsxs("div", { className: "border-b border-surface-border pb-6", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsx("p", { className: "text-lg font-semibold tracking-tight", children: "Delivery details" }), onEditDelivery && (_jsx("button", { type: "button", disabled: pending, className: `${commerceControl} border-transparent bg-transparent px-2 text-sm underline underline-offset-4 hover:border-transparent`, onClick: onEditDelivery, children: "Edit delivery" }))] }), _jsx("address", { className: "mt-3 text-sm leading-relaxed not-italic text-grey-600", children: deliveryAddress.map((line, i) => (_jsx("span", { className: "block", children: line }, i))) }), _jsx("p", { className: "mt-3 text-sm", children: deliveryMethod })] }), _jsxs("div", { className: "border-b border-surface-border pb-6", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsx("p", { className: "text-lg font-semibold tracking-tight", children: "Payment method" }), onEditPayment && (_jsx("button", { type: "button", disabled: pending, className: `${commerceControl} border-transparent bg-transparent px-2 text-sm underline underline-offset-4 hover:border-transparent`, onClick: onEditPayment, children: "Edit payment" }))] }), _jsx("p", { className: "mt-3 text-sm text-grey-600", children: paymentSummary })] }), _jsxs("div", { children: [_jsxs("div", { className: "mb-3 flex flex-wrap items-center justify-between gap-3", children: [_jsx("p", { className: "font-semibold", children: "Items in your order" }), onEditCart && (_jsx("button", { type: "button", disabled: pending, className: `${commerceControl} border-transparent bg-transparent px-2 text-sm underline underline-offset-4 hover:border-transparent`, onClick: onEditCart, children: "Edit bag" }))] }), _jsx("ul", { className: "divide-y divide-surface-border", children: items.map((item) => (_jsxs("li", { className: "grid grid-cols-[48px_minmax(0,1fr)_auto] items-center gap-3 py-4 text-sm", children: [_jsx(CommercePhoto, { image: item.image, className: "rounded" }), _jsxs("div", { children: [_jsx("p", { className: "font-medium", children: item.name }), _jsxs("p", { className: "mt-1 text-grey-600", children: [item.variant ? `${item.variant} · ` : "", "Quantity: ", item.quantity] })] }), _jsx("p", { className: "text-right tabular-nums", children: formatCommerceMoney(item.price * item.quantity, currency, locale) })] }, item.id))) })] })] }), _jsxs("div", { className: "rounded-xl border border-surface-border bg-surface-muted p-5 @min-[440px]:p-6", children: [_jsx("p", { className: "mb-6 text-lg font-semibold tracking-tight", children: "Order total" }), _jsx(CommerceTotals, { items: items, shipping: shipping, tax: tax, discount: discount, currency: currency, locale: locale }), totalsNote && _jsx("p", { className: "mt-4 text-sm text-grey-600", children: totalsNote }), terms && _jsx("div", { className: "mt-5 text-sm leading-relaxed text-grey-600", children: terms }), errorMessage && (_jsx("p", { role: "alert", className: "mt-4 text-sm text-error-700", children: errorMessage })), !canConfirm && (_jsx("p", { role: "status", className: "mt-4 text-sm text-error-700", children: "Add available items and complete the delivery and payment details to continue." })), onConfirm && (_jsx(Button, { disabled: pending || !canConfirm, className: "mt-6 h-auto min-h-12 w-full whitespace-normal", onClick: onConfirm, children: pending ? "Placing order…" : confirmLabel }))] })] })) }));
13
+ }