@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,72 @@
1
+ import { useLayoutEffect, type RefObject } from "react";
2
+ import {
3
+ columnResizingFeature,
4
+ columnSizingFeature,
5
+ tableFeatures,
6
+ useTable,
7
+ type ColumnSizingState,
8
+ type OnChangeFn,
9
+ type columnResizingState,
10
+ } from "@tanstack/react-table";
11
+
12
+ /** Starts a pointer resize of one column from its handle's mousedown or touchstart. */
13
+ export type StartResize = (
14
+ columnId: string,
15
+ event: { type: string; clientX?: number; touches?: ArrayLike<{ clientX: number }> },
16
+ ) => void;
17
+
18
+ const features = tableFeatures({ columnSizingFeature, columnResizingFeature });
19
+
20
+ const NO_ROWS: Record<string, unknown>[] = [];
21
+
22
+ /**
23
+ * The TanStack Table column engine behind a DataTable's pointer resize. DataTable loads it on the
24
+ * first interaction with a resize handle (ADR 0027): the table renders from its own column state
25
+ * until then, and this engine drives the same state, controlled, from that point on. It renders
26
+ * nothing.
27
+ */
28
+ export function DataTableResizer({
29
+ columns,
30
+ sizing,
31
+ resizing,
32
+ onSizingChange,
33
+ onResizingChange,
34
+ direction,
35
+ startRef,
36
+ onReady,
37
+ }: {
38
+ columns: { id: string; size: number; minSize: number; maxSize: number }[];
39
+ sizing: ColumnSizingState;
40
+ resizing: columnResizingState;
41
+ onSizingChange: OnChangeFn<ColumnSizingState>;
42
+ onResizingChange: OnChangeFn<columnResizingState>;
43
+ direction: "ltr" | "rtl";
44
+ startRef: RefObject<StartResize | null>;
45
+ /** Called once the engine can start a resize. */
46
+ onReady: () => void;
47
+ }): null {
48
+ const table = useTable({
49
+ features,
50
+ columns,
51
+ data: NO_ROWS,
52
+ state: { columnSizing: sizing, columnResizing: resizing },
53
+ onColumnSizingChange: onSizingChange,
54
+ onColumnResizingChange: onResizingChange,
55
+ columnResizeMode: "onChange",
56
+ columnResizeDirection: direction,
57
+ });
58
+ useLayoutEffect(() => {
59
+ startRef.current = (columnId, event) => {
60
+ const header = table.getFlatHeaders().find((h) => h.column.id === columnId);
61
+ header?.getResizeHandler()(event);
62
+ };
63
+ });
64
+ useLayoutEffect(() => {
65
+ onReady();
66
+ return () => {
67
+ startRef.current = null;
68
+ };
69
+ // Once per mount: the handle that loaded the engine may be waiting to start its drag.
70
+ }, []);
71
+ return null;
72
+ }
@@ -0,0 +1,58 @@
1
+ import { useLayoutEffect, type RefObject } from "react";
2
+ import { useVirtualizer } from "@tanstack/react-virtual";
3
+
4
+ /** The rows a table renders, inclusive; `end` below `start` when none fit. */
5
+ export interface RowWindow {
6
+ readonly start: number;
7
+ readonly end: number;
8
+ }
9
+
10
+ /**
11
+ * The TanStack Virtual engine behind a DataTable over its row limit. DataTable loads it on the first
12
+ * interaction with the table (ADR 0027): until then the first screen of rows needs no engine, and
13
+ * this one moves the same window from that point on. It renders nothing.
14
+ */
15
+ export function DataTableVirtualizer({
16
+ count,
17
+ rowHeight,
18
+ overscan,
19
+ viewport,
20
+ scrollRef,
21
+ scrollToRef,
22
+ onWindow,
23
+ onReady,
24
+ }: {
25
+ count: number;
26
+ rowHeight: number;
27
+ overscan: number;
28
+ /** The height the table has measured, until the engine has measured its own. */
29
+ viewport: number;
30
+ scrollRef: RefObject<HTMLDivElement | null>;
31
+ scrollToRef: RefObject<((index: number) => void) | null>;
32
+ onWindow: (window: RowWindow) => void;
33
+ /** Called once the engine can scroll. */
34
+ onReady: () => void;
35
+ }): null {
36
+ const virtualizer = useVirtualizer({
37
+ count,
38
+ getScrollElement: () => scrollRef.current,
39
+ estimateSize: () => rowHeight,
40
+ overscan,
41
+ initialRect: { width: 0, height: viewport },
42
+ // The first scroll is often what loaded the engine, and it scrolls to its offset as it mounts.
43
+ initialOffset: () => scrollRef.current?.scrollTop ?? 0,
44
+ });
45
+ const items = virtualizer.getVirtualItems();
46
+ const start = items[0]?.index ?? 0;
47
+ const end = items[items.length - 1]?.index ?? -1;
48
+
49
+ useLayoutEffect(() => onWindow({ start, end }), [onWindow, start, end]);
50
+ useLayoutEffect(() => {
51
+ scrollToRef.current = (index) => virtualizer.scrollToIndex(index);
52
+ onReady();
53
+ return () => {
54
+ scrollToRef.current = null;
55
+ };
56
+ }, [virtualizer, scrollToRef, onReady]);
57
+ return null;
58
+ }
@@ -0,0 +1,9 @@
1
+ # DataTable
2
+
3
+ DataTable lists records in 36 px rows with tabular money and NULL-aware totals.
4
+
5
+ - Densities: `compact` 32 px, default 36 px, `comfortable` 44 px.
6
+ - A column with `wrap` wraps its text instead of widening the table; use it for long text such as descriptions or shared-field lists.
7
+ - A total that includes any unpriced line renders Unpriced; aggregates of blanks are blank.
8
+ - Production adds virtualization, column pinning, resize, grouping and keyboard grid navigation.
9
+ - Over its row limit (100 by default) a table renders its first screen itself, and TanStack Virtual loads when the table is first scrolled, pointed at or focused.
@@ -0,0 +1,5 @@
1
+ # DatePicker
2
+
3
+ DatePicker picks one date from a month grid; dates display as Oct 30, 2026.
4
+
5
+ - Typed date phrases are handled by QuickAdd.
@@ -0,0 +1,3 @@
1
+ # DateRangePicker
2
+
3
+ DateRangePicker picks a start and end date and shows the length in days.
@@ -0,0 +1,3 @@
1
+ # DaySheetView
2
+
3
+ DaySheetView is the day's schedule and contacts in large touch rows, with one-tap call and message.
@@ -0,0 +1,3 @@
1
+ # DepartmentChip
2
+
3
+ DepartmentChip shows the department name first and its class code in a mono chip.
@@ -0,0 +1,18 @@
1
+ # DepartmentGlyph
2
+
3
+ DepartmentGlyph draws the Lucide icon assigned to each of the 10 department classes.
4
+
5
+ | Code | Department | Lucide icon |
6
+ | ---- | ----------- | ----------------- |
7
+ | 0000 | Executive | Briefcase |
8
+ | 1000 | Creative | Palette |
9
+ | 2000 | Talent | MicVocal |
10
+ | 3000 | Marketing | Megaphone |
11
+ | 4000 | Environment | Tent |
12
+ | 5000 | Production | SlidersHorizontal |
13
+ | 6000 | Operations | ClipboardList |
14
+ | 7000 | Experience | Sparkles |
15
+ | 8000 | Hospitality | ConciergeBell |
16
+ | 9000 | Technology | Cpu |
17
+
18
+ The map is exported as `XOS.glyphs.departments`. Always shown beside the department name, never alone.
@@ -0,0 +1,3 @@
1
+ # Dialog
2
+
3
+ Dialog is reserved for irreversible actions; everything else uses Undo.
@@ -0,0 +1,3 @@
1
+ # DiffViewer
2
+
3
+ DiffViewer shows field-level changes for record history and canon changes, with color and strike or underline.
@@ -0,0 +1,3 @@
1
+ # Divider
2
+
3
+ Divider separates groups with a 1 px `border-subtle` rule, optionally labeled.
@@ -0,0 +1,3 @@
1
+ # Drawer
2
+
3
+ Drawer slides in from an edge for secondary tasks; below md it opens full screen.
@@ -0,0 +1,3 @@
1
+ # DropdownMenu
2
+
3
+ DropdownMenu opens a short list of actions from a button.
@@ -0,0 +1,3 @@
1
+ # EPKViewer
2
+
3
+ EPKViewer presents an artist's press kit: media grid, bio, verified badges and links to plot and rider.
@@ -0,0 +1,125 @@
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 {
6
+ controlClass,
7
+ errorClass,
8
+ fieldClass,
9
+ helpClass,
10
+ labelClass,
11
+ useFieldId,
12
+ } from "../Field/Field.tsx";
13
+ import { type ColorCheck, type ColorPickerProps } from "./Editing.types.ts";
14
+ import { contrastRatio, overlaid } from "./contrastRatio.tsx";
15
+
16
+ const HEX = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;
17
+
18
+ /** A 3-digit hex color as 6 digits, the form a color input takes. */
19
+ function expand(hex: string): string {
20
+ return hex.length === 4
21
+ ? `#${hex.slice(1).replace(/./g, "$&$&")}`.toUpperCase()
22
+ : hex.toUpperCase();
23
+ }
24
+
25
+ /** The ratio of one check for a color: the color as foreground or background, under any overlay. */
26
+ function measure(check: ColorCheck, color: string): number {
27
+ const fg = check.fgIsValue ? color : (check.fg ?? color);
28
+ const fill = check.fgIsValue ? (check.bg ?? color) : color;
29
+ const bg = check.overlay ? overlaid(fill, check.overlay.color, check.overlay.opacity) : fill;
30
+ return contrastRatio(fg, bg);
31
+ }
32
+
33
+ /** A tenant color with live WCAG 2.2 AA checks; a color that fails any check cannot be saved. */
34
+ export function ColorPicker({
35
+ label,
36
+ value,
37
+ checks,
38
+ onChange,
39
+ disabled,
40
+ help,
41
+ error,
42
+ id: idProp,
43
+ }: ColorPickerProps): ReactElement {
44
+ const t = useT();
45
+ const id = useFieldId(idProp);
46
+ const [color, setColor] = useState(value);
47
+ const valid = HEX.test(color);
48
+ const [swatch, setSwatch] = useState(HEX.test(value) ? expand(value) : "");
49
+ const results = valid
50
+ ? checks.map((c) => {
51
+ const r = measure(c, color);
52
+ return { ...c, ratio: r, pass: r >= (c.min ?? 4.5) };
53
+ })
54
+ : [];
55
+ const allPass = valid && results.every((r) => r.pass);
56
+ const set = (next: string) => {
57
+ setColor(next);
58
+ const ok = HEX.test(next);
59
+ if (ok) setSwatch(expand(next));
60
+ onChange?.(next, ok && checks.every((c) => measure(c, next) >= (c.min ?? 4.5)));
61
+ };
62
+ return (
63
+ <div className={cx(fieldClass, "w-(--layout-property-column)")}>
64
+ <span id={`${id}-label`} className={labelClass}>
65
+ {label}
66
+ </span>
67
+ <div className="flex items-center gap-8">
68
+ <input
69
+ type="color"
70
+ aria-labelledby={`${id}-label`}
71
+ value={swatch}
72
+ disabled={disabled}
73
+ onChange={(e) => set(e.target.value.toUpperCase())}
74
+ className="xos-hit h-control-md min-w-control-md p-0 rounded-control border border-border-control bg-transparent cursor-pointer pointer-coarse:min-h-target-coarse pointer-coarse:min-w-target-coarse disabled:opacity-disabled disabled:cursor-not-allowed"
75
+ />
76
+ <input
77
+ id={id}
78
+ spellCheck={false}
79
+ aria-label={t("color.hex", { label })}
80
+ aria-invalid={valid && !error ? undefined : true}
81
+ aria-describedby={`${id}-status${help ? ` ${id}-help` : ""}`}
82
+ value={color}
83
+ disabled={disabled}
84
+ onChange={(e) => set(e.target.value.trim())}
85
+ className={cx(controlClass, "flex-1 font-mono")}
86
+ />
87
+ </div>
88
+ {help ? (
89
+ <span id={`${id}-help`} className={helpClass}>
90
+ {help}
91
+ </span>
92
+ ) : null}
93
+ <div id={`${id}-status`} aria-live="polite" className="flex flex-col gap-4">
94
+ {valid ? (
95
+ results.map((r) => (
96
+ <div key={r.label} className="flex items-center justify-between gap-8">
97
+ <span className="text-text-secondary">{r.label}</span>
98
+ <span className="flex items-center gap-4">
99
+ <span className="tabular-nums">
100
+ {t("contrast.ratio", { r: r.ratio.toFixed(2) })}
101
+ </span>
102
+ <span className={r.pass ? "text-success" : "text-danger"}>
103
+ <Icon name={r.pass ? "CircleCheck" : "CircleX"} size={14} />
104
+ </span>
105
+ <span>{r.pass ? t("contrast.pass") : t("contrast.fail")}</span>
106
+ </span>
107
+ </div>
108
+ ))
109
+ ) : (
110
+ <div className={errorClass}>
111
+ <Icon name="alert" size={12} />
112
+ {t("color.invalid")}
113
+ </div>
114
+ )}
115
+ {valid && !allPass ? <span className={helpClass}>{t("color.blocked")}</span> : null}
116
+ {error ? (
117
+ <div className={errorClass} role="alert">
118
+ <Icon name="alert" size={12} />
119
+ {error}
120
+ </div>
121
+ ) : null}
122
+ </div>
123
+ </div>
124
+ );
125
+ }
@@ -0,0 +1,49 @@
1
+ import { type ReactElement } from "react";
2
+ import { cx } from "../lib/cx.ts";
3
+ import { useT } from "../lib/context.tsx";
4
+ import { ScrollRegion } from "../Layout/Layout.tsx";
5
+ import { type DiffViewerProps } from "./Editing.types.ts";
6
+
7
+ /** Field-level changes with color plus strike-through or underline, so change never relies on color. */
8
+ export function DiffViewer({ caption, rows }: DiffViewerProps): ReactElement {
9
+ const t = useT();
10
+ const th = cx(
11
+ "h-control-lg px-12 text-start font-medium text-text-12 text-text-secondary bg-bg-surface border-b border-border-subtle",
12
+ );
13
+ const td = cx("h-row-default px-12 border-b border-border-subtle");
14
+ return (
15
+ <ScrollRegion label={caption ?? t("scroll.region")}>
16
+ <table className="w-full border-collapse text-text-13">
17
+ {caption ? <caption className="pb-8 text-start font-semibold">{caption}</caption> : null}
18
+ <thead>
19
+ <tr>
20
+ <th scope="col" className={th}>
21
+ {t("diff.field")}
22
+ </th>
23
+ <th scope="col" className={th}>
24
+ {t("diff.before")}
25
+ </th>
26
+ <th scope="col" className={th}>
27
+ {t("diff.after")}
28
+ </th>
29
+ </tr>
30
+ </thead>
31
+ <tbody>
32
+ {rows.map((r) => (
33
+ <tr key={r.field}>
34
+ <td className={cx(td, "text-text-secondary")}>{r.field}</td>
35
+ <td className={td}>
36
+ <del className="line-through text-danger-text">{r.before}</del>
37
+ </td>
38
+ <td className={td}>
39
+ <ins className="underline underline-offset-(length:--space-2) text-success-text">
40
+ {r.after}
41
+ </ins>
42
+ </td>
43
+ </tr>
44
+ ))}
45
+ </tbody>
46
+ </table>
47
+ </ScrollRegion>
48
+ );
49
+ }
@@ -0,0 +1,29 @@
1
+ export {
2
+ type FilterBuilderProps,
3
+ type QuickAddProps,
4
+ type ColorPickerProps,
5
+ type ColorCheck,
6
+ type DiffViewerProps,
7
+ type QuickAddToken,
8
+ type QuickAddResult,
9
+ type QuickAddCandidate,
10
+ type QuickAddParse,
11
+ type QuickAddResolution,
12
+ type QuickAddResolver,
13
+ type QuickAddSpan,
14
+ type QuickAddTokenType,
15
+ } from "./Editing.types.ts";
16
+ export { parseQuickAdd, type QuickAddOptions } from "./parseQuickAdd.tsx";
17
+ export { finalizeQuickAdd, quickAddKey, zonedInstant } from "./quickAddCore.ts";
18
+ export {
19
+ loadQuickAddParser,
20
+ useQuickAdd,
21
+ type QuickAddController,
22
+ type UseQuickAddOptions,
23
+ } from "./useQuickAdd.ts";
24
+ export { QuickAddChips, type QuickAddChipsProps, type QuickAddCopy } from "./QuickAddChips.tsx";
25
+ export { contrastRatio } from "./contrastRatio.tsx";
26
+ export { FilterBuilder } from "./FilterBuilder.tsx";
27
+ export { QuickAdd } from "./QuickAdd.tsx";
28
+ export { ColorPicker } from "./ColorPicker.tsx";
29
+ export { DiffViewer } from "./DiffViewer.tsx";
@@ -0,0 +1,71 @@
1
+ import type {
2
+ ColorPickerProps as ReferenceColorPickerProps,
3
+ DiffViewerProps as ReferenceDiffViewerProps,
4
+ FilterBuilderProps as ReferenceFilterBuilderProps,
5
+ QuickAddProps as ReferenceQuickAddProps,
6
+ } from "../types/reference";
7
+ import type { QuickAddCopy } from "./QuickAddChips.tsx";
8
+ import type { QuickAddResolver, QuickAddResult, QuickAddTokenType } from "./quickAddCore.ts";
9
+
10
+ export type Filter = ReferenceFilterBuilderProps["filters"][number];
11
+
12
+ export type FilterBuilderProps = ReferenceFilterBuilderProps & {
13
+ onChange?: (filters: Filter[]) => void;
14
+ onAdd?: () => void;
15
+ onSave?: (filters: Filter[]) => void;
16
+ /** Opens the editor for one filter chip. */
17
+ onEdit?: (filter: Filter, index: number) => void;
18
+ };
19
+
20
+ export type QuickAddProps = ReferenceQuickAddProps & {
21
+ /**
22
+ * Called with the line to save on Enter. The field clears afterwards unless it returns (or resolves
23
+ * to) false, for example when the save failed. Without it the field is a preview and chips cannot be
24
+ * removed.
25
+ */
26
+ onSubmit?: (parsed: QuickAddResult) => unknown;
27
+ /** Reference date for relative phrases such as tomorrow; now by default. */
28
+ referenceDate?: Date;
29
+ /** The language date phrases are read in (Spanish for `es-*`); the provider's locale by default. */
30
+ locale?: string;
31
+ /** The IANA zone date phrases are read in, such as the org's; the device's by default. */
32
+ timeZone?: string;
33
+ /** Resolves people, tags, kinds and scopes to what the person may see; unresolved tokens stay text. */
34
+ resolve?: QuickAddResolver;
35
+ /** What each kind of token sets, for chip names and the announcement, such as Owner or Due. */
36
+ labels?: Partial<Record<QuickAddTokenType, string>>;
37
+ /** Sentences for chip names, the announcement and candidate lists, from the app's catalog. */
38
+ copy?: QuickAddCopy;
39
+ id?: string;
40
+ disabled?: boolean;
41
+ };
42
+
43
+ /** One contrast check: the value against a fixed color, as the foreground or the background. */
44
+ export type ColorCheck = ReferenceColorPickerProps["checks"][number] & {
45
+ /** A state drawn over the background (hover, pressed): `color` at `opacity`, composited first. */
46
+ overlay?: { color: string; opacity: number };
47
+ };
48
+
49
+ export type ColorPickerProps = Omit<ReferenceColorPickerProps, "checks"> & {
50
+ checks: ColorCheck[];
51
+ /** Called with the value and whether it is a valid hex that passes every check. */
52
+ onChange?: (value: string, savable: boolean) => void;
53
+ disabled?: boolean;
54
+ help?: string;
55
+ /** A refusal from the server, shown under the checks. */
56
+ error?: string;
57
+ id?: string;
58
+ };
59
+
60
+ export type DiffViewerProps = ReferenceDiffViewerProps;
61
+
62
+ export type {
63
+ QuickAddCandidate,
64
+ QuickAddParse,
65
+ QuickAddResolution,
66
+ QuickAddResolver,
67
+ QuickAddResult,
68
+ QuickAddSpan,
69
+ QuickAddToken,
70
+ QuickAddTokenType,
71
+ } from "./quickAddCore.ts";
@@ -0,0 +1,72 @@
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 { chipClass } from "../Chips/Chips.tsx";
6
+ import { type Filter, type FilterBuilderProps } from "./Editing.types.ts";
7
+
8
+ /**
9
+ * Filters as chips: each opens its editor, removes with its button, and the set saves as a view. Add
10
+ * filter is the target of the shell's Open the filters shortcut (data-shortcut="view.filters",
11
+ * lib/shortcut-targets.ts).
12
+ */
13
+ export function FilterBuilder({
14
+ filters,
15
+ addLabel,
16
+ saveLabel,
17
+ onChange,
18
+ onAdd,
19
+ onSave,
20
+ onEdit,
21
+ }: FilterBuilderProps): ReactElement {
22
+ const t = useT();
23
+ const [current, setCurrent] = useState(filters);
24
+ const set = (next: Filter[]) => {
25
+ setCurrent(next);
26
+ onChange?.(next);
27
+ };
28
+ return (
29
+ <div role="group" aria-label={t("filter.label")} className="flex flex-wrap items-center gap-6">
30
+ {current.map((f, i) => (
31
+ <span key={`${f.field}-${i}`} className={chipClass}>
32
+ <button
33
+ type="button"
34
+ onClick={() => onEdit?.(f, i)}
35
+ className="xos-hit inline-flex items-center gap-4 p-0 border-0 bg-transparent cursor-pointer text-inherit"
36
+ >
37
+ <span className="text-text-secondary">{f.field}</span>{" "}
38
+ <span className="text-text-secondary">{f.op}</span>{" "}
39
+ <strong className="font-medium">{f.value}</strong>
40
+ </button>
41
+ <button
42
+ type="button"
43
+ aria-label={t("filter.remove", { field: f.field })}
44
+ onClick={() => set(current.filter((_, j) => j !== i))}
45
+ className="xos-hit inline-grid place-items-center ms-2 p-0 border-0 bg-transparent text-text-tertiary hover:text-text-primary rounded-mark cursor-pointer"
46
+ >
47
+ <Icon name="X" size={12} />
48
+ </button>
49
+ </span>
50
+ ))}
51
+ <Button
52
+ size="sm"
53
+ variant="ghost"
54
+ icon="ListFilter"
55
+ onClick={onAdd}
56
+ data-shortcut="view.filters"
57
+ >
58
+ {addLabel ?? t("filter.add")}
59
+ </Button>
60
+ {current.length ? (
61
+ <Button size="sm" variant="ghost" onClick={() => set([])}>
62
+ {t("action.clear")}
63
+ </Button>
64
+ ) : null}
65
+ {saveLabel ? (
66
+ <Button size="sm" icon="Bookmark" onClick={() => onSave?.(current)}>
67
+ {saveLabel}
68
+ </Button>
69
+ ) : null}
70
+ </div>
71
+ );
72
+ }
@@ -0,0 +1,102 @@
1
+ import { useEffect, useRef, useState, type ReactElement } from "react";
2
+ import { useT } from "../lib/context.tsx";
3
+ import { Icon } from "../Icon/Icon.tsx";
4
+ import { Kbd } from "../Kbd/Kbd.tsx";
5
+ import { type QuickAddProps } from "./Editing.types.ts";
6
+ import { QuickAddChips } from "./QuickAddChips.tsx";
7
+ import { loadQuickAddParser, useQuickAdd } from "./useQuickAdd.ts";
8
+
9
+ /**
10
+ * One line that turns date phrases, @person, #tag, /kind and ~scope into chips; Enter saves. With
11
+ * `resolve`, tokens show what they resolved to and the rest stay in the title. With `onSubmit`, each
12
+ * chip can be removed, which leaves its text in the title.
13
+ */
14
+ export function QuickAdd({
15
+ label,
16
+ placeholder: hint,
17
+ value,
18
+ onSubmit,
19
+ referenceDate,
20
+ locale,
21
+ timeZone,
22
+ resolve,
23
+ labels,
24
+ copy,
25
+ id,
26
+ disabled = false,
27
+ }: QuickAddProps): ReactElement {
28
+ const t = useT();
29
+ const [text, setText] = useState(value ?? "");
30
+ const [saving, setSaving] = useState(false);
31
+ const input = useRef<HTMLInputElement>(null);
32
+ // A line typed before the page hydrated is in the field but not in state: take it up.
33
+ useEffect(() => {
34
+ const early = input.current?.value ?? "";
35
+ if (early !== "") setText(early);
36
+ }, []);
37
+ const quick = useQuickAdd({
38
+ text,
39
+ ...(referenceDate ? { referenceDate } : {}),
40
+ ...(locale ? { locale } : {}),
41
+ ...(timeZone ? { timeZone } : {}),
42
+ ...(resolve ? { resolve } : {}),
43
+ });
44
+ const submit = async () => {
45
+ if (!text.trim() || saving || disabled) return;
46
+ setSaving(true);
47
+ try {
48
+ const result = await quick.finalize();
49
+ const keep = await onSubmit?.(result);
50
+ if (keep !== false) {
51
+ setText("");
52
+ quick.reset();
53
+ }
54
+ } finally {
55
+ setSaving(false);
56
+ }
57
+ };
58
+ return (
59
+ <div className="flex flex-col gap-8 w-(--ui-alert) max-w-full">
60
+ <form
61
+ onSubmit={(e) => {
62
+ e.preventDefault();
63
+ void submit();
64
+ }}
65
+ aria-busy={saving || undefined}
66
+ className="flex items-center gap-8 h-row-default ps-12 pe-8 rounded-control border border-border-control bg-bg-surface focus-within:outline-solid focus-within:outline-stroke-focus focus-within:outline-focus-ring"
67
+ >
68
+ <Icon name="Plus" color="var(--color-text-secondary)" />
69
+ <input
70
+ ref={input}
71
+ {...(id ? { id } : {})}
72
+ aria-label={label ?? t("quickAdd.label")}
73
+ placeholder={hint}
74
+ value={text}
75
+ disabled={disabled}
76
+ onChange={(e) => setText(e.target.value)}
77
+ onFocus={() => void loadQuickAddParser().catch(() => undefined)}
78
+ className="flex-1 min-w-0 border-0 bg-transparent outline-none text-text-primary placeholder:text-text-tertiary pointer-coarse:min-h-target-coarse"
79
+ />
80
+ <Kbd>{t("key.enter")}</Kbd>
81
+ </form>
82
+ {text ? (
83
+ <QuickAddChips
84
+ parse={quick.parse}
85
+ {...(quick.resolutions ? { resolutions: quick.resolutions } : {})}
86
+ choices={quick.choices}
87
+ onChoose={quick.choose}
88
+ {...(labels ? { labels } : {})}
89
+ {...(copy ? { copy } : {})}
90
+ {...(onSubmit
91
+ ? {
92
+ onDismiss: (token) => {
93
+ quick.dismiss(token);
94
+ input.current?.focus();
95
+ },
96
+ }
97
+ : {})}
98
+ />
99
+ ) : null}
100
+ </div>
101
+ );
102
+ }