pixelize-design-library 2.4.2-beta.65 → 2.4.2-beta.67

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 (489) hide show
  1. package/CHANGELOG.md +447 -13
  2. package/COMPONENT-GOTCHAS.md +150 -91
  3. package/DESIGN-GUIDE.md +47 -7
  4. package/README.md +37 -3
  5. package/dist/Components/Accordion/Accordion.js +11 -8
  6. package/dist/Components/Accordion/AccordionProps.d.ts +4 -0
  7. package/dist/Components/Accordion/accordionColors.js +1 -2
  8. package/dist/Components/Apexcharts/ApexLineChart/ApexLineChart.js +1 -0
  9. package/dist/Components/Apexcharts/ApexLineChart/ApexLineChartProps.d.ts +2 -2
  10. package/dist/Components/Apexcharts/ApexPieChart/ApexPieChart.d.ts +1 -1
  11. package/dist/Components/Apexcharts/ApexPieChart/ApexPieChart.js +6 -5
  12. package/dist/Components/Apexcharts/ApexPieChart/ApexPieChartProps.d.ts +3 -1
  13. package/dist/Components/Apexcharts/ApexPieChart/pieImageTexture.d.ts +2 -0
  14. package/dist/Components/Apexcharts/ApexPieChart/pieImageTexture.js +13 -0
  15. package/dist/Components/AppSwitcher/AppSwitcher.js +6 -3
  16. package/dist/Components/AppSwitcher/AppSwitcherProps.d.ts +3 -1
  17. package/dist/Components/AppSwitcher/AppSwitcherProps.js +18 -11
  18. package/dist/Components/AppSwitcher/pixelizeSuite.d.ts +24 -0
  19. package/dist/Components/AppSwitcher/pixelizeSuite.js +71 -0
  20. package/dist/Components/AppearanceSettings/AppearanceSettings.js +3 -3
  21. package/dist/Components/AppearanceSettings/AppearanceSettingsProps.d.ts +2 -2
  22. package/dist/Components/Avatar/avatarColorway.d.ts +2 -2
  23. package/dist/Components/Avatar/avatarColorway.js +7 -6
  24. package/dist/Components/Breadcrumbs/BreadcrumbsProps.d.ts +1 -1
  25. package/dist/Components/Button/Button.styles.js +5 -2
  26. package/dist/Components/Button/ButtonProps.d.ts +2 -4
  27. package/dist/Components/ButtonGroupIcon/ButtonGroupIcon.js +3 -1
  28. package/dist/Components/CalendarGrid/CalendarGrid.js +5 -3
  29. package/dist/Components/CalendarGrid/CalendarGridProps.d.ts +1 -1
  30. package/dist/Components/Card/Card.d.ts +1 -0
  31. package/dist/Components/Card/Card.js +1 -0
  32. package/dist/Components/Checkbox/Checkbox.styles.js +3 -1
  33. package/dist/Components/CheckoutKit/selectable.d.ts +3 -1
  34. package/dist/Components/CheckoutKit/selectable.js +10 -7
  35. package/dist/Components/CheckoutKit/tonalHover.d.ts +2 -0
  36. package/dist/Components/CheckoutKit/tonalHover.js +6 -0
  37. package/dist/Components/ChoiceCard/ChoiceCard.d.ts +1 -1
  38. package/dist/Components/ChoiceCard/ChoiceCard.js +2 -1
  39. package/dist/Components/ChoiceCard/ChoiceCardProps.d.ts +6 -0
  40. package/dist/Components/Common/FieldMessage.d.ts +1 -0
  41. package/dist/Components/Common/FormLabel.d.ts +1 -1
  42. package/dist/Components/Common/FormLabel.js +4 -3
  43. package/dist/Components/Common/HelperText.d.ts +2 -2
  44. package/dist/Components/Common/HelperText.js +1 -2
  45. package/dist/Components/Common/activationKey.d.ts +5 -0
  46. package/dist/Components/Common/activationKey.js +12 -0
  47. package/dist/Components/Common/dataAttributes.d.ts +4 -0
  48. package/dist/Components/Common/fieldMessageStyles.js +2 -1
  49. package/dist/Components/Common/findSlot.d.ts +2 -0
  50. package/dist/Components/Common/findSlot.js +24 -0
  51. package/dist/Components/Common/surfaceFocusRing.d.ts +1 -0
  52. package/dist/Components/Common/surfaceFocusRing.js +7 -0
  53. package/dist/Components/ConfirmDialog/ConfirmDialog.js +17 -5
  54. package/dist/Components/ConfirmDialog/ConfirmDialogProps.d.ts +38 -10
  55. package/dist/Components/CopyButton/CopyButton.d.ts +1 -0
  56. package/dist/Components/CopyButton/CopyButton.js +3 -6
  57. package/dist/Components/CouponField/CouponField.js +5 -2
  58. package/dist/Components/CustomModulesTable/CustomModulesTable.js +3 -1
  59. package/dist/Components/DatePicker/CalendarPanel.d.ts +1 -0
  60. package/dist/Components/DatePicker/CalendarPanel.js +3 -1
  61. package/dist/Components/DatePicker/DatePicker.js +24 -26
  62. package/dist/Components/DatePicker/DatePickerProps.d.ts +8 -0
  63. package/dist/Components/DatePicker/PickerPortal.js +1 -1
  64. package/dist/Components/DatePicker/RangeDatePicker.d.ts +7 -0
  65. package/dist/Components/DatePicker/RangeDatePicker.js +10 -29
  66. package/dist/Components/DatePicker/SingleDatePicker.js +5 -21
  67. package/dist/Components/DatePicker/TimeOnlyPicker.js +2 -20
  68. package/dist/Components/DescriptionList/DescriptionList.js +1 -1
  69. package/dist/Components/DetailSections/DetailSections.js +2 -1
  70. package/dist/Components/Divider/Divider.d.ts +3 -3
  71. package/dist/Components/Divider/Divider.js +3 -3
  72. package/dist/Components/Drawer/Drawer.d.ts +2 -0
  73. package/dist/Components/Drawer/Drawer.js +23 -25
  74. package/dist/Components/Dropdown/DropDown.js +6 -21
  75. package/dist/Components/Editor/Editor.js +6 -2
  76. package/dist/Components/Editor/EditorProps.d.ts +17 -1
  77. package/dist/Components/Editor/editorLabels.js +1 -0
  78. package/dist/Components/Editor/editorTokenStyles.d.ts +8 -0
  79. package/dist/Components/Editor/editorTokenStyles.js +9 -1
  80. package/dist/Components/EmailCards/VerifyEmailOtp/VerifyEmailOtp.d.ts +1 -1
  81. package/dist/Components/EmailCards/VerifyEmailOtp/VerifyEmailOtp.js +9 -2
  82. package/dist/Components/EmailCards/VerifyEmailOtp/VerifyEmailOtpProps.d.ts +15 -1
  83. package/dist/Components/EmptyState/EmptyStateProps.d.ts +21 -0
  84. package/dist/Components/EmptyState/FilteredEmptyState.d.ts +5 -0
  85. package/dist/Components/EmptyState/FilteredEmptyState.js +23 -0
  86. package/dist/Components/FieldSelectModal/FieldSelectModal.d.ts +1 -0
  87. package/dist/Components/FilePreview/FilePreview.js +7 -3
  88. package/dist/Components/FilePreview/FilePreviewProps.d.ts +2 -1
  89. package/dist/Components/FileUpload/FileUpload.js +8 -9
  90. package/dist/Components/FileUpload/FileUploadProps.d.ts +2 -2
  91. package/dist/Components/FileUploader/FileUploader.js +5 -6
  92. package/dist/Components/FilterSidebar/FilterSidebar.d.ts +7 -9
  93. package/dist/Components/FilterSidebar/FilterSidebar.js +90 -233
  94. package/dist/Components/FilterSidebar/OptionsSection.d.ts +14 -0
  95. package/dist/Components/FilterSidebar/OptionsSection.js +46 -0
  96. package/dist/Components/FilterSidebar/RangeSection.d.ts +17 -0
  97. package/dist/Components/FilterSidebar/RangeSection.js +80 -0
  98. package/dist/Components/FilterSidebar/SectionHeader.d.ts +13 -0
  99. package/dist/Components/FilterSidebar/SectionHeader.js +29 -0
  100. package/dist/Components/FilterSidebar/useStableCallback.d.ts +1 -0
  101. package/dist/Components/FilterSidebar/useStableCallback.js +12 -0
  102. package/dist/Components/Form/FormWrapper.d.ts +7 -7
  103. package/dist/Components/Form/FormWrapper.js +5 -3
  104. package/dist/Components/FormField/FormField.js +1 -1
  105. package/dist/Components/Header/Header.js +1 -1
  106. package/dist/Components/Header/HeaderActions.js +4 -2
  107. package/dist/Components/IconButton/IconButtonProps.d.ts +2 -1
  108. package/dist/Components/Input/TextInput.js +2 -2
  109. package/dist/Components/Input/TextInputProps.d.ts +3 -1
  110. package/dist/Components/KanbanBoard/AccountCard.js +1 -1
  111. package/dist/Components/KanbanBoard/KanbanBoard.d.ts +1 -1
  112. package/dist/Components/KanbanBoard/KanbanBoard.js +11 -7
  113. package/dist/Components/LauncherTrigger/LauncherTrigger.js +1 -1
  114. package/dist/Components/LazyWrapper/LazyWrapper.d.ts +2 -1
  115. package/dist/Components/LazyWrapper/LazyWrapper.js +1 -1
  116. package/dist/Components/MediaViewer/MediaViewer.js +4 -3
  117. package/dist/Components/MediaViewer/components/MediaAudioPlayer.js +5 -1
  118. package/dist/Components/MediaViewer/components/MediaImageViewer.js +19 -8
  119. package/dist/Components/MediaViewer/components/MediaScrubber.js +7 -2
  120. package/dist/Components/MediaViewer/components/MediaVideoPlayer.js +3 -1
  121. package/dist/Components/MediaViewer/components/ViewerIconButton.js +3 -1
  122. package/dist/Components/MediaViewer/hooks/useFileViewer.d.ts +1 -0
  123. package/dist/Components/MediaViewer/mediaItems.d.ts +1 -0
  124. package/dist/Components/MediaViewer/mediaItems.js +5 -0
  125. package/dist/Components/Modal/Modal.d.ts +1 -0
  126. package/dist/Components/Modal/Modal.js +7 -25
  127. package/dist/Components/Modal/warnDroppedSlotChildren.d.ts +1 -1
  128. package/dist/Components/Modal/warnDroppedSlotChildren.js +7 -3
  129. package/dist/Components/NavLauncher/LauncherTabs.js +2 -1
  130. package/dist/Components/NavLauncher/NavLauncher.js +47 -22
  131. package/dist/Components/NavLauncher/NavLauncherProps.d.ts +6 -4
  132. package/dist/Components/NavLauncher/ScopeBar.js +4 -2
  133. package/dist/Components/NavLauncher/engine/engine.js +2 -1
  134. package/dist/Components/NavLauncher/engine/fold.js +2 -1
  135. package/dist/Components/NavLauncher/launcherMotion.d.ts +19 -0
  136. package/dist/Components/NavLauncher/launcherMotion.js +15 -0
  137. package/dist/Components/NavLauncher/launcherParts.d.ts +12 -0
  138. package/dist/Components/NavLauncher/launcherParts.js +45 -11
  139. package/dist/Components/NavLauncher/searchLayout.d.ts +1 -0
  140. package/dist/Components/NavLauncher/searchLayout.js +3 -1
  141. package/dist/Components/NavLauncher/spotlightParts.d.ts +6 -2
  142. package/dist/Components/NavLauncher/spotlightParts.js +22 -9
  143. package/dist/Components/NavLauncher/useCopiedFlash.d.ts +6 -0
  144. package/dist/Components/NavLauncher/useCopiedFlash.js +21 -0
  145. package/dist/Components/NavigationBar/NavigationBar.js +6 -5
  146. package/dist/Components/NoteTextArea/NoteTextArea.js +12 -17
  147. package/dist/Components/NoteTextArea/NoteTextAreaProps.d.ts +5 -3
  148. package/dist/Components/Notification/Notification.js +19 -21
  149. package/dist/Components/Notification/NotificationProps.d.ts +1 -1
  150. package/dist/Components/NotificationBell/notificationHelpers.d.ts +16 -1
  151. package/dist/Components/NotificationBell/notificationHelpers.js +13 -7
  152. package/dist/Components/OffersList/OffersList.js +4 -2
  153. package/dist/Components/OptionChip/OptionChip.js +3 -2
  154. package/dist/Components/OptionChip/optionInk.js +4 -2
  155. package/dist/Components/OrderStatusTimeline/OrderStatusTimeline.js +2 -1
  156. package/dist/Components/OrgSwitcher/OrgSwitcher.js +13 -6
  157. package/dist/Components/OrgSwitcher/OrgSwitcherProps.d.ts +1 -1
  158. package/dist/Components/OrganizationDetails/OrganizationDetails.js +4 -7
  159. package/dist/Components/OrganizationDetails/OrganizationDetailsProps.d.ts +4 -2
  160. package/dist/Components/PdfViewer/PdfViewer.d.ts +1 -0
  161. package/dist/Components/PlanBadge/PlanBadgeProps.d.ts +1 -1
  162. package/dist/Components/PlanPill/PlanPill.js +4 -2
  163. package/dist/Components/PlanPill/PlanPillProps.d.ts +1 -1
  164. package/dist/Components/ProductCard/ProductCardAction.js +2 -1
  165. package/dist/Components/ProductCard/ProductCardSwatches.js +2 -1
  166. package/dist/Components/ProductDetails/ProductDetails.js +2 -1
  167. package/dist/Components/ProfileCard/ProfileCard.d.ts +1 -0
  168. package/dist/Components/ProfileCard/ProfileCard.js +12 -26
  169. package/dist/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +4 -2
  170. package/dist/Components/ProgressBar/ProgressBar.js +2 -1
  171. package/dist/Components/QuantityStepper/QuantityStepper.js +5 -2
  172. package/dist/Components/QueryState/QueryStateBoundary.d.ts +1 -1
  173. package/dist/Components/QueryState/QueryStateBoundary.js +5 -1
  174. package/dist/Components/QueryState/QueryStateProps.d.ts +6 -2
  175. package/dist/Components/RadioButton/RadioButton.js +2 -3
  176. package/dist/Components/RolesPermission/RolesPermission.js +12 -8
  177. package/dist/Components/ScrollToTop/ScrollToTop.d.ts +1 -0
  178. package/dist/Components/ScrollbarBox/ScrollbarBox.d.ts +4 -1
  179. package/dist/Components/ScrollbarBox/ScrollbarBox.js +10 -4
  180. package/dist/Components/SearchSelect/SearchSelect.d.ts +1 -1
  181. package/dist/Components/SearchSelect/SearchSelect.js +8 -5
  182. package/dist/Components/SearchSelect/SearchSelectProps.d.ts +3 -3
  183. package/dist/Components/SegmentedControl/SegmentedControl.d.ts +1 -1
  184. package/dist/Components/SegmentedControl/SegmentedControl.js +1 -1
  185. package/dist/Components/Select/Select.js +6 -0
  186. package/dist/Components/Select/SelectNative.d.ts +16 -0
  187. package/dist/Components/Select/SelectPopup.js +170 -63
  188. package/dist/Components/Select/SelectProps.d.ts +30 -2
  189. package/dist/Components/Select/groupedWindow.d.ts +21 -0
  190. package/dist/Components/Select/groupedWindow.js +50 -0
  191. package/dist/Components/SelectSearch/SelectSearch.d.ts +1 -1
  192. package/dist/Components/SelectSearch/SelectSearch.js +48 -38
  193. package/dist/Components/SelectSearch/SelectSearchProps.d.ts +3 -3
  194. package/dist/Components/SelectV2/SelectV2.d.ts +1 -1
  195. package/dist/Components/SelectV2/SelectV2.js +1 -1
  196. package/dist/Components/SelectV2/SelectV2Props.d.ts +3 -3
  197. package/dist/Components/SideBar/SecondaryBar.js +3 -2
  198. package/dist/Components/SideBar/components/MenuItemBox.js +3 -2
  199. package/dist/Components/SideBar/components/MenuItems.js +1 -1
  200. package/dist/Components/SideBar/components/OtherApps.js +2 -2
  201. package/dist/Components/SideBar/components/PinnedSection.js +1 -1
  202. package/dist/Components/SideBar/sidebarScale.d.ts +2 -2
  203. package/dist/Components/SideBar/sidebarScale.js +2 -2
  204. package/dist/Components/SignInActivityTable/SignInActivityTable.js +7 -2
  205. package/dist/Components/SignInActivityTable/SignInActivityTableProps.d.ts +1 -1
  206. package/dist/Components/SignInActivityTable/scrollRegionRing.d.ts +10 -0
  207. package/dist/Components/SignInActivityTable/scrollRegionRing.js +14 -0
  208. package/dist/Components/Skeletons/SkeletonProps.d.ts +5 -1
  209. package/dist/Components/Slider/Slider.d.ts +2 -0
  210. package/dist/Components/Slider/Slider.js +5 -4
  211. package/dist/Components/StageProgress/StageItem.js +2 -1
  212. package/dist/Components/StageProgress/StageProgress.js +8 -2
  213. package/dist/Components/StageProgress/StageProgressProps.d.ts +2 -0
  214. package/dist/Components/StageProgress/StepperStage.js +2 -1
  215. package/dist/Components/StickyBuyBar/StickyBuyBar.js +2 -1
  216. package/dist/Components/Table/Table.js +5 -3
  217. package/dist/Components/Table/TableProps.d.ts +1 -1
  218. package/dist/Components/Table/components/HeaderActions.js +5 -3
  219. package/dist/Components/Table/components/TableBody.js +22 -8
  220. package/dist/Components/Table/components/TableGroupRow.js +2 -1
  221. package/dist/Components/Table/components/TableHeader.js +14 -20
  222. package/dist/Components/Table/components/rowDetail.js +3 -2
  223. package/dist/Components/Table/components/rowFocusRing.d.ts +21 -0
  224. package/dist/Components/Table/components/rowFocusRing.js +20 -0
  225. package/dist/Components/Table/filters/ActiveFilters.js +6 -3
  226. package/dist/Components/Table/filters/CompactSelect.js +2 -1
  227. package/dist/Components/Table/filters/FilterDatePicker.d.ts +6 -0
  228. package/dist/Components/Table/filters/FilterDatePicker.js +61 -0
  229. package/dist/Components/Table/filters/LeftFilterPane.d.ts +1 -0
  230. package/dist/Components/Table/filters/LeftFilterPane.js +14 -6
  231. package/dist/Components/Table/hooks/useTable.js +11 -7
  232. package/dist/Components/Table/settings/ManageColumns.js +4 -3
  233. package/dist/Components/Table/settings/TableSettings.js +4 -4
  234. package/dist/Components/Tabs/Tabs.d.ts +1 -0
  235. package/dist/Components/Tabs/Tabs.js +1 -0
  236. package/dist/Components/Tabs/components/CountBadge.d.ts +1 -0
  237. package/dist/Components/Tabs/components/TabList.d.ts +1 -0
  238. package/dist/Components/Tabs/components/TabList.js +1 -0
  239. package/dist/Components/Tabs/components/TabPanel.d.ts +1 -0
  240. package/dist/Components/Tabs/components/TabPanel.js +1 -0
  241. package/dist/Components/Tabs/tabStyles.js +4 -2
  242. package/dist/Components/Tag/Tag.js +5 -4
  243. package/dist/Components/Tag/Tag.styles.js +5 -4
  244. package/dist/Components/Tag/TagProps.d.ts +4 -1
  245. package/dist/Components/Tag/tagDot.js +10 -3
  246. package/dist/Components/TagInput/TagInput.js +6 -5
  247. package/dist/Components/TagInput/TagInputProps.d.ts +15 -0
  248. package/dist/Components/TagInput/tagEntries.d.ts +7 -1
  249. package/dist/Components/TagInput/tagEntries.js +18 -5
  250. package/dist/Components/TimePicker/TimePicker.js +7 -3
  251. package/dist/Components/TimePicker/TimePickerProps.d.ts +2 -0
  252. package/dist/Components/Timeline/Timeline.js +13 -9
  253. package/dist/Components/Toaster/Toaster.js +2 -1
  254. package/dist/Components/Toggle/TableToggle.d.ts +1 -1
  255. package/dist/Components/Toggle/TableToggle.js +1 -1
  256. package/dist/Components/UpgradeButton/UpgradeButton.js +3 -2
  257. package/dist/Components/UpgradeButton/UpgradeButtonProps.d.ts +1 -1
  258. package/dist/Components/UserDetails/UserDetails.js +5 -7
  259. package/dist/Components/WishlistToggle/WishlistToggle.js +2 -1
  260. package/dist/Components/WorkspaceWindow/WorkspaceTrayPreview.js +11 -1
  261. package/dist/Components/WorkspaceWindow/WorkspaceWindow.js +3 -1
  262. package/dist/Components/WorkspaceWindow/WorkspaceWindowProps.d.ts +14 -7
  263. package/dist/Hooks/useOutsideMouseDown.d.ts +11 -0
  264. package/dist/Hooks/useOutsideMouseDown.js +30 -0
  265. package/dist/Hooks/usePreferences.js +30 -12
  266. package/dist/Hooks/useScrollableRegion.d.ts +17 -0
  267. package/dist/Hooks/useScrollableRegion.js +36 -0
  268. package/dist/Hooks/useSidebarPrefs.d.ts +1 -0
  269. package/dist/Theme/chakra/Menu.styles.d.ts +4 -0
  270. package/dist/Theme/chakra/Menu.styles.js +6 -0
  271. package/dist/Theme/chakra/componentStyles.d.ts +4 -0
  272. package/dist/Theme/chakra/componentStyles.js +1 -1
  273. package/dist/Theme/chakra/createBrandTheme.d.ts +1 -0
  274. package/dist/Theme/chakra/focusRing.styles.d.ts +1 -1
  275. package/dist/Theme/chakra/focusRing.styles.js +3 -3
  276. package/dist/Theme/chakra/paletteFromTheme.d.ts +2 -1
  277. package/dist/Theme/chakra/paletteFromTheme.js +18 -4
  278. package/dist/Theme/provider/PixelizeThemeProvider.d.ts +1 -0
  279. package/dist/Theme/provider/ThemeSwitcher.d.ts +1 -0
  280. package/dist/Theme/provider/ThemeSwitcher.js +1 -1
  281. package/dist/Theme/testing/testPalette.d.ts +1 -0
  282. package/dist/Theme/tokens/builders/buildDarkPalette.d.ts +1 -0
  283. package/dist/Theme/tokens/builders/filledSurface.js +3 -2
  284. package/dist/Theme/tokens/builders/focusRing.js +4 -1
  285. package/dist/Theme/tokens/builders/paletteScale.d.ts +2 -0
  286. package/dist/Theme/tokens/builders/paletteScale.js +10 -0
  287. package/dist/Theme/tokens/types.d.ts +1 -0
  288. package/dist/Utils/accountHandoff.d.ts +3 -0
  289. package/dist/Utils/price.d.ts +1 -0
  290. package/dist/Utils/tabular.d.ts +30 -0
  291. package/dist/Utils/tabular.js +61 -0
  292. package/dist/esm/Components/Accordion/Accordion.js +11 -8
  293. package/dist/esm/Components/Accordion/accordionColors.js +2 -3
  294. package/dist/esm/Components/Apexcharts/ApexLineChart/ApexLineChart.js +2 -1
  295. package/dist/esm/Components/Apexcharts/ApexPieChart/ApexPieChart.js +6 -5
  296. package/dist/esm/Components/Apexcharts/ApexPieChart/pieImageTexture.js +10 -0
  297. package/dist/esm/Components/AppSwitcher/AppSwitcher.js +6 -3
  298. package/dist/esm/Components/AppSwitcher/AppSwitcherProps.js +18 -11
  299. package/dist/esm/Components/AppSwitcher/pixelizeSuite.js +67 -0
  300. package/dist/esm/Components/AppearanceSettings/AppearanceSettings.js +3 -3
  301. package/dist/esm/Components/Avatar/avatarColorway.js +4 -4
  302. package/dist/esm/Components/Button/Button.styles.js +5 -2
  303. package/dist/esm/Components/ButtonGroupIcon/ButtonGroupIcon.js +3 -1
  304. package/dist/esm/Components/CalendarGrid/CalendarGrid.js +5 -3
  305. package/dist/esm/Components/Card/Card.js +1 -0
  306. package/dist/esm/Components/Checkbox/Checkbox.styles.js +3 -1
  307. package/dist/esm/Components/CheckoutKit/selectable.js +10 -7
  308. package/dist/esm/Components/CheckoutKit/tonalHover.js +2 -0
  309. package/dist/esm/Components/ChoiceCard/ChoiceCard.js +2 -1
  310. package/dist/esm/Components/Common/FormLabel.js +4 -3
  311. package/dist/esm/Components/Common/HelperText.js +1 -2
  312. package/dist/esm/Components/Common/activationKey.js +7 -0
  313. package/dist/esm/Components/Common/fieldMessageStyles.js +2 -1
  314. package/dist/esm/Components/Common/findSlot.js +17 -0
  315. package/dist/esm/Components/Common/surfaceFocusRing.js +3 -0
  316. package/dist/esm/Components/ConfirmDialog/ConfirmDialog.js +18 -6
  317. package/dist/esm/Components/CopyButton/CopyButton.js +3 -6
  318. package/dist/esm/Components/CouponField/CouponField.js +5 -2
  319. package/dist/esm/Components/CustomModulesTable/CustomModulesTable.js +3 -1
  320. package/dist/esm/Components/DatePicker/CalendarPanel.js +3 -1
  321. package/dist/esm/Components/DatePicker/DatePicker.js +25 -27
  322. package/dist/esm/Components/DatePicker/PickerPortal.js +2 -2
  323. package/dist/esm/Components/DatePicker/RangeDatePicker.js +10 -29
  324. package/dist/esm/Components/DatePicker/SingleDatePicker.js +5 -21
  325. package/dist/esm/Components/DatePicker/TimeOnlyPicker.js +2 -20
  326. package/dist/esm/Components/DescriptionList/DescriptionList.js +1 -1
  327. package/dist/esm/Components/DetailSections/DetailSections.js +2 -1
  328. package/dist/esm/Components/Divider/Divider.js +3 -3
  329. package/dist/esm/Components/Drawer/Drawer.js +19 -18
  330. package/dist/esm/Components/Dropdown/DropDown.js +7 -22
  331. package/dist/esm/Components/Editor/Editor.js +7 -3
  332. package/dist/esm/Components/Editor/editorLabels.js +1 -0
  333. package/dist/esm/Components/Editor/editorTokenStyles.js +7 -0
  334. package/dist/esm/Components/EmailCards/VerifyEmailOtp/VerifyEmailOtp.js +8 -4
  335. package/dist/esm/Components/EmptyState/FilteredEmptyState.js +18 -0
  336. package/dist/esm/Components/FilePreview/FilePreview.js +8 -4
  337. package/dist/esm/Components/FileUpload/FileUpload.js +8 -9
  338. package/dist/esm/Components/FileUploader/FileUploader.js +6 -7
  339. package/dist/esm/Components/FilterSidebar/FilterSidebar.js +94 -237
  340. package/dist/esm/Components/FilterSidebar/OptionsSection.js +41 -0
  341. package/dist/esm/Components/FilterSidebar/RangeSection.js +78 -0
  342. package/dist/esm/Components/FilterSidebar/SectionHeader.js +23 -0
  343. package/dist/esm/Components/FilterSidebar/useStableCallback.js +8 -0
  344. package/dist/esm/Components/Form/FormWrapper.js +5 -3
  345. package/dist/esm/Components/FormField/FormField.js +1 -1
  346. package/dist/esm/Components/Header/Header.js +1 -1
  347. package/dist/esm/Components/Header/HeaderActions.js +6 -4
  348. package/dist/esm/Components/Input/TextInput.js +2 -2
  349. package/dist/esm/Components/KanbanBoard/AccountCard.js +1 -1
  350. package/dist/esm/Components/KanbanBoard/KanbanActions/KanbanActions.js +2 -2
  351. package/dist/esm/Components/KanbanBoard/KanbanBoard.js +11 -7
  352. package/dist/esm/Components/LauncherTrigger/LauncherTrigger.js +1 -1
  353. package/dist/esm/Components/LazyWrapper/LazyWrapper.js +1 -1
  354. package/dist/esm/Components/MediaViewer/MediaViewer.js +5 -4
  355. package/dist/esm/Components/MediaViewer/components/MediaAudioPlayer.js +5 -1
  356. package/dist/esm/Components/MediaViewer/components/MediaImageViewer.js +19 -8
  357. package/dist/esm/Components/MediaViewer/components/MediaScrubber.js +7 -2
  358. package/dist/esm/Components/MediaViewer/components/MediaVideoPlayer.js +3 -1
  359. package/dist/esm/Components/MediaViewer/components/ViewerIconButton.js +3 -1
  360. package/dist/esm/Components/MediaViewer/mediaItems.js +4 -0
  361. package/dist/esm/Components/Modal/Modal.js +2 -17
  362. package/dist/esm/Components/Modal/warnDroppedSlotChildren.js +7 -3
  363. package/dist/esm/Components/NavLauncher/LauncherTabs.js +2 -1
  364. package/dist/esm/Components/NavLauncher/NavLauncher.js +51 -26
  365. package/dist/esm/Components/NavLauncher/ScopeBar.js +4 -2
  366. package/dist/esm/Components/NavLauncher/engine/engine.js +2 -1
  367. package/dist/esm/Components/NavLauncher/engine/fold.js +2 -1
  368. package/dist/esm/Components/NavLauncher/launcherMotion.js +11 -0
  369. package/dist/esm/Components/NavLauncher/launcherParts.js +40 -8
  370. package/dist/esm/Components/NavLauncher/searchLayout.js +1 -0
  371. package/dist/esm/Components/NavLauncher/spotlightParts.js +23 -10
  372. package/dist/esm/Components/NavLauncher/useCopiedFlash.js +17 -0
  373. package/dist/esm/Components/NavigationBar/NavigationBar.js +6 -5
  374. package/dist/esm/Components/NoteTextArea/NoteTextArea.js +12 -17
  375. package/dist/esm/Components/Notification/Notification.js +20 -22
  376. package/dist/esm/Components/NotificationBell/notificationHelpers.js +12 -6
  377. package/dist/esm/Components/OffersList/OffersList.js +4 -2
  378. package/dist/esm/Components/OptionChip/OptionChip.js +3 -2
  379. package/dist/esm/Components/OptionChip/optionInk.js +4 -2
  380. package/dist/esm/Components/OrderStatusTimeline/OrderStatusTimeline.js +2 -1
  381. package/dist/esm/Components/OrgSwitcher/OrgSwitcher.js +14 -7
  382. package/dist/esm/Components/OrganizationDetails/OrganizationDetails.js +5 -8
  383. package/dist/esm/Components/PlanPill/PlanPill.js +4 -2
  384. package/dist/esm/Components/ProductCard/ProductCardAction.js +2 -1
  385. package/dist/esm/Components/ProductCard/ProductCardSwatches.js +2 -1
  386. package/dist/esm/Components/ProductDetails/ProductDetails.js +2 -1
  387. package/dist/esm/Components/ProfileCard/ProfileCard.js +6 -17
  388. package/dist/esm/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +4 -2
  389. package/dist/esm/Components/ProgressBar/ProgressBar.js +2 -1
  390. package/dist/esm/Components/QuantityStepper/QuantityStepper.js +5 -2
  391. package/dist/esm/Components/QueryState/QueryStateBoundary.js +5 -1
  392. package/dist/esm/Components/RadioButton/RadioButton.js +2 -3
  393. package/dist/esm/Components/RolesPermission/RolesPermission.js +12 -8
  394. package/dist/esm/Components/ScrollbarBox/ScrollbarBox.js +9 -3
  395. package/dist/esm/Components/SearchSelect/SearchSelect.js +8 -5
  396. package/dist/esm/Components/SegmentedControl/SegmentedControl.js +1 -1
  397. package/dist/esm/Components/Select/Select.js +6 -0
  398. package/dist/esm/Components/Select/SelectPopup.js +171 -64
  399. package/dist/esm/Components/Select/groupedWindow.js +44 -0
  400. package/dist/esm/Components/SelectSearch/SelectSearch.js +49 -39
  401. package/dist/esm/Components/SelectV2/SelectV2.js +1 -1
  402. package/dist/esm/Components/SideBar/SecondaryBar.js +3 -2
  403. package/dist/esm/Components/SideBar/components/MenuItemBox.js +3 -2
  404. package/dist/esm/Components/SideBar/components/MenuItems.js +1 -1
  405. package/dist/esm/Components/SideBar/components/OtherApps.js +2 -2
  406. package/dist/esm/Components/SideBar/components/PinnedSection.js +1 -1
  407. package/dist/esm/Components/SideBar/sidebarScale.js +2 -2
  408. package/dist/esm/Components/SignInActivityTable/SignInActivityTable.js +8 -3
  409. package/dist/esm/Components/SignInActivityTable/scrollRegionRing.js +9 -0
  410. package/dist/esm/Components/Slider/Slider.js +6 -5
  411. package/dist/esm/Components/StageProgress/StageItem.js +2 -1
  412. package/dist/esm/Components/StageProgress/StageProgress.js +8 -2
  413. package/dist/esm/Components/StageProgress/StepperStage.js +2 -1
  414. package/dist/esm/Components/StickyBuyBar/StickyBuyBar.js +2 -1
  415. package/dist/esm/Components/Table/Table.js +8 -6
  416. package/dist/esm/Components/Table/components/HeaderActions.js +7 -5
  417. package/dist/esm/Components/Table/components/TableBody.js +22 -8
  418. package/dist/esm/Components/Table/components/TableGroupRow.js +2 -1
  419. package/dist/esm/Components/Table/components/TableHeader.js +15 -21
  420. package/dist/esm/Components/Table/components/rowDetail.js +3 -2
  421. package/dist/esm/Components/Table/components/rowFocusRing.js +16 -0
  422. package/dist/esm/Components/Table/filters/ActiveFilters.js +8 -5
  423. package/dist/esm/Components/Table/filters/CompactSelect.js +2 -1
  424. package/dist/esm/Components/Table/filters/FilterDatePicker.js +20 -0
  425. package/dist/esm/Components/Table/filters/LeftFilterPane.js +14 -6
  426. package/dist/esm/Components/Table/hooks/useTable.js +11 -7
  427. package/dist/esm/Components/Table/settings/ManageColumns.js +4 -3
  428. package/dist/esm/Components/Table/settings/TableSettings.js +4 -4
  429. package/dist/esm/Components/Tabs/Tabs.js +1 -0
  430. package/dist/esm/Components/Tabs/components/TabList.js +1 -0
  431. package/dist/esm/Components/Tabs/components/TabPanel.js +1 -0
  432. package/dist/esm/Components/Tabs/tabStyles.js +5 -3
  433. package/dist/esm/Components/Tag/Tag.js +5 -4
  434. package/dist/esm/Components/Tag/Tag.styles.js +5 -4
  435. package/dist/esm/Components/Tag/tagDot.js +10 -3
  436. package/dist/esm/Components/TagInput/TagInput.js +8 -7
  437. package/dist/esm/Components/TagInput/tagEntries.js +16 -4
  438. package/dist/esm/Components/TimePicker/TimePicker.js +7 -3
  439. package/dist/esm/Components/Timeline/Timeline.js +14 -10
  440. package/dist/esm/Components/Toaster/Toaster.js +2 -1
  441. package/dist/esm/Components/Toggle/TableToggle.js +1 -1
  442. package/dist/esm/Components/UpgradeButton/UpgradeButton.js +3 -2
  443. package/dist/esm/Components/UserDetails/UserDetails.js +5 -7
  444. package/dist/esm/Components/WishlistToggle/WishlistToggle.js +2 -1
  445. package/dist/esm/Components/WorkspaceWindow/WorkspaceTrayPreview.js +12 -2
  446. package/dist/esm/Components/WorkspaceWindow/WorkspaceWindow.js +3 -1
  447. package/dist/esm/Hooks/useOutsideMouseDown.js +26 -0
  448. package/dist/esm/Hooks/usePreferences.js +30 -12
  449. package/dist/esm/Hooks/useScrollableRegion.js +33 -0
  450. package/dist/esm/Theme/chakra/Menu.styles.js +6 -0
  451. package/dist/esm/Theme/chakra/componentStyles.js +1 -1
  452. package/dist/esm/Theme/chakra/focusRing.styles.js +3 -3
  453. package/dist/esm/Theme/chakra/paletteFromTheme.js +16 -3
  454. package/dist/esm/Theme/provider/ThemeSwitcher.js +1 -1
  455. package/dist/esm/Theme/tokens/builders/filledSurface.js +3 -2
  456. package/dist/esm/Theme/tokens/builders/focusRing.js +4 -1
  457. package/dist/esm/Theme/tokens/builders/paletteScale.js +6 -0
  458. package/dist/esm/Utils/tabular.js +56 -0
  459. package/dist/esm/index.js +16 -24
  460. package/dist/index.d.ts +54 -2
  461. package/dist/index.js +33 -29
  462. package/package.json +3 -1
  463. package/dist/Components/Buttons/Buttons.d.ts +0 -3
  464. package/dist/Components/Buttons/Buttons.js +0 -9
  465. package/dist/Components/Buttons/ButtonsProps.d.ts +0 -12
  466. package/dist/Components/Common/ErrorComponent.d.ts +0 -7
  467. package/dist/Components/Common/ErrorComponent.js +0 -16
  468. package/dist/Components/Common/FormattedDescription.d.ts +0 -7
  469. package/dist/Components/Common/FormattedDescription.js +0 -62
  470. package/dist/Components/Common/Label.d.ts +0 -9
  471. package/dist/Components/Common/Label.js +0 -12
  472. package/dist/Components/Input/Input/Input.d.ts +0 -4
  473. package/dist/Components/Input/Input/Input.js +0 -75
  474. package/dist/Components/Input/Input/InputProps.d.ts +0 -24
  475. package/dist/Components/Input/Input/InputProps.js +0 -2
  476. package/dist/Components/ProductCard/productCardFixtures.d.ts +0 -7
  477. package/dist/Components/ProductCard/productCardFixtures.js +0 -61
  478. package/dist/esm/Components/Buttons/Buttons.js +0 -4
  479. package/dist/esm/Components/Common/ErrorComponent.js +0 -14
  480. package/dist/esm/Components/Common/FormattedDescription.js +0 -60
  481. package/dist/esm/Components/Common/Label.js +0 -10
  482. package/dist/esm/Components/Input/Input/Input.js +0 -37
  483. package/dist/esm/Components/Input/Input/InputProps.js +0 -1
  484. package/dist/esm/Components/ProductCard/productCardFixtures.js +0 -58
  485. package/dist/esm/services/feedback.js +0 -15
  486. package/dist/services/feedback.d.ts +0 -12
  487. package/dist/services/feedback.js +0 -18
  488. /package/dist/Components/{Buttons/ButtonsProps.js → Common/dataAttributes.js} +0 -0
  489. /package/dist/esm/Components/{Buttons/ButtonsProps.js → Common/dataAttributes.js} +0 -0
@@ -50,30 +50,37 @@ export const shortcutKeys = (shortcut, isApple = isAppleNow()) => {
50
50
  return parts.map((p, i) => { var _a; return (i === parts.length - 1 ? p.toUpperCase() : ((_a = table[p]) !== null && _a !== void 0 ? _a : p.toUpperCase())); });
51
51
  };
52
52
  export const formatShortcut = (shortcut, isApple = isAppleNow()) => shortcutKeys(shortcut, isApple).join(isApple ? "" : "+");
53
- /**
54
- * Derives every app's origin from the host the consumer is already served on, so one deployment
55
- * variable keeps dev, test and prod in step. An app may still carry its own `url`, which wins.
56
- */
57
- export const buildSuiteApps = (apps, { baseUrl, baseSubdomain }) => {
58
- let base;
53
+ const parseAbsolute = (option, raw) => {
59
54
  try {
60
- base = new URL(baseUrl.trim());
55
+ return new URL(raw.trim());
61
56
  }
62
57
  catch {
63
- throw new Error(`[AppSwitcher] buildSuiteApps: baseUrl ${JSON.stringify(baseUrl)} is not an absolute URL.`);
58
+ throw new Error(`[AppSwitcher] buildSuiteApps: ${option} ${JSON.stringify(raw)} is not an absolute URL.`);
64
59
  }
65
- const labels = base.hostname.split(".");
60
+ };
61
+ /**
62
+ * Derives every app's origin from the host the consumer is already served on, so one deployment
63
+ * variable keeps dev, test and prod in step. An app may still carry its own `url`, which wins.
64
+ */
65
+ export const buildSuiteApps = (apps, { baseUrl, baseSubdomain, devFallbackBaseUrl }) => {
66
+ const base = parseAbsolute("baseUrl", baseUrl);
67
+ const hostHasLabel = base.hostname.split(".").includes(baseSubdomain);
68
+ const useFallback = !hostHasLabel && devFallbackBaseUrl !== undefined;
69
+ const source = useFallback ? parseAbsolute("devFallbackBaseUrl", devFallbackBaseUrl) : base;
70
+ const labels = source.hostname.split(".");
66
71
  const at = labels.indexOf(baseSubdomain);
67
72
  return apps.map(({ subdomain, url, ...app }) => {
68
73
  if (url)
69
74
  return { ...app, url: url.trim() };
75
+ if (useFallback && subdomain === baseSubdomain)
76
+ return { ...app, url: base.origin };
70
77
  // Without the label there is nothing to swap, and every app would silently share one origin.
71
78
  if (at === -1) {
72
79
  throw new Error(`[AppSwitcher] buildSuiteApps: ${JSON.stringify(baseSubdomain)} is not a label in ` +
73
- `"${base.hostname}", so ${JSON.stringify(app.name)} has no derivable url. ` +
80
+ `"${source.hostname}", so ${JSON.stringify(app.name)} has no derivable url. ` +
74
81
  `Give that app an explicit url, or pass a baseUrl that contains the label.`);
75
82
  }
76
- const next = new URL(base.toString());
83
+ const next = new URL(source.toString());
77
84
  next.hostname = labels.map((l, i) => (i === at ? subdomain : l)).join(".");
78
85
  return { ...app, url: next.origin };
79
86
  });
@@ -0,0 +1,67 @@
1
+ import { Building2, Headphones, LayoutGrid, Megaphone, Receipt, Users } from "lucide-react";
2
+ import { buildSuiteApps } from "./AppSwitcherProps.js";
3
+ /** The default Pixelize app list; `resolveSuiteApps` `overrides` change a single app without forking it. */
4
+ export const PIXELIZE_SUITE = [
5
+ {
6
+ id: "crm",
7
+ subdomain: "crm",
8
+ name: "CRM",
9
+ description: "Leads, deals and pipeline",
10
+ icon: LayoutGrid,
11
+ keywords: ["leads", "deals", "pipeline", "contacts", "sales"],
12
+ },
13
+ {
14
+ id: "account",
15
+ subdomain: "account",
16
+ name: "Account",
17
+ description: "Organization and members",
18
+ icon: Building2,
19
+ keywords: ["organization", "members", "roles", "settings", "profile"],
20
+ },
21
+ {
22
+ id: "tickets",
23
+ subdomain: "tickets",
24
+ name: "Tickets",
25
+ description: "Support requests and queues",
26
+ icon: Headphones,
27
+ keywords: ["support", "helpdesk", "issues", "sla"],
28
+ },
29
+ {
30
+ id: "billing",
31
+ subdomain: "billing",
32
+ name: "Billing",
33
+ description: "Invoices and plans",
34
+ icon: Receipt,
35
+ keywords: ["invoices", "plans", "payments", "subscription"],
36
+ preRelease: true,
37
+ },
38
+ {
39
+ id: "hrms",
40
+ subdomain: "hrms",
41
+ name: "HRMS",
42
+ description: "People, leave and payroll",
43
+ icon: Users,
44
+ keywords: ["people", "employees", "leave", "attendance", "payroll"],
45
+ preRelease: true,
46
+ },
47
+ {
48
+ id: "social",
49
+ subdomain: "social",
50
+ name: "Social",
51
+ description: "Campaigns and inbox",
52
+ icon: Megaphone,
53
+ keywords: ["campaigns", "posts", "inbox", "marketing"],
54
+ preRelease: true,
55
+ },
56
+ ];
57
+ /** The catalogue as a ready `AppSwitcher` list: pre-release filtering, per-app `urls` and `overrides`, then `buildSuiteApps`. */
58
+ export const resolveSuiteApps = ({ currentAppId, isProduction, urls, overrides, ...urlOptions }) => {
59
+ const sources = PIXELIZE_SUITE.flatMap((entry) => {
60
+ const { preRelease, ...app } = { ...entry, ...overrides === null || overrides === void 0 ? void 0 : overrides[entry.id] };
61
+ if (isProduction && preRelease && app.id !== currentAppId)
62
+ return [];
63
+ const url = urls === null || urls === void 0 ? void 0 : urls[app.id];
64
+ return [url ? { ...app, url } : app];
65
+ });
66
+ return buildSuiteApps(sources, urlOptions);
67
+ };
@@ -7,7 +7,7 @@ import { FONT_SIZE_OPTIONS } from "../../Theme/provider/fontSize.js";
7
7
  import { lightPalettes } from "../../Theme/tokens/brands/index.js";
8
8
  import { CHROME_RULE, ruleInk } from "../../Theme/tokens/builders/outlineRung.js";
9
9
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
10
- import SelectV2 from "../SelectV2/SelectV2.js";
10
+ import Select from "../Select/Select.js";
11
11
  const FieldLabel = ({ children }) => {
12
12
  const { colors } = useCustomTheme();
13
13
  return (_jsx(Text, { fontSize: "sm", fontWeight: 500, color: colors.textMuted, mb: 2, children: children }));
@@ -24,11 +24,11 @@ export const AppearanceSettings = ({ brand, fontSize, onBrandChange, onFontSizeC
24
24
  const themeLabel = (_a = labels === null || labels === void 0 ? void 0 : labels.theme) !== null && _a !== void 0 ? _a : "Theme";
25
25
  const colorModeLabel = (_b = labels === null || labels === void 0 ? void 0 : labels.colorMode) !== null && _b !== void 0 ? _b : "Color mode";
26
26
  const fontSizeLabel = (_c = labels === null || labels === void 0 ? void 0 : labels.fontSize) !== null && _c !== void 0 ? _c : "Font Size";
27
- return (_jsxs(VStack, { align: "stretch", spacing: 4, children: [showBrand && (_jsxs(Box, { children: [_jsx(FieldLabel, { children: themeLabel }), _jsx(SelectV2, { options: brandOptions, value: brand, isSearchable: false, size: size, "aria-label": themeLabel, "data-testid": "appearance-brand-select", onChange: (option) => {
27
+ return (_jsxs(VStack, { align: "stretch", spacing: 4, children: [showBrand && (_jsxs(Box, { children: [_jsx(FieldLabel, { children: themeLabel }), _jsx(Select, { native: false, options: brandOptions, value: brand, isSearchable: false, size: size, "aria-label": themeLabel, "data-testid": "appearance-brand-select", onChange: (option) => {
28
28
  if (!option)
29
29
  return;
30
30
  onBrandChange === null || onBrandChange === void 0 ? void 0 : onBrandChange(String(option.id));
31
- } })] })), showColorMode && (_jsxs(Box, { children: [_jsx(FieldLabel, { children: colorModeLabel }), _jsx(Box, { "data-testid": "appearance-mode-switcher", children: _jsx(ThemeSwitcher, { variant: "segmented", showBrandPicker: false, size: size, "aria-label": colorModeLabel }) })] })), showFontSize && (_jsxs(Box, { children: [_jsx(FieldLabel, { children: fontSizeLabel }), _jsx(SelectV2, { options: FONT_SIZE_OPTIONS, value: fontSize, isSearchable: false, size: size, "aria-label": fontSizeLabel, "data-testid": "appearance-font-size-select",
31
+ } })] })), showColorMode && (_jsxs(Box, { children: [_jsx(FieldLabel, { children: colorModeLabel }), _jsx(Box, { "data-testid": "appearance-mode-switcher", children: _jsx(ThemeSwitcher, { variant: "segmented", showBrandPicker: false, size: size, "aria-label": colorModeLabel }) })] })), showFontSize && (_jsxs(Box, { children: [_jsx(FieldLabel, { children: fontSizeLabel }), _jsx(Select, { native: false, options: FONT_SIZE_OPTIONS, value: fontSize, isSearchable: false, size: size, "aria-label": fontSizeLabel, "data-testid": "appearance-font-size-select",
32
32
  // Each row previews the size it sets, so the list is self-explaining.
33
33
  renderOption: (option) => (_jsx(Text, { as: "span", style: { fontSize: String(option.id) }, children: option.label })), onChange: (option) => {
34
34
  if (!option)
@@ -1,5 +1,5 @@
1
1
  import { resolveFilledSurface } from "../../Theme/tokens/builders/filledSurface.js";
2
- const AVATAR_SCALE_KEYS = [
2
+ export const AVATAR_SCALE_KEYS = [
3
3
  "red", "orange", "yellow", "green", "teal", "blue", "cyan", "purple", "pink",
4
4
  ];
5
5
  const hashSeed = (seed) => {
@@ -10,11 +10,11 @@ const hashSeed = (seed) => {
10
10
  };
11
11
  export const avatarScaleKeyFor = (seed) => AVATAR_SCALE_KEYS[hashSeed(seed) % AVATAR_SCALE_KEYS.length];
12
12
  // Always via resolveFilledSurface, never scale[500] + a guessed ink.
13
- export const resolveAvatarColorway = (seed, colors) => {
14
- const scale = colors[avatarScaleKeyFor(seed)];
15
- const { fill, color } = resolveFilledSurface(scale, colors);
13
+ export const avatarColorwayFor = (key, colors) => {
14
+ const { fill, color } = resolveFilledSurface(colors[key], colors);
16
15
  return { bg: fill, color };
17
16
  };
17
+ export const resolveAvatarColorway = (seed, colors) => avatarColorwayFor(avatarScaleKeyFor(seed), colors);
18
18
  export const initialsFor = (name) => {
19
19
  const words = name.trim().split(/\s+/).filter(Boolean);
20
20
  if (words.length === 0)
@@ -5,6 +5,8 @@ import { focusVisibleStyles } from "../../Theme/chakra/focusRing.styles.js";
5
5
  import { listRowBackgrounds } from "../../Theme/tokens/builders/rowStates.js";
6
6
  import { MOTION_OK_QUERY, reducedMotionSx } from "../../Theme/chakra/motion.js";
7
7
  import { BUTTON_SIZES, DEFAULT_CONTROL_SIZE, MOTION_PRESS_SCALE, transitionFor } from "../../Theme/tokens/primitives/index.js";
8
+ import { BORDER_WIDTHS } from "../../Theme/tokens/primitives/borderWidths.js";
9
+ import { DISABLED_OPACITY } from "../../Theme/tokens/primitives/states.js";
8
10
  const BUTTON_TRANSITION = [
9
11
  transitionFor(["background-color", "border-color", "color", "box-shadow", "filter"]),
10
12
  transitionFor(["transform"], "fast", "out"),
@@ -24,6 +26,7 @@ const controlSize = (size) => {
24
26
  // NOTE: a bare button sits on the canvas, a card or an overlay; dark overlays are the hardest plane.
25
27
  const onCanvasText = (theme, colorScheme) => accentTextOnPlanes(theme.colors[colorScheme], [
26
28
  theme.colors.backgroundColor.main,
29
+ theme.colors.backgroundColor.base,
27
30
  theme.colors.background[50],
28
31
  theme.colors.surfaceRaised,
29
32
  ]);
@@ -72,7 +75,7 @@ export const Button = {
72
75
  transition: BUTTON_TRANSITION,
73
76
  ...reducedMotionSx(),
74
77
  _disabled: {
75
- opacity: 0.6,
78
+ opacity: DISABLED_OPACITY,
76
79
  cursor: "not-allowed",
77
80
  },
78
81
  ...focusRing(theme),
@@ -111,7 +114,7 @@ export const Button = {
111
114
  outline: ({ theme, colorScheme = "primary" }) => {
112
115
  const ink = onCanvasText(theme, colorScheme);
113
116
  return {
114
- border: "0.0625rem solid",
117
+ border: `${BORDER_WIDTHS.hairline} solid`,
115
118
  borderColor: ink,
116
119
  color: ink,
117
120
  bg: "transparent",
@@ -5,6 +5,8 @@ import { useCustomTheme } from "../../Theme/useCustomTheme.js";
5
5
  import { resolveGradient, gradientCss } from "../../Theme/tokens/builders/gradientInk.js";
6
6
  import { hexToRgb } from "../../Theme/tokens/builders/color.js";
7
7
  import { rafThrottle } from "../../Utils/rafThrottle.js";
8
+ import { transitionFor } from "../../Theme/tokens/primitives/motion.js";
9
+ const BACKGROUND_TRANSITION = transitionFor(["background"]);
8
10
  export default function ButtonGroupIcon({ leftIcon, rightIcon, onLeftIconClick, onRightIconClick, buttonText, onButtonClick, onButtongroupClick, size, variant, color, buttonGroupStyle, buttonGroupLeftIconStyle, buttonGroupRightIconStyle, buttonStyle, onBlurLeftIcon, onBlurRightIcon, dropdownOptions, // New prop for dropdown options
9
11
  onDropdownOptionClick, // New prop to handle option clicks
10
12
  rightIconDropdown, menulistStyle, menuItemStyle, isLoading, divider = true, leftIconLoading, RightIconLoading, }) {
@@ -73,7 +75,7 @@ rightIconDropdown, menulistStyle, menuItemStyle, isLoading, divider = true, left
73
75
  fontSize: "xs-plus",
74
76
  fontWeight: 500,
75
77
  color: theme.colors.text[700],
76
- transition: "background 0.12s",
78
+ transition: BACKGROUND_TRANSITION,
77
79
  "& svg": { width: "16px", height: "16px" },
78
80
  ...(divider
79
81
  ? {
@@ -4,10 +4,12 @@ import { Box, Flex, Grid, Text } from "@chakra-ui/react";
4
4
  import { ChevronLeft, ChevronRight } from "lucide-react";
5
5
  import Button from "../Button/Button.js";
6
6
  import Skeletons from "../Skeletons/Skeletons.js";
7
+ import VisuallyHidden from "../VisuallyHidden/VisuallyHidden.js";
7
8
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
8
9
  import { focusVisibleStyles, insetFocusRingShadow } from "../../Theme/chakra/focusRing.styles.js";
9
10
  import { resolveSoftTone, toneScale } from "../../Theme/tokens/builders/tone.js";
10
11
  import { dayKey, eventsOnDay, formatFullDate, formatTitle, isNavKey, isSameDay, isWeekend, layoutWeek, moveFocus, shiftAnchor, startOfDay, visibleWeeks, weekdayLabels, } from "./calendarMath.js";
12
+ import { isActivationKey } from "../Common/activationKey.js";
11
13
  const plural = (n, one, many) => `${n} ${n === 1 ? one : many}`;
12
14
  const DEFAULT_LABELS = {
13
15
  today: "Today",
@@ -113,7 +115,7 @@ const CalendarGrid = ({ view, date, events, onViewChange, onDateChange, onEventC
113
115
  onDateChange === null || onDateChange === void 0 ? void 0 : onDateChange(next);
114
116
  return;
115
117
  }
116
- if ((e.key === "Enter" || e.key === " ") && onDateChange) {
118
+ if (isActivationKey(e) && onDateChange) {
117
119
  e.preventDefault();
118
120
  onDateChange(cellDate);
119
121
  }
@@ -156,9 +158,9 @@ const CalendarGrid = ({ view, date, events, onViewChange, onDateChange, onEventC
156
158
  cellRefs.current.set(key, el);
157
159
  else
158
160
  cellRefs.current.delete(key);
159
- }, "data-date": key, "aria-label": label, "aria-current": isToday ? "date" : undefined, tabIndex: active ? 0 : -1, onFocus: () => setFocusedKey(key), onKeyDown: (e) => handleCellKeyDown(e, day), position: "relative", minH: MIN_CELL_HEIGHT[view], p: 1, bg: surface, borderRight: "1px solid", borderBottom: "1px solid", borderColor: border, outline: "none", _focusVisible: {
161
+ }, "data-date": key, "aria-current": isToday ? "date" : undefined, tabIndex: active ? 0 : -1, onFocus: () => setFocusedKey(key), onKeyDown: (e) => handleCellKeyDown(e, day), position: "relative", minH: MIN_CELL_HEIGHT[view], p: 1, bg: surface, borderRight: "1px solid", borderBottom: "1px solid", borderColor: border, outline: "none", _focusVisible: {
160
162
  boxShadow: insetFocusRingShadow(colors),
161
- }, children: [_jsx(Text, { as: "span", display: "inline-flex", alignItems: "center", justifyContent: "center", minW: "1.5rem", h: "1.5rem", px: 1, borderRadius: "full", fontSize: "xs-plus", fontWeight: isToday ? 700 : 500, color: isToday ? colors.accentText : inMonth ? colors.header[900] : colors.textMuted, boxShadow: isToday ? `inset 0 0 0 1.5px ${colors.accentText}` : undefined, "aria-hidden": true, children: day.getDate() }), body] }, key));
163
+ }, children: [_jsx(Text, { as: "span", display: "inline-flex", alignItems: "center", justifyContent: "center", minW: "1.5rem", h: "1.5rem", px: 1, borderRadius: "full", fontSize: "xs-plus", fontWeight: isToday ? 700 : 500, color: isToday ? colors.accentText : inMonth ? colors.header[900] : colors.textMuted, boxShadow: isToday ? `inset 0 0 0 1.5px ${colors.accentText}` : undefined, "aria-hidden": true, children: day.getDate() }), _jsx(VisuallyHidden, { position: "absolute", children: label }), body] }, key));
162
164
  };
163
165
  return (_jsxs(Box, { children: [_jsxs(Flex, { align: "center", justify: "space-between", wrap: "wrap", gap: 2, mb: 3, children: [_jsxs(Flex, { align: "center", gap: 2, children: [onDateChange ? (_jsxs(_Fragment, { children: [_jsx(Button, { label: text.today, size: "sm", variant: "outline", onClick: () => onDateChange(startOfDay(new Date())) }), _jsx(Button, { "aria-label": text.previous, size: "sm", variant: "ghost", leftIcon: _jsx(ChevronLeft, { size: 16, "aria-hidden": true }), onClick: () => onDateChange(shiftAnchor(view, anchor, -1)) }), _jsx(Button, { "aria-label": text.next, size: "sm", variant: "ghost", leftIcon: _jsx(ChevronRight, { size: 16, "aria-hidden": true }), onClick: () => onDateChange(shiftAnchor(view, anchor, 1)) })] })) : null, _jsx(Text, { as: "h2", fontSize: "md", fontWeight: 600, color: colors.header[900], children: title })] }), onViewChange ? (_jsx(Flex, { role: "group", "aria-label": text[view], gap: 1, children: VIEWS.map((v) => (_jsx(Button, { label: text[v], size: "sm", variant: v === view ? "solid" : "outline", "aria-pressed": v === view, onClick: () => onViewChange(v) }, v))) })) : null] }), _jsx(Box, { overflowX: "auto", children: _jsxs(Box, { role: "grid", "aria-label": title, "aria-busy": isLoading || undefined, "data-view": view, minW: view === "day" ? undefined : "42rem", borderTop: "1px solid", borderLeft: "1px solid", borderColor: border, borderRadius: "lg", overflow: "hidden", children: [_jsx(Grid, { role: "row", templateColumns: template, children: headerDays.map((i) => (_jsx(Box, { role: "columnheader", "aria-label": weekdayLong[i], px: 2, py: 1, fontSize: "xs", fontWeight: 600, color: colors.textMuted, bg: colors.backgroundColor.main, borderRight: "1px solid", borderBottom: "1px solid", borderColor: border, children: weekdayShort[i] }, i))) }), weeks.map((week, weekIndex) => {
164
166
  const layout = layoutWeek(week, shownEvents, maxLanes);
@@ -10,6 +10,7 @@ const PADDING_VALUES = {
10
10
  md: "1rem 1.25rem",
11
11
  lg: "1.25rem 1.5rem",
12
12
  };
13
+ /** Themed card; `header` and `footer` render outside the body, `padding` sets density. */
13
14
  const Card = forwardRef(function Card({ header, footer, children, color, colorScheme, direction = "column", align, justify, bodyProps, padding, ...rest }, ref) {
14
15
  const cardProps = { ...rest };
15
16
  delete cardProps.dividercolor;
@@ -3,6 +3,8 @@ import { resolveHoverTint } from "../../Theme/tokens/builders/outlineRung.js";
3
3
  import { onFilled } from "../../Theme/tokens/builders/accentText.js";
4
4
  import { focusVisibleRing } from "../../Theme/chakra/focusRing.styles.js";
5
5
  import { fieldHoverBorder } from "../Common/fieldStyles.js";
6
+ import { transitionFor } from "../../Theme/tokens/primitives/motion.js";
7
+ const BACKGROUND_BORDER_COLOR_BOX_SHADOW_TRANSITION = transitionFor(["background", "border-color", "box-shadow"]);
6
8
  // One fill rule for every colour scheme, via resolveFilledSurface — was a flat [600].
7
9
  export const Checkbox = {
8
10
  baseStyle: ({ theme, colorScheme = "primary" }) => {
@@ -19,7 +21,7 @@ export const Checkbox = {
19
21
  borderWidth: "1px",
20
22
  borderRadius: "base",
21
23
  borderColor: fieldHoverBorder(theme.colors),
22
- transition: "background 0.15s, border-color 0.15s, box-shadow 0.15s",
24
+ transition: BACKGROUND_BORDER_COLOR_BOX_SHADOW_TRANSITION,
23
25
  _invalid: {
24
26
  borderColor: theme.colors.semanticText.error,
25
27
  },
@@ -3,25 +3,28 @@ import { Children, createContext, isValidElement, useContext, useMemo, useState
3
3
  import { Box, Flex } from "@chakra-ui/react";
4
4
  import { Check } from "lucide-react";
5
5
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
6
+ import { DISABLED_OPACITY } from "../../Theme/tokens/primitives/states.js";
6
7
  import { transitionFor } from "../../Theme/tokens/primitives/motion.js";
7
8
  import { reducedMotionSx } from "../../Theme/chakra/motion.js";
8
9
  import { focusVisibleRing } from "../../Theme/chakra/focusRing.styles.js";
9
10
  import { onFilled } from "../../Theme/tokens/builders/accentText.js";
11
+ import { tonalHover } from "./tonalHover.js";
12
+ import { isActivationKey } from "../Common/activationKey.js";
10
13
  const GroupContext = createContext(null);
11
14
  export const useSelectableGroup = () => useContext(GroupContext);
12
15
  const firstEnabledValue = (children) => {
13
16
  for (const child of Children.toArray(children)) {
14
17
  if (!isValidElement(child))
15
18
  continue;
16
- const { value, disabled } = child.props;
17
- if (typeof value === "string" && !disabled)
19
+ const { value, disabled, isDisabled } = child.props;
20
+ if (typeof value === "string" && !disabled && !isDisabled)
18
21
  return value;
19
22
  }
20
23
  return undefined;
21
24
  };
22
25
  const STEP = { ArrowDown: 1, ArrowRight: 1, ArrowUp: -1, ArrowLeft: -1 };
23
26
  /** Radiogroup with a roving tab stop; arrows move focus and selection together, like native radios. */
24
- export const SelectableGroup = ({ value, defaultValue, onValueChange, gap = 3, children, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "data-testid": testId, }) => {
27
+ export const SelectableGroup = ({ value, defaultValue, onValueChange, gap = 3, columns = 1, children, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "data-testid": testId, }) => {
25
28
  const [inner, setInner] = useState(defaultValue);
26
29
  const current = value !== null && value !== void 0 ? value : inner;
27
30
  const state = useMemo(() => ({
@@ -51,16 +54,16 @@ export const SelectableGroup = ({ value, defaultValue, onValueChange, gap = 3, c
51
54
  if (next !== null)
52
55
  state.select(next);
53
56
  };
54
- return (_jsx(GroupContext.Provider, { value: state, children: _jsx(Flex, { role: "radiogroup", "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, direction: "column", gap: gap, onKeyDown: onKeyDown, "data-testid": testId, children: children }) }));
57
+ return (_jsx(GroupContext.Provider, { value: state, children: _jsx(Flex, { role: "radiogroup", "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, direction: "column", gap: gap, ...(columns > 1 ? { display: "grid", gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))` } : {}), onKeyDown: onKeyDown, "data-testid": testId, children: children }) }));
55
58
  };
56
59
  /** Tonal card surface; selection is a 2px ink ring plus a check, never colour alone. */
57
60
  export const selectableSurface = (colors, { selected, disabled, interactive, ringed }) => ({
58
61
  bg: colors.background[100],
59
62
  borderRadius: "2xl",
60
63
  boxShadow: selected ? `inset 0 0 0 2px ${colors.header[900]}` : "none",
61
- opacity: disabled ? 0.6 : 1,
64
+ opacity: disabled ? DISABLED_OPACITY : 1,
62
65
  transition: transitionFor(["background-color", "box-shadow"]),
63
- _hover: interactive && !selected && !disabled ? { bg: colors.background[200] } : undefined,
66
+ _hover: interactive && !selected && !disabled ? { bg: tonalHover(colors) } : undefined,
64
67
  sx: { ...(ringed ? focusVisibleRing(colors) : {}), ...reducedMotionSx() },
65
68
  });
66
69
  /** The 20px circle that carries selection state beside the text. */
@@ -93,7 +96,7 @@ export const useSelectable = ({ value, selected, disabled, onSelect, }) => {
93
96
  onKeyDown: (event) => {
94
97
  if (event.target !== event.currentTarget)
95
98
  return;
96
- if (event.key === " " || event.key === "Enter") {
99
+ if (isActivationKey(event)) {
97
100
  event.preventDefault();
98
101
  choose();
99
102
  }
@@ -0,0 +1,2 @@
1
+ import { bandOn } from "../../Theme/tokens/builders/planeStep.js";
2
+ export const tonalHover = (colors, rest = colors.background[100], fill = colors.background[200]) => bandOn(fill, rest);
@@ -3,7 +3,8 @@ import { useId } from "react";
3
3
  import { Box, Flex, Text } from "@chakra-ui/react";
4
4
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
5
5
  import { RadioIndicator, selectableSurface, useSelectable } from "../CheckoutKit/selectable.js";
6
- const ChoiceCard = ({ value, label, description, icon, disabled = false, "data-testid": testId }) => {
6
+ const ChoiceCard = ({ value, label, description, icon, disabled: disabledProp = false, isDisabled = false, "data-testid": testId }) => {
7
+ const disabled = disabledProp || isDisabled;
7
8
  const { colors } = useCustomTheme();
8
9
  const uid = useId();
9
10
  const labelId = `${uid}-label`;
@@ -3,15 +3,16 @@ import { Box, Icon } from "@chakra-ui/react";
3
3
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
4
4
  import { InfoIcon } from "lucide-react";
5
5
  import ToolTip from "../ToolTip/ToolTip.js";
6
+ import { fontSizes } from "../../Theme/tokens/primitives/typography.js";
6
7
  /** The one field-label look (13px / 500 / `text[700]`); `Label` and `TextLabel` both read it. */
7
8
  export const fieldLabelStyles = (colors) => ({
8
9
  color: colors.text[700],
9
10
  fontWeight: 500,
10
- fontSize: "0.8125rem",
11
+ fontSize: fontSizes["xs-plus"],
11
12
  lineHeight: "1.2",
12
13
  mb: "0.375rem",
13
14
  });
14
- /** Renders a real `<label htmlFor>` only when `id` is given, else a `<span>` — not a substitute for `Label` (Common/Label.tsx), which always renders a `FormLabel`. */
15
+ /** Renders a real `<label htmlFor>` only when `id` is given, else a `<span>`. */
15
16
  export const TextLabel = ({ label, id, isRequired = false, isInformation = false, informationMessage = "", fontSize, showTooltip, tooltipLabel, clampLines, inline = false, }) => {
16
17
  const theme = useCustomTheme();
17
18
  const clampStyles = clampLines ? {
@@ -30,7 +31,7 @@ export const TextLabel = ({ label, id, isRequired = false, isInformation = false
30
31
  mb: inline ? 0 : base.mb,
31
32
  fontSize: fontSize !== null && fontSize !== void 0 ? fontSize : base.fontSize,
32
33
  };
33
- const content = (_jsxs(Box, { as: "span", display: "inline-flex", alignItems: "center", gap: "0.35rem", children: [showTooltip ? (_jsx(ToolTip, { label: tooltipLabel !== null && tooltipLabel !== void 0 ? tooltipLabel : label, hasArrow: true, placement: "top", fontSize: "xs", children: _jsx(Box, { as: "span", sx: clampStyles, children: label }) })) : (_jsx(Box, { as: "span", sx: clampStyles, children: label })), isRequired && (_jsx("span", { style: { color: theme.colors.semanticText.error, marginLeft: "0.125rem" }, children: "*" })), isInformation && informationMessage && (_jsx(ToolTip, { label: informationMessage, hasArrow: true, placement: "top", fontSize: "xs", children: _jsx(Icon, { as: InfoIcon, color: theme.colors.text[700], boxSize: 3.5 }) }))] }));
34
+ const content = (_jsxs(Box, { as: "span", display: "inline-flex", alignItems: "center", gap: "0.35rem", children: [showTooltip ? (_jsx(ToolTip, { label: tooltipLabel !== null && tooltipLabel !== void 0 ? tooltipLabel : label, hasArrow: true, placement: "top", fontSize: "xs", children: _jsx(Box, { as: "span", sx: clampStyles, children: label }) })) : (_jsx(Box, { as: "span", sx: clampStyles, children: label })), isRequired && (_jsx("span", { "aria-hidden": "true", style: { color: theme.colors.semanticText.error, marginLeft: "0.125rem" }, children: "*" })), isInformation && informationMessage && (_jsx(ToolTip, { label: informationMessage, hasArrow: true, placement: "top", fontSize: "xs", children: _jsx(Icon, { as: InfoIcon, color: theme.colors.text[700], boxSize: 3.5 }) }))] }));
34
35
  // NOTE: real <label> only with a control id — Checkbox/Radio render this inline inside their own <label>.
35
36
  return id ? (_jsx(Box, { as: "label", htmlFor: id, ...wrapperStyles, children: content })) : (_jsx(Box, { as: "span", ...wrapperStyles, children: content }));
36
37
  };
@@ -6,8 +6,7 @@ const UnregisteredHelperText = ({ helperText, id, style }) => {
6
6
  const styles = useFormControlStyles();
7
7
  return (_jsx(chakra.div, { id: id, ...style, __css: styles.helperText, className: "chakra-form__helper-text", children: helperText }));
8
8
  };
9
- /** `id` is optional — pass one to own aria-describedby; omitted, a FormControl wires its own. */
10
- /** Renders `helperText` unconditionally; prefer `FieldMessage`, which swaps it for the error. */
9
+ /** Always renders `helperText`; prefer `FieldMessage`, which swaps it for the error. */
11
10
  const HelperText = ({ helperText, id }) => {
12
11
  const theme = useCustomTheme();
13
12
  const field = useFormControlContext();
@@ -0,0 +1,7 @@
1
+ export const isActivationKey = (event) => event.key === "Enter" || event.key === " ";
2
+ export const onActivationKey = (activate) => (event) => {
3
+ if (!isActivationKey(event))
4
+ return;
5
+ event.preventDefault();
6
+ activate(event);
7
+ };
@@ -1,8 +1,9 @@
1
+ import { fontSizes } from "../../Theme/tokens/primitives/typography.js";
1
2
  export const FIELD_MESSAGE_GAP = "0.25rem";
2
3
  /** Shared type for helper and error text, so switching between them never shifts the row. */
3
4
  export const fieldMessageStyles = (colors) => ({
4
5
  mt: FIELD_MESSAGE_GAP,
5
- fontSize: "0.75rem",
6
+ fontSize: fontSizes.xs,
6
7
  lineHeight: "1.125rem",
7
8
  color: colors.textMuted,
8
9
  });
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ const isReactElement = (child) => child !== null && typeof child === "object" && "type" in child;
3
+ // NOTE: matches by element type through nested Fragments, so `<>{cond && <Footer />}</>` is not dropped.
4
+ export const findSlot = (children, slot) => {
5
+ for (const child of React.Children.toArray(children)) {
6
+ if (!isReactElement(child))
7
+ continue;
8
+ if (child.type === slot)
9
+ return child;
10
+ if (child.type === React.Fragment) {
11
+ const nested = findSlot(child.props.children, slot);
12
+ if (nested)
13
+ return nested;
14
+ }
15
+ }
16
+ return undefined;
17
+ };
@@ -0,0 +1,3 @@
1
+ import { FOCUS_HALO_WIDTH, FOCUS_RING_WIDTH } from "../../Theme/chakra/focusRing.styles.js";
2
+ // NOTE: for chrome painted on a fixed dark surface, where the palette's focusRing pair is tuned for the page canvas instead.
3
+ export const surfaceFocusRing = (surface, ring) => `0 0 0 ${FOCUS_HALO_WIDTH}px ${surface}, 0 0 0 ${FOCUS_RING_WIDTH}px ${ring}`;
@@ -1,19 +1,31 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useRef, useState } from "react";
3
- import { Modal, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, ModalBody, Flex, HStack, VStack, Text, } from "@chakra-ui/react";
3
+ import { Modal, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, ModalBody, Box, Flex, HStack, VStack, Text, } from "@chakra-ui/react";
4
4
  import { AlertTriangle } from "lucide-react";
5
5
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
6
6
  import { raisedRule } from "../../Theme/tokens/builders/surfaceRaised.js";
7
+ import { resolveSoftTone } from "../../Theme/tokens/builders/tone.js";
7
8
  import Button from "../Button/Button.js";
8
9
  import TextInput from "../Input/TextInput.js";
9
- const ConfirmDialog = ({ isOpen, onClose, onConfirm, title, children, icon, iconBg, iconColor, tone = "destructive", cancelLabel = "Cancel", confirmLabel = "Confirm", confirmIcon, isConfirmLoading = false, disableCancelWhilePending = true, confirmationText, confirmationLabel, bodyLayout = "flush", bodySpacing = 4, actionsPt = 0, focusCancelOnOpen = true, isCentered = true, closeOnEsc, closeOnOverlayClick, }) => {
10
+ const ConfirmDialog = ({ isOpen, onClose, onConfirm, title, children, icon, iconBg, iconColor, entityName, entityKind, dependents, consequence, alternative, isConfirmDisabled: isConfirmHeld = false, tone = "destructive", cancelLabel = "Cancel", confirmLabel = "Confirm", confirmIcon, isConfirmLoading = false, disableCancelWhilePending = true, confirmationText, confirmationLabel, bodyLayout = "flush", bodySpacing = 4, actionsPt = 0, focusCancelOnOpen = true, isCentered = true, closeOnEsc, closeOnOverlayClick, }) => {
10
11
  const { colors } = useCustomTheme();
11
12
  const cancelRef = useRef(null);
12
13
  const [typedText, setTypedText] = useState("");
13
14
  const requiresTypedConfirmation = confirmationText !== undefined;
14
- const isConfirmDisabled = isConfirmLoading || (requiresTypedConfirmation && typedText !== confirmationText);
15
- const actions = (_jsxs(HStack, { justifyContent: "flex-end", spacing: 3, pt: actionsPt, children: [_jsx(Button, { ref: cancelRef, label: cancelLabel, onClick: onClose, variant: "outline", colorScheme: "gray", size: "sm", isDisabled: disableCancelWhilePending && isConfirmLoading }), _jsx(Button, { label: confirmLabel, onClick: onConfirm, colorScheme: tone === "destructive" ? "red" : "primary", size: "sm", isLoading: isConfirmLoading, isDisabled: isConfirmDisabled, leftIcon: confirmIcon })] }));
16
- const body = requiresTypedConfirmation ? (_jsxs(_Fragment, { children: [children, _jsx(TextInput, { label: confirmationLabel, value: typedText, onChange: (event) => setTypedText(event.target.value) })] })) : (children);
17
- return (_jsxs(Modal, { isOpen: isOpen, onClose: onClose, isCentered: isCentered, closeOnEsc: closeOnEsc, closeOnOverlayClick: closeOnOverlayClick, initialFocusRef: focusCancelOnOpen ? cancelRef : undefined, children: [_jsx(ModalOverlay, { backdropFilter: "blur(4px)" }), _jsxs(ModalContent, { bg: colors.surfaceRaised, borderRadius: "xl", overflow: "hidden", children: [_jsxs(ModalHeader, { borderBottom: "1px solid", borderColor: raisedRule(colors), display: "flex", alignItems: "center", gap: 3, children: [_jsx(Flex, { align: "center", justify: "center", boxSize: "36px", borderRadius: "full", bg: iconBg, color: iconColor, children: icon !== null && icon !== void 0 ? icon : _jsx(AlertTriangle, { size: 18 }) }), _jsx(Text, { fontSize: "1.05rem", fontWeight: 600, children: title })] }), _jsx(ModalCloseButton, {}), _jsx(ModalBody, { py: 6, children: bodyLayout === "stack" ? (_jsxs(VStack, { spacing: bodySpacing, align: "stretch", children: [body, actions] })) : (_jsxs(_Fragment, { children: [body, actions] })) })] })] }));
15
+ const isAlternativeLoading = (alternative === null || alternative === void 0 ? void 0 : alternative.isLoading) === true;
16
+ const isConfirmDisabled = isConfirmLoading ||
17
+ isAlternativeLoading ||
18
+ isConfirmHeld ||
19
+ (requiresTypedConfirmation && typedText !== confirmationText);
20
+ const swatch = resolveSoftTone(colors, tone === "destructive" ? colors.semantic.error : colors.primary, colors.surfaceRaised);
21
+ const isEntityPrompt = entityName !== undefined;
22
+ const resolvedTitle = title !== null && title !== void 0 ? title : `Delete ${entityKind ? `${entityKind} ` : ""}"${entityName}"?`;
23
+ const dependentFacts = dependents ? dependents.filter(Boolean) : [];
24
+ const resolvedConsequence = consequence !== null && consequence !== void 0 ? consequence : (isEntityPrompt ? "This cannot be undone." : undefined);
25
+ const hasFacts = dependentFacts.length > 0 || resolvedConsequence !== undefined || (alternative === null || alternative === void 0 ? void 0 : alternative.description) !== undefined;
26
+ const actions = (_jsxs(HStack, { justifyContent: "flex-end", spacing: 3, pt: actionsPt, children: [_jsx(Button, { ref: cancelRef, label: cancelLabel, onClick: onClose, variant: "outline", colorScheme: "gray", size: "sm", isDisabled: disableCancelWhilePending && (isConfirmLoading || isAlternativeLoading) }), alternative && (_jsx(Button, { label: alternative.label, onClick: alternative.onSelect, colorScheme: "primary", size: "sm", isLoading: alternative.isLoading, loadingText: alternative.label, isDisabled: isConfirmLoading })), _jsx(Button, { label: confirmLabel, onClick: onConfirm, variant: alternative ? "outline" : undefined, colorScheme: tone === "destructive" ? "red" : "primary", size: "sm", isLoading: isConfirmLoading, isDisabled: isConfirmDisabled, leftIcon: confirmIcon })] }));
27
+ const facts = hasFacts && (_jsxs(VStack, { spacing: 3, align: "stretch", mt: bodyLayout === "flush" && children ? 3 : 0, mb: bodyLayout === "flush" ? 4 : 0, children: [dependentFacts.length > 0 && (_jsx(Text, { fontSize: "sm", fontWeight: 500, children: dependentFacts.join(" · ") })), resolvedConsequence !== undefined && (_jsx(Box, { fontSize: "sm", color: colors.textMuted, children: resolvedConsequence })), (alternative === null || alternative === void 0 ? void 0 : alternative.description) !== undefined && (_jsx(Box, { fontSize: "sm", p: 3, borderRadius: "md", border: "1px solid", borderColor: raisedRule(colors), children: alternative.description }))] }));
28
+ const body = requiresTypedConfirmation ? (_jsxs(_Fragment, { children: [children, facts, _jsx(TextInput, { label: confirmationLabel, value: typedText, onChange: (event) => setTypedText(event.target.value) })] })) : (_jsxs(_Fragment, { children: [children, facts] }));
29
+ return (_jsxs(Modal, { isOpen: isOpen, onClose: onClose, isCentered: isCentered, closeOnEsc: closeOnEsc, closeOnOverlayClick: closeOnOverlayClick, initialFocusRef: focusCancelOnOpen ? cancelRef : undefined, children: [_jsx(ModalOverlay, { backdropFilter: "blur(4px)" }), _jsxs(ModalContent, { bg: colors.surfaceRaised, borderRadius: "xl", overflow: "hidden", children: [_jsxs(ModalHeader, { borderBottom: "1px solid", borderColor: raisedRule(colors), display: "flex", alignItems: "center", gap: 3, children: [_jsx(Flex, { align: "center", justify: "center", boxSize: "36px", borderRadius: "full", bg: iconBg !== null && iconBg !== void 0 ? iconBg : swatch.bg, color: iconColor !== null && iconColor !== void 0 ? iconColor : swatch.fg, children: icon !== null && icon !== void 0 ? icon : _jsx(AlertTriangle, { size: 18 }) }), _jsx(Text, { fontSize: "1.05rem", fontWeight: 600, children: resolvedTitle })] }), _jsx(ModalCloseButton, {}), _jsx(ModalBody, { py: 6, children: bodyLayout === "stack" ? (_jsxs(VStack, { spacing: bodySpacing, align: "stretch", children: [body, actions] })) : (_jsxs(_Fragment, { children: [body, actions] })) })] })] }));
18
30
  };
19
31
  export default ConfirmDialog;
@@ -9,6 +9,8 @@ import { liftToContrast } from "../../Theme/tokens/builders/outlineRung.js";
9
9
  import { transitionFor } from "../../Theme/tokens/primitives/index.js";
10
10
  import { focusVisibleRing } from "../../Theme/chakra/focusRing.styles.js";
11
11
  import ToolTip from "../ToolTip/ToolTip.js";
12
+ import { onActivationKey } from "../Common/activationKey.js";
13
+ const BACKGROUND_TRANSITION = transitionFor(["background"]);
12
14
  /** Copies `value` to the clipboard in 3 layouts (icon/button/menu-item) — not a full share/export action. */
13
15
  const CopyButton = ({ value, variant = "icon", label = "Copy", copiedLabel = "Copied!", tooltip = "Copy", feedbackDuration = 1500, iconSize = 16, size = "sm", onCopy, onCopyError, }) => {
14
16
  const theme = useCustomTheme();
@@ -36,12 +38,7 @@ const CopyButton = ({ value, variant = "icon", label = "Copy", copiedLabel = "Co
36
38
  if (variant === "menu-item") {
37
39
  const hoverAccent = accentTextOnCanvas(theme.colors.primary, rowBackgrounds.active);
38
40
  const hoverSuccess = liftToContrast(theme.colors.semantic.success[500], rowBackgrounds.active, AA_NORMAL_TEXT);
39
- return (_jsxs(_Fragment, { children: [_jsxs(Flex, { role: "button", tabIndex: 0, align: "center", gap: "0.5rem", px: "12px", py: "8px", width: "100%", cursor: "pointer", borderRadius: "md", transition: "background 0.15s ease", _hover: { bg: rowBackgrounds.active }, _focusVisible: focusVisibleRing(theme.colors), onClick: handleCopy, onKeyDown: (e) => {
40
- if (e.key !== "Enter" && e.key !== " ")
41
- return;
42
- e.preventDefault();
43
- handleCopy(e);
44
- }, children: [copied ? (_jsx(Check, { size: iconSize, color: hoverSuccess })) : (_jsx(Copy, { size: iconSize, color: hoverAccent })), _jsx(Box, { fontSize: "sm", fontWeight: 500, color: copied ? hoverSuccess : hoverAccent, children: copied ? copiedLabel : label })] }), announcement] }));
41
+ return (_jsxs(_Fragment, { children: [_jsxs(Flex, { role: "button", tabIndex: 0, align: "center", gap: "0.5rem", px: "12px", py: "8px", width: "100%", cursor: "pointer", borderRadius: "md", transition: BACKGROUND_TRANSITION, _hover: { bg: rowBackgrounds.active }, _focusVisible: focusVisibleRing(theme.colors), onClick: handleCopy, onKeyDown: onActivationKey(handleCopy), children: [copied ? (_jsx(Check, { size: iconSize, color: hoverSuccess })) : (_jsx(Copy, { size: iconSize, color: hoverAccent })), _jsx(Box, { fontSize: "sm", fontWeight: 500, color: copied ? hoverSuccess : hoverAccent, children: copied ? copiedLabel : label })] }), announcement] }));
45
42
  }
46
43
  if (variant === "button") {
47
44
  return (_jsxs(_Fragment, { children: [_jsxs(Flex, { as: "button", align: "center", gap: "6px", px: "12px", py: "6px", borderRadius: "lg", border: "1px solid",
@@ -3,6 +3,7 @@ import { useId, useState } from "react";
3
3
  import { Box, Flex, Text, VisuallyHidden } from "@chakra-ui/react";
4
4
  import { BadgeCheck, ChevronDown, Ticket } from "lucide-react";
5
5
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
6
+ import { DISABLED_OPACITY } from "../../Theme/tokens/primitives/states.js";
6
7
  import { transitionFor } from "../../Theme/tokens/primitives/motion.js";
7
8
  import { NUMERIC_TEXT } from "../../Theme/tokens/primitives/typography.js";
8
9
  import { reducedMotionSx } from "../../Theme/chakra/motion.js";
@@ -11,6 +12,7 @@ import { resolveSoftTone, toneScale } from "../../Theme/tokens/builders/tone.js"
11
12
  import { formatPrice } from "../../Utils/price.js";
12
13
  import Button from "../Button/Button.js";
13
14
  import TextInput from "../Input/TextInput.js";
15
+ import { tonalHover } from "../CheckoutKit/tonalHover.js";
14
16
  const DEFAULT_LABELS = {
15
17
  prompt: "Have a coupon?",
16
18
  inputLabel: "Coupon code",
@@ -26,6 +28,7 @@ const normalise = (raw) => raw.replace(/\s+/g, "").toUpperCase();
26
28
  /** Coupon entry that stays out of the way: a quiet prompt row, a field with tap-to-apply offers, then an applied state with the saving. */
27
29
  const CouponField = ({ status = "idle", appliedCode, savedAmount, error, onApply, onRemove, suggestions, value, defaultValue = "", onValueChange, expanded, defaultExpanded = false, onExpandedChange, currency, locale, labels, "data-testid": testId, }) => {
28
30
  const { colors } = useCustomTheme();
31
+ const hoverFill = tonalHover(colors);
29
32
  const uid = useId();
30
33
  const panelId = `${uid}-panel`;
31
34
  const copy = { ...DEFAULT_LABELS, ...labels };
@@ -60,9 +63,9 @@ const CouponField = ({ status = "idle", appliedCode, savedAmount, error, onApply
60
63
  if (status === "applied" && appliedCode) {
61
64
  return (_jsxs(Flex, { align: "center", gap: 3, p: 3, pl: 4, borderRadius: "2xl", bg: colors.background[100], "data-testid": testId, "data-status": "applied", children: [_jsx(Flex, { as: "span", align: "center", justify: "center", boxSize: 8, flexShrink: 0, borderRadius: "full", bg: success.bg, color: success.fg, children: _jsx(BadgeCheck, { size: 16, "aria-hidden": true }) }), _jsxs(Box, { flex: 1, minW: 0, role: "status", children: [_jsx(Text, { as: "span", display: "block", fontSize: "sm", fontWeight: 700, lineHeight: 1.4, color: colors.header[900], noOfLines: 1, children: copy.applied(appliedCode) }), savedAmount !== undefined && savedAmount > 0 && (_jsx(Text, { as: "span", display: "block", fontSize: "xs", fontWeight: 600, lineHeight: 1.4, color: colors.semanticText.success, sx: NUMERIC_TEXT, children: copy.saved(formatPrice(savedAmount, { currency, locale })) }))] }), _jsx(Button, { variant: "ghost", colorScheme: "gray", size: "sm", onClick: onRemove, "aria-label": `${copy.remove} coupon ${appliedCode}`, children: copy.remove })] }));
62
65
  }
63
- return (_jsxs(Flex, { direction: "column", gap: 3, "data-testid": testId, "data-status": status, children: [_jsxs(Box, { as: "button", type: "button", "aria-expanded": open, "aria-controls": panelId, disabled: applying || status === "error", onClick: () => setOpen(!open), display: "flex", alignItems: "center", gap: 3, w: "100%", minH: "3rem", px: 4, borderRadius: "2xl", bg: colors.background[100], color: colors.header[900], textAlign: "left", transition: transitionFor(["background-color"]), _hover: { bg: colors.background[200] }, sx: { ...focusVisibleStyles(colors), ...reducedMotionSx() }, children: [_jsx(Ticket, { size: 18, "aria-hidden": true }), _jsx(Text, { as: "span", flex: 1, fontSize: "sm", fontWeight: 600, children: copy.prompt }), _jsx(Box, { as: "span", display: "inline-flex", "aria-hidden": true, transform: open ? "rotate(180deg)" : undefined, transition: transitionFor(["transform"]), sx: reducedMotionSx({ transform: open ? "rotate(180deg)" : "none" }), children: _jsx(ChevronDown, { size: 16 }) })] }), _jsxs(Box, { id: panelId, hidden: !open, display: open ? "block" : "none", onKeyDown: onKeyDown, children: [_jsxs(Flex, { gap: 2, align: "flex-start", children: [_jsx(Box, { flex: 1, minW: 0, children: _jsx(TextInput, { size: "lg", variant: "filled", "aria-label": copy.inputLabel, placeholder: copy.placeholder, value: text, onChange: (event) => setText(normalise(event.target.value)), error: status === "error", errorMessage: status === "error" ? error : undefined, isDisabled: applying, autoComplete: "off", autoCapitalize: "characters", spellCheck: false }) }), _jsx(Button, { variant: "outline", colorScheme: "gray", size: "lg", isLoading: applying, isDisabled: !normalise(text), onClick: () => submit(text), children: copy.apply })] }), suggestions && suggestions.length > 0 && (_jsxs(Box, { mt: 4, children: [_jsx(Text, { as: "p", fontSize: "xs", fontWeight: 600, color: colors.textMuted, mb: 2, children: copy.suggestionsTitle }), _jsx(Flex, { as: "ul", direction: "column", gap: 2, m: 0, p: 0, listStyleType: "none", children: suggestions.map((s) => (_jsx(Box, { as: "li", children: _jsxs(Box, { as: "button", type: "button", disabled: applying, "aria-label": `${copy.applySuggestion(s.code)}: ${s.title}`, onClick: () => {
66
+ return (_jsxs(Flex, { direction: "column", gap: 3, "data-testid": testId, "data-status": status, children: [_jsxs(Box, { as: "button", type: "button", "aria-expanded": open, "aria-controls": panelId, disabled: applying || status === "error", onClick: () => setOpen(!open), display: "flex", alignItems: "center", gap: 3, w: "100%", minH: "3rem", px: 4, borderRadius: "2xl", bg: colors.background[100], color: colors.header[900], textAlign: "left", transition: transitionFor(["background-color"]), _hover: { bg: hoverFill }, sx: { ...focusVisibleStyles(colors), ...reducedMotionSx() }, children: [_jsx(Ticket, { size: 18, "aria-hidden": true }), _jsx(Text, { as: "span", flex: 1, fontSize: "sm", fontWeight: 600, children: copy.prompt }), _jsx(Box, { as: "span", display: "inline-flex", "aria-hidden": true, transform: open ? "rotate(180deg)" : undefined, transition: transitionFor(["transform"]), sx: reducedMotionSx({ transform: open ? "rotate(180deg)" : "none" }), children: _jsx(ChevronDown, { size: 16 }) })] }), _jsxs(Box, { id: panelId, hidden: !open, display: open ? "block" : "none", onKeyDown: onKeyDown, children: [_jsxs(Flex, { gap: 2, align: "flex-start", children: [_jsx(Box, { flex: 1, minW: 0, children: _jsx(TextInput, { size: "lg", variant: "filled", "aria-label": copy.inputLabel, placeholder: copy.placeholder, value: text, onChange: (event) => setText(normalise(event.target.value)), error: status === "error", errorMessage: status === "error" ? error : undefined, isDisabled: applying, autoComplete: "off", autoCapitalize: "characters", spellCheck: false }) }), _jsx(Button, { variant: "outline", colorScheme: "gray", size: "lg", isLoading: applying, isDisabled: !normalise(text), onClick: () => submit(text), children: copy.apply })] }), suggestions && suggestions.length > 0 && (_jsxs(Box, { mt: 4, children: [_jsx(Text, { as: "p", fontSize: "xs", fontWeight: 600, color: colors.textMuted, mb: 2, children: copy.suggestionsTitle }), _jsx(Flex, { as: "ul", direction: "column", gap: 2, m: 0, p: 0, listStyleType: "none", children: suggestions.map((s) => (_jsx(Box, { as: "li", children: _jsxs(Box, { as: "button", type: "button", disabled: applying, "aria-label": `${copy.applySuggestion(s.code)}: ${s.title}`, onClick: () => {
64
67
  setText(s.code);
65
68
  submit(s.code);
66
- }, display: "flex", alignItems: "center", gap: 3, w: "100%", p: 3, borderRadius: "xl", bg: colors.background[100], textAlign: "left", transition: transitionFor(["background-color"]), _hover: { bg: colors.background[200] }, _disabled: { cursor: "not-allowed", opacity: 0.6 }, sx: { ...focusVisibleStyles(colors), ...reducedMotionSx() }, children: [_jsx(Text, { as: "span", flexShrink: 0, px: 2, py: 1, borderRadius: "lg", bg: colors.background[200], fontSize: "xs", fontWeight: 700, letterSpacing: "0.04em", color: colors.header[900], children: s.code }), _jsxs(Box, { as: "span", flex: 1, minW: 0, children: [_jsx(Text, { as: "span", display: "block", fontSize: "sm", fontWeight: 600, lineHeight: 1.4, color: colors.header[900], children: s.title }), s.detail && (_jsx(Text, { as: "span", display: "block", fontSize: "xs", lineHeight: 1.4, color: colors.textMuted, children: s.detail }))] }), _jsx(Text, { as: "span", "aria-hidden": true, fontSize: "sm", fontWeight: 600, color: colors.accentText, children: copy.apply })] }) }, s.code))) })] }))] }), _jsx(VisuallyHidden, { role: "status", children: applying ? `${copy.apply}…` : "" })] }));
69
+ }, display: "flex", alignItems: "center", gap: 3, w: "100%", p: 3, borderRadius: "xl", bg: colors.background[100], textAlign: "left", transition: transitionFor(["background-color"]), _hover: { bg: hoverFill }, _disabled: { cursor: "not-allowed", opacity: DISABLED_OPACITY }, sx: { ...focusVisibleStyles(colors), ...reducedMotionSx() }, children: [_jsx(Text, { as: "span", flexShrink: 0, px: 2, py: 1, borderRadius: "lg", bg: colors.background[200], fontSize: "xs", fontWeight: 700, letterSpacing: "0.04em", color: colors.header[900], children: s.code }), _jsxs(Box, { as: "span", flex: 1, minW: 0, children: [_jsx(Text, { as: "span", display: "block", fontSize: "sm", fontWeight: 600, lineHeight: 1.4, color: colors.header[900], children: s.title }), s.detail && (_jsx(Text, { as: "span", display: "block", fontSize: "xs", lineHeight: 1.4, color: colors.textMuted, children: s.detail }))] }), _jsx(Text, { as: "span", "aria-hidden": true, fontSize: "sm", fontWeight: 600, color: colors.accentText, children: copy.apply })] }) }, s.code))) })] }))] }), _jsx(VisuallyHidden, { role: "status", children: applying ? `${copy.apply}…` : "" })] }));
67
70
  };
68
71
  export default CouponField;