@lar-works/design-system 0.2.0 → 0.3.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 (433) hide show
  1. package/README.md +5 -1
  2. package/dist/actions/Button.d.ts +39 -1
  3. package/dist/actions/Button.js +39 -9
  4. package/dist/actions/Button.js.map +1 -1
  5. package/dist/actions/ButtonLink.d.ts +5 -1
  6. package/dist/actions/ButtonLink.js +28 -2
  7. package/dist/actions/ButtonLink.js.map +1 -1
  8. package/dist/actions/ButtonRecipes.js +7 -0
  9. package/dist/actions/ButtonRecipes.js.map +1 -0
  10. package/dist/actions/IconButton.d.ts +2 -2
  11. package/dist/actions/IconButton.js +1 -1
  12. package/dist/actions/IconButton.js.map +1 -1
  13. package/dist/actions/ThemeSwitch.js +1 -1
  14. package/dist/board/ActivityLine.d.ts +36 -0
  15. package/dist/board/ActivityLine.js +144 -0
  16. package/dist/board/ActivityLine.js.map +1 -0
  17. package/dist/board/ActivityTrack.d.ts +11 -0
  18. package/dist/board/ActivityTrack.js +25 -0
  19. package/dist/board/ActivityTrack.js.map +1 -0
  20. package/dist/board/AddItem.d.ts +82 -0
  21. package/dist/board/AddItem.js +185 -0
  22. package/dist/board/AddItem.js.map +1 -0
  23. package/dist/board/Archive.d.ts +21 -0
  24. package/dist/board/Archive.js +63 -0
  25. package/dist/board/Archive.js.map +1 -0
  26. package/dist/board/Attention.d.ts +66 -0
  27. package/dist/board/Attention.js +122 -0
  28. package/dist/board/Attention.js.map +1 -0
  29. package/dist/board/BoardShell.d.ts +16 -0
  30. package/dist/board/BoardShell.js +35 -0
  31. package/dist/board/BoardShell.js.map +1 -0
  32. package/dist/board/BoardTitleBar.d.ts +50 -0
  33. package/dist/board/BoardTitleBar.js +125 -0
  34. package/dist/board/BoardTitleBar.js.map +1 -0
  35. package/dist/board/ButtonKinds.d.ts +24 -0
  36. package/dist/board/ButtonKinds.js +19 -0
  37. package/dist/board/ButtonKinds.js.map +1 -0
  38. package/dist/board/Cleanup.d.ts +8 -0
  39. package/dist/board/Cleanup.js +15 -0
  40. package/dist/board/Cleanup.js.map +1 -0
  41. package/dist/board/Counters.d.ts +101 -0
  42. package/dist/board/Counters.js +202 -0
  43. package/dist/board/Counters.js.map +1 -0
  44. package/dist/board/DataAttributes.d.ts +6 -0
  45. package/dist/board/Dependencies.d.ts +17 -0
  46. package/dist/board/Dependencies.js +44 -0
  47. package/dist/board/Dependencies.js.map +1 -0
  48. package/dist/board/Desk.d.ts +52 -0
  49. package/dist/board/Desk.js +130 -0
  50. package/dist/board/Desk.js.map +1 -0
  51. package/dist/board/Dossier.d.ts +100 -0
  52. package/dist/board/Dossier.js +194 -0
  53. package/dist/board/Dossier.js.map +1 -0
  54. package/dist/board/Filters.d.ts +33 -0
  55. package/dist/board/Filters.js +64 -0
  56. package/dist/board/Filters.js.map +1 -0
  57. package/dist/board/ItemDetails.d.ts +167 -0
  58. package/dist/board/ItemDetails.js +339 -0
  59. package/dist/board/ItemDetails.js.map +1 -0
  60. package/dist/board/ItemDialog.d.ts +73 -0
  61. package/dist/board/ItemDialog.js +140 -0
  62. package/dist/board/ItemDialog.js.map +1 -0
  63. package/dist/board/ItemParts.d.ts +42 -0
  64. package/dist/board/ItemParts.js +82 -0
  65. package/dist/board/ItemParts.js.map +1 -0
  66. package/dist/board/ItemProgress.d.ts +56 -0
  67. package/dist/board/ItemProgress.js +138 -0
  68. package/dist/board/ItemProgress.js.map +1 -0
  69. package/dist/board/List.d.ts +65 -0
  70. package/dist/board/List.js +118 -0
  71. package/dist/board/List.js.map +1 -0
  72. package/dist/board/LoadingScreen.d.ts +38 -0
  73. package/dist/board/LoadingScreen.js +74 -0
  74. package/dist/board/LoadingScreen.js.map +1 -0
  75. package/dist/board/NeedsYou.d.ts +13 -0
  76. package/dist/board/NeedsYou.js +31 -0
  77. package/dist/board/NeedsYou.js.map +1 -0
  78. package/dist/board/Onboarding.d.ts +53 -0
  79. package/dist/board/Onboarding.js +122 -0
  80. package/dist/board/Onboarding.js.map +1 -0
  81. package/dist/board/PartsList.d.ts +60 -0
  82. package/dist/board/PartsList.js +115 -0
  83. package/dist/board/PartsList.js.map +1 -0
  84. package/dist/board/ProjectIcon.d.ts +51 -0
  85. package/dist/board/ProjectIcon.js +120 -0
  86. package/dist/board/ProjectIcon.js.map +1 -0
  87. package/dist/board/PullRequests.d.ts +43 -0
  88. package/dist/board/PullRequests.js +83 -0
  89. package/dist/board/PullRequests.js.map +1 -0
  90. package/dist/board/RowStyles.js +14 -0
  91. package/dist/board/RowStyles.js.map +1 -0
  92. package/dist/board/Settings.d.ts +54 -0
  93. package/dist/board/Settings.js +112 -0
  94. package/dist/board/Settings.js.map +1 -0
  95. package/dist/board/Slices.d.ts +32 -0
  96. package/dist/board/Slices.js +88 -0
  97. package/dist/board/Slices.js.map +1 -0
  98. package/dist/board/SourceIcon.d.ts +12 -0
  99. package/dist/board/SourceIcon.js +24 -0
  100. package/dist/board/SourceIcon.js.map +1 -0
  101. package/dist/board/StagePane.d.ts +43 -0
  102. package/dist/board/StagePane.js +97 -0
  103. package/dist/board/StagePane.js.map +1 -0
  104. package/dist/board/StageRow.d.ts +141 -0
  105. package/dist/board/StageRow.js +287 -0
  106. package/dist/board/StageRow.js.map +1 -0
  107. package/dist/board/StageTrack.d.ts +18 -0
  108. package/dist/board/StageTrack.js +38 -0
  109. package/dist/board/StageTrack.js.map +1 -0
  110. package/dist/board/StartControls.d.ts +30 -0
  111. package/dist/board/StartControls.js +51 -0
  112. package/dist/board/StartControls.js.map +1 -0
  113. package/dist/board/StatusColors.d.ts +5 -0
  114. package/dist/board/StatusColors.js +17 -0
  115. package/dist/board/StatusColors.js.map +1 -0
  116. package/dist/board/StatusGlyph.d.ts +18 -0
  117. package/dist/board/StatusGlyph.js +51 -0
  118. package/dist/board/StatusGlyph.js.map +1 -0
  119. package/dist/board/Threads.d.ts +13 -0
  120. package/dist/board/Threads.js +35 -0
  121. package/dist/board/Threads.js.map +1 -0
  122. package/dist/board/TrackerLabels.d.ts +27 -0
  123. package/dist/board/TrackerLabels.js +56 -0
  124. package/dist/board/TrackerLabels.js.map +1 -0
  125. package/dist/board/UpdatePill.d.ts +52 -0
  126. package/dist/board/UpdatePill.js +188 -0
  127. package/dist/board/UpdatePill.js.map +1 -0
  128. package/dist/board/Vocabulary.d.ts +56 -0
  129. package/dist/board/Vocabulary.js +104 -0
  130. package/dist/board/Vocabulary.js.map +1 -0
  131. package/dist/board/Warnings.d.ts +35 -0
  132. package/dist/board/Warnings.js +85 -0
  133. package/dist/board/Warnings.js.map +1 -0
  134. package/dist/board/WorkMap.d.ts +136 -0
  135. package/dist/board/WorkMap.js +274 -0
  136. package/dist/board/WorkMap.js.map +1 -0
  137. package/dist/board/index.d.ts +42 -0
  138. package/dist/collections/CollectionState.d.ts +10 -1
  139. package/dist/collections/CollectionState.js +12 -5
  140. package/dist/collections/CollectionState.js.map +1 -1
  141. package/dist/collections/ResultList.js +1 -1
  142. package/dist/collections/ScrollRow.js +1 -1
  143. package/dist/collections/VirtualList.js +1 -1
  144. package/dist/display/Avatar.d.ts +5 -2
  145. package/dist/display/Avatar.js +2 -2
  146. package/dist/display/Avatar.js.map +1 -1
  147. package/dist/display/Badge.d.ts +6 -1
  148. package/dist/display/Badge.js +9 -4
  149. package/dist/display/Badge.js.map +1 -1
  150. package/dist/display/CheckList.js +1 -1
  151. package/dist/display/Comment.d.ts +12 -0
  152. package/dist/display/Comment.js +39 -0
  153. package/dist/display/Comment.js.map +1 -0
  154. package/dist/display/CopyButton.d.ts +10 -2
  155. package/dist/display/CopyButton.js +29 -16
  156. package/dist/display/CopyButton.js.map +1 -1
  157. package/dist/display/Diagram.d.ts +17 -0
  158. package/dist/display/Diagram.js +49 -0
  159. package/dist/display/Diagram.js.map +1 -0
  160. package/dist/display/ImagePicker.js +1 -1
  161. package/dist/display/InfoBox.js +2 -2
  162. package/dist/display/InsetPanel.d.ts +3 -1
  163. package/dist/display/InsetPanel.js +7 -4
  164. package/dist/display/InsetPanel.js.map +1 -1
  165. package/dist/display/ItemAction.js +2 -2
  166. package/dist/display/LabelChip.d.ts +26 -0
  167. package/dist/display/LabelChip.js +41 -0
  168. package/dist/display/LabelChip.js.map +1 -0
  169. package/dist/display/LabelTint.js +60 -0
  170. package/dist/display/LabelTint.js.map +1 -0
  171. package/dist/display/Person.d.ts +5 -0
  172. package/dist/display/Person.js +19 -0
  173. package/dist/display/Person.js.map +1 -0
  174. package/dist/display/PropertySheet.js +1 -1
  175. package/dist/display/RadioChoice.d.ts +9 -2
  176. package/dist/display/RadioChoice.js +5 -1
  177. package/dist/display/RadioChoice.js.map +1 -1
  178. package/dist/display/RatingLink.js +1 -1
  179. package/dist/display/RichText.d.ts +12 -0
  180. package/dist/display/RichText.js +94 -0
  181. package/dist/display/RichText.js.map +1 -0
  182. package/dist/display/RowList.js +1 -1
  183. package/dist/display/index.d.ts +6 -1
  184. package/dist/feedback/Alert.js +1 -1
  185. package/dist/feedback/AsyncState.js +1 -1
  186. package/dist/feedback/DismissButton.d.ts +12 -0
  187. package/dist/feedback/DismissButton.js +20 -0
  188. package/dist/feedback/DismissButton.js.map +1 -0
  189. package/dist/feedback/ErrorNotification.js +2 -0
  190. package/dist/feedback/ErrorNotification.js.map +1 -1
  191. package/dist/feedback/FormResult.d.ts +16 -0
  192. package/dist/feedback/FormResult.js +30 -0
  193. package/dist/feedback/FormResult.js.map +1 -0
  194. package/dist/feedback/LiveRegion.d.ts +7 -0
  195. package/dist/feedback/LiveRegion.js +15 -0
  196. package/dist/feedback/LiveRegion.js.map +1 -0
  197. package/dist/feedback/Loading.d.ts +19 -0
  198. package/dist/feedback/Loading.js +63 -0
  199. package/dist/feedback/Loading.js.map +1 -0
  200. package/dist/feedback/Notifications.d.ts +35 -1
  201. package/dist/feedback/Notifications.js +196 -4
  202. package/dist/feedback/Notifications.js.map +1 -1
  203. package/dist/feedback/Progress.d.ts +15 -0
  204. package/dist/feedback/Progress.js +38 -0
  205. package/dist/feedback/Progress.js.map +1 -0
  206. package/dist/feedback/ProgressStatusRow.js +1 -1
  207. package/dist/feedback/StatusIndicator.d.ts +6 -1
  208. package/dist/feedback/StatusIndicator.js +19 -5
  209. package/dist/feedback/StatusIndicator.js.map +1 -1
  210. package/dist/feedback/index.d.ts +8 -4
  211. package/dist/forms/Checkbox.js +1 -1
  212. package/dist/forms/ColorSwatches.d.ts +21 -0
  213. package/dist/forms/ColorSwatches.js +26 -0
  214. package/dist/forms/ColorSwatches.js.map +1 -0
  215. package/dist/forms/FormSection.d.ts +68 -6
  216. package/dist/forms/FormSection.js +139 -8
  217. package/dist/forms/FormSection.js.map +1 -1
  218. package/dist/forms/HiddenField.d.ts +6 -0
  219. package/dist/forms/HiddenField.js +13 -0
  220. package/dist/forms/HiddenField.js.map +1 -0
  221. package/dist/forms/Input.d.ts +12 -2
  222. package/dist/forms/Input.js +10 -3
  223. package/dist/forms/Input.js.map +1 -1
  224. package/dist/forms/LabelPicker.d.ts +43 -0
  225. package/dist/forms/LabelPicker.js +107 -0
  226. package/dist/forms/LabelPicker.js.map +1 -0
  227. package/dist/forms/MarkdownEditor.d.ts +21 -0
  228. package/dist/forms/MarkdownEditor.js +175 -0
  229. package/dist/forms/MarkdownEditor.js.map +1 -0
  230. package/dist/forms/MarkdownToolbar.js +204 -0
  231. package/dist/forms/MarkdownToolbar.js.map +1 -0
  232. package/dist/forms/OptionSelect.d.ts +30 -9
  233. package/dist/forms/OptionSelect.js +53 -13
  234. package/dist/forms/OptionSelect.js.map +1 -1
  235. package/dist/forms/Select.d.ts +4 -1
  236. package/dist/forms/Select.js +3 -1
  237. package/dist/forms/Select.js.map +1 -1
  238. package/dist/forms/Switch.d.ts +4 -1
  239. package/dist/forms/Switch.js +5 -2
  240. package/dist/forms/Switch.js.map +1 -1
  241. package/dist/forms/TagInput.js +1 -1
  242. package/dist/forms/index.d.ts +7 -3
  243. package/dist/foundations/AmbientMotion.d.ts +2 -0
  244. package/dist/foundations/AmbientMotion.js +39 -0
  245. package/dist/foundations/AmbientMotion.js.map +1 -0
  246. package/dist/foundations/DesignSystemProvider.d.ts +34 -0
  247. package/dist/foundations/DesignSystemProvider.js +26 -1
  248. package/dist/foundations/DesignSystemProvider.js.map +1 -1
  249. package/dist/foundations/index.d.ts +2 -1
  250. package/dist/icons/BrandIcons.d.ts +8 -2
  251. package/dist/icons/BrandIcons.js +14 -3
  252. package/dist/icons/BrandIcons.js.map +1 -1
  253. package/dist/icons/dynamic.d.ts +2 -0
  254. package/dist/icons/dynamic.js +1 -0
  255. package/dist/icons/index.d.ts +2 -2
  256. package/dist/icons/index.js +1 -1
  257. package/dist/icons.d.ts +2 -2
  258. package/dist/icons.js +1 -1
  259. package/dist/index.d.ts +71 -10
  260. package/dist/index.js +78 -21
  261. package/dist/layout/Site.js +1 -1
  262. package/dist/layout/TitleBar.js +1 -1
  263. package/dist/layout/index.d.ts +2 -2
  264. package/dist/layout/index.js +3 -3
  265. package/dist/layout/toolbar/CommandPaletteTrigger.d.ts +17 -2
  266. package/dist/layout/toolbar/CommandPaletteTrigger.js +89 -6
  267. package/dist/layout/toolbar/CommandPaletteTrigger.js.map +1 -1
  268. package/dist/layout/toolbar/TriggerFit.js +56 -0
  269. package/dist/layout/toolbar/TriggerFit.js.map +1 -0
  270. package/dist/navigation/CollectionBrowseSelector.js +1 -1
  271. package/dist/navigation/CollectionViewToggle.d.ts +26 -0
  272. package/dist/navigation/CollectionViewToggle.js +54 -23
  273. package/dist/navigation/CollectionViewToggle.js.map +1 -1
  274. package/dist/navigation/DrilldownBrowseSelector.js +1 -1
  275. package/dist/navigation/FolderSelector.js +2 -2
  276. package/dist/navigation/SortMenu.d.ts +10 -0
  277. package/dist/navigation/SortMenu.js +33 -0
  278. package/dist/navigation/SortMenu.js.map +1 -0
  279. package/dist/navigation/index.d.ts +3 -2
  280. package/dist/overlays/CommandPalette.d.ts +38 -4
  281. package/dist/overlays/CommandPalette.js +140 -54
  282. package/dist/overlays/CommandPalette.js.map +1 -1
  283. package/dist/overlays/Drawer.js +1 -1
  284. package/dist/overlays/DropdownMenu.d.ts +7 -1
  285. package/dist/overlays/DropdownMenu.js +13 -2
  286. package/dist/overlays/DropdownMenu.js.map +1 -1
  287. package/dist/overlays/HelpTip.d.ts +8 -0
  288. package/dist/overlays/HelpTip.js +29 -0
  289. package/dist/overlays/HelpTip.js.map +1 -0
  290. package/dist/overlays/ImageViewer.js +2 -2
  291. package/dist/overlays/Modal.d.ts +5 -0
  292. package/dist/overlays/Modal.js +17 -2
  293. package/dist/overlays/Modal.js.map +1 -1
  294. package/dist/overlays/ModalExpandButton.d.ts +18 -0
  295. package/dist/overlays/ModalExpandButton.js +43 -0
  296. package/dist/overlays/ModalExpandButton.js.map +1 -0
  297. package/dist/overlays/Popover.d.ts +2 -1
  298. package/dist/overlays/Popover.js +1 -0
  299. package/dist/overlays/Popover.js.map +1 -1
  300. package/dist/overlays/index.d.ts +4 -2
  301. package/dist/showcase/Cards.js +1 -1
  302. package/dist/showcase/FeatureRow.js +1 -1
  303. package/dist/showcase/PhotoSearchConcept.js +1 -1
  304. package/dist/showcase/ProductBand.js +1 -1
  305. package/dist/showcase/Status.js +1 -1
  306. package/dist/typography/Code.d.ts +18 -0
  307. package/dist/typography/Code.js +24 -0
  308. package/dist/typography/Code.js.map +1 -0
  309. package/dist/typography/Link.d.ts +7 -2
  310. package/dist/typography/Link.js +15 -5
  311. package/dist/typography/Link.js.map +1 -1
  312. package/dist/typography/Typography.d.ts +19 -1
  313. package/dist/typography/Typography.js +11 -3
  314. package/dist/typography/Typography.js.map +1 -1
  315. package/dist/typography/index.d.ts +3 -3
  316. package/package.json +26 -3
  317. package/src/actions/Button.tsx +78 -11
  318. package/src/actions/ButtonLink.tsx +34 -0
  319. package/src/actions/ButtonRecipes.ts +10 -0
  320. package/src/actions/IconButton.tsx +7 -4
  321. package/src/board/ActivityLine.tsx +176 -0
  322. package/src/board/ActivityTrack.tsx +23 -0
  323. package/src/board/AddItem.tsx +259 -0
  324. package/src/board/Archive.tsx +75 -0
  325. package/src/board/Attention.tsx +135 -0
  326. package/src/board/BoardShell.tsx +30 -0
  327. package/src/board/BoardTitleBar.tsx +167 -0
  328. package/src/board/ButtonKinds.ts +32 -0
  329. package/src/board/Cleanup.tsx +19 -0
  330. package/src/board/Counters.tsx +224 -0
  331. package/src/board/DataAttributes.ts +3 -0
  332. package/src/board/Dependencies.tsx +49 -0
  333. package/src/board/Desk.tsx +155 -0
  334. package/src/board/Dossier.tsx +262 -0
  335. package/src/board/Filters.tsx +85 -0
  336. package/src/board/ItemDetails.tsx +435 -0
  337. package/src/board/ItemDialog.tsx +179 -0
  338. package/src/board/ItemParts.tsx +128 -0
  339. package/src/board/ItemProgress.tsx +164 -0
  340. package/src/board/List.tsx +154 -0
  341. package/src/board/LoadingScreen.tsx +78 -0
  342. package/src/board/NeedsYou.tsx +30 -0
  343. package/src/board/Onboarding.tsx +124 -0
  344. package/src/board/PartsList.tsx +160 -0
  345. package/src/board/ProjectIcon.tsx +172 -0
  346. package/src/board/PullRequests.tsx +106 -0
  347. package/src/board/RowStyles.ts +17 -0
  348. package/src/board/Settings.tsx +124 -0
  349. package/src/board/Slices.tsx +103 -0
  350. package/src/board/SourceIcon.tsx +33 -0
  351. package/src/board/StagePane.tsx +128 -0
  352. package/src/board/StageRow.tsx +320 -0
  353. package/src/board/StageTrack.tsx +61 -0
  354. package/src/board/StartControls.tsx +77 -0
  355. package/src/board/StatusColors.ts +28 -0
  356. package/src/board/StatusGlyph.tsx +70 -0
  357. package/src/board/Threads.tsx +38 -0
  358. package/src/board/TrackerLabels.tsx +75 -0
  359. package/src/board/UpdatePill.tsx +222 -0
  360. package/src/board/Vocabulary.tsx +155 -0
  361. package/src/board/Warnings.tsx +83 -0
  362. package/src/board/WorkMap.tsx +436 -0
  363. package/src/board/base.css +121 -0
  364. package/src/board/button-kinds.css +8 -0
  365. package/src/board/index.ts +224 -0
  366. package/src/board/items.css +75 -0
  367. package/src/board/loading-screen.css +171 -0
  368. package/src/board/rows.css +180 -0
  369. package/src/board/title-bar.css +56 -0
  370. package/src/board/tokens.css +52 -0
  371. package/src/board.css +19 -0
  372. package/src/collections/CollectionState.tsx +20 -7
  373. package/src/display/Avatar.tsx +6 -3
  374. package/src/display/Badge.tsx +25 -3
  375. package/src/display/Comment.tsx +26 -0
  376. package/src/display/CopyButton.tsx +48 -18
  377. package/src/display/Diagram.tsx +59 -0
  378. package/src/display/InsetPanel.tsx +4 -1
  379. package/src/display/LabelChip.tsx +73 -0
  380. package/src/display/LabelTint.ts +72 -0
  381. package/src/display/Person.tsx +11 -0
  382. package/src/display/RadioChoice.tsx +11 -2
  383. package/src/display/RichText.tsx +114 -0
  384. package/src/display/index.ts +5 -0
  385. package/src/feedback/DismissButton.tsx +28 -0
  386. package/src/feedback/ErrorNotification.ts +3 -0
  387. package/src/feedback/FormResult.tsx +50 -0
  388. package/src/feedback/LiveRegion.tsx +10 -0
  389. package/src/feedback/Loading.tsx +75 -0
  390. package/src/feedback/Notifications.tsx +267 -2
  391. package/src/feedback/Progress.tsx +44 -0
  392. package/src/feedback/StatusIndicator.tsx +34 -3
  393. package/src/feedback/index.ts +12 -2
  394. package/src/forms/ColorSwatches.tsx +50 -0
  395. package/src/forms/FormSection.tsx +245 -10
  396. package/src/forms/HiddenField.tsx +4 -0
  397. package/src/forms/Input.tsx +26 -4
  398. package/src/forms/LabelPicker.tsx +140 -0
  399. package/src/forms/MarkdownEditor.tsx +283 -0
  400. package/src/forms/MarkdownToolbar.tsx +267 -0
  401. package/src/forms/OptionSelect.tsx +110 -25
  402. package/src/forms/Select.tsx +20 -13
  403. package/src/forms/Switch.tsx +16 -2
  404. package/src/forms/index.ts +16 -2
  405. package/src/foundations/AmbientMotion.ts +51 -0
  406. package/src/foundations/DesignSystemProvider.tsx +19 -0
  407. package/src/foundations/index.ts +1 -0
  408. package/src/foundations/theme.css +64 -0
  409. package/src/icons/BrandIcons.tsx +12 -3
  410. package/src/icons/dynamic.ts +4 -0
  411. package/src/icons/index.ts +1 -1
  412. package/src/index.ts +2 -1
  413. package/src/layout/index.ts +1 -1
  414. package/src/layout/toolbar/CommandPaletteTrigger.tsx +187 -31
  415. package/src/layout/toolbar/TriggerFit.ts +84 -0
  416. package/src/navigation/CollectionViewToggle.tsx +94 -24
  417. package/src/navigation/SortMenu.tsx +41 -0
  418. package/src/navigation/index.ts +2 -1
  419. package/src/overlays/CommandPalette.tsx +190 -60
  420. package/src/overlays/DropdownMenu.tsx +12 -1
  421. package/src/overlays/HelpTip.tsx +29 -0
  422. package/src/overlays/Modal.tsx +23 -0
  423. package/src/overlays/ModalExpandButton.tsx +48 -0
  424. package/src/overlays/Popover.tsx +3 -1
  425. package/src/overlays/index.ts +9 -1
  426. package/src/showcase.css +6 -0
  427. package/src/styles.css +9 -1
  428. package/src/typography/Code.tsx +24 -0
  429. package/src/typography/Link.tsx +19 -10
  430. package/src/typography/Typography.tsx +25 -2
  431. package/src/typography/index.ts +1 -1
  432. package/dist/feedback/index.js +0 -11
  433. package/dist/typography/index.js +0 -4
@@ -0,0 +1,70 @@
1
+ // One glyph per status of Lar Factory's work, the way T3 marks a thread working, waiting or done, in the status's
2
+ // colour (board/tokens.css's --st-* colours).
3
+
4
+ import {
5
+ CheckIcon,
6
+ CircleArrowRightIcon,
7
+ CircleDashedIcon,
8
+ CircleDotIcon,
9
+ CircleIcon,
10
+ Clock3Icon,
11
+ EyeIcon,
12
+ GitMergeIcon,
13
+ ListIcon,
14
+ } from 'lucide-react';
15
+
16
+ import { SpinnerIcon } from '../feedback/Loading';
17
+ import { ambientMotion } from '../foundations/AmbientMotion';
18
+ import { type BoardStatus, statusColor } from './StatusColors';
19
+
20
+ const sizes = { compact: 'size-3', default: 'size-3.5', title: 'size-4' } as const;
21
+
22
+ /** The statuses whose glyph pulses while their work runs; In progress spins instead. */
23
+ const pulses: BoardStatus[] = ['Shaping', 'Review', 'Verify', 'Ready to merge'];
24
+
25
+ /**
26
+ * A status's glyph in its colour. `running` animates it while its work is known to run: In progress spins, and
27
+ * Shaping, Review, Verify and Ready to merge pulse. `presentation` sizes it: 12px beside small text, 14px by default,
28
+ * 16px beside a title.
29
+ */
30
+ export function StatusGlyph({
31
+ status,
32
+ running = false,
33
+ presentation = 'default',
34
+ }: {
35
+ status: BoardStatus;
36
+ running?: boolean;
37
+ presentation?: keyof typeof sizes;
38
+ }) {
39
+ const pulse = running && pulses.includes(status);
40
+ const props = {
41
+ ref: pulse ? ambientMotion : undefined,
42
+ className: `shrink-0 ${sizes[presentation]}${pulse ? ' status-pulse' : ''}`,
43
+ style: { color: statusColor[status] },
44
+ strokeWidth: 2.25,
45
+ };
46
+
47
+ switch (status) {
48
+ case 'List':
49
+ return <ListIcon {...props} />;
50
+ case 'Needs you':
51
+ case 'Verify':
52
+ return <CircleDotIcon {...props} />;
53
+ case 'In progress':
54
+ return running ? <SpinnerIcon motion="status" {...props} /> : <CircleIcon {...props} />;
55
+ case 'Ready':
56
+ return <CircleArrowRightIcon {...props} />;
57
+ case 'Shaping':
58
+ return <CircleDashedIcon {...props} />;
59
+ case 'Review':
60
+ return <EyeIcon {...props} />;
61
+ case 'Ready to merge':
62
+ return <GitMergeIcon {...props} />;
63
+ case 'Done':
64
+ return <CheckIcon {...props} />;
65
+ case 'Queued':
66
+ return <Clock3Icon {...props} />;
67
+ default:
68
+ return <CircleIcon {...props} />;
69
+ }
70
+ }
@@ -0,0 +1,38 @@
1
+ // A piece of work's earlier T3 threads, in the item dialog.
2
+
3
+ import type { ReactNode } from 'react';
4
+
5
+ /** The earlier threads, one EarlierThread each, in small muted text. */
6
+ export function EarlierThreadList({ children }: { children: ReactNode }) {
7
+ return (
8
+ <ul className="m-0 grid list-none gap-1 p-0 text-xs text-(--muted-foreground)" data-earlier-threads>
9
+ {children}
10
+ </ul>
11
+ );
12
+ }
13
+
14
+ /** An earlier thread: its `name`, linked when `href` opens it, then its `state`; `title` names it in full. */
15
+ export function EarlierThread({
16
+ name,
17
+ title,
18
+ href,
19
+ state,
20
+ }: {
21
+ name: string;
22
+ title: string;
23
+ href?: string | undefined;
24
+ state: ReactNode;
25
+ }) {
26
+ return (
27
+ <li className="flex min-w-0 items-center gap-1.5" title={title}>
28
+ {href ? (
29
+ <a href={href} className="truncate underline">
30
+ {name}
31
+ </a>
32
+ ) : (
33
+ <span className="truncate">{name}</span>
34
+ )}{' '}
35
+ <span className="shrink-0">· {state}</span>
36
+ </li>
37
+ );
38
+ }
@@ -0,0 +1,75 @@
1
+ // The tracker's labels on a Lar Factory project's settings page: the list of them, each row with its chip, detail and
2
+ // actions and the editor it opens, and the line that creates one.
3
+
4
+ import type { FormEvent, ReactNode } from 'react';
5
+
6
+ import type { DataAttributes } from './DataAttributes';
7
+
8
+ /** The tracker's labels, a row each, in a bordered list that never grows past its section. */
9
+ export function TrackerLabelList({ children }: { children: ReactNode }) {
10
+ return (
11
+ <ul className="m-0 grid list-none grid-cols-[minmax(0,1fr)] overflow-hidden rounded-lg border p-0">
12
+ {children}
13
+ </ul>
14
+ );
15
+ }
16
+
17
+ /**
18
+ * A label's row: its `chip`, its `detail` (truncating, its tooltip giving it whole), then its `actions`, with the
19
+ * `editor` it has open under them.
20
+ */
21
+ export function TrackerLabelRow({
22
+ chip,
23
+ detail,
24
+ actions,
25
+ editor,
26
+ ...data
27
+ }: {
28
+ chip: ReactNode;
29
+ detail?: string | undefined;
30
+ actions?: ReactNode;
31
+ editor?: ReactNode;
32
+ } & DataAttributes) {
33
+ return (
34
+ <li {...data} className="border-b last:border-b-0">
35
+ <div className="flex min-w-0 items-center gap-3 px-3 py-1.5">
36
+ <span className="max-w-[45%] min-w-0">{chip}</span>
37
+ <span className="text-base-700 min-w-0 flex-1 truncate text-xs" title={detail}>
38
+ {detail}
39
+ </span>
40
+ {actions && <span className="flex shrink-0 gap-1">{actions}</span>}
41
+ </div>
42
+ {editor}
43
+ </li>
44
+ );
45
+ }
46
+
47
+ /** The editor a label's row opens, ruled off under it on a faint tint. */
48
+ export function TrackerLabelEditor({
49
+ onSubmit,
50
+ children,
51
+ }: {
52
+ onSubmit: (event: FormEvent<HTMLFormElement>) => void;
53
+ children: ReactNode;
54
+ }) {
55
+ return (
56
+ <form className="bg-base-200/40 grid gap-3 border-t p-3" onSubmit={onSubmit}>
57
+ {children}
58
+ </form>
59
+ );
60
+ }
61
+
62
+ /** The line that creates a label: its name field and the button that submits it, wrapping when they don't fit. */
63
+ export function CreateLabelForm({
64
+ onSubmit,
65
+ children,
66
+ }: {
67
+ onSubmit: (event: FormEvent<HTMLFormElement>) => void;
68
+ children: ReactNode;
69
+ }) {
70
+ return (
71
+ <form className="flex max-w-full min-w-0 flex-wrap gap-2" onSubmit={onSubmit}>
72
+ {children}
73
+ </form>
74
+ );
75
+ }
@@ -0,0 +1,222 @@
1
+ // The title bar's update pill, from T3 Code's update pill (apps/web/src/components/sidebar/SidebarUpdatePill.tsx at
2
+ // d53873b) and its status icon (DesktopUpdateStatusIcon.tsx at 9a391eb), drawn as the board's other App controls are,
3
+ // tinted in every state, instead of as T3's pill. Copyright (c) 2026 T3 Tools Inc. MIT License.
4
+
5
+ import { ArrowDownToLineIcon, RotateCcwIcon } from 'lucide-react';
6
+ import { type PointerEvent, type ReactNode, useEffect, useRef, useState } from 'react';
7
+
8
+ import { Button } from '../actions/Button';
9
+ import { Popover } from '../overlays/Popover';
10
+ import { Tooltip, TooltipPopup, TooltipTrigger } from '../overlays/Tooltip';
11
+ import { buttonKind } from './ButtonKinds';
12
+
13
+ const RADIUS = 7;
14
+ const CIRCUMFERENCE = 2 * Math.PI * RADIUS;
15
+ const CLOSE_DELAY_MS = 150;
16
+
17
+ /** The pill's icon: an arrow for an available update, a progress ring in the primary colour while it downloads, and a
18
+ * restart arrow once it's downloaded. 16 px, as every title bar icon is. */
19
+ export function UpdateStatusIcon({
20
+ status,
21
+ percent = 0,
22
+ }: {
23
+ status: 'available' | 'downloading' | 'downloaded';
24
+ /** The download's whole percentage, 0 to 100. */
25
+ percent?: number;
26
+ }) {
27
+ if (status === 'downloading')
28
+ return (
29
+ <svg aria-hidden="true" className="size-4 shrink-0 -rotate-90" viewBox="0 0 20 20">
30
+ <circle
31
+ cx="10"
32
+ cy="10"
33
+ r={RADIUS}
34
+ fill="none"
35
+ stroke="currentColor"
36
+ strokeOpacity="0.2"
37
+ strokeWidth="2"
38
+ />
39
+ <circle
40
+ cx="10"
41
+ cy="10"
42
+ r={RADIUS}
43
+ fill="none"
44
+ className="stroke-primary transition-[stroke-dashoffset] duration-300 ease-out motion-reduce:transition-none"
45
+ strokeDasharray={CIRCUMFERENCE}
46
+ strokeDashoffset={CIRCUMFERENCE * (1 - percent / 100)}
47
+ strokeLinecap="round"
48
+ strokeWidth="2"
49
+ />
50
+ </svg>
51
+ );
52
+
53
+ const Icon = status === 'downloaded' ? RotateCcwIcon : ArrowDownToLineIcon;
54
+
55
+ return <Icon className="size-4 shrink-0" aria-hidden="true" />;
56
+ }
57
+
58
+ /** The pill while the update downloads: nothing to click, a progress bar to screen readers, with more in its tooltip.
59
+ * `text` is what it says before the percentage, `label` its accessible name. */
60
+ export function UpdateDownloading({
61
+ percent,
62
+ text,
63
+ label,
64
+ tooltip,
65
+ }: {
66
+ percent: number;
67
+ text: string;
68
+ label: string;
69
+ tooltip: string;
70
+ }) {
71
+ return (
72
+ <Tooltip>
73
+ <TooltipTrigger asChild>
74
+ <span
75
+ tabIndex={0}
76
+ role="progressbar"
77
+ aria-label={label}
78
+ aria-valuemin={0}
79
+ aria-valuemax={100}
80
+ aria-valuenow={percent}
81
+ data-kind="control"
82
+ className="update-button text-primary focus-visible:ring-primary inline-flex h-7 items-center gap-1.5 rounded-md bg-[color-mix(in_srgb,var(--color-primary)_10%,var(--color-base-100))] px-[11px] text-xs font-medium outline-none hover:bg-[color-mix(in_srgb,var(--color-primary)_18%,var(--color-base-100))] focus-visible:ring-2"
83
+ >
84
+ <UpdateStatusIcon status="downloading" percent={percent} />
85
+ {text} <span className="w-7 tabular-nums">{percent}%</span>
86
+ </span>
87
+ </TooltipTrigger>
88
+ <TooltipPopup side="bottom">{tooltip}</TooltipPopup>
89
+ </Tooltip>
90
+ );
91
+ }
92
+
93
+ /** Open while the pointer is on the pill or its popover, and for 150 ms after it leaves both. */
94
+ function useHoverOpen() {
95
+ const [open, setOpen] = useState(false);
96
+ const timer = useRef<ReturnType<typeof setTimeout>>(undefined);
97
+
98
+ useEffect(() => () => clearTimeout(timer.current), []);
99
+
100
+ const show = () => {
101
+ clearTimeout(timer.current);
102
+ setOpen(true);
103
+ };
104
+ const close = () => {
105
+ clearTimeout(timer.current);
106
+ setOpen(false);
107
+ };
108
+ const hover = {
109
+ // A touch has no hover: a tap runs the step.
110
+ onPointerEnter: (event: PointerEvent) => event.pointerType !== 'touch' && show(),
111
+ onPointerLeave: (event: PointerEvent) => {
112
+ if (event.pointerType === 'touch') return;
113
+
114
+ clearTimeout(timer.current);
115
+ timer.current = setTimeout(() => setOpen(false), CLOSE_DELAY_MS);
116
+ },
117
+ };
118
+
119
+ return { open, show, close, hover };
120
+ }
121
+
122
+ interface UpdatePillProps {
123
+ /** Whether the update is downloaded and waits for a restart, or still to download. */
124
+ status: 'available' | 'downloaded';
125
+ /** What the pill says, such as "Update available" or "Installing…". */
126
+ label: string;
127
+ /** The popover's heading, such as "Lar Factory 1.4.0 is available". */
128
+ heading: string;
129
+ /** The update's changes, such as ReleaseNotes. */
130
+ notes?: ReactNode;
131
+ /** The popover's button, such as "Download". */
132
+ actionLabel: string;
133
+ disabled: boolean;
134
+ /** Runs the step: the pill and the popover's button both run it. */
135
+ onRun: () => void;
136
+ }
137
+
138
+ /**
139
+ * The pill with an update to download or install. Clicking it runs that step. Hovering it, or focusing it from the
140
+ * keyboard, opens the changelog below it, with the step's button; it closes 150 ms after the pointer leaves both, and
141
+ * on Escape. The focus stays on the pill.
142
+ */
143
+ export function UpdatePill({ status, label, heading, notes, actionLabel, disabled, onRun }: UpdatePillProps) {
144
+ const { open, show, close, hover } = useHoverOpen();
145
+
146
+ return (
147
+ <Popover open={open} onOpenChange={(next) => !next && close()}>
148
+ <Popover.Trigger asChild>
149
+ <Button
150
+ {...buttonKind('control')}
151
+ variant="tinted"
152
+ aria-disabled={disabled || undefined}
153
+ className={`update-button gap-1.5 font-medium ${disabled ? 'cursor-not-allowed' : ''}`}
154
+ // The pill runs the step; the changelog opens on hover and focus, not on the click.
155
+ onClick={(event) => {
156
+ event.preventDefault();
157
+
158
+ if (!disabled) onRun();
159
+ }}
160
+ onFocus={(event) => event.currentTarget.matches(':focus-visible') && show()}
161
+ {...hover}
162
+ >
163
+ <UpdateStatusIcon status={status} />
164
+ {label}
165
+ </Button>
166
+ </Popover.Trigger>
167
+ <Popover.Content
168
+ side="bottom"
169
+ align="end"
170
+ onOpenAutoFocus={(event) => event.preventDefault()}
171
+ onCloseAutoFocus={(event) => event.preventDefault()}
172
+ {...hover}
173
+ >
174
+ <div className="grid w-80 max-w-full gap-3 text-left">
175
+ <p className="update-heading text-base-content m-0 text-sm font-medium">{heading}</p>
176
+ {notes ? <div className="max-h-[min(28rem,calc(100vh-10rem))] overflow-y-auto">{notes}</div> : null}
177
+ <span className="justify-self-start">
178
+ <Button {...buttonKind('main')} className="update-next" disabled={disabled} onClick={onRun}>
179
+ {actionLabel}
180
+ </Button>
181
+ </span>
182
+ </div>
183
+ </Popover.Content>
184
+ </Popover>
185
+ );
186
+ }
187
+
188
+ export interface ReleaseNote {
189
+ version: string;
190
+ /** The section's heading, such as "What's changed" or "Changes in 1.3.0". */
191
+ title: string;
192
+ items: readonly string[];
193
+ /** What the app left out, such as "3 more changes in this Release". */
194
+ more?: string;
195
+ }
196
+
197
+ /** Each Release's changes, newest first, and a note of older Releases left out. */
198
+ export function ReleaseNotes({ releases, older }: { releases: readonly ReleaseNote[]; older?: string }) {
199
+ return (
200
+ <>
201
+ {releases.map((note) => (
202
+ <section
203
+ className="not-first:border-base-300 not-first:mt-3 not-first:border-t not-first:pt-3"
204
+ key={note.version}
205
+ >
206
+ <h3 className="text-base-content m-0 text-xs leading-4 font-semibold">{note.title}</h3>
207
+ <ul className="text-base-700 m-0 mt-2 space-y-1.5 pl-4 text-xs leading-5">
208
+ {note.items.map((item, i) => (
209
+ <li className="list-disc break-words" key={i}>
210
+ {item}
211
+ </li>
212
+ ))}
213
+ </ul>
214
+ {note.more ? <p className="text-base-700 m-0 mt-2 text-xs leading-5">{note.more}</p> : null}
215
+ </section>
216
+ ))}
217
+ {older ? (
218
+ <p className="border-base-300 text-base-700 m-0 mt-3 border-t pt-3 text-xs leading-5">{older}</p>
219
+ ) : null}
220
+ </>
221
+ );
222
+ }
@@ -0,0 +1,155 @@
1
+ // A project's kind vocabulary in Lar Factory's settings and onboarding: each kind's row, with its type and the chips of
2
+ // its labels, and the chooser that picks them from the tracker's labels.
3
+
4
+ import type { ReactNode } from 'react';
5
+
6
+ import type { DataAttributes } from './DataAttributes';
7
+
8
+ /**
9
+ * One kind's row: its `title`, its `type` control, then its labels' chips in a group `labelsLabel` names, which take a
10
+ * line of their own on a narrow page, ending with the `chooser` that edits them; what the row says about them (notes,
11
+ * problems, actions) follows under it.
12
+ */
13
+ export function VocabularyRow({
14
+ title,
15
+ type,
16
+ labels,
17
+ labelsLabel,
18
+ chooser,
19
+ children,
20
+ ...data
21
+ }: {
22
+ title: string;
23
+ type: ReactNode;
24
+ labels: ReactNode;
25
+ labelsLabel: string;
26
+ chooser: ReactNode;
27
+ children?: ReactNode;
28
+ } & DataAttributes) {
29
+ return (
30
+ <div {...data} className="grid min-w-0 gap-2 px-3 py-3">
31
+ <div className="grid min-w-0 grid-cols-[minmax(0,1fr)_8.5rem] items-center gap-x-3 gap-y-2 sm:grid-cols-[5.5rem_8.5rem_minmax(0,1fr)]">
32
+ <span className="text-[13px] font-medium">{title}</span>
33
+ {type}
34
+ <div
35
+ role="group"
36
+ aria-label={labelsLabel}
37
+ className="col-span-2 flex min-w-0 flex-wrap items-center gap-1 sm:col-span-1"
38
+ >
39
+ {labels}
40
+ <span className="ms-auto flex">{chooser}</span>
41
+ </div>
42
+ </div>
43
+ {children}
44
+ </div>
45
+ );
46
+ }
47
+
48
+ /** The chip that stands for the labels past the first few, which opens the chooser (`label` names it). */
49
+ export function VocabularyMore({ label, onClick, children }: { label: string; onClick: () => void; children: string }) {
50
+ return (
51
+ <button
52
+ type="button"
53
+ className="cursor-pointer rounded-full bg-(--muted) px-2 text-xs"
54
+ aria-label={label}
55
+ onClick={onClick}
56
+ >
57
+ {children}
58
+ </button>
59
+ );
60
+ }
61
+
62
+ /** A suggested label, dashed, which a press maps. */
63
+ export function VocabularySuggestion({
64
+ disabled = false,
65
+ onClick,
66
+ children,
67
+ }: {
68
+ disabled?: boolean;
69
+ onClick: () => void;
70
+ children: ReactNode;
71
+ }) {
72
+ return (
73
+ <button
74
+ type="button"
75
+ disabled={disabled}
76
+ className="cursor-pointer rounded-full border border-dashed border-(--border) px-2 py-0.5 text-xs"
77
+ onClick={onClick}
78
+ >
79
+ {children}
80
+ </button>
81
+ );
82
+ }
83
+
84
+ /** The chooser's panel inside its popover: the search field, the list, then its actions, one under the other. */
85
+ export function LabelChooser({ children, ...data }: { children: ReactNode } & DataAttributes) {
86
+ return (
87
+ <div {...data} className="grid w-full min-w-0 gap-2">
88
+ {children}
89
+ </div>
90
+ );
91
+ }
92
+
93
+ /** The chooser's list of labels, which picks several (`label` names it); its wheel scrolls the list alone. */
94
+ export function LabelChooserList({ id, label, children }: { id: string; label: string; children: ReactNode }) {
95
+ return (
96
+ <ul
97
+ id={id}
98
+ role="listbox"
99
+ aria-multiselectable
100
+ aria-label={label}
101
+ className="m-0 h-64 list-none overflow-y-auto overscroll-contain p-0"
102
+ onWheel={(event) => event.stopPropagation()}
103
+ >
104
+ {children}
105
+ </ul>
106
+ );
107
+ }
108
+
109
+ /** One label in the chooser's list, highlighted while `active`. A press picks it and keeps focus in the search field. */
110
+ export function LabelChooserOption({
111
+ id,
112
+ selected,
113
+ disabled,
114
+ active,
115
+ onHover,
116
+ onPick,
117
+ children,
118
+ }: {
119
+ id: string;
120
+ selected: boolean;
121
+ disabled: boolean;
122
+ active: boolean;
123
+ onHover: () => void;
124
+ onPick: () => void;
125
+ children: ReactNode;
126
+ }) {
127
+ return (
128
+ <li
129
+ id={id}
130
+ role="option"
131
+ aria-selected={selected}
132
+ aria-disabled={disabled}
133
+ className={`cursor-pointer rounded px-2 py-1 text-[13px] wrap-anywhere ${active ? 'bg-(--muted)' : ''}`}
134
+ onMouseMove={onHover}
135
+ onMouseDown={(event) => event.preventDefault()}
136
+ onClick={onPick}
137
+ >
138
+ {children}
139
+ </li>
140
+ );
141
+ }
142
+
143
+ /** What the chooser's list says when no label matches, announced. */
144
+ export function LabelChooserEmpty({ children }: { children: ReactNode }) {
145
+ return (
146
+ <li role="status" className="px-2 py-2 text-xs text-(--muted-foreground)">
147
+ {children}
148
+ </li>
149
+ );
150
+ }
151
+
152
+ /** The chooser's closing actions, at either end of a ruled line. */
153
+ export function LabelChooserFooter({ children }: { children: ReactNode }) {
154
+ return <div className="flex justify-between gap-2 border-t border-(--border) pt-2">{children}</div>;
155
+ }
@@ -0,0 +1,83 @@
1
+ import type { MouseEvent, ReactNode } from 'react';
2
+
3
+ import { BrandMark } from '../display/BrandMark';
4
+ import { DismissButton } from '../feedback/DismissButton';
5
+
6
+ interface BoardWarningsProps {
7
+ /** A warning shown open above the rest, such as a lost board server, which every number on the page depends on. */
8
+ lead?: ReactNode;
9
+ /** The collapsed list's summary, such as "2 connections need attention"; without it, no list. */
10
+ summary?: ReactNode;
11
+ /** The warnings in the collapsed list. */
12
+ children?: ReactNode;
13
+ /** At the banner's right, such as Diagnostics. */
14
+ action: ReactNode;
15
+ }
16
+
17
+ /** The board's warnings, in a banner under the title bar: connection problems stay in a collapsed list, inline
18
+ * details that never open a notification or a dialog. */
19
+ export function BoardWarnings({ lead, summary, children, action }: BoardWarningsProps) {
20
+ return (
21
+ <aside data-board-notices className="shrink-0 border-b bg-(--warning-surface) px-6 py-2 text-(--foreground)">
22
+ <div className="flex items-start justify-between gap-3">
23
+ <div className="min-w-0 flex-1">
24
+ {lead}
25
+ {summary ? (
26
+ <details>
27
+ <summary className="cursor-pointer text-xs font-medium">{summary}</summary>
28
+ <div className="mt-2 max-h-48 overflow-auto">{children}</div>
29
+ </details>
30
+ ) : null}
31
+ </div>
32
+ {action}
33
+ </div>
34
+ </aside>
35
+ );
36
+ }
37
+
38
+ interface BoardWarningProps {
39
+ /** What the warning is about, as `data-warning`. */
40
+ name: string;
41
+ title: string;
42
+ dismissLabel: string;
43
+ onDismiss: (event: MouseEvent<HTMLButtonElement>) => void;
44
+ /** Under the text, such as a button that fixes it. */
45
+ action?: ReactNode;
46
+ children: ReactNode;
47
+ }
48
+
49
+ /** One warning in the banner: its title, what to do, and a close button. Commands in it wrap anywhere. */
50
+ export function BoardWarning({ name, title, dismissLabel, onDismiss, action, children }: BoardWarningProps) {
51
+ return (
52
+ <div data-slot="notice" className="relative border-t py-3 pr-8 text-xs first:border-t-0 first:py-1">
53
+ <div data-warning={name} className="[&_code]:wrap-anywhere">
54
+ <DismissButton label={dismissLabel} onClick={onDismiss} />
55
+ <div data-slot="title" className="font-medium">
56
+ {title}
57
+ </div>
58
+ <div data-slot="description" className="text-base-700 mt-1">
59
+ {children}
60
+ </div>
61
+ {action && <div className="mt-2">{action}</div>}
62
+ </div>
63
+ </div>
64
+ );
65
+ }
66
+
67
+ /** What fills the board's main area while a tool it can't work without is missing: the Lar mark, what's missing, why
68
+ * and how to fix it, and a way to look again. */
69
+ export function ToolMissing({ title, children, action }: { title: string; children: ReactNode; action: ReactNode }) {
70
+ return (
71
+ <div className="tool-missing grid flex-1 place-items-center p-5">
72
+ <div
73
+ className="tool-missing-box max-w-130 rounded-(--radius) border bg-(--card) px-6 py-5 [&_code]:wrap-anywhere [&_code]:text-(--foreground)"
74
+ role="alert"
75
+ >
76
+ <BrandMark label="Lar" />
77
+ <h1 className="mt-3 mb-0 text-(length:--text-base) font-semibold tracking-[-0.01em]">{title}</h1>
78
+ <p className="mt-3 mb-0 text-(--muted-foreground)">{children}</p>
79
+ <p className="mt-3 mb-0 text-(--muted-foreground)">{action}</p>
80
+ </div>
81
+ </div>
82
+ );
83
+ }