@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,107 @@
1
+ import { useLayoutEffect, useRef, useState, type ReactElement } from "react";
2
+ import { cx } from "../lib/cx.ts";
3
+ import { type ScrollRegionProps } from "./Layout.types.ts";
4
+
5
+ interface Edges {
6
+ /** Content is hidden past the logical start (scrolled away from it). */
7
+ readonly start: boolean;
8
+ /** Content is hidden past the logical end. */
9
+ readonly end: boolean;
10
+ }
11
+
12
+ const NO_EDGES: Edges = { start: false, end: false };
13
+
14
+ const edgeClass = cx(
15
+ "pointer-events-none absolute inset-y-0 z-sticky w-(--space-48) from-bg-canvas to-transparent",
16
+ "print:hidden forced-colors:hidden",
17
+ );
18
+
19
+ /**
20
+ * Keeps wide content inside the page width: it scrolls horizontally in a labeled region that joins
21
+ * the tab order only while it overflows. While content is hidden past an edge, that edge fades, so a
22
+ * table or board cut off at the right shows that it scrolls (A59-012).
23
+ */
24
+ export function ScrollRegion({
25
+ label,
26
+ children,
27
+ className,
28
+ frameClassName,
29
+ style,
30
+ ref: outer,
31
+ }: ScrollRegionProps): ReactElement {
32
+ const ref = useRef<HTMLDivElement>(null);
33
+ const setRef = (el: HTMLDivElement | null) => {
34
+ ref.current = el;
35
+ if (typeof outer === "function") outer(el);
36
+ else if (outer) outer.current = el;
37
+ };
38
+ // Server rendered markup cannot measure, so the region starts in the tab order and leaves it once
39
+ // the first measure finds nothing to scroll. Starting out of it left wide content unreachable by
40
+ // keyboard until hydration (A23-015).
41
+ const [overflows, setOverflows] = useState(true);
42
+ const [edges, setEdges] = useState<Edges>(NO_EDGES);
43
+ useLayoutEffect(() => {
44
+ const el = ref.current;
45
+ if (!el) return undefined;
46
+ const measure = () => {
47
+ const room = el.scrollWidth - el.clientWidth;
48
+ setOverflows(room > 1);
49
+ // scrollLeft runs negative from the start in right-to-left, so the distance is its magnitude.
50
+ const at = Math.abs(el.scrollLeft);
51
+ const start = room > 1 && at > 1;
52
+ const end = room > 1 && at < room - 1;
53
+ setEdges((old) => (old.start === start && old.end === end ? old : { start, end }));
54
+ };
55
+ measure();
56
+ el.addEventListener("scroll", measure, { passive: true });
57
+ if (typeof ResizeObserver === "undefined") {
58
+ return () => el.removeEventListener("scroll", measure);
59
+ }
60
+ // Content can grow wider after the first measure (rows load, fonts swap), so watch the region's
61
+ // children as well as its own box, and re-observe when children change.
62
+ const observer = new ResizeObserver(measure);
63
+ const observeAll = () => {
64
+ observer.disconnect();
65
+ observer.observe(el);
66
+ for (const child of Array.from(el.children)) observer.observe(child);
67
+ measure();
68
+ };
69
+ observeAll();
70
+ const mutations =
71
+ typeof MutationObserver === "undefined" ? null : new MutationObserver(observeAll);
72
+ mutations?.observe(el, { childList: true });
73
+ return () => {
74
+ el.removeEventListener("scroll", measure);
75
+ observer.disconnect();
76
+ mutations?.disconnect();
77
+ };
78
+ }, []);
79
+ return (
80
+ <div className={cx("relative min-w-0 max-w-full", frameClassName)}>
81
+ <div
82
+ ref={setRef}
83
+ role="region"
84
+ aria-label={label}
85
+ tabIndex={overflows ? 0 : undefined}
86
+ style={style}
87
+ className={cx("relative max-w-full overflow-x-auto overscroll-x-contain", className)}
88
+ >
89
+ {children}
90
+ </div>
91
+ {edges.start ? (
92
+ <span
93
+ aria-hidden="true"
94
+ data-scroll-edge="start"
95
+ className={cx(edgeClass, "start-0 bg-linear-to-r rtl:bg-linear-to-l")}
96
+ />
97
+ ) : null}
98
+ {edges.end ? (
99
+ <span
100
+ aria-hidden="true"
101
+ data-scroll-edge="end"
102
+ className={cx(edgeClass, "end-0 bg-linear-to-l rtl:bg-linear-to-r")}
103
+ />
104
+ ) : null}
105
+ </div>
106
+ );
107
+ }
@@ -0,0 +1,78 @@
1
+ import { useRef, useState, type ReactElement } from "react";
2
+ import { cx } from "../lib/cx.ts";
3
+ import { rovingIndex, useControllable } from "../lib/hooks.ts";
4
+ import { StateIcon } from "../StateIcon/StateIcon.tsx";
5
+ import { type SplitViewProps } from "./Layout.types.ts";
6
+
7
+ /**
8
+ * A list beside the selected record (Inbox, Dispatch, Advancing). The list is a listbox: arrow keys
9
+ * move, Home and End jump, Enter or Space selects.
10
+ */
11
+ export function SplitView({
12
+ label,
13
+ selected,
14
+ items,
15
+ detail,
16
+ onSelect,
17
+ }: SplitViewProps): ReactElement {
18
+ const [current, setCurrent] = useControllable<number>(undefined, selected, onSelect);
19
+ const [focused, setFocused] = useState(selected);
20
+ const refs = useRef<(HTMLDivElement | null)[]>([]);
21
+ return (
22
+ <div
23
+ className={cx(
24
+ "grid grid-cols-[var(--ui-split-list)_minmax(0,1fr)] max-lg:grid-cols-[minmax(0,1fr)]",
25
+ "min-h-(--ui-split-min) overflow-hidden rounded-card border border-border-subtle",
26
+ )}
27
+ >
28
+ <div
29
+ role="listbox"
30
+ aria-label={label}
31
+ className="bg-bg-surface border-e border-border-subtle max-lg:border-e-0 max-lg:border-b"
32
+ >
33
+ {items.map((item, i) => (
34
+ <div
35
+ key={`${item.title}-${i}`}
36
+ ref={(el) => {
37
+ refs.current[i] = el;
38
+ }}
39
+ role="option"
40
+ aria-selected={i === current}
41
+ tabIndex={i === focused ? 0 : -1}
42
+ onClick={() => {
43
+ setFocused(i);
44
+ setCurrent(i);
45
+ }}
46
+ onKeyDown={(e) => {
47
+ if (e.key === "Enter" || e.key === " ") {
48
+ e.preventDefault();
49
+ setCurrent(i);
50
+ return;
51
+ }
52
+ const next = rovingIndex(e.key, i, items.length, "vertical");
53
+ if (next === null) return;
54
+ e.preventDefault();
55
+ setFocused(next);
56
+ refs.current[next]?.focus();
57
+ }}
58
+ className={cx(
59
+ "flex items-start gap-8 p-12 border-b border-border-subtle cursor-pointer",
60
+ "aria-selected:bg-bg-hover hover:bg-bg-hover focus-visible:outline-offset-[calc(var(--stroke-width-focus)*-1)]",
61
+ )}
62
+ >
63
+ {item.state ? (
64
+ <span className="mt-2">
65
+ <StateIcon state={item.state} />
66
+ </span>
67
+ ) : null}
68
+ <div className="flex flex-col min-w-0">
69
+ <strong className="font-medium truncate">{item.title}</strong>
70
+ <span className="text-text-secondary">{item.meta}</span>
71
+ </div>
72
+ </div>
73
+ ))}
74
+ </div>
75
+ <div className="p-20 min-w-0">{detail}</div>
76
+ </div>
77
+ );
78
+ }
@@ -0,0 +1,39 @@
1
+ import { type ReactElement } from "react";
2
+ import { cx } from "../lib/cx.ts";
3
+ import { Icon } from "../Icon/Icon.tsx";
4
+ import { type StepperProps } from "./Layout.types.ts";
5
+
6
+ /** Wizard progress: done steps show a check, the current step is marked for assistive technology. */
7
+ export function Stepper({ steps, current }: StepperProps): ReactElement {
8
+ return (
9
+ <ol className="flex flex-wrap items-center gap-8 m-0 p-0 list-none">
10
+ {steps.map((step, i) => {
11
+ const state = i < current ? "done" : i === current ? "current" : "todo";
12
+ return (
13
+ <li
14
+ key={step}
15
+ aria-current={state === "current" ? "step" : undefined}
16
+ className={cx(
17
+ "flex items-center gap-6 text-text-secondary",
18
+ "[&+&]:before:w-(--ui-step-line) [&+&]:before:h-(--stroke-width-hairline) [&+&]:before:bg-border-strong [&+&]:before:me-2",
19
+ state === "current" && "text-text-primary font-medium",
20
+ )}
21
+ >
22
+ <span
23
+ className={cx(
24
+ "inline-grid place-items-center flex-none size-icon-20 rounded-full text-text-11 font-semibold tabular-nums",
25
+ state === "todo" &&
26
+ "ring-(length:--stroke-width-hairline) ring-inset ring-border-strong",
27
+ state === "current" && "bg-accent text-accent-text-on",
28
+ state === "done" && "bg-bg-hover text-success",
29
+ )}
30
+ >
31
+ {state === "done" ? <Icon name="Check" size={12} /> : i + 1}
32
+ </span>
33
+ <span>{step}</span>
34
+ </li>
35
+ );
36
+ })}
37
+ </ol>
38
+ );
39
+ }
@@ -0,0 +1,289 @@
1
+ import type { ReactElement, ReactNode } from "react";
2
+ import {
3
+ LEGAL_HISTORY_ID,
4
+ type LegalBlock,
5
+ type LegalInline,
6
+ type LegalVersion,
7
+ } from "./legal-markdown.ts";
8
+
9
+ /** Where a document's path leads in this app; null leaves the text as it is written. */
10
+ export type LegalHref = (slug: string) => string | null;
11
+
12
+ const LINK = "text-accent-text underline";
13
+ const CODE =
14
+ "font-mono text-mono-12 px-4 py-1 rounded-control bg-bg-raised border border-border-subtle";
15
+ const CELL_PAD = "p-8 align-top";
16
+ /** Past two columns, a table keeps a readable width and scrolls in its region on a phone. */
17
+ const MANY_COLUMNS = 3;
18
+
19
+ const HEADING_CLASS = {
20
+ 1: "m-0 text-heading-24 font-semibold",
21
+ 2: "m-0 mt-16 text-heading-20 font-semibold scroll-mt-16",
22
+ 3: "m-0 mt-8 text-heading-16 font-semibold scroll-mt-16",
23
+ 4: "m-0 mt-8 text-text-14 font-semibold scroll-mt-16",
24
+ 5: "m-0 mt-8 text-text-14 font-semibold scroll-mt-16",
25
+ 6: "m-0 mt-8 text-text-14 font-semibold scroll-mt-16",
26
+ } as const;
27
+
28
+ function Inlines({ parts, hrefFor }: { parts: readonly LegalInline[]; hrefFor: LegalHref }) {
29
+ return parts.map((part, i): ReactNode => {
30
+ switch (part.t) {
31
+ case "text":
32
+ return part.v;
33
+ case "strong":
34
+ return (
35
+ <strong key={i}>
36
+ <Inlines parts={part.c} hrefFor={hrefFor} />
37
+ </strong>
38
+ );
39
+ case "em":
40
+ return (
41
+ <em key={i}>
42
+ <Inlines parts={part.c} hrefFor={hrefFor} />
43
+ </em>
44
+ );
45
+ case "code":
46
+ return (
47
+ <code key={i} className={CODE}>
48
+ {part.v}
49
+ </code>
50
+ );
51
+ case "link":
52
+ return (
53
+ <a key={i} href={part.href} rel="noreferrer" className={LINK}>
54
+ <Inlines parts={part.c} hrefFor={hrefFor} />
55
+ </a>
56
+ );
57
+ case "mail":
58
+ return (
59
+ <a key={i} href={`mailto:${part.v}`} className={LINK}>
60
+ {part.v}
61
+ </a>
62
+ );
63
+ case "section":
64
+ return (
65
+ <a key={i} href={`#${part.id}`} className={LINK}>
66
+ {part.v}
67
+ </a>
68
+ );
69
+ case "document": {
70
+ const href = hrefFor(part.slug);
71
+ return href === null ? (
72
+ part.v
73
+ ) : (
74
+ <a key={i} href={href} className={LINK}>
75
+ {part.v}
76
+ </a>
77
+ );
78
+ }
79
+ }
80
+ });
81
+ }
82
+
83
+ function Blocks({ blocks, hrefFor }: { blocks: readonly LegalBlock[]; hrefFor: LegalHref }) {
84
+ return blocks.map((block, i): ReactNode => {
85
+ switch (block.t) {
86
+ case "heading": {
87
+ const Heading = `h${block.level}` as const;
88
+ return (
89
+ <Heading key={i} id={block.id} className={HEADING_CLASS[block.level]}>
90
+ {block.v}
91
+ </Heading>
92
+ );
93
+ }
94
+ case "p":
95
+ return (
96
+ <p key={i} id={block.id} className="m-0 text-text-14 scroll-mt-16">
97
+ <Inlines parts={block.c} hrefFor={hrefFor} />
98
+ </p>
99
+ );
100
+ case "quote":
101
+ return (
102
+ <blockquote
103
+ key={i}
104
+ className="m-0 flex flex-col gap-8 border-s-2 border-border-strong ps-12"
105
+ >
106
+ <Blocks blocks={block.c} hrefFor={hrefFor} />
107
+ </blockquote>
108
+ );
109
+ case "list": {
110
+ const List = block.ordered ? "ol" : "ul";
111
+ return (
112
+ <List
113
+ key={i}
114
+ {...(block.ordered && block.start !== 1 ? { start: block.start } : {})}
115
+ className={`m-0 flex flex-col gap-4 ps-20 text-text-14 ${block.ordered ? "list-decimal" : "list-disc"}`}
116
+ >
117
+ {block.items.map((item, j) => (
118
+ <li key={j}>
119
+ <Inlines parts={item.c} hrefFor={hrefFor} />
120
+ {item.children.length > 0 ? (
121
+ <div className="mt-4 flex flex-col gap-4">
122
+ <Blocks blocks={item.children} hrefFor={hrefFor} />
123
+ </div>
124
+ ) : null}
125
+ </li>
126
+ ))}
127
+ </List>
128
+ );
129
+ }
130
+ case "table":
131
+ // In the tab order so a keyboard can scroll it; this page runs no script to measure it.
132
+ return (
133
+ <div
134
+ key={i}
135
+ role="region"
136
+ aria-label={block.label}
137
+ tabIndex={0}
138
+ className="overflow-x-auto"
139
+ >
140
+ <table
141
+ className={`w-full border-collapse text-text-13 ${block.head.length >= MANY_COLUMNS ? "min-w-(--layout-form)" : ""}`.trim()}
142
+ >
143
+ <thead>
144
+ <tr>
145
+ {block.head.map((cell, j) => (
146
+ <th
147
+ key={j}
148
+ scope="col"
149
+ className="p-8 text-start align-bottom font-semibold border-b border-border-strong"
150
+ >
151
+ <Inlines parts={cell} hrefFor={hrefFor} />
152
+ </th>
153
+ ))}
154
+ </tr>
155
+ </thead>
156
+ <tbody>
157
+ {block.rows.map((row, j) => (
158
+ <tr key={j}>
159
+ {row.map((cell, k) => (
160
+ <td key={k} className={`${CELL_PAD} border-b border-border-subtle`}>
161
+ <Inlines parts={cell} hrefFor={hrefFor} />
162
+ </td>
163
+ ))}
164
+ </tr>
165
+ ))}
166
+ </tbody>
167
+ </table>
168
+ </div>
169
+ );
170
+ }
171
+ });
172
+ }
173
+
174
+ /**
175
+ * A legal document's text as plain elements, for a server component: no hooks and no script, so it
176
+ * adds nothing to the browser's bundle. The text is written in English whatever the page's locale,
177
+ * so it says so to assistive technology, and the pseudo-locale check treats it as content.
178
+ */
179
+ export function LegalText({
180
+ blocks,
181
+ hrefFor,
182
+ }: {
183
+ blocks: readonly LegalBlock[];
184
+ hrefFor: LegalHref;
185
+ }): ReactElement {
186
+ return (
187
+ <div data-pseudo-exempt lang="en-US" dir="ltr" className="contents break-words">
188
+ <Blocks blocks={blocks} hrefFor={hrefFor} />
189
+ </div>
190
+ );
191
+ }
192
+
193
+ function topHeadings(blocks: readonly LegalBlock[]) {
194
+ return blocks.filter((b): b is Extract<LegalBlock, { t: "heading" }> => {
195
+ return b.t === "heading" && b.level === 2;
196
+ });
197
+ }
198
+
199
+ function OutlineLinks({ blocks }: { blocks: readonly LegalBlock[] }) {
200
+ return (
201
+ <ul lang="en-US" dir="ltr" data-pseudo-exempt className="m-0 flex list-none flex-col gap-8 p-0">
202
+ {topHeadings(blocks).map((h) => (
203
+ <li key={h.id}>
204
+ <a href={`#${h.id}`} className="text-text-secondary hover:text-text-primary no-underline">
205
+ {h.v}
206
+ </a>
207
+ </li>
208
+ ))}
209
+ </ul>
210
+ );
211
+ }
212
+
213
+ /** The fewest headings worth an outline; a shorter document is read in one look. */
214
+ const OUTLINE_MIN = 3;
215
+
216
+ /** The outline for TemplateDocument's sidebar: the document's sections as in-page links. */
217
+ export function LegalOutline({
218
+ blocks,
219
+ label,
220
+ }: {
221
+ blocks: readonly LegalBlock[];
222
+ label: string;
223
+ }): ReactElement | null {
224
+ if (topHeadings(blocks).length < OUTLINE_MIN) return null;
225
+ return (
226
+ <nav
227
+ aria-label={label}
228
+ className="sticky top-0 flex max-h-dvh flex-col gap-8 overflow-y-auto text-text-13"
229
+ >
230
+ <p className="m-0 text-text-12 font-semibold text-text-secondary">{label}</p>
231
+ <OutlineLinks blocks={blocks} />
232
+ </nav>
233
+ );
234
+ }
235
+
236
+ /** The same outline in the flow of the page, closed until asked for; it needs no script. */
237
+ export function LegalContents({
238
+ blocks,
239
+ label,
240
+ }: {
241
+ blocks: readonly LegalBlock[];
242
+ label: string;
243
+ }): ReactElement | null {
244
+ if (topHeadings(blocks).length < OUTLINE_MIN) return null;
245
+ return (
246
+ <nav aria-label={label} className="text-text-13">
247
+ <details className="rounded-card border border-border-subtle bg-bg-surface p-12">
248
+ <summary className="cursor-pointer font-semibold">{label}</summary>
249
+ <div className="mt-8">
250
+ <OutlineLinks blocks={blocks} />
251
+ </div>
252
+ </details>
253
+ </nav>
254
+ );
255
+ }
256
+
257
+ /**
258
+ * The document's versions, newest first, each with its version number and whether and since when
259
+ * it is in effect (`describe`, in the page's language) and its summary of changes, which is written
260
+ * in English with the text. Terms of Service 15 promises this list.
261
+ */
262
+ export function LegalHistory({
263
+ history,
264
+ title,
265
+ describe,
266
+ }: {
267
+ history: readonly LegalVersion[];
268
+ title: string;
269
+ describe: (version: LegalVersion) => string;
270
+ }): ReactElement | null {
271
+ if (history.length === 0) return null;
272
+ return (
273
+ <section aria-labelledby={LEGAL_HISTORY_ID} className="flex flex-col gap-8">
274
+ <h2 id={LEGAL_HISTORY_ID} className={HEADING_CLASS[2]}>
275
+ {title}
276
+ </h2>
277
+ <ol className="m-0 flex list-none flex-col gap-12 p-0 text-text-14">
278
+ {history.map((v) => (
279
+ <li key={v.version} className="flex flex-col gap-4">
280
+ <span className="font-semibold">{describe(v)}</span>
281
+ <span data-pseudo-exempt lang="en-US" dir="ltr" className="text-text-secondary">
282
+ {v.summary}
283
+ </span>
284
+ </li>
285
+ ))}
286
+ </ol>
287
+ </section>
288
+ );
289
+ }
@@ -0,0 +1,10 @@
1
+ # LegalText
2
+
3
+ LegalText renders a legal document's Markdown as plain, styled elements on a server component. It has no hooks and no script, so it adds nothing to the browser's bundle, and it writes no HTML string.
4
+
5
+ - Import it from `@xos/ui/legal-text`, not through an app's client boundary.
6
+ - The text stays in English in every locale and is marked `lang="en-US"`.
7
+ - A wide table scrolls in a labeled region in the tab order; the page itself never scrolls sideways.
8
+ - A `/legal/{slug}` path in the text, an email address, and a "Section 3.6" of the same document become links. The page decides where a document's path leads through `hrefFor`.
9
+ - `LegalOutline` fits TemplateDocument's sidebar; `LegalContents` is the same list in the flow of the page, for where there is no sidebar.
10
+ - `legalTextSource` writes the module an app's generator checks in, so the text reaches the server without reading a file at runtime.
@@ -0,0 +1,29 @@
1
+ export {
2
+ frontmatterField,
3
+ inlineText,
4
+ isDraftVersion,
5
+ LEGAL_HISTORY_ID,
6
+ legalDay,
7
+ legalDocumentLinks,
8
+ legalPlainText,
9
+ legalTextSource,
10
+ legalVersionInEffect,
11
+ legalVersions,
12
+ legalVersionState,
13
+ parseLegalMarkdown,
14
+ stripFrontmatter,
15
+ type LegalBlock,
16
+ type LegalHistoryEntry,
17
+ type LegalInline,
18
+ type LegalListItem,
19
+ type LegalTextEntry,
20
+ type LegalVersion,
21
+ type LegalVersionState,
22
+ } from "./legal-markdown.ts";
23
+ export {
24
+ LegalContents,
25
+ LegalHistory,
26
+ LegalOutline,
27
+ LegalText,
28
+ type LegalHref,
29
+ } from "./LegalText.tsx";