@ghxstship/xos-ui 0.0.0-stage → 4.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (487) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +32 -2
  3. package/package.json +76 -4
  4. package/scripts/generate-stories.mjs +85 -0
  5. package/src/AIDisclosureBadge/README.md +7 -0
  6. package/src/AccessGridMatrix/README.md +3 -0
  7. package/src/Accordion/README.md +7 -0
  8. package/src/ActivityFeedItem/README.md +3 -0
  9. package/src/AgencySlate/README.md +3 -0
  10. package/src/AppShell/README.md +5 -0
  11. package/src/ApplicationForm/README.md +3 -0
  12. package/src/AssertionRankBadge/README.md +5 -0
  13. package/src/AvailabilityCalendar/README.md +3 -0
  14. package/src/Avatar/Avatar.tsx +56 -0
  15. package/src/Avatar/README.md +3 -0
  16. package/src/Avatar/avatar-class.ts +19 -0
  17. package/src/AvatarStack/README.md +3 -0
  18. package/src/Badge/README.md +3 -0
  19. package/src/Banner/README.md +3 -0
  20. package/src/BidSheet/README.md +3 -0
  21. package/src/Board/README.md +6 -0
  22. package/src/BrandMark/BrandMark.tsx +95 -0
  23. package/src/BrandMark/README.md +7 -0
  24. package/src/BrandSlot/README.md +6 -0
  25. package/src/Breadcrumbs/README.md +3 -0
  26. package/src/BudgetGrid/README.md +10 -0
  27. package/src/BulkActionBar/README.md +3 -0
  28. package/src/Button/Button.tsx +100 -0
  29. package/src/Button/README.md +10 -0
  30. package/src/Button/button-class.ts +54 -0
  31. package/src/ButtonLink/README.md +7 -0
  32. package/src/Calendar/README.md +3 -0
  33. package/src/Card/README.md +3 -0
  34. package/src/Chart/README.md +9 -0
  35. package/src/Charts/Calendar.tsx +228 -0
  36. package/src/Charts/Chart.tsx +547 -0
  37. package/src/Charts/Charts.tsx +20 -0
  38. package/src/Charts/Charts.types.ts +40 -0
  39. package/src/Charts/Gallery.tsx +25 -0
  40. package/src/Charts/Heatmap.tsx +116 -0
  41. package/src/Charts/OrgChart.tsx +53 -0
  42. package/src/Charts/ResourceSchedule.tsx +91 -0
  43. package/src/Charts/Sparkline.tsx +59 -0
  44. package/src/Charts/Timeline.tsx +777 -0
  45. package/src/Charts/categories.ts +21 -0
  46. package/src/Charts/timeline-plan.ts +191 -0
  47. package/src/Checkbox/README.md +6 -0
  48. package/src/ChecklistRunner/README.md +3 -0
  49. package/src/Chips/Badge.tsx +27 -0
  50. package/src/Chips/Chips.shared.tsx +34 -0
  51. package/src/Chips/Chips.tsx +21 -0
  52. package/src/Chips/Chips.types.ts +35 -0
  53. package/src/Chips/DepartmentChip.tsx +16 -0
  54. package/src/Chips/PhaseChip.tsx +16 -0
  55. package/src/Chips/PropertyChip.tsx +15 -0
  56. package/src/Chips/RecordKindChip.tsx +14 -0
  57. package/src/Chips/StateChip.tsx +19 -0
  58. package/src/Chips/Tag.tsx +47 -0
  59. package/src/Chips/URIDChip.tsx +14 -0
  60. package/src/Chips/chipClass.tsx +8 -0
  61. package/src/Chips/codeClass.tsx +6 -0
  62. package/src/ClockButton/README.md +6 -0
  63. package/src/CodeSample/README.md +7 -0
  64. package/src/ColorPicker/README.md +5 -0
  65. package/src/Combobox/README.md +7 -0
  66. package/src/CommandMenu/CommandMenu.tsx +179 -0
  67. package/src/CommandMenu/README.md +5 -0
  68. package/src/ComparisonTable/README.md +9 -0
  69. package/src/Compass/ChecklistRunner.tsx +128 -0
  70. package/src/Compass/ClockButton.tsx +57 -0
  71. package/src/Compass/Compass.shared.tsx +58 -0
  72. package/src/Compass/Compass.tsx +26 -0
  73. package/src/Compass/Compass.types.ts +79 -0
  74. package/src/Compass/DaySheetView.tsx +104 -0
  75. package/src/Compass/ForceUpdateScreen.tsx +29 -0
  76. package/src/Compass/LiveActivity.tsx +60 -0
  77. package/src/Compass/OfflineBanner.tsx +31 -0
  78. package/src/Compass/PhotoCapture.tsx +69 -0
  79. package/src/Compass/QuickIncidentSheet.tsx +46 -0
  80. package/src/Compass/ScanSheet.tsx +83 -0
  81. package/src/Compass/ShiftCard.tsx +55 -0
  82. package/src/Compass/SignaturePad.tsx +71 -0
  83. package/src/Compass/SyncConflictSheet.tsx +60 -0
  84. package/src/ConsentBanner/ConsentBanner.tsx +210 -0
  85. package/src/ConsentBanner/ConsentBannerStatic.tsx +163 -0
  86. package/src/ConsentBanner/ConsentSettings.tsx +213 -0
  87. package/src/ConsentBanner/README.md +101 -0
  88. package/src/ConsentBanner/consent.ts +238 -0
  89. package/src/ConsentBanner/index.ts +40 -0
  90. package/src/ConsentBanner/static.ts +11 -0
  91. package/src/ConsentBanner/useConsent.ts +160 -0
  92. package/src/ContextMenu/README.md +3 -0
  93. package/src/CoordinateMatrix/README.md +6 -0
  94. package/src/CredentialBadge/README.md +7 -0
  95. package/src/CurrencyInput/README.md +7 -0
  96. package/src/DataTable/DataTable.tsx +1034 -0
  97. package/src/DataTable/DataTableResizer.tsx +72 -0
  98. package/src/DataTable/DataTableVirtualizer.tsx +58 -0
  99. package/src/DataTable/README.md +9 -0
  100. package/src/DatePicker/README.md +5 -0
  101. package/src/DateRangePicker/README.md +3 -0
  102. package/src/DaySheetView/README.md +3 -0
  103. package/src/DepartmentChip/README.md +3 -0
  104. package/src/DepartmentGlyph/README.md +18 -0
  105. package/src/Dialog/README.md +3 -0
  106. package/src/DiffViewer/README.md +3 -0
  107. package/src/Divider/README.md +3 -0
  108. package/src/Drawer/README.md +3 -0
  109. package/src/DropdownMenu/README.md +3 -0
  110. package/src/EPKViewer/README.md +3 -0
  111. package/src/Editing/ColorPicker.tsx +125 -0
  112. package/src/Editing/DiffViewer.tsx +49 -0
  113. package/src/Editing/Editing.tsx +29 -0
  114. package/src/Editing/Editing.types.ts +71 -0
  115. package/src/Editing/FilterBuilder.tsx +72 -0
  116. package/src/Editing/QuickAdd.tsx +102 -0
  117. package/src/Editing/QuickAddChips.tsx +180 -0
  118. package/src/Editing/contrastRatio.tsx +11 -0
  119. package/src/Editing/parseQuickAdd.tsx +187 -0
  120. package/src/Editing/quickAddCore.ts +204 -0
  121. package/src/Editing/timeShorthand.ts +157 -0
  122. package/src/Editing/useQuickAdd.ts +201 -0
  123. package/src/EmergencyCodeCard/README.md +10 -0
  124. package/src/EmptyState/README.md +5 -0
  125. package/src/EngagementTimeline/README.md +3 -0
  126. package/src/ErrorState/README.md +3 -0
  127. package/src/FAQ/README.md +7 -0
  128. package/src/FeatureGrid/README.md +7 -0
  129. package/src/Feedback/Banner.tsx +40 -0
  130. package/src/Feedback/EmptyState.tsx +32 -0
  131. package/src/Feedback/ErrorState.tsx +32 -0
  132. package/src/Feedback/Feedback.shared.tsx +38 -0
  133. package/src/Feedback/Feedback.tsx +18 -0
  134. package/src/Feedback/Feedback.types.ts +40 -0
  135. package/src/Feedback/InlineAlert.tsx +19 -0
  136. package/src/Feedback/RefusalNotice.tsx +46 -0
  137. package/src/Feedback/RegionBoundary.tsx +102 -0
  138. package/src/Feedback/Toast.tsx +31 -0
  139. package/src/Feedback/ToastRegion.tsx +26 -0
  140. package/src/Feedback/UndoToast.tsx +97 -0
  141. package/src/FeedbackWidget/README.md +3 -0
  142. package/src/Field/Field.tsx +81 -0
  143. package/src/FileDrop/README.md +3 -0
  144. package/src/FilePreviewer/README.md +3 -0
  145. package/src/FilterBuilder/README.md +3 -0
  146. package/src/ForceUpdateScreen/README.md +3 -0
  147. package/src/Forms/Checkbox.tsx +14 -0
  148. package/src/Forms/CurrencyInput.tsx +40 -0
  149. package/src/Forms/Forms.shared.tsx +5 -0
  150. package/src/Forms/Forms.tsx +20 -0
  151. package/src/Forms/Forms.types.ts +33 -0
  152. package/src/Forms/Input.tsx +28 -0
  153. package/src/Forms/Money.tsx +15 -0
  154. package/src/Forms/NumberInput.tsx +85 -0
  155. package/src/Forms/Radio.tsx +31 -0
  156. package/src/Forms/Select.tsx +54 -0
  157. package/src/Forms/Switch.tsx +14 -0
  158. package/src/Forms/Textarea.tsx +30 -0
  159. package/src/Gallery/README.md +5 -0
  160. package/src/GateLifecycleRail/README.md +7 -0
  161. package/src/GateReadinessPanel/README.md +8 -0
  162. package/src/Gateway/AgencySlate.tsx +76 -0
  163. package/src/Gateway/ApplicationForm.tsx +48 -0
  164. package/src/Gateway/AvailabilityCalendar.tsx +82 -0
  165. package/src/Gateway/EPKViewer.tsx +77 -0
  166. package/src/Gateway/EngagementTimeline.tsx +43 -0
  167. package/src/Gateway/Gateway.shared.tsx +5 -0
  168. package/src/Gateway/Gateway.tsx +30 -0
  169. package/src/Gateway/Gateway.types.ts +69 -0
  170. package/src/Gateway/OnboardingPacket.tsx +61 -0
  171. package/src/Gateway/OpportunityCard.tsx +73 -0
  172. package/src/Gateway/OpportunityFilters.tsx +64 -0
  173. package/src/Gateway/PaymentTracker.tsx +71 -0
  174. package/src/Gateway/PayoutDetailsForm.tsx +62 -0
  175. package/src/Gateway/ProfileEditor.tsx +45 -0
  176. package/src/Gateway/ProgressBar.tsx +30 -0
  177. package/src/Gateway/RatingDialog.tsx +83 -0
  178. package/src/Gateway/UpNextCard.tsx +76 -0
  179. package/src/Glyphs/Glyphs.tsx +66 -0
  180. package/src/Grids/BidSheet.tsx +63 -0
  181. package/src/Grids/BudgetGrid.tsx +164 -0
  182. package/src/Grids/Grids.shared.tsx +5 -0
  183. package/src/Grids/Grids.tsx +11 -0
  184. package/src/Grids/Grids.types.ts +38 -0
  185. package/src/Grids/SpreadsheetGrid.tsx +445 -0
  186. package/src/Grids/columnTotal.tsx +14 -0
  187. package/src/Grids/glForCode.tsx +11 -0
  188. package/src/Grids/parseCell.tsx +16 -0
  189. package/src/Help/FeedbackWidget.tsx +89 -0
  190. package/src/Help/Help.tsx +14 -0
  191. package/src/Help/Help.types.ts +51 -0
  192. package/src/Help/HelpPanel.tsx +116 -0
  193. package/src/Help/NotificationCenter.tsx +100 -0
  194. package/src/Help/OnboardingChecklist.tsx +57 -0
  195. package/src/Help/ShortcutEditor.tsx +81 -0
  196. package/src/Help/WhatsNew.tsx +33 -0
  197. package/src/HelpPanel/README.md +5 -0
  198. package/src/HoverCard/README.md +3 -0
  199. package/src/Icon/Icon.tsx +47 -0
  200. package/src/Icon/README.md +9 -0
  201. package/src/IconButton/README.md +6 -0
  202. package/src/Identity/BrandSlot.tsx +20 -0
  203. package/src/Identity/BrandSlotFrame.tsx +38 -0
  204. package/src/Identity/CredentialBadge.tsx +92 -0
  205. package/src/Identity/Identity.tsx +14 -0
  206. package/src/Identity/Identity.types.ts +25 -0
  207. package/src/Identity/PresenceIndicator.tsx +37 -0
  208. package/src/Identity/QRCode.tsx +22 -0
  209. package/src/Identity/WhiteLabelPreview.tsx +33 -0
  210. package/src/Identity/qrPath.tsx +16 -0
  211. package/src/Identity/tokenVariable.tsx +9 -0
  212. package/src/InlineAlert/README.md +3 -0
  213. package/src/Input/README.md +8 -0
  214. package/src/Kbd/Kbd.tsx +30 -0
  215. package/src/Kbd/README.md +6 -0
  216. package/src/Layout/AppShell.tsx +151 -0
  217. package/src/Layout/Layout.tsx +14 -0
  218. package/src/Layout/Layout.types.ts +43 -0
  219. package/src/Layout/PageHeader.tsx +22 -0
  220. package/src/Layout/ResizablePanel.tsx +81 -0
  221. package/src/Layout/ScrollRegion.tsx +107 -0
  222. package/src/Layout/SplitView.tsx +78 -0
  223. package/src/Layout/Stepper.tsx +39 -0
  224. package/src/LegalText/LegalText.tsx +289 -0
  225. package/src/LegalText/README.md +10 -0
  226. package/src/LegalText/index.ts +29 -0
  227. package/src/LegalText/legal-markdown.ts +581 -0
  228. package/src/Link/Link.tsx +25 -0
  229. package/src/Link/README.md +5 -0
  230. package/src/Link/link-class.ts +10 -0
  231. package/src/LiveActivity/README.md +3 -0
  232. package/src/LogoSlotWall/README.md +7 -0
  233. package/src/MapView/README.md +5 -0
  234. package/src/Marketing/AIDisclosureBadge.tsx +31 -0
  235. package/src/Marketing/ButtonLink.tsx +32 -0
  236. package/src/Marketing/CodeSample.tsx +47 -0
  237. package/src/Marketing/ComparisonScroll.tsx +7 -0
  238. package/src/Marketing/ComparisonTable.tsx +104 -0
  239. package/src/Marketing/FAQ.tsx +26 -0
  240. package/src/Marketing/FeatureGrid.tsx +65 -0
  241. package/src/Marketing/GateLifecycleRail.tsx +52 -0
  242. package/src/Marketing/LogoSlotWall.tsx +53 -0
  243. package/src/Marketing/Marketing.tsx +49 -0
  244. package/src/Marketing/Marketing.types.ts +64 -0
  245. package/src/Marketing/MarketingFooter.tsx +88 -0
  246. package/src/Marketing/MarketingHero.tsx +45 -0
  247. package/src/Marketing/MarketingNav.tsx +76 -0
  248. package/src/Marketing/MarketingPoints.tsx +16 -0
  249. package/src/Marketing/MarketingSection.tsx +52 -0
  250. package/src/Marketing/PersonaSwitcher.tsx +137 -0
  251. package/src/Marketing/PriceDisplay.tsx +56 -0
  252. package/src/Marketing/PricingTable.tsx +122 -0
  253. package/src/Marketing/ProofStatStrip.tsx +35 -0
  254. package/src/Marketing/ScreenshotFrame.tsx +56 -0
  255. package/src/Marketing/SurfaceTriptych.tsx +43 -0
  256. package/src/Marketing/Testimonial.tsx +45 -0
  257. package/src/Marketing/marketing-copy.ts +25 -0
  258. package/src/Marketing/provided.tsx +36 -0
  259. package/src/MarketingFooter/README.md +7 -0
  260. package/src/MarketingHero/README.md +7 -0
  261. package/src/MarketingNav/README.md +7 -0
  262. package/src/MarketingSection/README.md +7 -0
  263. package/src/Media/FilePreviewer.tsx +86 -0
  264. package/src/Media/MapView.tsx +200 -0
  265. package/src/Media/Media.tsx +11 -0
  266. package/src/Media/Media.types.ts +47 -0
  267. package/src/Media/RichTextEditor.tsx +198 -0
  268. package/src/Media/toLngLat.tsx +13 -0
  269. package/src/Menus/ContextMenu.tsx +106 -0
  270. package/src/Menus/DropdownMenu.tsx +51 -0
  271. package/src/Menus/Menus.shared.tsx +67 -0
  272. package/src/Menus/Menus.tsx +13 -0
  273. package/src/Menus/Menus.types.ts +49 -0
  274. package/src/Menus/OrgSwitcher.tsx +69 -0
  275. package/src/Menus/compactTriggerClass.tsx +7 -0
  276. package/src/Menus/menuClass.tsx +4 -0
  277. package/src/Menus/menuItemClass.tsx +7 -0
  278. package/src/Menus/orgSwitcherTriggerClass.tsx +7 -0
  279. package/src/Money/README.md +6 -0
  280. package/src/MultiSelect/README.md +3 -0
  281. package/src/Navigation/Accordion.tsx +59 -0
  282. package/src/Navigation/Breadcrumbs.tsx +59 -0
  283. package/src/Navigation/MoreFields.tsx +42 -0
  284. package/src/Navigation/Navigation.shared.tsx +32 -0
  285. package/src/Navigation/Navigation.tsx +21 -0
  286. package/src/Navigation/Navigation.types.ts +63 -0
  287. package/src/Navigation/Pagination.tsx +30 -0
  288. package/src/Navigation/SegmentedControl.tsx +87 -0
  289. package/src/Navigation/Sidebar.tsx +106 -0
  290. package/src/Navigation/TabBar.tsx +61 -0
  291. package/src/Navigation/Tabs.tsx +79 -0
  292. package/src/Navigation/TopNav.tsx +86 -0
  293. package/src/Navigation/sidebar-classes.ts +18 -0
  294. package/src/NotificationCenter/README.md +3 -0
  295. package/src/NumberInput/README.md +3 -0
  296. package/src/OfflineBanner/README.md +3 -0
  297. package/src/OnboardingChecklist/README.md +3 -0
  298. package/src/OnboardingPacket/README.md +3 -0
  299. package/src/OpportunityCard/README.md +5 -0
  300. package/src/OpportunityFilters/README.md +3 -0
  301. package/src/OrgChart/README.md +5 -0
  302. package/src/OrgSwitcher/README.md +3 -0
  303. package/src/Overlays/Dialog.tsx +54 -0
  304. package/src/Overlays/Drawer.tsx +62 -0
  305. package/src/Overlays/HoverCard.tsx +59 -0
  306. package/src/Overlays/Overlays.shared.tsx +12 -0
  307. package/src/Overlays/Overlays.tsx +20 -0
  308. package/src/Overlays/Overlays.types.ts +66 -0
  309. package/src/Overlays/Popover.tsx +70 -0
  310. package/src/Overlays/PropertyList.tsx +19 -0
  311. package/src/Overlays/ShortcutSheet.tsx +62 -0
  312. package/src/Overlays/SidePeek.tsx +117 -0
  313. package/src/Overlays/Tooltip.tsx +73 -0
  314. package/src/Overlays/panelClass.tsx +6 -0
  315. package/src/Overlays/popoverPanelClass.tsx +6 -0
  316. package/src/PageHeader/README.md +3 -0
  317. package/src/Pagination/README.md +3 -0
  318. package/src/PaymentTracker/README.md +3 -0
  319. package/src/PayoutDetailsForm/README.md +3 -0
  320. package/src/PersonaSwitcher/README.md +7 -0
  321. package/src/PhaseChip/README.md +5 -0
  322. package/src/PhaseGlyph/README.md +17 -0
  323. package/src/PhotoCapture/README.md +3 -0
  324. package/src/Pickers/Combobox.tsx +91 -0
  325. package/src/Pickers/DatePicker.tsx +60 -0
  326. package/src/Pickers/DateRangePicker.tsx +78 -0
  327. package/src/Pickers/FileDrop.tsx +84 -0
  328. package/src/Pickers/MultiSelect.tsx +118 -0
  329. package/src/Pickers/Pickers.shared.tsx +337 -0
  330. package/src/Pickers/Pickers.tsx +17 -0
  331. package/src/Pickers/Pickers.types.ts +47 -0
  332. package/src/Pickers/Slider.tsx +59 -0
  333. package/src/Pickers/TimePicker.tsx +68 -0
  334. package/src/Pickers/rankOptions.tsx +12 -0
  335. package/src/Popover/README.md +3 -0
  336. package/src/PresenceIndicator/README.md +3 -0
  337. package/src/PriceDisplay/README.md +7 -0
  338. package/src/PricingTable/README.md +9 -0
  339. package/src/ProfileEditor/README.md +3 -0
  340. package/src/ProgressBar/README.md +3 -0
  341. package/src/ProofStatStrip/README.md +7 -0
  342. package/src/PropertyChip/README.md +3 -0
  343. package/src/ProvenanceBadge/README.md +3 -0
  344. package/src/QRCode/README.md +6 -0
  345. package/src/QuickAdd/README.md +5 -0
  346. package/src/QuickIncidentSheet/README.md +3 -0
  347. package/src/Radio/README.md +3 -0
  348. package/src/RadioChannelTable/README.md +7 -0
  349. package/src/RatingDialog/README.md +3 -0
  350. package/src/ReconciliationTable/README.md +3 -0
  351. package/src/RecordKindChip/README.md +3 -0
  352. package/src/RecordKindGlyph/README.md +34 -0
  353. package/src/RecordRow/README.md +7 -0
  354. package/src/RefusalNotice/README.md +5 -0
  355. package/src/ResizablePanel/README.md +3 -0
  356. package/src/ResourceSchedule/README.md +6 -0
  357. package/src/RichTextEditor/README.md +3 -0
  358. package/src/RichTextEditor/extensions.ts +217 -0
  359. package/src/RunOfShowLive/README.md +5 -0
  360. package/src/ScanSheet/README.md +3 -0
  361. package/src/ScreenshotFrame/README.md +7 -0
  362. package/src/ScrollRegion/README.md +9 -0
  363. package/src/SegmentedControl/README.md +5 -0
  364. package/src/Select/README.md +5 -0
  365. package/src/ShiftCard/README.md +3 -0
  366. package/src/ShortcutEditor/README.md +3 -0
  367. package/src/ShortcutSheet/README.md +3 -0
  368. package/src/SidePeek/README.md +6 -0
  369. package/src/Sidebar/README.md +5 -0
  370. package/src/SignaturePad/README.md +3 -0
  371. package/src/Skeleton/README.md +3 -0
  372. package/src/Slider/README.md +3 -0
  373. package/src/SplitView/README.md +3 -0
  374. package/src/SpreadsheetGrid/README.md +9 -0
  375. package/src/StalenessIndicator/README.md +3 -0
  376. package/src/StatTile/README.md +6 -0
  377. package/src/StateChip/README.md +6 -0
  378. package/src/StateIcon/README.md +6 -0
  379. package/src/StateIcon/StateIcon.tsx +127 -0
  380. package/src/StatusHeatmap/README.md +15 -0
  381. package/src/Stepper/README.md +3 -0
  382. package/src/Surface/Skeleton.tsx +21 -0
  383. package/src/Surface/Surface.tsx +63 -0
  384. package/src/SurfaceTriptych/README.md +7 -0
  385. package/src/Switch/README.md +5 -0
  386. package/src/SyncConflictSheet/README.md +3 -0
  387. package/src/TabBar/README.md +7 -0
  388. package/src/Tabs/README.md +6 -0
  389. package/src/Tag/README.md +3 -0
  390. package/src/TemplateAuth/README.md +6 -0
  391. package/src/TemplateCollection/README.md +6 -0
  392. package/src/TemplateDashboard/README.md +8 -0
  393. package/src/TemplateDocument/README.md +5 -0
  394. package/src/TemplateGatewayShell/README.md +5 -0
  395. package/src/TemplateGridEditor/README.md +3 -0
  396. package/src/TemplateRecord/README.md +3 -0
  397. package/src/TemplateSettings/README.md +5 -0
  398. package/src/TemplateSplitView/README.md +3 -0
  399. package/src/TemplateSystem/README.md +5 -0
  400. package/src/TemplateWizard/README.md +3 -0
  401. package/src/Templates/TemplateAuth.tsx +16 -0
  402. package/src/Templates/TemplateCollection.tsx +35 -0
  403. package/src/Templates/TemplateDashboard.tsx +200 -0
  404. package/src/Templates/TemplateDocument.tsx +24 -0
  405. package/src/Templates/TemplateGatewayShell.tsx +36 -0
  406. package/src/Templates/TemplateGridEditor.tsx +17 -0
  407. package/src/Templates/TemplateRecord.tsx +31 -0
  408. package/src/Templates/TemplateSettings.tsx +26 -0
  409. package/src/Templates/TemplateSplitView.tsx +27 -0
  410. package/src/Templates/TemplateSystem.tsx +19 -0
  411. package/src/Templates/TemplateSystemLink.tsx +55 -0
  412. package/src/Templates/TemplateWizard.tsx +43 -0
  413. package/src/Templates/Templates.tsx +29 -0
  414. package/src/Templates/Templates.types.ts +153 -0
  415. package/src/Testimonial/README.md +7 -0
  416. package/src/Textarea/README.md +3 -0
  417. package/src/TimePicker/README.md +5 -0
  418. package/src/Timeline/README.md +6 -0
  419. package/src/Toast/README.md +3 -0
  420. package/src/Tooltip/README.md +3 -0
  421. package/src/TopNav/README.md +5 -0
  422. package/src/TreeView/README.md +3 -0
  423. package/src/URIDChip/README.md +5 -0
  424. package/src/UndoToast/README.md +3 -0
  425. package/src/UpNextCard/README.md +6 -0
  426. package/src/Views/ActivityFeedItem.tsx +52 -0
  427. package/src/Views/Board.tsx +229 -0
  428. package/src/Views/BulkActionBar.tsx +76 -0
  429. package/src/Views/RecordList.tsx +146 -0
  430. package/src/Views/RecordRow.tsx +132 -0
  431. package/src/Views/StatTile.tsx +88 -0
  432. package/src/Views/TreeView.tsx +161 -0
  433. package/src/Views/Views.tsx +18 -0
  434. package/src/Views/Views.types.ts +99 -0
  435. package/src/WhatsNew/README.md +3 -0
  436. package/src/WhiteLabelPreview/README.md +8 -0
  437. package/src/XOS/AccessGridMatrix.tsx +111 -0
  438. package/src/XOS/AssertionRankBadge.tsx +27 -0
  439. package/src/XOS/CoordinateMatrix.tsx +123 -0
  440. package/src/XOS/EmergencyCodeCard.tsx +109 -0
  441. package/src/XOS/GateReadinessPanel.tsx +100 -0
  442. package/src/XOS/ProvenanceBadge.tsx +19 -0
  443. package/src/XOS/RadioChannelTable.tsx +50 -0
  444. package/src/XOS/ReconciliationTable.tsx +64 -0
  445. package/src/XOS/RunOfShowLive.tsx +97 -0
  446. package/src/XOS/StalenessIndicator.tsx +31 -0
  447. package/src/XOS/StatusHeatmap.tsx +200 -0
  448. package/src/XOS/XOS.shared.tsx +90 -0
  449. package/src/XOS/XOS.tsx +29 -0
  450. package/src/XOS/XOS.types.ts +99 -0
  451. package/src/XOS/resolveStep.tsx +16 -0
  452. package/src/brand/defaults/README.md +13 -0
  453. package/src/brand/defaults/app-icon.svg +6 -0
  454. package/src/brand/defaults/favicon.svg +6 -0
  455. package/src/brand/defaults/logo-dark.svg +6 -0
  456. package/src/brand/defaults/logo-light.svg +6 -0
  457. package/src/brand/defaults/splash.svg +6 -0
  458. package/src/index.ts +606 -0
  459. package/src/lib/context.tsx +156 -0
  460. package/src/lib/cx.ts +4 -0
  461. package/src/lib/format.ts +200 -0
  462. package/src/lib/hooks.ts +187 -0
  463. package/src/lib/i18n.ts +97 -0
  464. package/src/lib/icons.ts +45 -0
  465. package/src/lib/live.ts +92 -0
  466. package/src/lib/preferences.ts +242 -0
  467. package/src/lib/route-transition.tsx +22 -0
  468. package/src/lib/selection.ts +92 -0
  469. package/src/lib/shortcut-targets.ts +125 -0
  470. package/src/lib/theme.ts +50 -0
  471. package/src/lib/undo-stack.ts +125 -0
  472. package/src/marketing.ts +33 -0
  473. package/src/pwa/action-outcome.tsx +81 -0
  474. package/src/pwa/analytics.ts +236 -0
  475. package/src/pwa/browser-push.tsx +132 -0
  476. package/src/pwa/client.ts +126 -0
  477. package/src/pwa/index.ts +40 -0
  478. package/src/pwa/offline-key.ts +18 -0
  479. package/src/pwa/service-worker.ts +229 -0
  480. package/src/static.ts +10 -0
  481. package/src/styles/base.css +208 -0
  482. package/src/styles/components.css +453 -0
  483. package/src/styles/index.css +16 -0
  484. package/src/styles/marketing.css +1260 -0
  485. package/src/styles/reference.css +5792 -0
  486. package/src/types/reference.d.ts +1608 -0
  487. package/tailwind.config.cjs +3 -0
@@ -0,0 +1,11 @@
1
+ import type { GLAccount } from "../types/reference";
2
+
3
+ /** The account a role code or URID posts to: its class's one account of the requested type, or null. */
4
+ export function glForCode(
5
+ code: string,
6
+ accounts: GLAccount[],
7
+ type: GLAccount["type"] = "Expense",
8
+ ): GLAccount | null {
9
+ const cls = code.split(".")[0];
10
+ return accounts.find((a) => a.classCode === cls && a.type === type) ?? null;
11
+ }
@@ -0,0 +1,16 @@
1
+ import type { GridColumn } from "../types/reference";
2
+ import { isNumeric } from "./Grids.shared.tsx";
3
+ import { type Cell } from "./Grids.types.ts";
4
+
5
+ /**
6
+ * A typed cell value: a column's own parse decides first; otherwise blank is null, numbers parse (a trailing x on
7
+ * multipliers is dropped) and text stays text.
8
+ */
9
+ export function parseCell(c: GridColumn, text: string): Cell {
10
+ if (c.parse) return c.parse(text);
11
+ const trimmed = text.trim();
12
+ if (trimmed === "") return null;
13
+ if (!isNumeric(c)) return trimmed;
14
+ const n = Number(trimmed.replace(/x$/i, "").replace(/[$,\s]/g, ""));
15
+ return Number.isFinite(n) ? n : null;
16
+ }
@@ -0,0 +1,89 @@
1
+ import { useState, type ReactElement } from "react";
2
+ import { useT } from "../lib/context.tsx";
3
+ import { Icon } from "../Icon/Icon.tsx";
4
+ import { Button } from "../Button/Button.tsx";
5
+ import { Card } from "../Surface/Surface.tsx";
6
+ import { Checkbox, Textarea } from "../Forms/Forms.tsx";
7
+ import { type FeedbackWidgetProps } from "./Help.types.ts";
8
+
9
+ /** Feedback with a privacy note; only what the person chooses is sent. */
10
+ export function FeedbackWidget({
11
+ onSend,
12
+ onCancel,
13
+ screenshotField,
14
+ context,
15
+ thanks,
16
+ }: FeedbackWidgetProps): ReactElement {
17
+ const t = useT();
18
+ const [sent, setSent] = useState(false);
19
+ const [sending, setSending] = useState(false);
20
+ const [failed, setFailed] = useState(false);
21
+ const [text, setText] = useState("");
22
+ const [screenshot, setScreenshot] = useState(false);
23
+ const send = () => {
24
+ const result = onSend?.({ text, screenshot });
25
+ if (!(result instanceof Promise)) {
26
+ setSent(true);
27
+ return;
28
+ }
29
+ setSending(true);
30
+ setFailed(false);
31
+ void result.then(
32
+ (ok) => {
33
+ setSending(false);
34
+ setSent(ok);
35
+ setFailed(!ok);
36
+ },
37
+ () => {
38
+ setSending(false);
39
+ setFailed(true);
40
+ },
41
+ );
42
+ };
43
+ return (
44
+ <Card
45
+ title={t("feedback.title")}
46
+ footer={
47
+ sent ? (
48
+ <span role="status" className="flex items-center gap-6">
49
+ <span className="text-success">
50
+ <Icon name="CircleCheck" />
51
+ </span>
52
+ {thanks ?? t("feedback.thanks")}
53
+ </span>
54
+ ) : (
55
+ <>
56
+ <Button variant="ghost" onClick={onCancel}>
57
+ {t("action.cancel")}
58
+ </Button>
59
+ <Button variant="primary" disabled={!text.trim() || sending} onClick={send}>
60
+ {t("action.send")}
61
+ </Button>
62
+ </>
63
+ )
64
+ }
65
+ >
66
+ <Textarea
67
+ label={t("feedback.question")}
68
+ placeholder={t("feedback.hint")}
69
+ width="100%"
70
+ value={text}
71
+ onChange={(e) => setText(e.target.value)}
72
+ />
73
+ {screenshotField ?? (
74
+ <Checkbox
75
+ label={t("feedback.screenshot")}
76
+ checked={screenshot}
77
+ onChange={(e) => setScreenshot(e.target.checked)}
78
+ />
79
+ )}
80
+ <span className="text-text-12 text-text-secondary">{t("feedback.privacy")}</span>
81
+ {context ? <div className="text-text-12 text-text-secondary">{context}</div> : null}
82
+ {failed ? (
83
+ <span role="alert" className="text-text-12 text-danger-text">
84
+ {t("feedback.failed")}
85
+ </span>
86
+ ) : null}
87
+ </Card>
88
+ );
89
+ }
@@ -0,0 +1,14 @@
1
+ export {
2
+ type NotificationCenterProps,
3
+ type OnboardingChecklistProps,
4
+ type WhatsNewProps,
5
+ type FeedbackWidgetProps,
6
+ type ShortcutEditorProps,
7
+ type HelpPanelProps,
8
+ } from "./Help.types.ts";
9
+ export { NotificationCenter } from "./NotificationCenter.tsx";
10
+ export { OnboardingChecklist } from "./OnboardingChecklist.tsx";
11
+ export { WhatsNew } from "./WhatsNew.tsx";
12
+ export { FeedbackWidget } from "./FeedbackWidget.tsx";
13
+ export { ShortcutEditor } from "./ShortcutEditor.tsx";
14
+ export { HelpPanel } from "./HelpPanel.tsx";
@@ -0,0 +1,51 @@
1
+ import type { ReactNode } from "react";
2
+ import type {
3
+ FeedbackWidgetProps as ReferenceFeedbackWidgetProps,
4
+ HelpPanelProps as ReferenceHelpPanelProps,
5
+ NotificationCenterProps as ReferenceNotificationCenterProps,
6
+ NotificationItem,
7
+ OnboardingChecklistProps as ReferenceOnboardingChecklistProps,
8
+ ShortcutEditorProps as ReferenceShortcutEditorProps,
9
+ WhatsNewProps as ReferenceWhatsNewProps,
10
+ } from "../types/reference";
11
+
12
+ export type NotificationCenterProps = ReferenceNotificationCenterProps & {
13
+ onAction?: (item: NotificationItem) => void;
14
+ onDone?: (item: NotificationItem) => void;
15
+ onSnooze?: (item: NotificationItem) => void;
16
+ };
17
+
18
+ export type OnboardingChecklistProps = ReferenceOnboardingChecklistProps & {
19
+ onAction?: (label: string) => void;
20
+ };
21
+
22
+ export type WhatsNewProps = ReferenceWhatsNewProps;
23
+
24
+ export type FeedbackWidgetProps = ReferenceFeedbackWidgetProps & {
25
+ /**
26
+ * Sends the feedback. A promise holds the widget in its sending state; false keeps the text and says it did not
27
+ * send, so the person can try again.
28
+ */
29
+ onSend?: (feedback: { text: string; screenshot: boolean }) => Promise<boolean> | undefined;
30
+ onCancel?: () => void;
31
+ /** Replaces the screenshot checkbox, for an app that attaches a file the person chooses (A96). */
32
+ screenshotField?: ReactNode;
33
+ /** What goes with the message, shown under the privacy note so nothing is sent unseen (Section 11.7). */
34
+ context?: ReactNode;
35
+ /** The thanks once sent, for example with the reference the platform team quotes. */
36
+ thanks?: string;
37
+ };
38
+
39
+ export type ShortcutEditorProps = ReferenceShortcutEditorProps & {
40
+ onChange?: (action: string) => void;
41
+ onReset?: (action: string) => void;
42
+ };
43
+
44
+ export type HelpPanelProps = ReferenceHelpPanelProps & {
45
+ onSearch?: (query: string) => void;
46
+ onArticle?: (title: string) => void;
47
+ onAsk?: (question: string) => void;
48
+ onWhatsNew?: () => void;
49
+ onContact?: () => void;
50
+ onClose?: () => void;
51
+ };
@@ -0,0 +1,116 @@
1
+ import { useState, type ReactElement } from "react";
2
+ import { cx } from "../lib/cx.ts";
3
+ import { useT } from "../lib/context.tsx";
4
+ import { Icon } from "../Icon/Icon.tsx";
5
+ import { Button, IconButton } from "../Button/Button.tsx";
6
+ import { Keys } from "../Kbd/Kbd.tsx";
7
+ import { linkClass } from "../Link/Link.tsx";
8
+ import { type HelpPanelProps } from "./Help.types.ts";
9
+
10
+ const searchFieldClass = cx(
11
+ "flex items-center gap-8 h-row-default ps-12 pe-8 rounded-control border border-border-control bg-bg-surface",
12
+ "focus-within:outline-solid focus-within:outline-stroke-focus focus-within:outline-focus-ring",
13
+ );
14
+
15
+ const searchInputClass = cx(
16
+ "flex-1 min-w-0 border-0 bg-transparent outline-none text-text-primary placeholder:text-text-tertiary pointer-coarse:min-h-target-coarse",
17
+ );
18
+
19
+ /** Help for this page: search, articles, its shortcuts, the assistant, What's New and support. */
20
+ export function HelpPanel({
21
+ articles,
22
+ shortcuts,
23
+ assistant = false,
24
+ onSearch,
25
+ onArticle,
26
+ onAsk,
27
+ onWhatsNew,
28
+ onContact,
29
+ onClose,
30
+ }: HelpPanelProps): ReactElement {
31
+ const t = useT();
32
+ const [question, setQuestion] = useState("");
33
+ return (
34
+ <aside
35
+ aria-label={t("help.title")}
36
+ className="flex flex-col w-(--layout-sidebar-max) max-w-full max-md:w-full rounded-card bg-bg-raised shadow-dialog"
37
+ >
38
+ <header className="flex items-center justify-between py-8 ps-20 pe-12 border-b border-border-subtle">
39
+ <h2 className="m-0 text-text-13 font-semibold">{t("help.title")}</h2>
40
+ <IconButton icon="X" label={t("action.close")} shortcut={t("key.esc")} onClick={onClose} />
41
+ </header>
42
+ <div className="flex flex-col gap-16 px-20 pt-16 pb-20">
43
+ <label className={searchFieldClass}>
44
+ <Icon name="Search" color="var(--color-text-secondary)" />
45
+ <input
46
+ type="search"
47
+ aria-label={t("help.search")}
48
+ placeholder={t("help.search")}
49
+ onChange={(e) => onSearch?.(e.target.value)}
50
+ className={searchInputClass}
51
+ />
52
+ </label>
53
+ <section>
54
+ <h3 className="m-0 mb-6 text-text-12 font-medium text-text-secondary">
55
+ {t("help.forThisPage")}
56
+ </h3>
57
+ <ul className="flex flex-col gap-6 m-0 p-0 list-none">
58
+ {articles.map((a) => (
59
+ <li key={a}>
60
+ <button
61
+ type="button"
62
+ onClick={() => onArticle?.(a)}
63
+ className={cx(linkClass, "p-0 border-0 bg-transparent cursor-pointer text-start")}
64
+ >
65
+ {a}
66
+ </button>
67
+ </li>
68
+ ))}
69
+ </ul>
70
+ </section>
71
+ <section>
72
+ <h3 className="m-0 mb-6 text-text-12 font-medium text-text-secondary">
73
+ {t("help.shortcuts")}
74
+ </h3>
75
+ {shortcuts.map((s) => (
76
+ <div key={s.label} className="flex items-center justify-between min-h-control-md">
77
+ <span>{s.label}</span>
78
+ <Keys keys={s.keys} />
79
+ </div>
80
+ ))}
81
+ </section>
82
+ {assistant ? (
83
+ <section>
84
+ <h3 className="m-0 mb-6 text-text-12 font-medium text-text-secondary">
85
+ {t("help.assistant")}
86
+ </h3>
87
+ <form
88
+ onSubmit={(e) => {
89
+ e.preventDefault();
90
+ if (question.trim()) onAsk?.(question.trim());
91
+ }}
92
+ className={searchFieldClass}
93
+ >
94
+ <Icon name="Sparkles" color="var(--color-text-secondary)" />
95
+ <input
96
+ aria-label={t("help.ask")}
97
+ placeholder={t("help.ask")}
98
+ value={question}
99
+ onChange={(e) => setQuestion(e.target.value)}
100
+ className={searchInputClass}
101
+ />
102
+ </form>
103
+ </section>
104
+ ) : null}
105
+ <div className="flex flex-wrap gap-8">
106
+ <Button icon="Megaphone" onClick={onWhatsNew}>
107
+ {t("help.whatsNew")}
108
+ </Button>
109
+ <Button icon="LifeBuoy" onClick={onContact}>
110
+ {t("help.contact")}
111
+ </Button>
112
+ </div>
113
+ </div>
114
+ </aside>
115
+ );
116
+ }
@@ -0,0 +1,100 @@
1
+ import { type KeyboardEvent, type ReactElement } from "react";
2
+ import type { NotificationItem } from "../types/reference";
3
+ import { useT } from "../lib/context.tsx";
4
+ import { singleKeyShortcutsEnabled } from "../lib/preferences.ts";
5
+ import { Icon } from "../Icon/Icon.tsx";
6
+ import { Button, IconButton } from "../Button/Button.tsx";
7
+ import { RecordKindGlyph } from "../Glyphs/Glyphs.tsx";
8
+ import { Tabs } from "../Navigation/Navigation.tsx";
9
+ import { type NotificationCenterProps } from "./Help.types.ts";
10
+
11
+ function NotificationList({
12
+ items,
13
+ onAction,
14
+ onDone,
15
+ onSnooze,
16
+ }: { items: NotificationItem[] } & Omit<NotificationCenterProps, "needsYou" | "fyi">) {
17
+ const t = useT();
18
+ const onKey = (e: KeyboardEvent<HTMLLIElement>, item: NotificationItem) => {
19
+ if (e.target !== e.currentTarget) return;
20
+ const key = singleKeyShortcutsEnabled() ? e.key.toLowerCase() : "";
21
+ if (key === "e") onDone?.(item);
22
+ else if (key === "h") onSnooze?.(item);
23
+ else if (e.key === "Enter") onAction?.(item);
24
+ else return;
25
+ e.preventDefault();
26
+ };
27
+ return (
28
+ <ul className="m-0 p-0 list-none">
29
+ {items.map((item, i) => (
30
+ <li
31
+ key={`${item.title}-${i}`}
32
+ tabIndex={0}
33
+ onKeyDown={(e) => onKey(e, item)}
34
+ className="xos-notif-item flex items-center gap-8 py-8 ps-16 pe-8 border-t border-border-subtle first:border-t-0 focus-visible:outline-offset-[calc(var(--stroke-width-focus)*-1)]"
35
+ >
36
+ {item.kind ? (
37
+ <RecordKindGlyph kind={item.kind} color="var(--color-text-secondary)" />
38
+ ) : (
39
+ <Icon name="Bell" />
40
+ )}
41
+ <div className="xos-notif-text flex flex-1 flex-col min-w-0">
42
+ <span className="truncate">{item.title}</span>
43
+ <span className="text-text-secondary">{item.meta}</span>
44
+ </div>
45
+ {item.action ? (
46
+ <Button
47
+ size="sm"
48
+ onClick={() => onAction?.(item)}
49
+ {...(item.actionKey ? { shortcut: item.actionKey } : {})}
50
+ >
51
+ {item.action}
52
+ </Button>
53
+ ) : null}
54
+ <IconButton
55
+ icon="Check"
56
+ label={t("action.done")}
57
+ shortcut="E"
58
+ onClick={() => onDone?.(item)}
59
+ />
60
+ <IconButton
61
+ icon="AlarmClock"
62
+ label={t("action.snooze")}
63
+ shortcut="H"
64
+ onClick={() => onSnooze?.(item)}
65
+ />
66
+ </li>
67
+ ))}
68
+ </ul>
69
+ );
70
+ }
71
+
72
+ /** Needs You and For Your Information. On a focused item E marks it done, H snoozes it and Enter runs its action. */
73
+ export function NotificationCenter({
74
+ needsYou,
75
+ fyi,
76
+ ...handlers
77
+ }: NotificationCenterProps): ReactElement {
78
+ const t = useT();
79
+ return (
80
+ <section
81
+ aria-label={t("inbox.label")}
82
+ className="xos-notif w-(--ui-empty) max-w-full box-border rounded-card border border-border-subtle bg-bg-raised"
83
+ >
84
+ <div className="px-16">
85
+ <Tabs
86
+ label={t("inbox.label")}
87
+ value="needs"
88
+ tabs={[
89
+ { value: "needs", label: t("inbox.needsYou"), count: needsYou.length },
90
+ { value: "fyi", label: t("inbox.fyi"), count: fyi.length },
91
+ ]}
92
+ panels={{
93
+ needs: <NotificationList items={needsYou} {...handlers} />,
94
+ fyi: <NotificationList items={fyi} {...handlers} />,
95
+ }}
96
+ />
97
+ </div>
98
+ </section>
99
+ );
100
+ }
@@ -0,0 +1,57 @@
1
+ import { type ReactElement } from "react";
2
+ import { cx } from "../lib/cx.ts";
3
+ import { useT } from "../lib/context.tsx";
4
+ import { Icon } from "../Icon/Icon.tsx";
5
+ import { Button } from "../Button/Button.tsx";
6
+ import { Card } from "../Surface/Surface.tsx";
7
+ import { type OnboardingChecklistProps } from "./Help.types.ts";
8
+
9
+ /** First-run steps with progress; done steps are struck through. */
10
+ export function OnboardingChecklist({
11
+ title,
12
+ steps,
13
+ onAction,
14
+ }: OnboardingChecklistProps): ReactElement {
15
+ const t = useT();
16
+ const done = steps.filter((s) => s.done).length;
17
+ return (
18
+ <Card title={title} meta={t("count.of", { n: done, total: steps.length })}>
19
+ <div
20
+ role="progressbar"
21
+ aria-label={title}
22
+ aria-valuenow={done}
23
+ aria-valuemin={0}
24
+ aria-valuemax={steps.length}
25
+ className="h-(--space-4) rounded-pill bg-bg-hover overflow-hidden"
26
+ >
27
+ <div
28
+ className="h-full rounded-pill bg-accent"
29
+ style={{ inlineSize: `${steps.length ? (done / steps.length) * 100 : 0}%` }}
30
+ />
31
+ </div>
32
+ <ol className="flex flex-col m-0 p-0 list-none">
33
+ {steps.map((s) => (
34
+ <li
35
+ key={s.label}
36
+ className="flex items-center gap-8 min-h-(--space-40) border-b border-border-subtle last:border-b-0"
37
+ >
38
+ <span className={s.done ? "text-success" : "text-text-tertiary"}>
39
+ <Icon
40
+ name={s.done ? "CircleCheck" : "Circle"}
41
+ {...(s.done ? { label: t("action.done") } : {})}
42
+ />
43
+ </span>
44
+ <span className={cx("flex-1", s.done && "text-text-secondary line-through")}>
45
+ {s.label}
46
+ </span>
47
+ {!s.done && s.action ? (
48
+ <Button size="sm" onClick={() => onAction?.(s.label)}>
49
+ {s.action}
50
+ </Button>
51
+ ) : null}
52
+ </li>
53
+ ))}
54
+ </ol>
55
+ </Card>
56
+ );
57
+ }
@@ -0,0 +1,81 @@
1
+ import { type ReactElement } from "react";
2
+ import { cx } from "../lib/cx.ts";
3
+ import { useT } from "../lib/context.tsx";
4
+ import { Icon } from "../Icon/Icon.tsx";
5
+ import { Button } from "../Button/Button.tsx";
6
+ import { Keys } from "../Kbd/Kbd.tsx";
7
+ import { ScrollRegion } from "../Layout/Layout.tsx";
8
+ import { type ShortcutEditorProps } from "./Help.types.ts";
9
+
10
+ /**
11
+ * Every action's shortcut with conflicts named in place; Change records new keys, Reset restores a
12
+ * custom one. An action without keys reads Not set.
13
+ */
14
+ export function ShortcutEditor({
15
+ label,
16
+ rows,
17
+ onChange,
18
+ onReset,
19
+ }: ShortcutEditorProps): ReactElement {
20
+ const t = useT();
21
+ const th = cx(
22
+ "h-control-lg px-12 text-start font-medium text-text-12 text-text-secondary bg-bg-surface border-b border-border-subtle",
23
+ );
24
+ const td = cx("h-row-default px-12 border-b border-border-subtle");
25
+ return (
26
+ <ScrollRegion label={label ?? t("shortcuts.title")}>
27
+ <table className="w-full border-collapse text-text-13">
28
+ <thead>
29
+ <tr>
30
+ <th scope="col" className={th}>
31
+ {t("shortcutEditor.action")}
32
+ </th>
33
+ <th scope="col" className={th}>
34
+ {t("shortcutEditor.shortcut")}
35
+ </th>
36
+ <th scope="col" className={th}>
37
+ <span className="sr-only">{t("shortcutEditor.edit")}</span>
38
+ </th>
39
+ </tr>
40
+ </thead>
41
+ <tbody>
42
+ {rows.map((r) => (
43
+ <tr key={r.action}>
44
+ <td className={td}>{r.action}</td>
45
+ <td className={td}>
46
+ <span className="inline-flex flex-wrap items-center gap-8">
47
+ {r.keys.trim() === "" ? (
48
+ <span className="text-text-secondary">{t("shortcutEditor.none")}</span>
49
+ ) : (
50
+ <Keys keys={r.keys} />
51
+ )}
52
+ {r.conflict ? (
53
+ <span className="inline-flex items-center gap-4 text-text-12 text-danger-text">
54
+ <Icon name="alert" size={12} />
55
+ {r.conflict}
56
+ </span>
57
+ ) : null}
58
+ </span>
59
+ </td>
60
+ <td className={cx(td, "text-end whitespace-nowrap")}>
61
+ <Button
62
+ size="sm"
63
+ variant="ghost"
64
+ aria-pressed={r.recording ?? false}
65
+ onClick={() => onChange?.(r.action)}
66
+ >
67
+ {r.recording ? t("shortcutEditor.press") : t("shortcutEditor.change")}
68
+ </Button>
69
+ {r.custom ? (
70
+ <Button size="sm" variant="ghost" onClick={() => onReset?.(r.action)}>
71
+ {t("action.reset")}
72
+ </Button>
73
+ ) : null}
74
+ </td>
75
+ </tr>
76
+ ))}
77
+ </tbody>
78
+ </table>
79
+ </ScrollRegion>
80
+ );
81
+ }
@@ -0,0 +1,33 @@
1
+ import { type ReactElement } from "react";
2
+ import { useT } from "../lib/context.tsx";
3
+ import { Tag } from "../Chips/Chips.tsx";
4
+ import { cardBodyClass, cardClass, cardHeadClass } from "../Surface/Surface.tsx";
5
+ import { linkClass } from "../Link/Link.tsx";
6
+ import { type WhatsNewProps } from "./Help.types.ts";
7
+
8
+ /** Recent changes with a link to the full changelog. */
9
+ export function WhatsNew({ changelogHref, entries }: WhatsNewProps): ReactElement {
10
+ const t = useT();
11
+ return (
12
+ <section aria-label={t("whatsNew.title")} className={cardClass}>
13
+ <header className={cardHeadClass}>
14
+ <h2 className="m-0 text-text-13 font-semibold">{t("whatsNew.title")}</h2>
15
+ <a href={changelogHref} className={linkClass}>
16
+ {t("whatsNew.changelog")}
17
+ </a>
18
+ </header>
19
+ <div className={cardBodyClass}>
20
+ {entries.map((e) => (
21
+ <article key={e.title} className="flex flex-col gap-4">
22
+ <div className="flex items-center gap-6">
23
+ <Tag tone={e.tone ?? "accent"}>{e.label}</Tag>
24
+ <span className="text-text-secondary">{e.date}</span>
25
+ </div>
26
+ <h3 className="m-0 text-text-13 font-semibold">{e.title}</h3>
27
+ <p className="m-0 text-text-secondary">{e.body}</p>
28
+ </article>
29
+ ))}
30
+ </div>
31
+ </section>
32
+ );
33
+ }
@@ -0,0 +1,5 @@
1
+ # HelpPanel
2
+
3
+ HelpPanel opens with the Help button or `?` in every shell: articles for the current page, shortcuts, the assistant (when the org turns it on), What's New and Contact Support.
4
+
5
+ - Articles are mapped by route in the help content; canon terms open their Bible definition in a hover card.
@@ -0,0 +1,3 @@
1
+ # HoverCard
2
+
3
+ HoverCard previews a record after 400 ms on its key: title, state, owner and next date.
@@ -0,0 +1,47 @@
1
+ import type { ReactElement } from "react";
2
+ import type { IconProps as ReferenceIconProps } from "../types/reference";
3
+ import { cx } from "../lib/cx.ts";
4
+ import { iconSpriteUrl, iconSymbol, isMirrored } from "../lib/icons.ts";
5
+
6
+ export type IconProps = ReferenceIconProps;
7
+
8
+ /**
9
+ * Draws a registered lucide icon at 1.5 stroke, sized from the icon tokens (16 by default), from the
10
+ * cached icon sprite (`<use href>`, ADR 0027), so no icon geometry ships in page JavaScript.
11
+ * Decorative unless `label` says the icon carries meaning alone; a labelled icon is an image named
12
+ * by its title.
13
+ */
14
+ export function Icon({
15
+ name,
16
+ size = 16,
17
+ label,
18
+ color,
19
+ className,
20
+ strokeWidth = 1.5,
21
+ }: IconProps): ReactElement {
22
+ const a11y = label ? { role: "img", "aria-label": label } : { "aria-hidden": true as const };
23
+ return (
24
+ <svg
25
+ xmlns="http://www.w3.org/2000/svg"
26
+ width={size}
27
+ height={size}
28
+ viewBox="0 0 24 24"
29
+ fill="none"
30
+ stroke="currentColor"
31
+ strokeWidth={strokeWidth}
32
+ strokeLinecap="round"
33
+ strokeLinejoin="round"
34
+ focusable="false"
35
+ {...a11y}
36
+ className={cx(
37
+ "inline-block flex-none align-middle",
38
+ isMirrored(name) && "xos-flip-rtl",
39
+ className,
40
+ )}
41
+ style={color === undefined ? undefined : { color }}
42
+ >
43
+ {label ? <title>{label}</title> : null}
44
+ <use href={`${iconSpriteUrl}#${iconSymbol(name)}`} />
45
+ </svg>
46
+ );
47
+ }
@@ -0,0 +1,9 @@
1
+ # Icon
2
+
3
+ Icon draws a registered lucide icon at 1.5 stroke, sized from the `icon-*` tokens.
4
+
5
+ - `name` takes PascalCase (`Hammer`) or kebab-case (`chevron-right`); a few short aliases are kept: `more`, `alert`, `check-circle`, `pin`, `home`, `undo`.
6
+ - Icons inherit `currentColor`. Pass `label` only when the icon carries meaning alone: the icon is then an image named by its label and a `<title>`. Otherwise it is hidden from screen readers.
7
+ - Icons draw from one SVG sprite (`@xos/icons/sprite.svg`) with `<use href>`, so no icon geometry ships in page JavaScript (ADR 0027). The bundler emits the sprite with a content hash under `/_next/static/media`, and browsers cache it as a static asset.
8
+ - Names come from the `@xos/icons` registry, the closed set the sprite is built from (RRR-70). To draw a new icon by name, add it to `packages/icons/registry/<owner>.txt` and run `pnpm --filter @xos/icons generate:registry`, which rewrites the sprite too. A name outside the registry renders an empty square of the same size and, in development, logs one console warning.
9
+ - For canon objects use DepartmentGlyph, PhaseGlyph and RecordKindGlyph so the assignment stays in one place.
@@ -0,0 +1,6 @@
1
+ # IconButton
2
+
3
+ IconButton is a square 28 px control with a single 16 px icon and a required accessible label.
4
+
5
+ - `label` becomes `aria-label` and the tooltip text; `shortcut` is appended to the tooltip.
6
+ - Use only for well-known actions (close, more, search, add). Anything else gets a text Button.
@@ -0,0 +1,20 @@
1
+ import { type ReactElement } from "react";
2
+ import { useT } from "../lib/context.tsx";
3
+ import { BrandSlotFrame } from "./BrandSlotFrame.tsx";
4
+ import { type BrandSlotProps } from "./Identity.types.ts";
5
+
6
+ /**
7
+ * Marks where a tenant uploads a brand file, drawn in proportion (at most 160 by 148) with its
8
+ * delivery size and formats.
9
+ */
10
+ export function BrandSlot({ width, height, ...slot }: BrandSlotProps): ReactElement {
11
+ const t = useT();
12
+ return (
13
+ <BrandSlotFrame
14
+ {...slot}
15
+ width={width}
16
+ height={height}
17
+ sizeLabel={t("brand.size", { width, height })}
18
+ />
19
+ );
20
+ }