pixelize-design-library 2.4.2-beta.3 → 2.4.2-beta.30

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 (279) hide show
  1. package/dist/Components/Accordion/Accordion.js +5 -3
  2. package/dist/Components/AppSwitcher/AppMark.d.ts +19 -0
  3. package/dist/Components/AppSwitcher/AppMark.js +62 -0
  4. package/dist/Components/AppSwitcher/AppSwitcher.d.ts +4 -0
  5. package/dist/Components/AppSwitcher/AppSwitcher.js +315 -0
  6. package/dist/Components/AppSwitcher/AppSwitcherProps.d.ts +64 -0
  7. package/dist/Components/AppSwitcher/AppSwitcherProps.js +86 -0
  8. package/dist/Components/AppSwitcher/useAppSwitcherShortcut.d.ts +3 -0
  9. package/dist/Components/AppSwitcher/useAppSwitcherShortcut.js +31 -0
  10. package/dist/Components/AppearanceSettings/AppearanceSettings.js +2 -1
  11. package/dist/Components/Button/Button.d.ts +2 -2
  12. package/dist/Components/Button/Button.js +4 -3
  13. package/dist/Components/Button/Button.styles.js +62 -15
  14. package/dist/Components/Button/ButtonProps.d.ts +6 -1
  15. package/dist/Components/ButtonGroupIcon/ButtonGroupIcon.js +6 -6
  16. package/dist/Components/Card/Card.d.ts +1 -1
  17. package/dist/Components/Card/Card.js +2 -2
  18. package/dist/Components/Card/CardProps.d.ts +0 -1
  19. package/dist/Components/Card/PaymentCard/PaymentCard.js +7 -7
  20. package/dist/Components/Checkbox/Checkbox.js +1 -1
  21. package/dist/Components/Checkbox/Checkbox.styles.js +12 -7
  22. package/dist/Components/Common/fieldStyles.js +1 -1
  23. package/dist/Components/CopyButton/CopyButton.js +6 -2
  24. package/dist/Components/CustomModulesTable/EditModuleModal.js +1 -1
  25. package/dist/Components/DatePicker/CalendarPanel.d.ts +5 -0
  26. package/dist/Components/DatePicker/CalendarPanel.js +24 -5
  27. package/dist/Components/DatePicker/DatePickerProps.d.ts +21 -0
  28. package/dist/Components/DatePicker/RangeDatePicker.js +4 -4
  29. package/dist/Components/DatePicker/SingleDatePicker.js +2 -2
  30. package/dist/Components/DatePicker/TimeOnlyPicker.js +1 -1
  31. package/dist/Components/DatePicker/dayStates.d.ts +56 -0
  32. package/dist/Components/DatePicker/dayStates.js +87 -0
  33. package/dist/Components/Dropdown/DropDown.js +7 -15
  34. package/dist/Components/EmailCards/VerifyEmailOtp/VerifyEmailOtp.js +1 -1
  35. package/dist/Components/EmptyState/EmptyState.js +2 -1
  36. package/dist/Components/FilePreview/FilePreview.js +1 -1
  37. package/dist/Components/FileUpload/FileUpload.js +5 -4
  38. package/dist/Components/FileUpload/FileUploadProps.d.ts +3 -1
  39. package/dist/Components/FileUpload/constants.js +1 -0
  40. package/dist/Components/FilterSidebar/FilterSidebar.js +4 -4
  41. package/dist/Components/FilterSidebar/filterHoverStyle.d.ts +0 -9
  42. package/dist/Components/FilterSidebar/filterHoverStyle.js +4 -10
  43. package/dist/Components/Form/FormWrapper.js +1 -1
  44. package/dist/Components/Header/components/mobileMenu.js +12 -3
  45. package/dist/Components/Input/TextInput.styles.js +6 -4
  46. package/dist/Components/InputTextArea/InputTextArea.style.js +5 -4
  47. package/dist/Components/KanbanBoard/KanbanBoard.js +5 -45
  48. package/dist/Components/LimitReachedModal/LimitReachedModal.js +4 -5
  49. package/dist/Components/Loading/Loading.js +15 -14
  50. package/dist/Components/MultiSelect/MultiSelect.js +1 -1
  51. package/dist/Components/NavigationBar/NavigationBar.js +3 -3
  52. package/dist/Components/NoteTextArea/NoteTextArea.js +9 -4
  53. package/dist/Components/NumberInput/NumberInput.js +3 -1
  54. package/dist/Components/NumberInput/NumberInput.styles.js +5 -4
  55. package/dist/Components/OrgSwitcher/OrgSwitcher.js +2 -2
  56. package/dist/Components/PdfViewer/PdfViewer.js +6 -1
  57. package/dist/Components/PinInput/PinInput.js +1 -1
  58. package/dist/Components/PlanPill/PlanPill.js +5 -5
  59. package/dist/Components/PlanPill/planPillGradient.d.ts +2 -14
  60. package/dist/Components/PlanPill/planPillGradient.js +3 -15
  61. package/dist/Components/Primitives/Primitives.d.ts +6 -0
  62. package/dist/Components/Primitives/Primitives.js +113 -0
  63. package/dist/Components/ProductCard/ProductPrice.js +1 -1
  64. package/dist/Components/ProductCard/ProductReview.js +6 -1
  65. package/dist/Components/ProductCard/ProductTags.js +1 -1
  66. package/dist/Components/ProfileCard/ProfileCard.js +1 -1
  67. package/dist/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +1 -1
  68. package/dist/Components/RadioButton/RadioButton.js +3 -2
  69. package/dist/Components/Reorder/Reorder.js +1 -1
  70. package/dist/Components/ScrollToTop/ScrollToTop.js +2 -0
  71. package/dist/Components/ScrollbarBox/ScrollbarBox.d.ts +13 -0
  72. package/dist/Components/ScrollbarBox/ScrollbarBox.js +11 -0
  73. package/dist/Components/Search/Search.js +2 -2
  74. package/dist/Components/SearchSelect/SearchSelect.js +14 -9
  75. package/dist/Components/SegmentedControl/SegmentedControl.d.ts +2 -0
  76. package/dist/Components/SegmentedControl/SegmentedControl.js +58 -0
  77. package/dist/Components/SegmentedControl/SegmentedControlProps.d.ts +16 -0
  78. package/dist/Components/SegmentedControl/SegmentedControlProps.js +2 -0
  79. package/dist/Components/Select/Select.d.ts +1 -1
  80. package/dist/Components/Select/Select.js +4 -2
  81. package/dist/Components/Select/Select.styles.js +3 -2
  82. package/dist/Components/Select/SelectProps.d.ts +3 -0
  83. package/dist/Components/SelectSearch/SelectSearch.js +7 -4
  84. package/dist/Components/SelectV2/SelectV2.js +18 -14
  85. package/dist/Components/SideBar/SecondaryBar.js +1 -1
  86. package/dist/Components/SideBar/SideBar.js +1 -1
  87. package/dist/Components/SideBar/components/MenuPopoverContent.js +2 -2
  88. package/dist/Components/Slider/Slider.js +8 -1
  89. package/dist/Components/StageProgress/StageProgress.js +2 -9
  90. package/dist/Components/StageProgress/StepperStage.js +2 -2
  91. package/dist/Components/Table/Table.d.ts +1 -1
  92. package/dist/Components/Table/Table.js +17 -24
  93. package/dist/Components/Table/TableProps.d.ts +4 -0
  94. package/dist/Components/Table/components/Pagination.js +1 -1
  95. package/dist/Components/Table/components/TableActions.js +2 -2
  96. package/dist/Components/Table/components/TableBody.js +41 -12
  97. package/dist/Components/Table/components/TableGroupRow.js +1 -1
  98. package/dist/Components/Table/components/TableHeader.js +21 -8
  99. package/dist/Components/Table/components/TableSearch.js +1 -1
  100. package/dist/Components/Table/filters/ActiveFilters.js +2 -18
  101. package/dist/Components/Table/settings/ManageColumns.js +4 -17
  102. package/dist/Components/Table/settings/TableSettings.js +5 -11
  103. package/dist/Components/Table/variants/TableVariantContext.d.ts +4 -0
  104. package/dist/Components/Table/variants/TableVariantContext.js +17 -0
  105. package/dist/Components/Table/variants/classic.d.ts +6 -0
  106. package/dist/Components/Table/variants/classic.js +47 -0
  107. package/dist/Components/Table/variants/index.d.ts +7 -0
  108. package/dist/Components/Table/variants/index.js +27 -0
  109. package/dist/Components/Table/variants/pillInk.d.ts +6 -0
  110. package/dist/Components/Table/variants/pillInk.js +21 -0
  111. package/dist/Components/Table/variants/studio.d.ts +6 -0
  112. package/dist/Components/Table/variants/studio.js +50 -0
  113. package/dist/Components/Table/variants/tokens.d.ts +49 -0
  114. package/dist/Components/Table/variants/tokens.js +2 -0
  115. package/dist/Components/Tag/Tag.styles.js +3 -4
  116. package/dist/Components/Timeline/Timeline.js +2 -2
  117. package/dist/Components/Toaster/Toaster.js +1 -1
  118. package/dist/Components/Toggle/TableToggle.js +11 -7
  119. package/dist/Components/ToggleSwitch/ToggleSwitch.d.ts +2 -0
  120. package/dist/Components/ToggleSwitch/ToggleSwitch.js +18 -0
  121. package/dist/Components/ToggleSwitch/ToggleSwitchProps.d.ts +11 -0
  122. package/dist/Components/ToggleSwitch/ToggleSwitchProps.js +2 -0
  123. package/dist/Components/ToolTip/ToolTip.js +6 -6
  124. package/dist/Components/ToolTip/ToolTipProps.d.ts +3 -1
  125. package/dist/Components/Trail/TrailWorks.js +1 -1
  126. package/dist/Components/UpgradeButton/UpgradeButton.js +3 -3
  127. package/dist/Constants/Sidebar.js +3 -2
  128. package/dist/Theme/assertPalette.d.ts +1 -1
  129. package/dist/Theme/assertPalette.js +3 -2
  130. package/dist/Theme/chakra/Menu.styles.d.ts +3 -0
  131. package/dist/Theme/chakra/Menu.styles.js +5 -0
  132. package/dist/Theme/chakra/Popover.styles.d.ts +3 -0
  133. package/dist/Theme/chakra/Popover.styles.js +5 -1
  134. package/dist/Theme/chakra/componentStyles.d.ts +6 -0
  135. package/dist/Theme/chakra/createBrandTheme.js +10 -16
  136. package/dist/Theme/chakra/focusRing.styles.d.ts +52 -0
  137. package/dist/Theme/chakra/focusRing.styles.js +46 -0
  138. package/dist/Theme/provider/ThemeSwitcher.js +5 -2
  139. package/dist/Theme/tokens/brands/index.js +6 -1
  140. package/dist/Theme/tokens/brands/zinc/palette.dark.d.ts +1 -0
  141. package/dist/Theme/tokens/builders/buildDarkPalette.js +6 -1
  142. package/dist/Theme/tokens/builders/chartColorsFromTheme.js +1 -1
  143. package/dist/Theme/tokens/builders/focusRing.d.ts +52 -0
  144. package/dist/Theme/tokens/builders/focusRing.js +92 -0
  145. package/dist/Theme/tokens/builders/gradientInk.d.ts +22 -0
  146. package/dist/Theme/tokens/builders/gradientInk.js +28 -0
  147. package/dist/Theme/tokens/builders/index.d.ts +4 -0
  148. package/dist/Theme/tokens/builders/index.js +4 -0
  149. package/dist/Theme/tokens/builders/outlineRung.d.ts +46 -3
  150. package/dist/Theme/tokens/builders/outlineRung.js +101 -5
  151. package/dist/Theme/tokens/builders/placeholderInk.d.ts +19 -0
  152. package/dist/Theme/tokens/builders/placeholderInk.js +35 -0
  153. package/dist/Theme/tokens/builders/resolvedRungs.d.ts +5 -1
  154. package/dist/Theme/tokens/builders/resolvedRungs.js +7 -2
  155. package/dist/Theme/tokens/builders/rowStates.d.ts +13 -0
  156. package/dist/Theme/tokens/builders/rowStates.js +19 -0
  157. package/dist/Theme/tokens/builders/scrollbar.d.ts +12 -0
  158. package/dist/Theme/tokens/builders/scrollbar.js +57 -0
  159. package/dist/Theme/tokens/builders/surfaceRungs.d.ts +5 -0
  160. package/dist/Theme/tokens/builders/surfaceRungs.js +20 -5
  161. package/dist/Theme/tokens/types.d.ts +21 -1
  162. package/dist/esm/Components/Accordion/Accordion.js +5 -3
  163. package/dist/esm/Components/AppSwitcher/AppMark.js +56 -0
  164. package/dist/esm/Components/AppSwitcher/AppSwitcher.js +280 -0
  165. package/dist/esm/Components/AppSwitcher/AppSwitcherProps.js +78 -0
  166. package/dist/esm/Components/AppSwitcher/useAppSwitcherShortcut.js +27 -0
  167. package/dist/esm/Components/AppearanceSettings/AppearanceSettings.js +2 -1
  168. package/dist/esm/Components/Button/Button.js +5 -4
  169. package/dist/esm/Components/Button/Button.styles.js +63 -16
  170. package/dist/esm/Components/ButtonGroupIcon/ButtonGroupIcon.js +6 -6
  171. package/dist/esm/Components/Card/Card.js +2 -2
  172. package/dist/esm/Components/Card/PaymentCard/PaymentCard.js +7 -7
  173. package/dist/esm/Components/Checkbox/Checkbox.js +1 -1
  174. package/dist/esm/Components/Checkbox/Checkbox.styles.js +13 -8
  175. package/dist/esm/Components/Common/fieldStyles.js +1 -1
  176. package/dist/esm/Components/CopyButton/CopyButton.js +7 -3
  177. package/dist/esm/Components/CustomModulesTable/EditModuleModal.js +1 -1
  178. package/dist/esm/Components/DatePicker/CalendarPanel.js +24 -5
  179. package/dist/esm/Components/DatePicker/RangeDatePicker.js +4 -4
  180. package/dist/esm/Components/DatePicker/SingleDatePicker.js +2 -2
  181. package/dist/esm/Components/DatePicker/TimeOnlyPicker.js +1 -1
  182. package/dist/esm/Components/DatePicker/dayStates.js +79 -0
  183. package/dist/esm/Components/Dropdown/DropDown.js +7 -15
  184. package/dist/esm/Components/EmailCards/VerifyEmailOtp/VerifyEmailOtp.js +1 -1
  185. package/dist/esm/Components/EmptyState/EmptyState.js +2 -1
  186. package/dist/esm/Components/FilePreview/FilePreview.js +1 -1
  187. package/dist/esm/Components/FileUpload/FileUpload.js +6 -5
  188. package/dist/esm/Components/FileUpload/constants.js +1 -0
  189. package/dist/esm/Components/FilterSidebar/FilterSidebar.js +4 -4
  190. package/dist/esm/Components/FilterSidebar/filterHoverStyle.js +4 -10
  191. package/dist/esm/Components/Form/FormWrapper.js +1 -1
  192. package/dist/esm/Components/Header/components/mobileMenu.js +12 -3
  193. package/dist/esm/Components/Input/TextInput.styles.js +6 -4
  194. package/dist/esm/Components/InputTextArea/InputTextArea.style.js +5 -4
  195. package/dist/esm/Components/KanbanBoard/KanbanBoard.js +5 -45
  196. package/dist/esm/Components/LimitReachedModal/LimitReachedModal.js +4 -5
  197. package/dist/esm/Components/Loading/Loading.js +12 -11
  198. package/dist/esm/Components/MultiSelect/MultiSelect.js +1 -1
  199. package/dist/esm/Components/NavigationBar/NavigationBar.js +3 -3
  200. package/dist/esm/Components/NoteTextArea/NoteTextArea.js +9 -4
  201. package/dist/esm/Components/NumberInput/NumberInput.js +4 -2
  202. package/dist/esm/Components/NumberInput/NumberInput.styles.js +5 -4
  203. package/dist/esm/Components/OrgSwitcher/OrgSwitcher.js +2 -2
  204. package/dist/esm/Components/PdfViewer/PdfViewer.js +6 -1
  205. package/dist/esm/Components/PinInput/PinInput.js +1 -1
  206. package/dist/esm/Components/PlanPill/PlanPill.js +6 -6
  207. package/dist/esm/Components/PlanPill/planPillGradient.js +3 -15
  208. package/dist/esm/Components/Primitives/Primitives.js +6 -0
  209. package/dist/esm/Components/ProductCard/ProductPrice.js +1 -1
  210. package/dist/esm/Components/ProductCard/ProductReview.js +6 -1
  211. package/dist/esm/Components/ProductCard/ProductTags.js +1 -1
  212. package/dist/esm/Components/ProfileCard/ProfileCard.js +1 -1
  213. package/dist/esm/Components/ProfilePhotoViewer/ProfilePhotoViewer.js +1 -1
  214. package/dist/esm/Components/RadioButton/RadioButton.js +3 -2
  215. package/dist/esm/Components/Reorder/Reorder.js +1 -1
  216. package/dist/esm/Components/ScrollToTop/ScrollToTop.js +2 -0
  217. package/dist/esm/Components/ScrollbarBox/ScrollbarBox.js +9 -0
  218. package/dist/esm/Components/Search/Search.js +2 -2
  219. package/dist/esm/Components/SearchSelect/SearchSelect.js +14 -9
  220. package/dist/esm/Components/SegmentedControl/SegmentedControl.js +55 -0
  221. package/dist/esm/Components/SegmentedControl/SegmentedControlProps.js +1 -0
  222. package/dist/esm/Components/Select/Select.js +5 -3
  223. package/dist/esm/Components/Select/Select.styles.js +3 -2
  224. package/dist/esm/Components/SelectSearch/SelectSearch.js +7 -4
  225. package/dist/esm/Components/SelectV2/SelectV2.js +18 -14
  226. package/dist/esm/Components/SideBar/SecondaryBar.js +1 -1
  227. package/dist/esm/Components/SideBar/SideBar.js +1 -1
  228. package/dist/esm/Components/SideBar/components/MenuPopoverContent.js +2 -2
  229. package/dist/esm/Components/Slider/Slider.js +8 -1
  230. package/dist/esm/Components/StageProgress/StageProgress.js +2 -9
  231. package/dist/esm/Components/StageProgress/StepperStage.js +2 -2
  232. package/dist/esm/Components/Table/Table.js +17 -24
  233. package/dist/esm/Components/Table/components/Pagination.js +1 -1
  234. package/dist/esm/Components/Table/components/TableActions.js +2 -2
  235. package/dist/esm/Components/Table/components/TableBody.js +42 -13
  236. package/dist/esm/Components/Table/components/TableGroupRow.js +1 -1
  237. package/dist/esm/Components/Table/components/TableHeader.js +21 -8
  238. package/dist/esm/Components/Table/components/TableSearch.js +1 -1
  239. package/dist/esm/Components/Table/filters/ActiveFilters.js +2 -18
  240. package/dist/esm/Components/Table/settings/ManageColumns.js +4 -17
  241. package/dist/esm/Components/Table/settings/TableSettings.js +5 -11
  242. package/dist/esm/Components/Table/variants/TableVariantContext.js +13 -0
  243. package/dist/esm/Components/Table/variants/classic.js +43 -0
  244. package/dist/esm/Components/Table/variants/index.js +9 -0
  245. package/dist/esm/Components/Table/variants/pillInk.js +18 -0
  246. package/dist/esm/Components/Table/variants/studio.js +46 -0
  247. package/dist/esm/Components/Table/variants/tokens.js +1 -0
  248. package/dist/esm/Components/Tag/Tag.styles.js +3 -4
  249. package/dist/esm/Components/Timeline/Timeline.js +2 -2
  250. package/dist/esm/Components/Toaster/Toaster.js +1 -1
  251. package/dist/esm/Components/Toggle/TableToggle.js +11 -7
  252. package/dist/esm/Components/ToggleSwitch/ToggleSwitch.js +15 -0
  253. package/dist/esm/Components/ToggleSwitch/ToggleSwitchProps.js +1 -0
  254. package/dist/esm/Components/ToolTip/ToolTip.js +6 -6
  255. package/dist/esm/Components/Trail/TrailWorks.js +1 -1
  256. package/dist/esm/Components/UpgradeButton/UpgradeButton.js +3 -3
  257. package/dist/esm/Constants/Sidebar.js +3 -2
  258. package/dist/esm/Theme/assertPalette.js +3 -2
  259. package/dist/esm/Theme/chakra/Menu.styles.js +5 -0
  260. package/dist/esm/Theme/chakra/Popover.styles.js +5 -1
  261. package/dist/esm/Theme/chakra/createBrandTheme.js +10 -16
  262. package/dist/esm/Theme/chakra/focusRing.styles.js +40 -0
  263. package/dist/esm/Theme/provider/ThemeSwitcher.js +5 -2
  264. package/dist/esm/Theme/tokens/brands/index.js +6 -1
  265. package/dist/esm/Theme/tokens/builders/buildDarkPalette.js +6 -1
  266. package/dist/esm/Theme/tokens/builders/chartColorsFromTheme.js +1 -1
  267. package/dist/esm/Theme/tokens/builders/focusRing.js +85 -0
  268. package/dist/esm/Theme/tokens/builders/gradientInk.js +22 -0
  269. package/dist/esm/Theme/tokens/builders/index.js +4 -0
  270. package/dist/esm/Theme/tokens/builders/outlineRung.js +96 -4
  271. package/dist/esm/Theme/tokens/builders/placeholderInk.js +29 -0
  272. package/dist/esm/Theme/tokens/builders/resolvedRungs.js +7 -2
  273. package/dist/esm/Theme/tokens/builders/rowStates.js +15 -0
  274. package/dist/esm/Theme/tokens/builders/scrollbar.js +52 -0
  275. package/dist/esm/Theme/tokens/builders/surfaceRungs.js +20 -5
  276. package/dist/esm/index.js +24 -1
  277. package/dist/index.d.ts +27 -3
  278. package/dist/index.js +64 -4
  279. package/package.json +8 -2
@@ -6,21 +6,23 @@ const react_2 = require("@chakra-ui/react");
6
6
  const lucide_react_1 = require("lucide-react");
7
7
  const useCustomTheme_1 = require("../../Theme/useCustomTheme");
8
8
  const accentText_1 = require("../../Theme/tokens/builders/accentText");
9
+ const outlineRung_1 = require("../../Theme/tokens/builders/outlineRung");
9
10
  const accordionColors_1 = require("./accordionColors");
10
11
  const Accordion = ({ allowMultiple, allowToggle, index, onChange, reduceMotion, items, ...rest }) => {
11
12
  const { colors } = (0, useCustomTheme_1.useCustomTheme)();
12
13
  const isDark = (0, accentText_1.isDarkCanvas)(colors.backgroundColor.main);
13
- const border = colors.boxborder[300];
14
+ const border = colors.boxborder[200];
14
15
  const headingColor = colors.text[800];
15
16
  const bodyColor = colors.text[600];
16
17
  const { expandedBg, softHover } = (0, react_1.useMemo)(() => (0, accordionColors_1.getAccordionHoverColors)(colors, isDark), [colors, isDark]);
18
+ const focusRing = (0, react_1.useMemo)(() => (0, outlineRung_1.liftToContrast)(colors.primary[300], colors.background[50], outlineRung_1.AA_NON_TEXT), [colors]);
17
19
  return ((0, jsx_runtime_1.jsx)(react_2.Accordion, { allowMultiple: allowMultiple, allowToggle: allowToggle, index: index, onChange: onChange, reduceMotion: reduceMotion, ...rest, children: items.map((item, idx) => {
18
20
  var _a;
19
- return ((0, jsx_runtime_1.jsx)(react_2.AccordionItem, { border: `0.063rem solid ${border}`, borderRadius: "xl", bg: colors.background[50], mb: 3, overflow: "hidden", transition: "border-color 0.15s ease, box-shadow 0.15s ease", _last: { mb: 0 }, _hover: { borderColor: colors.boxborder[400] }, ...item.itemProps, sx: (_a = item.customStyles) === null || _a === void 0 ? void 0 : _a.itemStyle, children: ({ isExpanded }) => {
21
+ return ((0, jsx_runtime_1.jsx)(react_2.AccordionItem, { border: `0.063rem solid ${border}`, borderRadius: "xl", bg: colors.background[50], mb: 3, overflow: "hidden", transition: "border-color 0.15s ease, box-shadow 0.15s ease", _last: { mb: 0 }, _hover: { borderColor: colors.boxborder[200] }, ...item.itemProps, sx: (_a = item.customStyles) === null || _a === void 0 ? void 0 : _a.itemStyle, children: ({ isExpanded }) => {
20
22
  var _a, _b, _c;
21
23
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("h2", { children: (0, jsx_runtime_1.jsxs)(react_2.AccordionButton, { px: 4, py: 3, gap: 3, fontSize: "0.875rem", fontWeight: 600, color: headingColor, bg: isExpanded ? expandedBg : "transparent", transition: "background 0.15s ease", _hover: { bg: isExpanded ? expandedBg : softHover }, _focusVisible: {
22
24
  boxShadow: "none",
23
- outline: `0.125rem solid ${colors.primary[300]}`,
25
+ outline: `0.125rem solid ${focusRing}`,
24
26
  outlineOffset: "-0.125rem",
25
27
  }, ...item.buttonProps, sx: {
26
28
  ...(_a = item.customStyles) === null || _a === void 0 ? void 0 : _a.buttonStyle,
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ import { chartMode } from "../../Theme/tokens/builders/chartColorsFromTheme";
3
+ import { type AppOption } from "./AppSwitcherProps";
4
+ /**
5
+ * One hue per app. `avatarColor` hashes into an 8-hue series, so six apps collide more often than
6
+ * not — Billing and Account shipped identical marks. Assigned over the WHOLE list, never the
7
+ * filtered one, so searching cannot repaint a mark.
8
+ */
9
+ export declare const assignAppHues: (apps: readonly AppOption[], mode: ReturnType<typeof chartMode>) => string[];
10
+ export declare const appTint: (hue: string, surface: string, white: string) => string;
11
+ export declare const appTintInk: (fill: string, white: string, black: string) => string;
12
+ declare const AppMark: React.FC<{
13
+ app: AppOption;
14
+ hue: string;
15
+ boxSize: string;
16
+ iconSize: number;
17
+ muted?: boolean;
18
+ }>;
19
+ export default AppMark;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.appTintInk = exports.appTint = exports.assignAppHues = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const react_2 = require("@chakra-ui/react");
7
+ const useCustomTheme_1 = require("../../Theme/useCustomTheme");
8
+ const color_1 = require("../../Theme/tokens/builders/color");
9
+ const accentText_1 = require("../../Theme/tokens/builders/accentText");
10
+ const outlineRung_1 = require("../../Theme/tokens/builders/outlineRung");
11
+ const accentText_2 = require("../../Theme/tokens/builders/accentText");
12
+ const chartColorsFromTheme_1 = require("../../Theme/tokens/builders/chartColorsFromTheme");
13
+ const statusTone_1 = require("../../Theme/tokens/builders/statusTone");
14
+ const OrgSwitcherProps_1 = require("../OrgSwitcher/OrgSwitcherProps");
15
+ const AppSwitcherProps_1 = require("./AppSwitcherProps");
16
+ // The app's own hue at 85% strength — the solid mark, softened just off full saturation.
17
+ const FILL_STRENGTH = 0.85;
18
+ /**
19
+ * One hue per app. `avatarColor` hashes into an 8-hue series, so six apps collide more often than
20
+ * not — Billing and Account shipped identical marks. Assigned over the WHOLE list, never the
21
+ * filtered one, so searching cannot repaint a mark.
22
+ */
23
+ const assignAppHues = (apps, mode) => {
24
+ const ramp = chartColorsFromTheme_1.CATEGORICAL_SERIES[mode].map(statusTone_1.resolveAvatarFill);
25
+ const taken = new Set(apps.flatMap((a) => (a.color ? [a.color] : [])));
26
+ return apps.map((app) => {
27
+ if (app.color)
28
+ return app.color;
29
+ const seed = (0, OrgSwitcherProps_1.avatarColor)(app.id || app.name, mode);
30
+ const start = Math.max(0, ramp.indexOf(seed));
31
+ for (let i = 0; i < ramp.length; i += 1) {
32
+ const next = ramp[(start + i) % ramp.length];
33
+ if (!taken.has(next)) {
34
+ taken.add(next);
35
+ return next;
36
+ }
37
+ }
38
+ // More apps than the series has hues; past this point a repeat is unavoidable.
39
+ return seed;
40
+ });
41
+ };
42
+ exports.assignAppHues = assignAppHues;
43
+ // Softening costs the fill contrast, so it is walked back until a WHITE glyph clears AA — every
44
+ // mark keeps the same white icon instead of some flipping to black.
45
+ const appTint = (hue, surface, white) => (0, outlineRung_1.liftToContrast)((0, color_1.mix)(hue, surface, 1 - FILL_STRENGTH), white, accentText_2.AA_NORMAL_TEXT);
46
+ exports.appTint = appTint;
47
+ const appTintInk = (fill, white, black) => (0, accentText_1.onFilled)(fill, white, black);
48
+ exports.appTintInk = appTintInk;
49
+ const AppMark = ({ app, hue, boxSize, iconSize, muted = false, }) => {
50
+ const { colors } = (0, useCustomTheme_1.useCustomTheme)();
51
+ if (app.iconUrl) {
52
+ return ((0, jsx_runtime_1.jsx)(react_2.Image, { src: app.iconUrl, alt: "", boxSize: boxSize, borderRadius: "lg", objectFit: "cover", flexShrink: 0, opacity: muted ? 0.55 : 1 }));
53
+ }
54
+ const surface = colors.backgroundColor.light;
55
+ const fill = muted ? colors.backgroundColor.quaternary : (0, exports.appTint)(hue, surface, colors.white);
56
+ const ink = muted ? colors.textMuted : (0, exports.appTintInk)(fill, colors.white, colors.black);
57
+ // lucide icons are forwardRef objects, not functions — a typeof check silently drops them.
58
+ const isElement = (0, react_1.isValidElement)(app.icon);
59
+ const Icon = !isElement && app.icon ? app.icon : null;
60
+ return ((0, jsx_runtime_1.jsx)(react_2.Flex, { align: "center", justify: "center", boxSize: boxSize, borderRadius: "lg", flexShrink: 0, bg: fill, color: ink, fontSize: `${Math.round(iconSize * 0.72)}px`, fontWeight: 700, "aria-hidden": true, children: Icon ? ((0, jsx_runtime_1.jsx)(Icon, { size: iconSize, color: ink })) : (0, react_1.isValidElement)(app.icon) ? ((0, jsx_runtime_1.jsx)(react_2.Box, { display: "flex", color: ink, children: app.icon })) : ((0, AppSwitcherProps_1.appInitials)(app.name)) }));
61
+ };
62
+ exports.default = AppMark;
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ import { type AppSwitcherProps } from "./AppSwitcherProps";
3
+ declare const AppSwitcher: React.FC<AppSwitcherProps>;
4
+ export default AppSwitcher;
@@ -0,0 +1,315 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const jsx_runtime_1 = require("react/jsx-runtime");
37
+ const react_1 = require("react");
38
+ const react_2 = require("@chakra-ui/react");
39
+ const lucide_react_1 = require("lucide-react");
40
+ const useCustomTheme_1 = require("../../Theme/useCustomTheme");
41
+ const chartColorsFromTheme_1 = require("../../Theme/tokens/builders/chartColorsFromTheme");
42
+ const accentText_1 = require("../../Theme/tokens/builders/accentText");
43
+ const outlineRung_1 = require("../../Theme/tokens/builders/outlineRung");
44
+ const AppMark_1 = __importStar(require("./AppMark"));
45
+ const AppSwitcherProps_1 = require("./AppSwitcherProps");
46
+ const useAppSwitcherShortcut_1 = require("./useAppSwitcherShortcut");
47
+ const COLUMNS = 2;
48
+ const HEADING = "Your apps";
49
+ const s = { trigger: "36px", mark: "32px", icon: 17, name: "0.875rem", sub: "0.75rem", row: "52px" };
50
+ const warned = new Set();
51
+ const warnOnce = (key, message) => {
52
+ if (process.env.NODE_ENV === "production" || warned.has(key))
53
+ return;
54
+ warned.add(key);
55
+ console.error(`[AppSwitcher] ${message}`);
56
+ };
57
+ const validate = (apps) => {
58
+ const seen = new Set();
59
+ apps.forEach((app, i) => {
60
+ var _a;
61
+ if (!app.id)
62
+ warnOnce(`id-${i}`, `apps[${i}] ("${(_a = app.name) !== null && _a !== void 0 ? _a : "unnamed"}") has no id.`);
63
+ else if (seen.has(app.id))
64
+ warnOnce(`dup-${app.id}`, `duplicate app id "${app.id}".`);
65
+ else
66
+ seen.add(app.id);
67
+ if (!app.url && !app.locked)
68
+ warnOnce(`url-${app.id || i}`, `app "${app.name}" has no url; it cannot be opened.`);
69
+ });
70
+ };
71
+ // Past a pointer's pause threshold, so crossing the launcher on the way elsewhere does not open it,
72
+ // but short enough that deliberately resting on it feels instant.
73
+ const HOVER_OPEN_DELAY = 450;
74
+ // Long enough to travel the gap between the launcher and the panel below it.
75
+ const HOVER_CLOSE_GRACE = 250;
76
+ // Flip back to true to restore `searchThreshold` opening the field on its own.
77
+ const SEARCH_OPENS_BY_COUNT = false;
78
+ const AppSwitcher = ({ apps, currentAppId, onSelect, onOpenChange, isSearchable, searchThreshold = 8, shortcut = null, showShortcutHint = true, hideWhenAlone = true, emptyMessage = "No app matches that name.", footer, ariaLabel = "Switch app", panelWidth, maxHeight = "24rem", isLoading = false, }) => {
79
+ const theme = (0, useCustomTheme_1.useCustomTheme)();
80
+ const { isOpen, onOpen, onClose } = (0, react_2.useDisclosure)();
81
+ const [query, setQuery] = (0, react_1.useState)("");
82
+ const [activeIndex, setActiveIndex] = (0, react_1.useState)(0);
83
+ const searchRef = (0, react_1.useRef)(null);
84
+ const triggerRef = (0, react_1.useRef)(null);
85
+ const panelRef = (0, react_1.useRef)(null);
86
+ const itemRefs = (0, react_1.useRef)([]);
87
+ const typeahead = (0, react_1.useRef)({ buffer: "", at: 0 });
88
+ const hoverTimer = (0, react_1.useRef)();
89
+ const openedByHover = (0, react_1.useRef)(false);
90
+ (0, react_1.useEffect)(() => validate(apps), [apps]);
91
+ // Search is off while the panel's design settles: the app count alone no longer opens it. An
92
+ // explicit `isSearchable` still wins, so nothing about the prop changed.
93
+ const showSearch = isSearchable !== null && isSearchable !== void 0 ? isSearchable : (SEARCH_OPENS_BY_COUNT && apps.length >= searchThreshold);
94
+ const hues = (0, react_1.useMemo)(() => (0, AppMark_1.assignAppHues)(apps, (0, chartColorsFromTheme_1.chartMode)(theme.colors)), [apps, theme.colors]);
95
+ const visible = (0, react_1.useMemo)(() => (0, AppSwitcherProps_1.filterApps)(apps, query), [apps, query]);
96
+ const setOpen = (0, react_1.useCallback)((next) => {
97
+ if (next)
98
+ onOpen();
99
+ else
100
+ onClose();
101
+ onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(next);
102
+ }, [onOpen, onClose, onOpenChange]);
103
+ const cancelHoverTimer = (0, react_1.useCallback)(() => {
104
+ if (hoverTimer.current)
105
+ clearTimeout(hoverTimer.current);
106
+ hoverTimer.current = undefined;
107
+ }, []);
108
+ (0, react_1.useEffect)(() => cancelHoverTimer, [cancelHoverTimer]);
109
+ // Touch and stylus report no hover; a timer there would open the panel on a tap-and-hold.
110
+ const pointerHovers = () => {
111
+ var _a;
112
+ return typeof window !== "undefined" &&
113
+ ((_a = window.matchMedia) === null || _a === void 0 ? void 0 : _a.call(window, "(hover: hover) and (pointer: fine)").matches);
114
+ };
115
+ const handleHoverStart = (0, react_1.useCallback)(() => {
116
+ if (isOpen || !pointerHovers())
117
+ return;
118
+ cancelHoverTimer();
119
+ hoverTimer.current = setTimeout(() => {
120
+ openedByHover.current = true;
121
+ setOpen(true);
122
+ }, HOVER_OPEN_DELAY);
123
+ }, [isOpen, cancelHoverTimer, setOpen]);
124
+ // A click-opened panel is sticky, and a keyboard user inside it is not "hovering away".
125
+ const handleHoverEnd = (0, react_1.useCallback)(() => {
126
+ cancelHoverTimer();
127
+ if (!isOpen || !openedByHover.current)
128
+ return;
129
+ hoverTimer.current = setTimeout(() => {
130
+ var _a;
131
+ if ((_a = panelRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement))
132
+ return;
133
+ openedByHover.current = false;
134
+ setOpen(false);
135
+ setQuery("");
136
+ }, HOVER_CLOSE_GRACE);
137
+ }, [isOpen, cancelHoverTimer, setOpen]);
138
+ const closeAndRefocus = (0, react_1.useCallback)(() => {
139
+ var _a;
140
+ setOpen(false);
141
+ setQuery("");
142
+ (_a = triggerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
143
+ }, [setOpen]);
144
+ (0, useAppSwitcherShortcut_1.useAppSwitcherShortcut)(shortcut, () => setOpen(true), !isOpen);
145
+ (0, react_1.useEffect)(() => {
146
+ if (!isOpen)
147
+ setQuery("");
148
+ setActiveIndex(0);
149
+ }, [isOpen]);
150
+ (0, react_1.useEffect)(() => setActiveIndex(0), [query]);
151
+ const focusItem = (0, react_1.useCallback)((next) => {
152
+ var _a;
153
+ setActiveIndex(next);
154
+ (_a = itemRefs.current[next]) === null || _a === void 0 ? void 0 : _a.focus();
155
+ }, []);
156
+ // Read the focused row, not state: two keydowns in one React batch would both compute from a
157
+ // stale activeIndex, so holding an arrow key silently dropped moves.
158
+ const currentIndex = (0, react_1.useCallback)(() => {
159
+ const focused = itemRefs.current.findIndex((el) => el === document.activeElement);
160
+ return focused === -1 ? activeIndex : focused;
161
+ }, [activeIndex]);
162
+ const step = (0, react_1.useCallback)((delta) => {
163
+ const count = visible.length;
164
+ if (count === 0)
165
+ return;
166
+ focusItem(((currentIndex() + delta) % count + count) % count);
167
+ }, [currentIndex, visible.length, focusItem]);
168
+ const jumpToLetter = (0, react_1.useCallback)((char) => {
169
+ const now = Date.now();
170
+ const buffer = now - typeahead.current.at < 600 ? typeahead.current.buffer + char : char;
171
+ typeahead.current = { buffer, at: now };
172
+ const at = currentIndex();
173
+ const from = buffer.length > 1 ? at : at + 1;
174
+ const order = visible.map((_, i) => (from + i) % visible.length);
175
+ const hit = order.find((i) => visible[i].name.toLowerCase().startsWith(buffer));
176
+ if (hit !== undefined)
177
+ focusItem(hit);
178
+ }, [visible, currentIndex, focusItem]);
179
+ // Chakra parks focus on the panel itself, where no arrow handler lives; route the first press in.
180
+ const handlePanelKeyDown = (0, react_1.useCallback)((e) => {
181
+ if (itemRefs.current.includes(document.activeElement))
182
+ return;
183
+ if (visible.length === 0)
184
+ return;
185
+ if (["ArrowDown", "ArrowRight", "Home"].includes(e.key)) {
186
+ e.preventDefault();
187
+ focusItem(0);
188
+ }
189
+ else if (["ArrowUp", "ArrowLeft", "End"].includes(e.key)) {
190
+ e.preventDefault();
191
+ focusItem(visible.length - 1);
192
+ }
193
+ else if (e.key === "Escape") {
194
+ e.preventDefault();
195
+ closeAndRefocus();
196
+ }
197
+ }, [visible.length, focusItem, closeAndRefocus]);
198
+ const handleItemKeyDown = (0, react_1.useCallback)((e, app) => {
199
+ if (e.key === "ArrowDown") {
200
+ e.preventDefault();
201
+ step(COLUMNS);
202
+ }
203
+ else if (e.key === "ArrowUp") {
204
+ e.preventDefault();
205
+ step(-COLUMNS);
206
+ }
207
+ else if (e.key === "ArrowRight") {
208
+ e.preventDefault();
209
+ step(1);
210
+ }
211
+ else if (e.key === "ArrowLeft") {
212
+ e.preventDefault();
213
+ step(-1);
214
+ }
215
+ else if (e.key === "Home") {
216
+ e.preventDefault();
217
+ focusItem(0);
218
+ }
219
+ else if (e.key === "End") {
220
+ e.preventDefault();
221
+ focusItem(visible.length - 1);
222
+ }
223
+ else if (e.key === "Escape") {
224
+ e.preventDefault();
225
+ closeAndRefocus();
226
+ }
227
+ else if (e.key === " " && !app.locked) {
228
+ e.preventDefault();
229
+ e.currentTarget.click();
230
+ }
231
+ else if (e.key.length === 1 && !e.metaKey && !e.ctrlKey && !e.altKey)
232
+ jumpToLetter(e.key.toLowerCase());
233
+ }, [step, focusItem, visible.length, closeAndRefocus, jumpToLetter]);
234
+ const handleSelect = (app, e) => {
235
+ if (app.locked) {
236
+ e.preventDefault();
237
+ return;
238
+ }
239
+ onSelect === null || onSelect === void 0 ? void 0 : onSelect(app, e);
240
+ if (!e.defaultPrevented)
241
+ setOpen(false);
242
+ };
243
+ const nothingToSwitchTo = apps.length === 0 || (hideWhenAlone && apps.every((a) => a.id === currentAppId));
244
+ if (nothingToSwitchTo)
245
+ return null;
246
+ const rowHoverBg = (0, outlineRung_1.resolveHoverTint)(theme.colors.gray[50], theme.colors.backgroundColor.light);
247
+ const footerRule = (0, outlineRung_1.ruleInk)(theme.colors.boxborder[200], [theme.colors.backgroundColor.subtle], outlineRung_1.CHROME_RULE);
248
+ // Neutral, not `backgroundColor.tertiary`: that rung is brand-tinted in the hand-authored light
249
+ // palettes, so lifting it painted the row a saturated block. The rail identifies the row, so the
250
+ // fill only has to be perceptible — pushed further it is a mid-grey slab that reads disabled.
251
+ const currentBg = (0, outlineRung_1.neutralStep)(theme.colors.backgroundColor.light, outlineRung_1.MIN_PERCEPTIBLE_STEP);
252
+ // The brand rail is the whole marker — no ring, no badge. `accentText` already clears AA as ink
253
+ // on the canvas; lifting it to AA_NON_TEXT here guarantees it on the row's own fill too, for a
254
+ // brand whose accent is pale.
255
+ const currentBar = (0, outlineRung_1.liftToContrast)(theme.colors.accentText, currentBg, outlineRung_1.AA_NON_TEXT);
256
+ // A derived surface is outside what `withSurfaceRungs` settled, so its ink is resolved here.
257
+ const currentName = (0, outlineRung_1.liftToContrast)(theme.colors.text[900], currentBg, accentText_1.AA_NORMAL_TEXT);
258
+ const currentSub = (0, outlineRung_1.liftToContrast)(theme.colors.textMuted, currentBg, accentText_1.AA_NORMAL_TEXT);
259
+ const width = panelWidth !== null && panelWidth !== void 0 ? panelWidth : "28rem";
260
+ const hint = shortcut && showShortcutHint ? (0, AppSwitcherProps_1.formatShortcut)(shortcut) : null;
261
+ return ((0, jsx_runtime_1.jsxs)(react_2.Popover, { isOpen: isOpen, onOpen: () => setOpen(true), onClose: () => { setOpen(false); setQuery(""); }, placement: "bottom-end", initialFocusRef: showSearch ? searchRef : undefined, isLazy: true, children: [(0, jsx_runtime_1.jsx)(react_2.PopoverTrigger, { children: (0, jsx_runtime_1.jsx)(react_2.Flex, { ref: triggerRef, as: "button", type: "button", "aria-label": ariaLabel, align: "center", justify: "center", boxSize: s.trigger, borderRadius: "lg", border: "1px solid", borderColor: isOpen ? theme.colors.boxborder[500] : theme.colors.boxborder[200], bg: isOpen ? theme.colors.backgroundColor.tertiary : "transparent", color: isOpen ? theme.colors.text[900] : theme.colors.textMuted, cursor: "pointer", transition: "background 0.15s ease, border-color 0.15s ease", _hover: { bg: rowHoverBg, color: theme.colors.text[900] }, onMouseEnter: handleHoverStart, onMouseLeave: handleHoverEnd, onClick: () => { openedByHover.current = false; cancelHoverTimer(); }, onKeyDown: (e) => {
262
+ if (!isOpen) {
263
+ if (e.key === "ArrowDown") {
264
+ e.preventDefault();
265
+ setOpen(true);
266
+ }
267
+ return;
268
+ }
269
+ handlePanelKeyDown(e);
270
+ }, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Grip, { size: s.icon + 1 }) }) }), (0, jsx_runtime_1.jsx)(react_2.PopoverContent, { ref: panelRef, onMouseEnter: cancelHoverTimer, onMouseLeave: handleHoverEnd, w: width, maxW: "calc(100vw - 1.5rem)", textAlign: "start", onKeyDown: handlePanelKeyDown, bg: theme.colors.backgroundColor.light, borderRadius: "xl", overflow: "hidden", boxShadow: `0 10px 30px ${theme.colors.boxShadow.default}`, _focus: { outline: "none", boxShadow: `0 10px 30px ${theme.colors.boxShadow.default}` }, children: (0, jsx_runtime_1.jsxs)(react_2.PopoverBody, { p: 0, children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: 2, px: 3, pt: 3, pb: showSearch ? 2 : 1, children: [(0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "0.6875rem", fontWeight: 600, letterSpacing: "0.08em", textTransform: "uppercase", color: theme.colors.textMuted, children: HEADING }), (0, jsx_runtime_1.jsx)(react_2.Box, { flex: "1" }), hint && ((0, jsx_runtime_1.jsx)(react_2.Text, { as: "kbd", fontSize: "0.6875rem", fontFamily: "inherit", color: theme.colors.textMuted, border: "1px solid", borderRadius: "base", px: 1.5, py: 0.5, children: hint }))] }), showSearch && ((0, jsx_runtime_1.jsx)(react_2.Box, { px: 3, pb: 2, children: (0, jsx_runtime_1.jsxs)(react_2.InputGroup, { size: "sm", children: [(0, jsx_runtime_1.jsx)(react_2.InputLeftElement, { pointerEvents: "none", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Search, { size: 15, color: theme.colors.textMuted }) }), (0, jsx_runtime_1.jsx)(react_2.Input, { ref: searchRef, value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Search apps", borderRadius: "lg", "aria-label": "Search apps", onKeyDown: (e) => {
271
+ if (e.key === "ArrowDown" && visible.length > 0) {
272
+ e.preventDefault();
273
+ focusItem(0);
274
+ }
275
+ else if (e.key === "Escape") {
276
+ e.preventDefault();
277
+ if (query)
278
+ setQuery("");
279
+ else
280
+ closeAndRefocus();
281
+ }
282
+ } })] }) })), (0, jsx_runtime_1.jsxs)(react_2.Box, { role: "menu", "aria-label": HEADING, maxH: maxHeight, overflowY: "auto", px: 2, pb: 2, display: "grid", gridTemplateColumns: `repeat(${COLUMNS}, minmax(0, 1fr))`, gap: "2px", children: [isLoading
283
+ ? [0, 1, 2, 3].map((i) => ((0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: 3, px: 2, py: 2, minH: s.row, children: [(0, jsx_runtime_1.jsx)(react_2.Skeleton, { boxSize: s.mark, borderRadius: "lg" }), (0, jsx_runtime_1.jsx)(react_2.Skeleton, { h: "0.75rem", flex: "1", borderRadius: "base" })] }, i)))
284
+ : visible.map((app, idx) => {
285
+ var _a;
286
+ const isCurrent = app.id === currentAppId;
287
+ const interactive = !isCurrent && !app.locked;
288
+ return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { as: interactive ? "a" : "div", role: "menuitem", ref: (el) => { itemRefs.current[idx] = el; }, tabIndex: idx === activeIndex ? 0 : -1, "aria-current": isCurrent ? "true" : undefined, "aria-disabled": app.locked ? true : undefined, title: app.locked ? ((_a = app.lockedReason) !== null && _a !== void 0 ? _a : `${app.name} is not available on your plan`) : undefined, ...(interactive
289
+ ? {
290
+ href: app.url,
291
+ target: "_blank",
292
+ rel: "noopener noreferrer",
293
+ }
294
+ : {}), align: "center", gap: 3, minH: s.row, px: 2, py: 2, borderRadius: "lg", textDecoration: "none", cursor: interactive ? "pointer" : "default", bg: isCurrent ? currentBg : "transparent", position: "relative",
295
+ // Full height, taking the row's own `lg` radius on its outer corners so the
296
+ // rail follows the row's curve instead of cutting across it.
297
+ _before: isCurrent
298
+ ? {
299
+ content: '""',
300
+ position: "absolute",
301
+ insetInlineStart: 0,
302
+ insetBlock: 0,
303
+ width: "3px",
304
+ borderStartStartRadius: "lg",
305
+ borderEndStartRadius: "lg",
306
+ bg: currentBar,
307
+ }
308
+ : undefined, transition: "background 0.12s ease", _hover: interactive ? { bg: rowHoverBg } : undefined, onClick: (e) => handleSelect(app, e), onKeyDown: (e) => handleItemKeyDown(e, app), children: [(0, jsx_runtime_1.jsx)(AppMark_1.default, { app: app, hue: hues[apps.indexOf(app)], boxSize: s.mark, iconSize: s.icon, muted: app.locked }), (0, jsx_runtime_1.jsxs)(react_2.Box, { flex: "1", minW: 0, children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: 1.5, children: [(0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: s.name, fontWeight: 600, color: app.locked
309
+ ? theme.colors.textMuted
310
+ : isCurrent
311
+ ? currentName
312
+ : theme.colors.text[900], overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", children: app.name }), app.badge !== undefined && !isCurrent && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "0.625rem", fontWeight: 600, color: theme.colors.semanticText.info, flexShrink: 0, children: app.badge }))] }), app.description && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: s.sub, color: isCurrent ? currentSub : theme.colors.textMuted, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", children: app.description }))] }), app.locked && ((0, jsx_runtime_1.jsx)(react_2.Box, { as: lucide_react_1.Lock, size: 14, color: theme.colors.textMuted, flexShrink: 0 }))] }, app.id || app.name));
313
+ }), !isLoading && visible.length === 0 && ((0, jsx_runtime_1.jsx)(react_2.Box, { gridColumn: `span ${COLUMNS}`, px: 2, py: 6, textAlign: "center", children: (0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: s.name, color: theme.colors.textMuted, children: emptyMessage }) }))] }), footer && ((0, jsx_runtime_1.jsx)(react_2.Flex, { align: "center", gap: 1.5, px: 3, py: 2.5, borderTop: "1px solid", borderTopColor: footerRule, bg: theme.colors.backgroundColor.subtle, children: footer }))] }) })] }));
314
+ };
315
+ exports.default = AppSwitcher;
@@ -0,0 +1,64 @@
1
+ import type { ComponentType, ReactNode } from "react";
2
+ export type AppIconComponent = ComponentType<{
3
+ size?: number | string;
4
+ color?: string;
5
+ }>;
6
+ /** A lucide-style component, a ready node, or nothing — then the mark falls back to initials. */
7
+ export type AppIcon = AppIconComponent | ReactNode;
8
+ export interface AppOption {
9
+ id: string;
10
+ name: string;
11
+ url: string;
12
+ description?: string;
13
+ icon?: AppIcon;
14
+ iconUrl?: string;
15
+ color?: string;
16
+ badge?: string | number;
17
+ /** Listed but not openable — renders locked with `lockedReason` as its title. */
18
+ locked?: boolean;
19
+ lockedReason?: string;
20
+ /** Extra terms the search should match, e.g. "helpdesk" for Tickets. */
21
+ keywords?: string[];
22
+ }
23
+ /** Fixed top-bar control: two columns, md density, bottom-end anchor, "Your apps", new tab. */
24
+ export interface AppSwitcherProps {
25
+ apps: AppOption[];
26
+ /** id of the app this UI is running inside. Its row is marked and never navigates. */
27
+ currentAppId?: string;
28
+ /** Called instead of following the link. Call `event.preventDefault()` to keep the panel's own navigation. */
29
+ onSelect?: (app: AppOption, event: React.MouseEvent | React.KeyboardEvent) => void;
30
+ onOpenChange?: (isOpen: boolean) => void;
31
+ isSearchable?: boolean;
32
+ searchThreshold?: number;
33
+ /** Keyboard shortcut that opens the panel, e.g. "mod+shift+a". `null` disables it. */
34
+ shortcut?: string | null;
35
+ showShortcutHint?: boolean;
36
+ /** Renders nothing when there is no other app to switch to. */
37
+ hideWhenAlone?: boolean;
38
+ emptyMessage?: string;
39
+ footer?: ReactNode;
40
+ ariaLabel?: string;
41
+ panelWidth?: string;
42
+ maxHeight?: string;
43
+ isLoading?: boolean;
44
+ }
45
+ /** Up to two initials, so a mark stays legible without an icon. */
46
+ export declare const appInitials: (name: string) => string;
47
+ export declare const filterApps: (apps: AppOption[], query: string) => AppOption[];
48
+ export type ShortcutEvent = Pick<KeyboardEvent, "key" | "altKey" | "ctrlKey" | "metaKey" | "shiftKey">;
49
+ /** "mod" is Cmd on Apple platforms and Ctrl everywhere else. */
50
+ export declare const matchesShortcut: (event: ShortcutEvent, shortcut: string, isApple?: boolean) => boolean;
51
+ export declare const formatShortcut: (shortcut: string, isApple?: boolean) => string;
52
+ export interface SuiteAppSource extends Omit<AppOption, "url"> {
53
+ subdomain: string;
54
+ url?: string;
55
+ }
56
+ export interface SuiteUrlOptions {
57
+ baseUrl: string;
58
+ baseSubdomain: string;
59
+ }
60
+ /**
61
+ * Derives every app's origin from the host the consumer is already served on, so one deployment
62
+ * variable keeps dev, test and prod in step. An app may still carry its own `url`, which wins.
63
+ */
64
+ export declare const buildSuiteApps: (apps: SuiteAppSource[], { baseUrl, baseSubdomain }: SuiteUrlOptions) => AppOption[];
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildSuiteApps = exports.formatShortcut = exports.matchesShortcut = exports.filterApps = exports.appInitials = void 0;
4
+ const NON_WORD = /[^\p{L}\p{N}]+/u;
5
+ /** Up to two initials, so a mark stays legible without an icon. */
6
+ const appInitials = (name) => {
7
+ const words = name.trim().split(NON_WORD).filter(Boolean);
8
+ if (words.length === 0)
9
+ return "?";
10
+ if (words.length === 1)
11
+ return words[0].slice(0, 2).toUpperCase();
12
+ return (words[0][0] + words[1][0]).toUpperCase();
13
+ };
14
+ exports.appInitials = appInitials;
15
+ const filterApps = (apps, query) => {
16
+ const q = query.trim().toLowerCase();
17
+ if (!q)
18
+ return apps;
19
+ return apps.filter((app) => {
20
+ var _a, _b;
21
+ return [app.name, (_a = app.description) !== null && _a !== void 0 ? _a : "", ...((_b = app.keywords) !== null && _b !== void 0 ? _b : [])]
22
+ .join(" ")
23
+ .toLowerCase()
24
+ .includes(q);
25
+ });
26
+ };
27
+ exports.filterApps = filterApps;
28
+ /** "mod" is Cmd on Apple platforms and Ctrl everywhere else. */
29
+ const matchesShortcut = (event, shortcut, isApple = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform)) => {
30
+ const parts = shortcut.toLowerCase().split("+").map((p) => p.trim()).filter(Boolean);
31
+ if (parts.length === 0)
32
+ return false;
33
+ const key = parts[parts.length - 1];
34
+ const mods = new Set(parts.slice(0, -1));
35
+ const wantsMod = mods.has("mod");
36
+ const wantsCtrl = mods.has("ctrl") || (wantsMod && !isApple);
37
+ const wantsMeta = mods.has("cmd") || mods.has("meta") || (wantsMod && isApple);
38
+ if (event.ctrlKey !== wantsCtrl)
39
+ return false;
40
+ if (event.metaKey !== wantsMeta)
41
+ return false;
42
+ if (event.shiftKey !== mods.has("shift"))
43
+ return false;
44
+ if (event.altKey !== mods.has("alt"))
45
+ return false;
46
+ return event.key.toLowerCase() === key;
47
+ };
48
+ exports.matchesShortcut = matchesShortcut;
49
+ const APPLE_SYMBOLS = { mod: "⌘", cmd: "⌘", meta: "⌘", ctrl: "⌃", shift: "⇧", alt: "⌥" };
50
+ const OTHER_LABELS = { mod: "Ctrl", cmd: "Win", meta: "Win", ctrl: "Ctrl", shift: "Shift", alt: "Alt" };
51
+ const formatShortcut = (shortcut, isApple = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform)) => {
52
+ const parts = shortcut.toLowerCase().split("+").map((p) => p.trim()).filter(Boolean);
53
+ const table = isApple ? APPLE_SYMBOLS : OTHER_LABELS;
54
+ const rendered = parts.map((p, i) => { var _a; return i === parts.length - 1 ? p.toUpperCase() : ((_a = table[p]) !== null && _a !== void 0 ? _a : p.toUpperCase()); });
55
+ return isApple ? rendered.join("") : rendered.join("+");
56
+ };
57
+ exports.formatShortcut = formatShortcut;
58
+ /**
59
+ * Derives every app's origin from the host the consumer is already served on, so one deployment
60
+ * variable keeps dev, test and prod in step. An app may still carry its own `url`, which wins.
61
+ */
62
+ const buildSuiteApps = (apps, { baseUrl, baseSubdomain }) => {
63
+ let base;
64
+ try {
65
+ base = new URL(baseUrl.trim());
66
+ }
67
+ catch {
68
+ throw new Error(`[AppSwitcher] buildSuiteApps: baseUrl ${JSON.stringify(baseUrl)} is not an absolute URL.`);
69
+ }
70
+ const labels = base.hostname.split(".");
71
+ const at = labels.indexOf(baseSubdomain);
72
+ return apps.map(({ subdomain, url, ...app }) => {
73
+ if (url)
74
+ return { ...app, url: url.trim() };
75
+ // Without the label there is nothing to swap, and every app would silently share one origin.
76
+ if (at === -1) {
77
+ throw new Error(`[AppSwitcher] buildSuiteApps: ${JSON.stringify(baseSubdomain)} is not a label in ` +
78
+ `"${base.hostname}", so ${JSON.stringify(app.name)} has no derivable url. ` +
79
+ `Give that app an explicit url, or pass a baseUrl that contains the label.`);
80
+ }
81
+ const next = new URL(base.toString());
82
+ next.hostname = labels.map((l, i) => (i === at ? subdomain : l)).join(".");
83
+ return { ...app, url: next.origin };
84
+ });
85
+ };
86
+ exports.buildSuiteApps = buildSuiteApps;
@@ -0,0 +1,3 @@
1
+ /** Fires `onTrigger` on the shortcut. Inert when `shortcut` is null, and never in SSR. */
2
+ export declare const useAppSwitcherShortcut: (shortcut: string | null | undefined, onTrigger: () => void, enabled?: boolean) => void;
3
+ export default useAppSwitcherShortcut;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useAppSwitcherShortcut = void 0;
4
+ const react_1 = require("react");
5
+ const AppSwitcherProps_1 = require("./AppSwitcherProps");
6
+ const isTypingTarget = (target) => {
7
+ if (!(target instanceof HTMLElement))
8
+ return false;
9
+ if (target.isContentEditable)
10
+ return true;
11
+ return ["INPUT", "TEXTAREA", "SELECT"].includes(target.tagName);
12
+ };
13
+ /** Fires `onTrigger` on the shortcut. Inert when `shortcut` is null, and never in SSR. */
14
+ const useAppSwitcherShortcut = (shortcut, onTrigger, enabled = true) => {
15
+ (0, react_1.useEffect)(() => {
16
+ if (!shortcut || !enabled || typeof window === "undefined")
17
+ return undefined;
18
+ const handler = (event) => {
19
+ if (event.defaultPrevented || isTypingTarget(event.target))
20
+ return;
21
+ if (!(0, AppSwitcherProps_1.matchesShortcut)(event, shortcut))
22
+ return;
23
+ event.preventDefault();
24
+ onTrigger();
25
+ };
26
+ window.addEventListener("keydown", handler);
27
+ return () => window.removeEventListener("keydown", handler);
28
+ }, [shortcut, enabled, onTrigger]);
29
+ };
30
+ exports.useAppSwitcherShortcut = useAppSwitcherShortcut;
31
+ exports.default = exports.useAppSwitcherShortcut;
@@ -11,13 +11,14 @@ const Theme_1 = require("../../Theme");
11
11
  const provider_1 = require("../../Theme/provider");
12
12
  const fontSize_1 = require("../../Theme/provider/fontSize");
13
13
  const brands_1 = require("../../Theme/tokens/brands");
14
+ const outlineRung_1 = require("../../Theme/tokens/builders/outlineRung");
14
15
  const useCustomTheme_1 = require("../../Theme/useCustomTheme");
15
16
  const SelectV2_1 = __importDefault(require("../SelectV2/SelectV2"));
16
17
  const FieldLabel = ({ children }) => {
17
18
  const { colors } = (0, useCustomTheme_1.useCustomTheme)();
18
19
  return ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "sm", fontWeight: "medium", color: colors.textMuted, mb: 2, children: children }));
19
20
  };
20
- const brandSwatch = (name, colors) => ((0, jsx_runtime_1.jsx)(react_2.Box, { w: "14px", h: "14px", borderRadius: "full", bg: brands_1.lightPalettes[name].primary[500], border: "1px solid", borderColor: colors.boxborder[500] }));
21
+ const brandSwatch = (name, colors) => ((0, jsx_runtime_1.jsx)(react_2.Box, { w: "14px", h: "14px", borderRadius: "full", bg: brands_1.lightPalettes[name].primary[500], border: "1px solid", borderColor: (0, outlineRung_1.ruleInk)(colors.boxborder[200], [colors.backgroundColor.light, colors.backgroundColor.tertiary], outlineRung_1.CHROME_RULE) }));
21
22
  const AppearanceSettings = ({ brand, fontSize, onBrandChange, onFontSizeChange, showBrand = true, showColorMode = true, showFontSize = true, size = "sm", labels, }) => {
22
23
  var _a, _b, _c;
23
24
  const { colors } = (0, useCustomTheme_1.useCustomTheme)();