@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,179 @@
1
+ import { useState, type ReactElement, type ReactNode } from "react";
2
+ import { Command } from "cmdk";
3
+ import { Dialog as RDialog } from "radix-ui";
4
+ import type {
5
+ CommandMenuProps as ReferenceCommandMenuProps,
6
+ IconName,
7
+ RecordState,
8
+ } from "../types/reference";
9
+ import { cx } from "../lib/cx.ts";
10
+ import { useT } from "../lib/context.tsx";
11
+ import { useControllable, useHotkey, useReturnFocus } from "../lib/hooks.ts";
12
+ import { Icon } from "../Icon/Icon.tsx";
13
+ import { Kbd, Keys } from "../Kbd/Kbd.tsx";
14
+ import { StateIcon } from "../StateIcon/StateIcon.tsx";
15
+ import { panelClass } from "../Overlays/Overlays.tsx";
16
+
17
+ export interface CommandItem {
18
+ label: string;
19
+ code?: string;
20
+ icon?: IconName;
21
+ state?: RecordState;
22
+ shortcut?: string;
23
+ selected?: boolean;
24
+ onSelect?: () => void;
25
+ /** Keeps the menu open after the item runs, for an item that edits the search (an operator hint). */
26
+ keepOpen?: boolean;
27
+ }
28
+
29
+ export type CommandMenuProps = Omit<ReferenceCommandMenuProps, "groups"> & {
30
+ groups: { label: string; items: CommandItem[] }[];
31
+ /** Called as the search text changes, for server-side results. With `query`, the text is controlled. */
32
+ onQueryChange?: (query: string) => void;
33
+ /** Shown between the search field and the results, for example the filters a query recognized. */
34
+ header?: ReactNode;
35
+ /** Dialog mode: the menu opens over the page. Omit `open` to render the palette inline. */
36
+ open?: boolean;
37
+ onOpenChange?: (open: boolean) => void;
38
+ /** In dialog mode, Cmd or Ctrl+K toggles the menu (on by default). */
39
+ hotkey?: boolean;
40
+ /** Turn off client filtering when the results come from a server search. */
41
+ filter?: boolean;
42
+ /** Names the menu for assistive technology; the command menu's own name by default. */
43
+ label?: string;
44
+ };
45
+
46
+ function itemValue(group: string, item: CommandItem): string {
47
+ return `${group} ${item.label} ${item.code ?? ""}`.trim();
48
+ }
49
+
50
+ function Palette({
51
+ query,
52
+ placeholder: hint,
53
+ groups,
54
+ onQueryChange,
55
+ filter = true,
56
+ header,
57
+ label,
58
+ onClose,
59
+ }: CommandMenuProps & { onClose?: () => void }) {
60
+ const t = useT();
61
+ const [search, setSearch] = useControllable<string>(query, "", onQueryChange);
62
+ const selected = groups.flatMap((g) =>
63
+ g.items.filter((i) => i.selected).map((i) => itemValue(g.label, i)),
64
+ )[0];
65
+ // With server results (filter off) nothing re-ranks the list, so a new search, or new results for it,
66
+ // move the highlight to the first item, and Enter runs what the person sees first.
67
+ const lead =
68
+ selected ?? groups.flatMap((g) => g.items.map((i) => itemValue(g.label, i)))[0] ?? "";
69
+ const [highlight, setHighlight] = useState(lead);
70
+ const [highlightFor, setHighlightFor] = useState(`${search}\u0000${lead}`);
71
+ if (!filter && highlightFor !== `${search}\u0000${lead}`) {
72
+ setHighlightFor(`${search}\u0000${lead}`);
73
+ setHighlight(lead);
74
+ }
75
+ return (
76
+ <Command
77
+ label={label ?? t("command.label")}
78
+ shouldFilter={filter}
79
+ loop
80
+ {...(filter
81
+ ? selected
82
+ ? { defaultValue: selected }
83
+ : {}
84
+ : { value: highlight, onValueChange: setHighlight })}
85
+ className={cx(panelClass, "xos-anim-dialog w-(--ui-command) overflow-hidden")}
86
+ >
87
+ <div className="flex items-center gap-8 h-(--ui-cmd-input) px-16 border-b border-border-subtle text-text-14">
88
+ <Icon name="search" color="var(--color-text-secondary)" />
89
+ <Command.Input
90
+ value={search}
91
+ onValueChange={setSearch}
92
+ placeholder={hint}
93
+ className="flex-1 min-w-0 bg-transparent border-0 outline-none text-text-primary placeholder:text-text-tertiary"
94
+ />
95
+ <Kbd>{t("key.esc")}</Kbd>
96
+ </div>
97
+ {header}
98
+ <Command.Empty className="px-16 py-12 text-text-secondary">{t("list.noMatch")}</Command.Empty>
99
+ <Command.List
100
+ label={t("command.results")}
101
+ className="max-h-(--ui-listbox-max) overflow-y-auto p-8 pt-4"
102
+ >
103
+ {groups.map((g, groupIndex) => (
104
+ <Command.Group
105
+ // Two groups may share a label (a caller's own results and pages); the index keeps them apart.
106
+ key={`${groupIndex}:${g.label}`}
107
+ heading={g.label}
108
+ className="[&_[cmdk-group-heading]]:mx-8 [&_[cmdk-group-heading]]:mt-8 [&_[cmdk-group-heading]]:mb-4 [&_[cmdk-group-heading]]:text-text-11 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-text-secondary"
109
+ >
110
+ {g.items.map((item) => (
111
+ <Command.Item
112
+ key={itemValue(g.label, item)}
113
+ value={itemValue(g.label, item)}
114
+ onSelect={() => {
115
+ item.onSelect?.();
116
+ if (!item.keepOpen) onClose?.();
117
+ }}
118
+ className={cx(
119
+ "flex items-center gap-8 h-row-default px-8 rounded-control text-text-primary cursor-pointer",
120
+ "data-[selected=true]:bg-bg-hover pointer-coarse:min-h-target-coarse [&_svg]:text-text-secondary",
121
+ )}
122
+ >
123
+ {item.state ? (
124
+ <StateIcon state={item.state} />
125
+ ) : (
126
+ <Icon name={item.icon ?? "chevron-right"} />
127
+ )}
128
+ <span>{item.label}</span>
129
+ {item.code ? (
130
+ <span className="font-mono text-text-12 text-text-secondary">{item.code}</span>
131
+ ) : null}
132
+ {item.shortcut ? (
133
+ <span className="ms-auto">
134
+ <Keys keys={item.shortcut} />
135
+ </span>
136
+ ) : null}
137
+ </Command.Item>
138
+ ))}
139
+ </Command.Group>
140
+ ))}
141
+ </Command.List>
142
+ </Command>
143
+ );
144
+ }
145
+
146
+ /**
147
+ * Finds records, people, pages, settings and actions. Inline by default; with `open` it is a dialog
148
+ * that Cmd or Ctrl+K toggles. Arrow keys move, Enter runs, Esc closes.
149
+ */
150
+ export function CommandMenu({
151
+ open,
152
+ onOpenChange,
153
+ hotkey = true,
154
+ ...props
155
+ }: CommandMenuProps): ReactElement {
156
+ const t = useT();
157
+ const dialog = open !== undefined;
158
+ const [isOpen, setOpen] = useControllable(open, false, onOpenChange);
159
+ useHotkey("k", () => setOpen(!isOpen), { mod: true, enabled: dialog && hotkey });
160
+ const returnFocus = useReturnFocus(dialog && isOpen);
161
+ if (!dialog) return <Palette {...props} />;
162
+ return (
163
+ <RDialog.Root open={isOpen} onOpenChange={setOpen}>
164
+ <RDialog.Portal>
165
+ <RDialog.Overlay className="xos-anim-fade fixed inset-0 z-command bg-scrim opacity-scrim-dark in-data-[theme=light]:opacity-scrim-light in-data-[theme=sunlight]:opacity-scrim-light" />
166
+ <div className="pointer-events-none fixed inset-0 z-command flex justify-center px-16 pt-64">
167
+ <RDialog.Content
168
+ aria-describedby={undefined}
169
+ onCloseAutoFocus={returnFocus}
170
+ className="pointer-events-auto h-fit max-w-full"
171
+ >
172
+ <RDialog.Title className="sr-only">{props.label ?? t("command.label")}</RDialog.Title>
173
+ <Palette {...props} onClose={() => setOpen(false)} />
174
+ </RDialog.Content>
175
+ </div>
176
+ </RDialog.Portal>
177
+ </RDialog.Root>
178
+ );
179
+ }
@@ -0,0 +1,5 @@
1
+ # CommandMenu
2
+
3
+ CommandMenu opens with Cmd or Ctrl+K everywhere and finds records, people, pages, settings and actions.
4
+
5
+ - Results group by type; the last 50 viewed records show before typing.
@@ -0,0 +1,9 @@
1
+ # ComparisonTable
2
+
3
+ ComparisonTable compares one product with others, feature by feature, in a real table.
4
+
5
+ Every cell carries a word beside its icon: Yes, Partial, No or Unpublished. Unpublished means the other product's public pages do not state the feature; it never means the feature is absent. The caption states when the cells were last verified, and a cell may link to its source. The own-product column is marked with `highlight`.
6
+
7
+ From bp-md the table scrolls inside a labeled region with sticky row headers. Below bp-md it stacks into one card per feature with each product on its own labeled line, and explicit table roles keep it a table for screen readers. Sorting is off by design.
8
+
9
+ The consumer provides only rows where its own product is shipped and each other cell has a dated source. Other products' names appear in plain text, never as logos. The preview uses neutral product names.
@@ -0,0 +1,128 @@
1
+ import { useEffect, 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 } from "../Button/Button.tsx";
6
+ import { Textarea } from "../Forms/Forms.tsx";
7
+ import { Phone } from "./Compass.shared.tsx";
8
+ import { type ChecklistRunnerProps } from "./Compass.types.ts";
9
+
10
+ function BigChoice({
11
+ pass,
12
+ on,
13
+ label,
14
+ onClick,
15
+ }: {
16
+ pass: boolean;
17
+ on: boolean;
18
+ label: string;
19
+ onClick: () => void;
20
+ }): ReactElement {
21
+ return (
22
+ <button
23
+ type="button"
24
+ aria-pressed={on}
25
+ onClick={onClick}
26
+ className={cx(
27
+ "flex flex-col items-center justify-center gap-4 h-(--ui-compass-thumb) border-0 rounded-dialog",
28
+ "text-heading-20 font-semibold cursor-pointer text-text-primary forced-colors:border forced-colors:border-[CanvasText]",
29
+ "focus-visible:outline-stroke-focus focus-visible:outline-offset-2 focus-visible:outline-focus-ring",
30
+ on
31
+ ? cx(
32
+ "bg-bg-hover ring-(length:--stroke-width-focus) ring-inset",
33
+ pass ? "ring-success" : "ring-danger",
34
+ )
35
+ : "bg-bg-surface ring-(length:--ui-hairline-half) ring-inset ring-border-control",
36
+ )}
37
+ >
38
+ <Icon
39
+ name={pass ? "Check" : "X"}
40
+ size={28}
41
+ className={pass ? "text-success" : "text-danger"}
42
+ />
43
+ {label}
44
+ </button>
45
+ );
46
+ }
47
+
48
+ /** Inspection runner: one item per card, large Pass and Fail; a Fail asks for a photo and a note. */
49
+ export function ChecklistRunner({
50
+ frame,
51
+ title,
52
+ index,
53
+ items,
54
+ onResult,
55
+ onAddPhoto,
56
+ onNoteChange,
57
+ }: ChecklistRunnerProps): ReactElement {
58
+ const t = useT();
59
+ const [results, setResults] = useState(() => items.map((i) => i.result));
60
+ useEffect(() => setResults(items.map((i) => i.result)), [items]);
61
+ const item = items[index];
62
+ const done = results.filter(Boolean).length;
63
+ const percent = items.length ? Math.round((done / items.length) * 100) : 0;
64
+ const result = results[index] ?? null;
65
+ const choose = (next: "pass" | "fail") => {
66
+ if (!item) return;
67
+ setResults((prev) => prev.map((r, i) => (i === index ? next : r)));
68
+ onResult?.(item.code, next);
69
+ };
70
+ return (
71
+ <Phone frame={frame}>
72
+ <div className="flex flex-col gap-12 p-16">
73
+ <div className="flex justify-between text-text-12 text-text-secondary">
74
+ <strong className="text-text-primary">{title}</strong>
75
+ <span className="tabular-nums">
76
+ {t("count.of", { n: index + 1, total: items.length })}
77
+ </span>
78
+ </div>
79
+ <div
80
+ role="progressbar"
81
+ aria-label={title}
82
+ aria-valuemin={0}
83
+ aria-valuemax={100}
84
+ aria-valuenow={percent}
85
+ className="h-4 rounded-pill bg-bg-hover overflow-hidden"
86
+ >
87
+ <div
88
+ className="h-full rounded-pill bg-accent forced-colors:bg-[CanvasText]"
89
+ style={{ inlineSize: `${percent}%` }}
90
+ />
91
+ </div>
92
+ {item ? (
93
+ <article className="flex flex-col gap-8 p-20 min-h-(--ui-compass-card-min) bg-bg-raised border border-border-subtle rounded-dialog">
94
+ <span className="font-mono text-mono-12 text-text-secondary">{item.code}</span>
95
+ <strong className="text-heading-20 font-semibold">{item.label}</strong>
96
+ {item.help ? <span className="text-text-secondary">{item.help}</span> : null}
97
+ {result === "fail" ? (
98
+ <div className="flex flex-col gap-8">
99
+ <Button icon="Camera" size="lg" onClick={() => onAddPhoto?.(item.code)}>
100
+ {t("inspection.addPhoto")}
101
+ </Button>
102
+ <Textarea
103
+ label={t("inspection.whatFailed")}
104
+ width="100%"
105
+ onChange={(e) => onNoteChange?.(item.code, e.target.value)}
106
+ />
107
+ </div>
108
+ ) : null}
109
+ </article>
110
+ ) : null}
111
+ <div className="grid grid-cols-2 gap-12">
112
+ <BigChoice
113
+ pass={false}
114
+ on={result === "fail"}
115
+ label={t("inspection.fail")}
116
+ onClick={() => choose("fail")}
117
+ />
118
+ <BigChoice
119
+ pass
120
+ on={result === "pass"}
121
+ label={t("inspection.pass")}
122
+ onClick={() => choose("pass")}
123
+ />
124
+ </div>
125
+ </div>
126
+ </Phone>
127
+ );
128
+ }
@@ -0,0 +1,57 @@
1
+ import { type ReactElement } from "react";
2
+ import { cx } from "../lib/cx.ts";
3
+ import { Icon } from "../Icon/Icon.tsx";
4
+ import { compassText } from "./Compass.shared.tsx";
5
+ import { type ClockButtonProps } from "./Compass.types.ts";
6
+
7
+ const CLOCK_STATE: Record<NonNullable<ClockButtonProps["state"]>, string> = {
8
+ out: "bg-accent text-accent-text-on",
9
+ on: "bg-bg-raised text-text-primary ring-(length:--stroke-width-focus) ring-inset ring-success",
10
+ break:
11
+ "bg-bg-raised text-text-primary ring-(length:--stroke-width-focus) ring-inset ring-warning",
12
+ blocked:
13
+ "bg-bg-surface text-text-secondary ring-(length:--stroke-width-hairline) ring-inset ring-border-strong cursor-not-allowed",
14
+ };
15
+
16
+ /** The Today screen's one primary control; it changes with the person's state. */
17
+ export function ClockButton({
18
+ state = "out",
19
+ label,
20
+ detail,
21
+ timer,
22
+ geofence,
23
+ geofenceOk,
24
+ onClick,
25
+ }: ClockButtonProps): ReactElement {
26
+ const blocked = state === "blocked";
27
+ return (
28
+ <div
29
+ className={cx(
30
+ "xos-compass flex flex-col items-stretch gap-8 w-(--ui-compass-card) max-w-full",
31
+ compassText,
32
+ )}
33
+ >
34
+ {geofence ? (
35
+ <span className="inline-flex items-center gap-6 text-text-14 text-text-secondary">
36
+ <Icon name="MapPin" size={16} className={geofenceOk ? "text-success" : "text-warning"} />
37
+ {geofence}
38
+ </span>
39
+ ) : null}
40
+ <button
41
+ type="button"
42
+ aria-disabled={blocked ? true : undefined}
43
+ onClick={blocked ? undefined : onClick}
44
+ className={cx(
45
+ "flex flex-col items-center justify-center gap-4 w-full min-h-(--ui-compass-thumb) p-16 border-0 rounded-dialog",
46
+ "text-heading-20 font-semibold cursor-pointer",
47
+ "focus-visible:outline-stroke-focus focus-visible:outline-offset-2 focus-visible:outline-focus-ring",
48
+ CLOCK_STATE[state],
49
+ )}
50
+ >
51
+ {timer ? <span className="text-heading-32 tabular-nums">{timer}</span> : null}
52
+ <span>{label}</span>
53
+ {detail ? <small className="text-text-14 font-regular">{detail}</small> : null}
54
+ </button>
55
+ </div>
56
+ );
57
+ }
@@ -0,0 +1,58 @@
1
+ import { type ReactElement, type ReactNode } from "react";
2
+ import { cx } from "../lib/cx.ts";
3
+
4
+ export const compassText = "font-sans text-text-16 text-text-primary";
5
+
6
+ export const blockClass = "w-full justify-center";
7
+
8
+ export function Phone({
9
+ frame,
10
+ tall,
11
+ children,
12
+ }: {
13
+ frame?: boolean | undefined;
14
+ tall?: boolean;
15
+ children: ReactNode;
16
+ }): ReactElement {
17
+ return (
18
+ <div
19
+ className={cx(
20
+ "xos-compass",
21
+ compassText,
22
+ frame &&
23
+ "flex flex-col justify-end w-(--ui-tabbar) max-w-full box-border overflow-hidden bg-bg-canvas border border-border-subtle rounded-device",
24
+ frame && tall && "min-h-(--ui-photo-view)",
25
+ )}
26
+ >
27
+ {children}
28
+ </div>
29
+ );
30
+ }
31
+
32
+ export function SheetFrame({
33
+ title,
34
+ step,
35
+ children,
36
+ }: {
37
+ title: string;
38
+ step?: string;
39
+ children: ReactNode;
40
+ }): ReactElement {
41
+ return (
42
+ <div
43
+ role="dialog"
44
+ aria-label={title}
45
+ className="flex flex-col gap-16 px-16 pt-8 pb-24 bg-bg-raised rounded-t-dialog shadow-dialog"
46
+ >
47
+ <span
48
+ aria-hidden="true"
49
+ className="self-center w-(--ui-grabber-inline) h-(--ui-grabber-block) rounded-pill bg-border-strong"
50
+ />
51
+ <header className="flex items-baseline justify-between">
52
+ <strong className="text-heading-20 font-semibold">{title}</strong>
53
+ {step ? <span className="text-text-secondary tabular-nums">{step}</span> : null}
54
+ </header>
55
+ {children}
56
+ </div>
57
+ );
58
+ }
@@ -0,0 +1,26 @@
1
+ export {
2
+ type ClockButtonProps,
3
+ type ScanSheetProps,
4
+ type OfflineBannerProps,
5
+ type QuickIncidentSheetProps,
6
+ type ChecklistRunnerProps,
7
+ type ShiftCardProps,
8
+ type DaySheetViewProps,
9
+ type SignaturePadProps,
10
+ type PhotoCaptureProps,
11
+ type LiveActivityProps,
12
+ type ForceUpdateScreenProps,
13
+ type SyncConflictSheetProps,
14
+ } from "./Compass.types.ts";
15
+ export { ClockButton } from "./ClockButton.tsx";
16
+ export { ScanSheet } from "./ScanSheet.tsx";
17
+ export { OfflineBanner } from "./OfflineBanner.tsx";
18
+ export { QuickIncidentSheet } from "./QuickIncidentSheet.tsx";
19
+ export { ChecklistRunner } from "./ChecklistRunner.tsx";
20
+ export { ShiftCard } from "./ShiftCard.tsx";
21
+ export { DaySheetView } from "./DaySheetView.tsx";
22
+ export { SignaturePad } from "./SignaturePad.tsx";
23
+ export { PhotoCapture } from "./PhotoCapture.tsx";
24
+ export { LiveActivity } from "./LiveActivity.tsx";
25
+ export { ForceUpdateScreen } from "./ForceUpdateScreen.tsx";
26
+ export { SyncConflictSheet } from "./SyncConflictSheet.tsx";
@@ -0,0 +1,79 @@
1
+ import { type ReactNode } from "react";
2
+ import type {
3
+ ChecklistRunnerProps as ReferenceChecklistRunnerProps,
4
+ ClockButtonProps as ReferenceClockButtonProps,
5
+ DaySheetViewProps as ReferenceDaySheetViewProps,
6
+ ForceUpdateScreenProps as ReferenceForceUpdateScreenProps,
7
+ LiveActivityProps as ReferenceLiveActivityProps,
8
+ OfflineBannerProps as ReferenceOfflineBannerProps,
9
+ PhotoCaptureProps as ReferencePhotoCaptureProps,
10
+ QuickIncidentSheetProps as ReferenceQuickIncidentSheetProps,
11
+ ScanSheetProps as ReferenceScanSheetProps,
12
+ ShiftCardProps as ReferenceShiftCardProps,
13
+ SignaturePadProps as ReferenceSignaturePadProps,
14
+ SyncConflictSheetProps as ReferenceSyncConflictSheetProps,
15
+ } from "../types/reference";
16
+
17
+ /**
18
+ * Compass components on the web (RRR-75): the same surfaces Compass draws natively in
19
+ * @xos/ui-native, for Atlas previews, the Gateway crew view and Storybook. Each one marks its root
20
+ * `xos-compass`, which raises every target to touch-min (48 pt). Props are the reference contracts
21
+ * plus the callbacks a product screen needs; `frame` draws the documentation phone frame and is for
22
+ * previews only.
23
+ */
24
+
25
+ export type ClockButtonProps = ReferenceClockButtonProps;
26
+
27
+ export type ScanSheetProps = ReferenceScanSheetProps & {
28
+ onModeChange?: (mode: ReferenceScanSheetProps["mode"]) => void;
29
+ onDone?: () => void;
30
+ onNfc?: () => void;
31
+ onTorch?: () => void;
32
+ /** The live camera feed, drawn inside the viewfinder under the reticle. */
33
+ camera?: ReactNode;
34
+ };
35
+
36
+ export type OfflineBannerProps = ReferenceOfflineBannerProps;
37
+
38
+ export type QuickIncidentSheetProps = ReferenceQuickIncidentSheetProps & {
39
+ onSelect?: (label: string) => void;
40
+ };
41
+
42
+ export type ChecklistRunnerProps = ReferenceChecklistRunnerProps & {
43
+ onResult?: (code: string, result: "pass" | "fail") => void;
44
+ onAddPhoto?: (code: string) => void;
45
+ onNoteChange?: (code: string, note: string) => void;
46
+ };
47
+
48
+ export type ShiftCardProps = ReferenceShiftCardProps;
49
+
50
+ export type DaySheetViewProps = ReferenceDaySheetViewProps & {
51
+ onCall?: (name: string) => void;
52
+ onMessage?: (name: string) => void;
53
+ };
54
+
55
+ export type SignaturePadProps = ReferenceSignaturePadProps & {
56
+ /** A PNG data URL of the signature, or null after Clear. */
57
+ onChange?: (signature: string | null) => void;
58
+ };
59
+
60
+ export type PhotoCaptureProps = ReferencePhotoCaptureProps & {
61
+ onCapture?: () => void;
62
+ onAnnotate?: () => void;
63
+ onDone?: () => void;
64
+ camera?: ReactNode;
65
+ };
66
+
67
+ export type LiveActivityProps = ReferenceLiveActivityProps & {
68
+ /** Break, or End Break while on break. */
69
+ onToggleBreak?: () => void;
70
+ onClockOut?: () => void;
71
+ };
72
+
73
+ export type ForceUpdateScreenProps = ReferenceForceUpdateScreenProps & {
74
+ onUpdate?: () => void;
75
+ };
76
+
77
+ export type SyncConflictSheetProps = ReferenceSyncConflictSheetProps & {
78
+ onKeep?: (choice: "mine" | "theirs") => void;
79
+ };
@@ -0,0 +1,104 @@
1
+ import { type ReactElement } from "react";
2
+ import { cx } from "../lib/cx.ts";
3
+ import { useT } from "../lib/context.tsx";
4
+ import { IconButton } from "../Button/Button.tsx";
5
+ import { Tag } from "../Chips/Chips.tsx";
6
+ import { Avatar } from "../Avatar/Avatar.tsx";
7
+ import { Icon } from "../Icon/Icon.tsx";
8
+ import { TL_CATEGORY } from "../Charts/categories.ts";
9
+ import { Phone } from "./Compass.shared.tsx";
10
+ import { type DaySheetViewProps } from "./Compass.types.ts";
11
+
12
+ /**
13
+ * The day sheet: schedule with the current entry marked, and contacts with call and message. `dayTypes` names what
14
+ * the day is (B4), as text with an icon and a categorical swatch.
15
+ */
16
+ export function DaySheetView({
17
+ frame,
18
+ date,
19
+ title,
20
+ venue,
21
+ entries,
22
+ contacts,
23
+ dayTypes = [],
24
+ onCall,
25
+ onMessage,
26
+ }: DaySheetViewProps): ReactElement {
27
+ const t = useT();
28
+ return (
29
+ <Phone frame={frame}>
30
+ <div className="flex flex-col gap-16 p-16">
31
+ <header className="flex flex-col gap-2">
32
+ <span className="text-text-secondary">{date}</span>
33
+ <strong className="text-heading-20 font-semibold">{title}</strong>
34
+ <span className="text-text-secondary">{venue}</span>
35
+ {dayTypes.length > 0 ? (
36
+ <ul
37
+ className="m-0 flex list-none flex-wrap gap-4 p-0"
38
+ aria-label={t("daysheet.dayTypes")}
39
+ >
40
+ {dayTypes.map((d) => (
41
+ <li
42
+ key={d.label}
43
+ className="inline-flex items-center gap-4 rounded-chip bg-bg-surface px-6 text-text-12"
44
+ >
45
+ <span
46
+ aria-hidden="true"
47
+ className={cx(
48
+ "inline-block size-(--space-8) rounded-mark",
49
+ TL_CATEGORY[d.category],
50
+ )}
51
+ />
52
+ {d.icon ? <Icon name={d.icon} size={12} /> : null}
53
+ {d.label}
54
+ </li>
55
+ ))}
56
+ </ul>
57
+ ) : null}
58
+ </header>
59
+ <ol className="m-0 p-0 list-none">
60
+ {entries.map((e, i) => (
61
+ <li
62
+ key={i}
63
+ aria-current={e.now ? "time" : undefined}
64
+ className={cx(
65
+ "grid grid-cols-[var(--ui-daysheet-time)_1fr_auto] items-center min-h-touch-min border-b border-border-subtle",
66
+ e.now && "font-semibold",
67
+ )}
68
+ >
69
+ <span className="text-text-secondary tabular-nums">{e.time}</span>
70
+ <span>{e.label}</span>
71
+ {e.now ? <Tag tone="accent">{t("daysheet.now")}</Tag> : null}
72
+ </li>
73
+ ))}
74
+ </ol>
75
+ <section className="flex flex-col">
76
+ <h4 className="m-0 text-text-12 font-medium text-text-secondary">
77
+ {t("daysheet.contacts")}
78
+ </h4>
79
+ {contacts.map((c) => (
80
+ <div key={c.name} className="flex items-center gap-8 py-6">
81
+ <Avatar name={c.name} />
82
+ <div className="flex flex-col flex-1">
83
+ <strong>{c.name}</strong>
84
+ <span className="text-text-secondary">{c.role}</span>
85
+ </div>
86
+ <IconButton
87
+ icon="Phone"
88
+ variant="secondary"
89
+ label={t("contact.call", { name: c.name })}
90
+ onClick={() => onCall?.(c.name)}
91
+ />
92
+ <IconButton
93
+ icon="MessageSquare"
94
+ variant="secondary"
95
+ label={t("contact.message", { name: c.name })}
96
+ onClick={() => onMessage?.(c.name)}
97
+ />
98
+ </div>
99
+ ))}
100
+ </section>
101
+ </div>
102
+ </Phone>
103
+ );
104
+ }
@@ -0,0 +1,29 @@
1
+ import { 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 { Phone, blockClass } from "./Compass.shared.tsx";
6
+ import { type ForceUpdateScreenProps } from "./Compass.types.ts";
7
+
8
+ /** Blocks the app below the forced minimum version (Section 5.1) until the person updates. */
9
+ export function ForceUpdateScreen({
10
+ frame,
11
+ message,
12
+ version,
13
+ onUpdate,
14
+ }: ForceUpdateScreenProps): ReactElement {
15
+ const t = useT();
16
+ return (
17
+ <Phone frame={frame} tall>
18
+ <div className="flex flex-1 flex-col items-center justify-center gap-12 px-24 py-32 text-center">
19
+ <Icon name="Smartphone" size={28} className="text-text-secondary" />
20
+ <strong className="text-heading-20 font-semibold">{t("update.title")}</strong>
21
+ <p className="m-0 text-text-secondary">{message}</p>
22
+ <span className="font-mono text-mono-12 text-text-secondary">{version}</span>
23
+ <Button variant="primary" size="lg" className={blockClass} onClick={onUpdate}>
24
+ {t("update.action")}
25
+ </Button>
26
+ </div>
27
+ </Phone>
28
+ );
29
+ }