@sincpro/web-ui 0.0.0-stage → 0.2.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 (376) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +184 -2
  3. package/dist/components/activity/Activity.d.ts +69 -0
  4. package/dist/components/activity/Activity.js +279 -0
  5. package/dist/components/activity/Messages.d.ts +66 -0
  6. package/dist/components/activity/Messages.js +46 -0
  7. package/dist/components/activity/Timeline.d.ts +21 -0
  8. package/dist/components/activity/Timeline.js +30 -0
  9. package/dist/components/activity/index.d.ts +3 -0
  10. package/dist/components/activity/index.js +4 -0
  11. package/dist/components/assist/AssistMark.d.ts +64 -0
  12. package/dist/components/assist/AssistMark.js +108 -0
  13. package/dist/components/assist/AssistPending.d.ts +24 -0
  14. package/dist/components/assist/AssistPending.js +26 -0
  15. package/dist/components/assist/AssistSuggestion.d.ts +42 -0
  16. package/dist/components/assist/AssistSuggestion.js +55 -0
  17. package/dist/components/assist/ChangeReview.d.ts +56 -0
  18. package/dist/components/assist/ChangeReview.js +121 -0
  19. package/dist/components/assist/assist.d.ts +77 -0
  20. package/dist/components/assist/assist.js +87 -0
  21. package/dist/components/assist/index.d.ts +5 -0
  22. package/dist/components/assist/index.js +7 -0
  23. package/dist/components/form/Form.d.ts +52 -0
  24. package/dist/components/form/Form.js +49 -0
  25. package/dist/components/form/Sheet.d.ts +47 -0
  26. package/dist/components/form/Sheet.js +90 -0
  27. package/dist/components/form/index.d.ts +2 -0
  28. package/dist/components/form/index.js +4 -0
  29. package/dist/components/frame/Chart.d.ts +13 -0
  30. package/dist/components/frame/Chart.js +24 -0
  31. package/dist/components/frame/FrameView.d.ts +33 -0
  32. package/dist/components/frame/FrameView.js +125 -0
  33. package/dist/components/frame/index.d.ts +3 -0
  34. package/dist/components/frame/index.js +3 -0
  35. package/dist/components/frame/model.d.ts +43 -0
  36. package/dist/components/frame/model.js +101 -0
  37. package/dist/components/index.d.ts +10 -0
  38. package/dist/components/index.js +11 -0
  39. package/dist/components/lines/LineItems.d.ts +111 -0
  40. package/dist/components/lines/LineItems.js +317 -0
  41. package/dist/components/lines/index.d.ts +1 -0
  42. package/dist/components/lines/index.js +2 -0
  43. package/dist/components/lines/lines.d.ts +23 -0
  44. package/dist/components/lines/lines.js +26 -0
  45. package/dist/components/listing/ColumnsMenu.d.ts +20 -0
  46. package/dist/components/listing/ColumnsMenu.js +46 -0
  47. package/dist/components/listing/GroupingLevels.d.ts +35 -0
  48. package/dist/components/listing/GroupingLevels.js +45 -0
  49. package/dist/components/listing/Listing.d.ts +27 -0
  50. package/dist/components/listing/Listing.js +86 -0
  51. package/dist/components/listing/ListingBar.d.ts +112 -0
  52. package/dist/components/listing/ListingBar.js +144 -0
  53. package/dist/components/listing/Pagination.d.ts +36 -0
  54. package/dist/components/listing/Pagination.js +69 -0
  55. package/dist/components/listing/RecordCard.d.ts +33 -0
  56. package/dist/components/listing/RecordCard.js +22 -0
  57. package/dist/components/listing/RecordLink.d.ts +7 -0
  58. package/dist/components/listing/RecordLink.js +22 -0
  59. package/dist/components/listing/Row.d.ts +110 -0
  60. package/dist/components/listing/Row.js +123 -0
  61. package/dist/components/listing/SortMenu.d.ts +62 -0
  62. package/dist/components/listing/SortMenu.js +105 -0
  63. package/dist/components/listing/ViewSwitcher.d.ts +24 -0
  64. package/dist/components/listing/ViewSwitcher.js +16 -0
  65. package/dist/components/listing/columns.d.ts +47 -0
  66. package/dist/components/listing/columns.js +72 -0
  67. package/dist/components/listing/grouping.d.ts +35 -0
  68. package/dist/components/listing/grouping.js +47 -0
  69. package/dist/components/listing/index.d.ts +17 -0
  70. package/dist/components/listing/index.js +20 -0
  71. package/dist/components/listing/modelColumns.d.ts +50 -0
  72. package/dist/components/listing/modelColumns.js +103 -0
  73. package/dist/components/listing/pages.d.ts +78 -0
  74. package/dist/components/listing/pages.js +135 -0
  75. package/dist/components/listing/selection.d.ts +21 -0
  76. package/dist/components/listing/selection.js +43 -0
  77. package/dist/components/listing/set.d.ts +48 -0
  78. package/dist/components/listing/set.js +24 -0
  79. package/dist/components/listing/tree.d.ts +28 -0
  80. package/dist/components/listing/tree.js +23 -0
  81. package/dist/components/navigation/CommandPalette.d.ts +40 -0
  82. package/dist/components/navigation/CommandPalette.js +114 -0
  83. package/dist/components/navigation/NavigationTree.d.ts +31 -0
  84. package/dist/components/navigation/NavigationTree.js +79 -0
  85. package/dist/components/navigation/commands.d.ts +30 -0
  86. package/dist/components/navigation/commands.js +30 -0
  87. package/dist/components/navigation/index.d.ts +3 -0
  88. package/dist/components/navigation/index.js +4 -0
  89. package/dist/components/record/Breadcrumb.d.ts +42 -0
  90. package/dist/components/record/Breadcrumb.js +98 -0
  91. package/dist/components/record/DirtyActions.d.ts +26 -0
  92. package/dist/components/record/DirtyActions.js +22 -0
  93. package/dist/components/record/Pager.d.ts +18 -0
  94. package/dist/components/record/Pager.js +33 -0
  95. package/dist/components/record/RecordHeader.d.ts +75 -0
  96. package/dist/components/record/RecordHeader.js +104 -0
  97. package/dist/components/record/RecordNotices.d.ts +37 -0
  98. package/dist/components/record/RecordNotices.js +75 -0
  99. package/dist/components/record/RecordSkeleton.d.ts +3 -0
  100. package/dist/components/record/RecordSkeleton.js +21 -0
  101. package/dist/components/record/SmartButtons.d.ts +35 -0
  102. package/dist/components/record/SmartButtons.js +38 -0
  103. package/dist/components/record/StatusBar.d.ts +51 -0
  104. package/dist/components/record/StatusBar.js +168 -0
  105. package/dist/components/record/ThumbBar.d.ts +36 -0
  106. package/dist/components/record/ThumbBar.js +86 -0
  107. package/dist/components/record/index.d.ts +6 -0
  108. package/dist/components/record/index.js +8 -0
  109. package/dist/components/search/CriteriaBuilder.d.ts +58 -0
  110. package/dist/components/search/CriteriaBuilder.js +278 -0
  111. package/dist/components/search/CriteriaChips.d.ts +22 -0
  112. package/dist/components/search/CriteriaChips.js +64 -0
  113. package/dist/components/search/FilterBuilder.d.ts +142 -0
  114. package/dist/components/search/FilterBuilder.js +421 -0
  115. package/dist/components/search/JoinWord.d.ts +8 -0
  116. package/dist/components/search/JoinWord.js +47 -0
  117. package/dist/components/search/JsonEditor.d.ts +19 -0
  118. package/dist/components/search/JsonEditor.js +78 -0
  119. package/dist/components/search/SearchBar.d.ts +78 -0
  120. package/dist/components/search/SearchBar.js +387 -0
  121. package/dist/components/search/criteria.d.ts +116 -0
  122. package/dist/components/search/criteria.js +159 -0
  123. package/dist/components/search/datePeriods.d.ts +122 -0
  124. package/dist/components/search/datePeriods.js +134 -0
  125. package/dist/components/search/dateRanges.d.ts +54 -0
  126. package/dist/components/search/dateRanges.js +89 -0
  127. package/dist/components/search/index.d.ts +9 -0
  128. package/dist/components/search/index.js +20 -0
  129. package/dist/components/search/model.d.ts +54 -0
  130. package/dist/components/search/model.js +37 -0
  131. package/dist/components/search/query.d.ts +166 -0
  132. package/dist/components/search/query.js +436 -0
  133. package/dist/components/shell/AppFrame.d.ts +14 -0
  134. package/dist/components/shell/AppFrame.js +80 -0
  135. package/dist/components/shell/TopBar.d.ts +73 -0
  136. package/dist/components/shell/TopBar.js +54 -0
  137. package/dist/components/shell/headerSlot.d.ts +17 -0
  138. package/dist/components/shell/headerSlot.js +21 -0
  139. package/dist/components/shell/index.d.ts +2 -0
  140. package/dist/components/shell/index.js +3 -0
  141. package/dist/foundations/aria.d.ts +14 -0
  142. package/dist/foundations/aria.js +18 -0
  143. package/dist/foundations/calendar.d.ts +28 -0
  144. package/dist/foundations/calendar.js +183 -0
  145. package/dist/foundations/copy.d.ts +703 -0
  146. package/dist/foundations/copy.es.d.ts +2 -0
  147. package/dist/foundations/copy.es.js +430 -0
  148. package/dist/foundations/copy.js +520 -0
  149. package/dist/foundations/density.d.ts +16 -0
  150. package/dist/foundations/density.js +21 -0
  151. package/dist/foundations/grouping.d.ts +281 -0
  152. package/dist/foundations/grouping.js +0 -0
  153. package/dist/foundations/index.d.ts +14 -0
  154. package/dist/foundations/index.js +30 -0
  155. package/dist/foundations/layout.d.ts +9 -0
  156. package/dist/foundations/layout.js +9 -0
  157. package/dist/foundations/pivot.d.ts +222 -0
  158. package/dist/foundations/pivot.js +198 -0
  159. package/dist/foundations/pivotSheet.d.ts +61 -0
  160. package/dist/foundations/pivotSheet.js +0 -0
  161. package/dist/foundations/slots.d.ts +67 -0
  162. package/dist/foundations/slots.js +63 -0
  163. package/dist/foundations/sticky.d.ts +53 -0
  164. package/dist/foundations/sticky.js +150 -0
  165. package/dist/foundations/surface.d.ts +9 -0
  166. package/dist/foundations/surface.js +26 -0
  167. package/dist/foundations/theme.d.ts +42 -0
  168. package/dist/foundations/theme.js +88 -0
  169. package/dist/foundations/types.d.ts +23 -0
  170. package/dist/foundations/types.js +50 -0
  171. package/dist/foundations/variants.d.ts +19 -0
  172. package/dist/foundations/variants.js +48 -0
  173. package/dist/foundations/xlsx.d.ts +86 -0
  174. package/dist/foundations/xlsx.js +0 -0
  175. package/dist/index.d.ts +19 -0
  176. package/dist/index.js +19 -0
  177. package/dist/primitives/block/Block.d.ts +66 -0
  178. package/dist/primitives/block/Block.js +34 -0
  179. package/dist/primitives/block/Line.d.ts +18 -0
  180. package/dist/primitives/block/Line.js +45 -0
  181. package/dist/primitives/block/SectionGrid.d.ts +30 -0
  182. package/dist/primitives/block/SectionGrid.js +29 -0
  183. package/dist/primitives/block/Steps.d.ts +76 -0
  184. package/dist/primitives/block/Steps.js +43 -0
  185. package/dist/primitives/block/index.d.ts +4 -0
  186. package/dist/primitives/block/index.js +7 -0
  187. package/dist/primitives/button/Button.d.ts +137 -0
  188. package/dist/primitives/button/Button.js +234 -0
  189. package/dist/primitives/button/index.d.ts +1 -0
  190. package/dist/primitives/button/index.js +2 -0
  191. package/dist/primitives/cell/CellStack.d.ts +47 -0
  192. package/dist/primitives/cell/CellStack.js +33 -0
  193. package/dist/primitives/cell/index.d.ts +1 -0
  194. package/dist/primitives/cell/index.js +3 -0
  195. package/dist/primitives/choice/ComboBox.d.ts +19 -0
  196. package/dist/primitives/choice/ComboBox.js +52 -0
  197. package/dist/primitives/choice/RadioGroup.d.ts +18 -0
  198. package/dist/primitives/choice/RadioGroup.js +50 -0
  199. package/dist/primitives/choice/SearchField.d.ts +33 -0
  200. package/dist/primitives/choice/SearchField.js +46 -0
  201. package/dist/primitives/choice/SegmentedControl.d.ts +16 -0
  202. package/dist/primitives/choice/SegmentedControl.js +69 -0
  203. package/dist/primitives/choice/Slider.d.ts +16 -0
  204. package/dist/primitives/choice/Slider.js +46 -0
  205. package/dist/primitives/choice/Switch.d.ts +14 -0
  206. package/dist/primitives/choice/Switch.js +65 -0
  207. package/dist/primitives/choice/ThemeSwitcher.d.ts +10 -0
  208. package/dist/primitives/choice/ThemeSwitcher.js +25 -0
  209. package/dist/primitives/choice/index.d.ts +8 -0
  210. package/dist/primitives/choice/index.js +11 -0
  211. package/dist/primitives/choice/options.d.ts +28 -0
  212. package/dist/primitives/choice/options.js +6 -0
  213. package/dist/primitives/date/Calendar.d.ts +31 -0
  214. package/dist/primitives/date/Calendar.js +134 -0
  215. package/dist/primitives/date/DatePicker.d.ts +42 -0
  216. package/dist/primitives/date/DatePicker.js +103 -0
  217. package/dist/primitives/date/DateTime.d.ts +35 -0
  218. package/dist/primitives/date/DateTime.js +100 -0
  219. package/dist/primitives/date/index.d.ts +3 -0
  220. package/dist/primitives/date/index.js +6 -0
  221. package/dist/primitives/dialog/Dialog.d.ts +118 -0
  222. package/dist/primitives/dialog/Dialog.js +121 -0
  223. package/dist/primitives/dialog/Drill.d.ts +90 -0
  224. package/dist/primitives/dialog/Drill.js +172 -0
  225. package/dist/primitives/dialog/index.d.ts +2 -0
  226. package/dist/primitives/dialog/index.js +4 -0
  227. package/dist/primitives/disclosure/Disclosure.d.ts +36 -0
  228. package/dist/primitives/disclosure/Disclosure.js +52 -0
  229. package/dist/primitives/disclosure/index.d.ts +1 -0
  230. package/dist/primitives/disclosure/index.js +2 -0
  231. package/dist/primitives/field/Checks.d.ts +57 -0
  232. package/dist/primitives/field/Checks.js +72 -0
  233. package/dist/primitives/field/DropZone.d.ts +42 -0
  234. package/dist/primitives/field/DropZone.js +52 -0
  235. package/dist/primitives/field/Field.d.ts +178 -0
  236. package/dist/primitives/field/Field.js +251 -0
  237. package/dist/primitives/field/Suggest.d.ts +48 -0
  238. package/dist/primitives/field/Suggest.js +43 -0
  239. package/dist/primitives/field/aria.d.ts +61 -0
  240. package/dist/primitives/field/aria.js +70 -0
  241. package/dist/primitives/field/context.d.ts +30 -0
  242. package/dist/primitives/field/context.js +13 -0
  243. package/dist/primitives/field/copy.d.ts +16 -0
  244. package/dist/primitives/field/copy.js +69 -0
  245. package/dist/primitives/field/index.d.ts +9 -0
  246. package/dist/primitives/field/index.js +15 -0
  247. package/dist/primitives/field/layout.d.ts +24 -0
  248. package/dist/primitives/field/layout.js +10 -0
  249. package/dist/primitives/field/mode.d.ts +9 -0
  250. package/dist/primitives/field/mode.js +13 -0
  251. package/dist/primitives/field/note.d.ts +55 -0
  252. package/dist/primitives/field/note.js +117 -0
  253. package/dist/primitives/hint/Hint.d.ts +31 -0
  254. package/dist/primitives/hint/Hint.js +42 -0
  255. package/dist/primitives/hint/index.d.ts +1 -0
  256. package/dist/primitives/hint/index.js +1 -0
  257. package/dist/primitives/index.d.ts +20 -0
  258. package/dist/primitives/index.js +21 -0
  259. package/dist/primitives/menu/Menu.d.ts +128 -0
  260. package/dist/primitives/menu/Menu.js +89 -0
  261. package/dist/primitives/menu/index.d.ts +1 -0
  262. package/dist/primitives/menu/index.js +2 -0
  263. package/dist/primitives/notice/Callout.d.ts +49 -0
  264. package/dist/primitives/notice/Callout.js +28 -0
  265. package/dist/primitives/notice/Flag.d.ts +13 -0
  266. package/dist/primitives/notice/Flag.js +31 -0
  267. package/dist/primitives/notice/Notice.d.ts +45 -0
  268. package/dist/primitives/notice/Notice.js +61 -0
  269. package/dist/primitives/notice/Toast.d.ts +55 -0
  270. package/dist/primitives/notice/Toast.js +142 -0
  271. package/dist/primitives/notice/index.d.ts +4 -0
  272. package/dist/primitives/notice/index.js +6 -0
  273. package/dist/primitives/overlay/Popover.d.ts +6 -0
  274. package/dist/primitives/overlay/Popover.js +27 -0
  275. package/dist/primitives/overlay/PopoverTrigger.d.ts +55 -0
  276. package/dist/primitives/overlay/PopoverTrigger.js +38 -0
  277. package/dist/primitives/overlay/Preview.d.ts +19 -0
  278. package/dist/primitives/overlay/Preview.js +60 -0
  279. package/dist/primitives/overlay/Tooltip.d.ts +38 -0
  280. package/dist/primitives/overlay/Tooltip.js +74 -0
  281. package/dist/primitives/overlay/index.d.ts +4 -0
  282. package/dist/primitives/overlay/index.js +7 -0
  283. package/dist/primitives/picker/Picker.d.ts +89 -0
  284. package/dist/primitives/picker/Picker.js +204 -0
  285. package/dist/primitives/picker/index.d.ts +1 -0
  286. package/dist/primitives/picker/index.js +2 -0
  287. package/dist/primitives/surface/Peek.d.ts +60 -0
  288. package/dist/primitives/surface/Peek.js +71 -0
  289. package/dist/primitives/surface/index.d.ts +1 -0
  290. package/dist/primitives/surface/index.js +2 -0
  291. package/dist/primitives/table/CellCopy.d.ts +20 -0
  292. package/dist/primitives/table/CellCopy.js +23 -0
  293. package/dist/primitives/table/CellEditor.d.ts +14 -0
  294. package/dist/primitives/table/CellEditor.js +83 -0
  295. package/dist/primitives/table/DataTable.d.ts +189 -0
  296. package/dist/primitives/table/DataTable.js +330 -0
  297. package/dist/primitives/table/EditableTable.d.ts +191 -0
  298. package/dist/primitives/table/EditableTable.js +617 -0
  299. package/dist/primitives/table/PivotTable.d.ts +14 -0
  300. package/dist/primitives/table/PivotTable.js +0 -0
  301. package/dist/primitives/table/ReportTable.d.ts +38 -0
  302. package/dist/primitives/table/ReportTable.js +106 -0
  303. package/dist/primitives/table/RowActions.d.ts +16 -0
  304. package/dist/primitives/table/RowActions.js +28 -0
  305. package/dist/primitives/table/SheetTable.d.ts +73 -0
  306. package/dist/primitives/table/SheetTable.js +230 -0
  307. package/dist/primitives/table/Table.d.ts +106 -0
  308. package/dist/primitives/table/Table.js +116 -0
  309. package/dist/primitives/table/index.d.ts +7 -0
  310. package/dist/primitives/table/index.js +9 -0
  311. package/dist/primitives/tabs/Tabs.d.ts +91 -0
  312. package/dist/primitives/tabs/Tabs.js +56 -0
  313. package/dist/primitives/tabs/index.d.ts +1 -0
  314. package/dist/primitives/tabs/index.js +1 -0
  315. package/dist/primitives/tag/Tag.d.ts +36 -0
  316. package/dist/primitives/tag/Tag.js +68 -0
  317. package/dist/primitives/tag/Tags.d.ts +57 -0
  318. package/dist/primitives/tag/Tags.js +104 -0
  319. package/dist/primitives/tag/TagsField.d.ts +35 -0
  320. package/dist/primitives/tag/TagsField.js +186 -0
  321. package/dist/primitives/tag/choices.d.ts +38 -0
  322. package/dist/primitives/tag/choices.js +26 -0
  323. package/dist/primitives/tag/index.d.ts +4 -0
  324. package/dist/primitives/tag/index.js +8 -0
  325. package/dist/primitives/toolbar/Toolbar.d.ts +13 -0
  326. package/dist/primitives/toolbar/Toolbar.js +36 -0
  327. package/dist/primitives/toolbar/index.d.ts +1 -0
  328. package/dist/primitives/toolbar/index.js +2 -0
  329. package/dist/primitives/tree/Tree.d.ts +56 -0
  330. package/dist/primitives/tree/Tree.js +74 -0
  331. package/dist/primitives/tree/index.d.ts +1 -0
  332. package/dist/primitives/tree/index.js +3 -0
  333. package/dist/primitives/value/Copyable.d.ts +48 -0
  334. package/dist/primitives/value/Copyable.js +71 -0
  335. package/dist/primitives/value/Fecha.d.ts +12 -0
  336. package/dist/primitives/value/Fecha.js +89 -0
  337. package/dist/primitives/value/Meter.d.ts +29 -0
  338. package/dist/primitives/value/Meter.js +46 -0
  339. package/dist/primitives/value/Metric.d.ts +42 -0
  340. package/dist/primitives/value/Metric.js +38 -0
  341. package/dist/primitives/value/Person.d.ts +90 -0
  342. package/dist/primitives/value/Person.js +208 -0
  343. package/dist/primitives/value/ProgressBar.d.ts +31 -0
  344. package/dist/primitives/value/ProgressBar.js +53 -0
  345. package/dist/primitives/value/Relation.d.ts +74 -0
  346. package/dist/primitives/value/Relation.js +74 -0
  347. package/dist/primitives/value/Totals.d.ts +121 -0
  348. package/dist/primitives/value/Totals.js +54 -0
  349. package/dist/primitives/value/Value.d.ts +40 -0
  350. package/dist/primitives/value/Value.js +80 -0
  351. package/dist/primitives/value/index.d.ts +9 -0
  352. package/dist/primitives/value/index.js +10 -0
  353. package/dist/tokens.css +1062 -0
  354. package/dist/views/index.d.ts +2 -0
  355. package/dist/views/index.js +3 -0
  356. package/dist/views/list/List.d.ts +119 -0
  357. package/dist/views/list/List.js +101 -0
  358. package/dist/views/list/ListView.d.ts +6 -0
  359. package/dist/views/list/ListView.js +295 -0
  360. package/dist/views/list/columns.d.ts +18 -0
  361. package/dist/views/list/columns.js +27 -0
  362. package/dist/views/list/derive.d.ts +87 -0
  363. package/dist/views/list/derive.js +207 -0
  364. package/dist/views/list/index.d.ts +2 -0
  365. package/dist/views/list/index.js +4 -0
  366. package/dist/views/list/presentations.d.ts +39 -0
  367. package/dist/views/list/presentations.js +105 -0
  368. package/dist/views/list/types.d.ts +284 -0
  369. package/dist/views/list/types.js +1 -0
  370. package/dist/views/list/useNarrowList.d.ts +17 -0
  371. package/dist/views/list/useNarrowList.js +32 -0
  372. package/dist/views/record/Record.d.ts +145 -0
  373. package/dist/views/record/Record.js +211 -0
  374. package/dist/views/record/index.d.ts +1 -0
  375. package/dist/views/record/index.js +2 -0
  376. package/package.json +113 -4
@@ -0,0 +1,42 @@
1
+ import { type ReactNode } from "react";
2
+ export type Theme = "system" | "light" | "dark";
3
+ /** What the palette actually is once `system` has been looked up. */
4
+ export type ResolvedTheme = "light" | "dark";
5
+ export declare const THEMES: readonly Theme[];
6
+ /** The attribute the stylesheet reads. */
7
+ export declare const THEME_ATTRIBUTE = "data-theme";
8
+ /** `system` is the operating system's answer; the other two are themselves. Pure, so it can
9
+ * be tested without a browser. */
10
+ export declare function resolveTheme(theme: Theme, systemPrefersDark: boolean): ResolvedTheme;
11
+ /** True for a string that is one of the three values — what comes out of storage or a URL
12
+ * is `string | null`, and this is the way back to `Theme`. */
13
+ export declare function isTheme(value: unknown): value is Theme;
14
+ /** Writes the choice on an element. `system` REMOVES the attribute: the stylesheet then
15
+ * follows `prefers-color-scheme` by itself, and an attribute saying "system" would be a
16
+ * value no selector reads. Returns nothing; the DOM is the output. */
17
+ export declare function applyTheme(theme: Theme, element?: Element): void;
18
+ type ThemeValue = {
19
+ /** What the app chose. */
20
+ theme: Theme;
21
+ /** What the palette is — `system` already looked up. */
22
+ resolved: ResolvedTheme;
23
+ setTheme: (next: Theme) => void;
24
+ };
25
+ export type ThemeProviderProps = {
26
+ /** Controlled: the app owns the value (and persists it). */
27
+ value?: Theme;
28
+ /** Uncontrolled: the starting choice. */
29
+ defaultValue?: Theme;
30
+ /** Called with every choice, controlled or not — the place to persist it. */
31
+ onChange?: (next: Theme) => void;
32
+ /** Where `data-theme` is written. `<html>` by default; pass an element to theme a subtree
33
+ * (a preview, a story). A portal mounted outside it keeps the document's theme. */
34
+ element?: Element | null;
35
+ children?: ReactNode;
36
+ };
37
+ export declare function ThemeProvider({ value, defaultValue, onChange, element, children, }: ThemeProviderProps): import("react").JSX.Element;
38
+ /** The choice, the palette it resolves to, and the way to change it. Without a provider it
39
+ * still reads (what `<html>` and the OS say) and `setTheme` writes `<html>` directly, so a
40
+ * one-off call site works without wrapping the app. */
41
+ export declare function useTheme(): ThemeValue;
42
+ export {};
@@ -0,0 +1,88 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, useCallback, useContext, useEffect, useMemo, useState, useSyncExternalStore, } from "react";
4
+ export const THEMES = ["system", "light", "dark"];
5
+ /** The attribute the stylesheet reads. */
6
+ export const THEME_ATTRIBUTE = "data-theme";
7
+ /** `system` is the operating system's answer; the other two are themselves. Pure, so it can
8
+ * be tested without a browser. */
9
+ export function resolveTheme(theme, systemPrefersDark) {
10
+ if (theme === "system")
11
+ return systemPrefersDark ? "dark" : "light";
12
+ return theme;
13
+ }
14
+ /** True for a string that is one of the three values — what comes out of storage or a URL
15
+ * is `string | null`, and this is the way back to `Theme`. */
16
+ export function isTheme(value) {
17
+ return value === "system" || value === "light" || value === "dark";
18
+ }
19
+ /** Writes the choice on an element. `system` REMOVES the attribute: the stylesheet then
20
+ * follows `prefers-color-scheme` by itself, and an attribute saying "system" would be a
21
+ * value no selector reads. Returns nothing; the DOM is the output. */
22
+ export function applyTheme(theme, element = document.documentElement) {
23
+ if (theme === "system")
24
+ element.removeAttribute(THEME_ATTRIBUTE);
25
+ else
26
+ element.setAttribute(THEME_ATTRIBUTE, theme);
27
+ }
28
+ const DARK_QUERY = "(prefers-color-scheme: dark)";
29
+ /** The operating system's preference, live. Server snapshot: light — the same as the
30
+ * stylesheet's default when it cannot ask. */
31
+ function useSystemPrefersDark() {
32
+ return useSyncExternalStore((notify) => {
33
+ const query = window.matchMedia(DARK_QUERY);
34
+ query.addEventListener("change", notify);
35
+ return () => query.removeEventListener("change", notify);
36
+ }, () => window.matchMedia(DARK_QUERY).matches, () => false);
37
+ }
38
+ /** What `<html>` says right now — read for code that has no provider above it (an editor
39
+ * that has to pick a built-in theme) and must still follow a switch made elsewhere. */
40
+ function useRootAttribute() {
41
+ return useSyncExternalStore((notify) => {
42
+ const observer = new MutationObserver(notify);
43
+ observer.observe(document.documentElement, {
44
+ attributes: true,
45
+ attributeFilter: [THEME_ATTRIBUTE],
46
+ });
47
+ return () => observer.disconnect();
48
+ }, () => document.documentElement.getAttribute(THEME_ATTRIBUTE), () => null);
49
+ }
50
+ const Ctx = createContext(null);
51
+ export function ThemeProvider({ value, defaultValue = "system", onChange, element, children, }) {
52
+ const [own, setOwn] = useState(defaultValue);
53
+ const theme = value ?? own;
54
+ const systemDark = useSystemPrefersDark();
55
+ const setTheme = useCallback((next) => {
56
+ setOwn(next);
57
+ onChange?.(next);
58
+ }, [onChange]);
59
+ /* An effect and not a render-time write: the DOM is outside React's tree, and writing it
60
+ during render would run on the server and twice in StrictMode. */
61
+ useEffect(() => {
62
+ const target = element === undefined ? document.documentElement : element;
63
+ if (target === null)
64
+ return;
65
+ applyTheme(theme, target);
66
+ return () => target.removeAttribute(THEME_ATTRIBUTE);
67
+ }, [theme, element]);
68
+ const context = useMemo(() => ({ theme, resolved: resolveTheme(theme, systemDark), setTheme }), [theme, systemDark, setTheme]);
69
+ return _jsx(Ctx.Provider, { value: context, children: children });
70
+ }
71
+ /** The choice, the palette it resolves to, and the way to change it. Without a provider it
72
+ * still reads (what `<html>` and the OS say) and `setTheme` writes `<html>` directly, so a
73
+ * one-off call site works without wrapping the app. */
74
+ export function useTheme() {
75
+ const provided = useContext(Ctx);
76
+ const attribute = useRootAttribute();
77
+ const systemDark = useSystemPrefersDark();
78
+ return useMemo(() => {
79
+ if (provided !== null)
80
+ return provided;
81
+ const theme = isTheme(attribute) ? attribute : "system";
82
+ return {
83
+ theme,
84
+ resolved: resolveTheme(theme, systemDark),
85
+ setTheme: (next) => applyTheme(next),
86
+ };
87
+ }, [provided, attribute, systemDark]);
88
+ }
@@ -0,0 +1,23 @@
1
+ /** Which background something is drawn on.
2
+ *
3
+ * The interface has TWO surfaces and the piece does not behave the same on
4
+ * both: on the canvas, a ghost button uses the navigation blue (8.26:1); on
5
+ * the chrome that blue gives 1.4:1 and the lightened one has to be used.
6
+ *
7
+ * It is a PROP and not a context on purpose — the opposite of `Density`. The
8
+ * color is decided per element and it has to be auditable one at a time; a
9
+ * global theme would resolve it by inheritance and then the decision would not
10
+ * be visible in the calling code. See the long note in `system/density.tsx`. */
11
+ export type Surface = "canvas" | "chrome";
12
+ /** The meaning of a state color. It is NOT a decorative palette.
13
+ *
14
+ * The moment a tag uses a hue because some variety was needed, all six stop
15
+ * meaning anything and you have to read the word anyway — and then the color
16
+ * is redundant. `neutral` is the default precisely because of that: most tags
17
+ * in a catalog are CLASSIFICATIONS, not states. */
18
+ export type Tone = "neutral" | "info" | "good" | "warn" | "bad" | "accent";
19
+ /** The size of a control, tied to `--size-control-*`.
20
+ *
21
+ * Three and not five: a fourth intermediate step gets picked out of habit and
22
+ * stops meaning a place. */
23
+ export type Size = "sm" | "md" | "lg";
@@ -0,0 +1,50 @@
1
+ /* ==================================================================== *
2
+ * THE SHARED TYPES — and why they live in a single place.
3
+ *
4
+ * `Surface` was defined TWICE, in `button/` and in `record/`. Both copies
5
+ * said the same thing, so the compiler never complained — and that is exactly
6
+ * the problem: the day a third surface appears, one of the two gets updated
7
+ * and the other does not, and nothing catches it until someone passes
8
+ * `"chrome"` to a component that no longer accepts it.
9
+ *
10
+ * What goes in here has a test: **more than one component family uses it AND
11
+ * it belongs to none of them**. A type that only `list/` uses lives in
12
+ * `list/`, even if it is shared across its three files.
13
+ * ==================================================================== */
14
+ export {};
15
+ /* ==================================================================== *
16
+ * THE SYSTEM'S TWO API CONVENTIONS
17
+ *
18
+ * They are here and not in the README because a convention that lives in the
19
+ * documentation breaks in the first component written in a hurry. Here it is
20
+ * read by whoever is going to write the next component.
21
+ *
22
+ * ── 1. How a callback is named ──────────────────────────────────────
23
+ *
24
+ * onXChange the component proposes a NEW value for `x`, and whoever
25
+ * uses it decides whether to accept it. It ALWAYS goes with
26
+ * the `x` prop.
27
+ * → onTermsChange(terms), onSelectedChange(set), onSortChange(sort)
28
+ *
29
+ * onX something happened that is not a value change: an intent.
30
+ * → onClose(), onOpen(), onPromote(), onBrowseAll()
31
+ *
32
+ * The test for knowing which one: **is there a prop with that name next to
33
+ * it?** If `value` exists, it is `onValueChange`. If not, it is an event and
34
+ * goes without a suffix.
35
+ *
36
+ * ── 2. Controlled, always ───────────────────────────────────────────
37
+ *
38
+ * Any state the consumer might want to read, store in the URL or restore on
39
+ * reload is CONTROLLED: `value` + `onValueChange`, with no internal memory.
40
+ * That is what lets the entire workspace live in the hash.
41
+ *
42
+ * The exception, and there is only one: **what dies with the component and
43
+ * nobody cares about afterwards.** An open menu, an expanded filter panel, the
44
+ * half-typed text in the search box. That does keep state inside, because
45
+ * exposing it would force every consumer to declare a `useState` for something
46
+ * they are never going to read.
47
+ *
48
+ * Put another way: if it makes sense to send it to a colleague over chat so
49
+ * they see the same thing, it is controlled.
50
+ * ==================================================================== */
@@ -0,0 +1,19 @@
1
+ /** The system's `tv`: a recipe of base classes and variants, merged with the scales above. */
2
+ export declare const tv: import("tailwind-variants/config").TV<import("tailwind-variants/config").TVCustomConfig>;
3
+ /** Joins classes, and when two set the same property, the LAST one wins. */
4
+ export declare function cn(...classes: (string | false | null | undefined)[]): string;
5
+ /**
6
+ * The focus ring of every interactive piece: the same outline `Button` draws, driven by
7
+ * React Aria's `isFocusVisible` — keyboard focus shows it, a mouse click does not.
8
+ */
9
+ export declare const focusRing: import("tailwind-variants/config").TVReturnType<{
10
+ isFocusVisible: {
11
+ false: string;
12
+ true: string;
13
+ };
14
+ }, undefined, "outline-primary outline-offset-2 forced-colors:outline-[Highlight]", undefined, undefined, undefined>;
15
+ /**
16
+ * A React Aria `className` can be a string or a function of the render state. This puts the
17
+ * system's classes first and the consumer's after, so the consumer's win where they fight.
18
+ */
19
+ export declare function composeClasses<T>(className: string | ((state: T) => string) | undefined, base: string): string | ((state: T) => string);
@@ -0,0 +1,48 @@
1
+ import { composeRenderProps } from "react-aria-components";
2
+ import { cnMerge, createTV } from "tailwind-variants/config";
3
+ /**
4
+ * How a component's classes are composed — the variants of a recipe, and the merge of a
5
+ * consumer's `className` on top of the system's.
6
+ *
7
+ * Context: merging Tailwind classes needs to know which classes fight over the same
8
+ * property. The merger only knows Tailwind's default scales, and this system has its own:
9
+ * `text-meta` is a SIZE and `text-ink` a COLOR, but to a merger that has never heard of
10
+ * `meta`, both are `text-*` colors — and `text-meta text-ink` silently loses one. Every
11
+ * named scale in `tokens.css` is declared here so the merger reads it as what it is.
12
+ * `tests/variants.test.ts` holds each pair that used to collide.
13
+ */
14
+ const twMergeConfig = {
15
+ extend: {
16
+ theme: {
17
+ text: ["micro", "meta", "body", "lead", "title", "display"],
18
+ radius: ["mark", "control", "box", "panel", "pill"],
19
+ shadow: ["raised", "float", "window"],
20
+ },
21
+ },
22
+ };
23
+ /** The system's `tv`: a recipe of base classes and variants, merged with the scales above. */
24
+ export const tv = createTV({ twMergeConfig });
25
+ /** Joins classes, and when two set the same property, the LAST one wins. */
26
+ export function cn(...classes) {
27
+ return cnMerge(...classes)({ twMergeConfig }) ?? "";
28
+ }
29
+ /**
30
+ * The focus ring of every interactive piece: the same outline `Button` draws, driven by
31
+ * React Aria's `isFocusVisible` — keyboard focus shows it, a mouse click does not.
32
+ */
33
+ export const focusRing = tv({
34
+ base: "outline-primary outline-offset-2 forced-colors:outline-[Highlight]",
35
+ variants: {
36
+ isFocusVisible: {
37
+ false: "outline-0",
38
+ true: "outline-2",
39
+ },
40
+ },
41
+ });
42
+ /**
43
+ * A React Aria `className` can be a string or a function of the render state. This puts the
44
+ * system's classes first and the consumer's after, so the consumer's win where they fight.
45
+ */
46
+ export function composeClasses(className, base) {
47
+ return composeRenderProps(className, (own) => cn(base, own));
48
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * ESCRIBIR UNA PLANILLA DE EXCEL, sin librería.
3
+ *
4
+ * ── Por qué no hay dependencia ──────────────────────────────────────
5
+ *
6
+ * Un `.xlsx` es un ZIP con seis XML adentro, y el ZIP sólo se pone difícil
7
+ * cuando hay que comprimir. **No hay que comprimir**: el formato admite entradas
8
+ * `stored` —método 0, los bytes tal cual— y Excel las abre igual. Lo único que
9
+ * queda del ZIP es un CRC32 y tres encabezados de posiciones fijas.
10
+ *
11
+ * Del otro lado, las librerías del rubro pesan entre medio mega y uno, traen su
12
+ * propio modelo de libro, de estilos y de fórmulas, y este sistema de diseño se
13
+ * publica como fuente para que lo compile quien lo consuma — incluido, algún
14
+ * día, un teléfono. Un mega de escritor de planillas adentro de un paquete de
15
+ * componentes lo carga todo el que importe un botón.
16
+ *
17
+ * ── Qué hace y qué no ───────────────────────────────────────────────
18
+ *
19
+ * Hace lo que una grilla necesita para no mentir al salir: texto y números en su
20
+ * tipo real, celdas combinadas, formato de número por celda, negrita, ancho de
21
+ * columna y paneles congelados. **Una celda ausente no se escribe**, que es como
22
+ * el formato dice «acá no hay nada» — un agujero sigue siendo un agujero
23
+ * adentro del archivo.
24
+ *
25
+ * No hace fórmulas, ni colores, ni bordes, ni varias hojas. El día que alguna de
26
+ * esas haga falta se agrega acá; ninguna cambia la forma de lo que ya está.
27
+ *
28
+ * ── Dónde termina esto y empieza el navegador ───────────────────────
29
+ *
30
+ * `writeXlsx` devuelve BYTES y no un archivo: `Uint8Array` existe en todos
31
+ * lados, y así lo mismo sirve para bajar un archivo, para mandarlo por la red o
32
+ * para escribirlo en una prueba. Bajarlo es `downloadXlsx`, que es la única
33
+ * función de este archivo que necesita un navegador.
34
+ */
35
+ /** Una celda. La posición va en la celda y no en una matriz porque una grilla
36
+ * con agujeros es mayormente vacío, y una matriz de 288 posiciones para 40
37
+ * valores es una matriz que hay que rellenar con algo. */
38
+ export type XlsxCell = {
39
+ /** Desde cero, como los índices de todo lo demás. */
40
+ row: number;
41
+ column: number;
42
+ /** Un número entra como número: sin eso, Excel recibe texto y no suma, que es
43
+ * la primera cosa que alguien intenta hacer con una planilla exportada. */
44
+ value: string | number;
45
+ bold?: boolean;
46
+ /** El código de formato de Excel —`#,##0.00`, `0.0%`, `#,##0 "Bs."`—, que es
47
+ * otra cosa que una función de JavaScript: un archivo no puede llevarse una
48
+ * función adentro. */
49
+ format?: string;
50
+ };
51
+ /** Una combinación: desde dónde, y cuántas filas y columnas cubre. */
52
+ export type XlsxMerge = {
53
+ row: number;
54
+ column: number;
55
+ rows: number;
56
+ columns: number;
57
+ };
58
+ export type XlsxSheet = {
59
+ /** El nombre de la pestaña. Excel prohíbe `[]:*?/\` y más de 31 caracteres, y
60
+ * un nombre inválido no da un error: da un archivo que no abre. Se recorta
61
+ * acá. */
62
+ name: string;
63
+ cells: readonly XlsxCell[];
64
+ merges?: readonly XlsxMerge[];
65
+ /** El ancho de cada columna, en caracteres. Faltantes = el ancho por omisión. */
66
+ widths?: readonly number[];
67
+ /** Cuántas filas de arriba y columnas de la izquierda se quedan quietas al
68
+ * desplazarse. Es lo mismo que hace `sticky` en la grilla, y por la misma
69
+ * razón: un número sin su rótulo es un número suelto. */
70
+ freeze?: {
71
+ rows: number;
72
+ columns: number;
73
+ };
74
+ };
75
+ /** El nombre de una columna en la notación de Excel: 0 → A, 25 → Z, 26 → AA. */
76
+ export declare function columnName(index: number): string;
77
+ /** Los bytes de un `.xlsx` con una hoja. */
78
+ export declare function writeXlsx(sheet: XlsxSheet): Uint8Array<ArrayBuffer>;
79
+ /**
80
+ * Bajar los bytes como archivo.
81
+ *
82
+ * Es la única función de este archivo que necesita un navegador, y por eso está
83
+ * separada de `writeXlsx`: lo que se escribe y lo que se baja son dos cosas, y
84
+ * del otro lado —el servidor, un teléfono, una prueba— la segunda no existe.
85
+ */
86
+ export declare function downloadXlsx(name: string, bytes: Uint8Array): void;
Binary file
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Context: the package is four levels, composed bottom-up, and each level only imports
3
+ * from the ones below:
4
+ *
5
+ * foundations the decisions — tokens, copy, density, surfaces, slots
6
+ * primitives a piece that does not know which screen it is on
7
+ * components primitives composed to answer one question of the product
8
+ * views the two macros: one record (`Record`), or N records (`List`)
9
+ *
10
+ * Each level is also its own entry (`@sincpro/web-ui/primitives`, …), so what a level
11
+ * offers is one import away. What a family makes public is what its `index.ts` exports.
12
+ *
13
+ * If something needs to know what an invoice, a dataset or a customer is, it does not
14
+ * belong here: that is domain, and it lives in the application.
15
+ */
16
+ export * from "./components/index.js";
17
+ export * from "./foundations/index.js";
18
+ export * from "./primitives/index.js";
19
+ export * from "./views/index.js";
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Context: the package is four levels, composed bottom-up, and each level only imports
3
+ * from the ones below:
4
+ *
5
+ * foundations the decisions — tokens, copy, density, surfaces, slots
6
+ * primitives a piece that does not know which screen it is on
7
+ * components primitives composed to answer one question of the product
8
+ * views the two macros: one record (`Record`), or N records (`List`)
9
+ *
10
+ * Each level is also its own entry (`@sincpro/web-ui/primitives`, …), so what a level
11
+ * offers is one import away. What a family makes public is what its `index.ts` exports.
12
+ *
13
+ * If something needs to know what an invoice, a dataset or a customer is, it does not
14
+ * belong here: that is domain, and it lives in the application.
15
+ */
16
+ export * from "./components/index.js";
17
+ export * from "./foundations/index.js";
18
+ export * from "./primitives/index.js";
19
+ export * from "./views/index.js";
@@ -0,0 +1,66 @@
1
+ import type { Tone } from "../../foundations/types.js";
2
+ import type { ReactNode } from "react";
3
+ /**
4
+ * Context: the diagnosis was not a lack of ornaments, it was that a view was a
5
+ * pile of `<div className="flex flex-col gap-3">` with no hierarchy — the lines,
6
+ * the taxes and the payments floated at the same height and nothing said where one
7
+ * ends and the other begins. In a 1.200 px panel that reads as a loose sheet.
8
+ *
9
+ * The block has an edge (a hair of border and the radius of the scale, not a
10
+ * shadow: over the canvas a shadow alone looks blurry) and its title lives ON the
11
+ * border, not floating above it.
12
+ */
13
+ /**
14
+ * What state whatever this section asks for or shows is in.
15
+ *
16
+ * Context: it is the only thing worth copying from the old console — each section
17
+ * said «Required» or «(Incomplete)» in its header, so you could see what is
18
+ * missing WITHOUT opening any of them. The system doesn't know what «incomplete»
19
+ * means for an invoice, so the word is put there by whoever composes.
20
+ */
21
+ export type BlockStatus = {
22
+ label: string;
23
+ tone?: Tone;
24
+ };
25
+ export type BlockProps = {
26
+ /** Without a title the block is only the box: it serves to group without
27
+ * naming. */
28
+ title?: string;
29
+ count?: number;
30
+ aside?: ReactNode;
31
+ /** What can be done with THIS block, to the right of its title. */
32
+ actions?: ReactNode;
33
+ status?: BlockStatus;
34
+ /** Without padding, for whatever already brings its own frame: a table inside a
35
+ * box with borders is two frames arguing. */
36
+ flush?: boolean;
37
+ children: ReactNode;
38
+ };
39
+ export declare function Block({ title, count, aside, actions, status, flush, children, }: BlockProps): import("react").JSX.Element;
40
+ /**
41
+ * A cut in the page: between two groups of fields, or between a sheet of
42
+ * facts and the table that hangs off them.
43
+ *
44
+ * Without a label it is a hairline. With one it is Odoo's separator — the
45
+ * word names what starts, the line says the previous group ended. `FormSection`
46
+ * is a GROUP of fields; this is what goes BETWEEN groups. A block with a
47
+ * border is a third thing: a region, not a cut.
48
+ */
49
+ export declare function Rule({ label }: {
50
+ label?: string;
51
+ }): import("react").JSX.Element;
52
+ /**
53
+ * `DATOS ── 3`. The title of a section and nothing else.
54
+ *
55
+ * Context: proportional and not monospaced — it is a written title, at the
56
+ * body size, in medium ink. The count is tabular, because it is a figure.
57
+ *
58
+ * The `aside` goes next to the title and not pushed to the opposite edge: with
59
+ * `justify-between`, «El vistazo» and «20 de 1.000 filas» ended up half a screen
60
+ * apart and the phrase read as split in two.
61
+ */
62
+ export declare function SectionHeader({ title, count, aside, }: {
63
+ title: string;
64
+ count?: number;
65
+ aside?: ReactNode;
66
+ }): import("react").JSX.Element;
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Tag } from "../tag/Tag.js";
3
+ export function Block({ title, count, aside, actions, status, flush = false, children, }) {
4
+ const withHeader = title !== undefined || actions !== undefined || status !== undefined;
5
+ return (_jsxs("section", { className: "min-w-0 rounded-box border border-line bg-surface", children: [!withHeader ? null : (_jsxs("header", { className: "flex min-w-0 flex-wrap items-baseline gap-x-3 gap-y-1 border-b border-line px-3 py-2", children: [title === undefined ? null : (_jsx(SectionHeader, { title: title, count: count, aside: aside })), status === undefined ? null : (_jsx(Tag, { tone: status.tone ?? "neutral", children: status.label })), actions === undefined ? null : (_jsx("div", { className: "ml-auto flex flex-wrap items-center gap-1", children: actions }))] })), _jsx("div", { className: flush ? "" : "px-3 py-2.5", children: children })] }));
6
+ }
7
+ /**
8
+ * A cut in the page: between two groups of fields, or between a sheet of
9
+ * facts and the table that hangs off them.
10
+ *
11
+ * Without a label it is a hairline. With one it is Odoo's separator — the
12
+ * word names what starts, the line says the previous group ended. `FormSection`
13
+ * is a GROUP of fields; this is what goes BETWEEN groups. A block with a
14
+ * border is a third thing: a region, not a cut.
15
+ */
16
+ export function Rule({ label }) {
17
+ if (label === undefined) {
18
+ return _jsx("hr", { className: "border-0 border-t border-line" });
19
+ }
20
+ return (_jsxs("div", { className: "flex min-w-0 items-center gap-3", children: [_jsx("span", { className: "shrink-0 text-micro font-medium text-muted", children: label }), _jsx("span", { className: "h-px min-w-0 flex-1 bg-line", "aria-hidden": true })] }));
21
+ }
22
+ /**
23
+ * `DATOS ── 3`. The title of a section and nothing else.
24
+ *
25
+ * Context: proportional and not monospaced — it is a written title, at the
26
+ * body size, in medium ink. The count is tabular, because it is a figure.
27
+ *
28
+ * The `aside` goes next to the title and not pushed to the opposite edge: with
29
+ * `justify-between`, «El vistazo» and «20 de 1.000 filas» ended up half a screen
30
+ * apart and the phrase read as split in two.
31
+ */
32
+ export function SectionHeader({ title, count, aside, }) {
33
+ return (_jsxs("div", { className: "flex flex-wrap items-baseline gap-x-3 gap-y-1", children: [_jsxs("h2", { className: "text-meta font-medium text-ink", children: [title, count === undefined ? null : (_jsxs(_Fragment, { children: [_jsx("span", { className: "mx-1.5 text-line-strong", children: "\u2500\u2500" }), _jsx("span", { className: "tabular-nums", children: count })] }))] }), aside === undefined ? null : (_jsxs(_Fragment, { children: [_jsx("span", { "aria-hidden": true, className: "text-meta text-line-strong", children: "\u00B7" }), aside] }))] }));
34
+ }
@@ -0,0 +1,18 @@
1
+ import type { ReactNode } from "react";
2
+ export declare function Line({ start, center, end,
3
+ /**
4
+ * Lo que PIDE cada lado antes de que la línea se parta. Los dos piden lo
5
+ * mismo —es lo que centra el centro— así que es un solo valor y no dos.
6
+ */
7
+ asks,
8
+ /** Lo que pide el centro. `auto` es «lo que mida»; un campo de búsqueda pide
9
+ * su ancho tope, que es lo que hace que no se estire a 700 px. */
10
+ centerAsks, gap, align, }: {
11
+ start?: ReactNode;
12
+ center?: ReactNode;
13
+ end?: ReactNode;
14
+ asks?: string;
15
+ centerAsks?: string;
16
+ gap?: string;
17
+ align?: string;
18
+ }): import("react").JSX.Element;
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /* ==================================================================== *
3
+ * LA LÍNEA DE TRES ZONAS — y por qué el centro se centra contra la LÍNEA.
4
+ *
5
+ * Es la forma de las dos bandas del producto: la del registro —de dónde
6
+ * vengo · lo que cuelga de esto · cuál de ochenta soy— y la de la lista —de
7
+ * dónde vengo · qué estoy buscando · qué página—. Las dos tienen el mismo
8
+ * problema y por eso tienen una sola solución.
9
+ *
10
+ * ── El problema: el centro no estaba en el centro ───────────────────
11
+ *
12
+ * Con `mx-auto`, o con una grilla `auto 1fr max-content`, el centro queda
13
+ * donde SOBRA lugar. Y entonces un nombre de cincuenta caracteres a la
14
+ * izquierda —que en este producto es lo normal— empuja los botones contra el
15
+ * borde derecho, y la misma pantalla con un nombre corto los dibuja en otro
16
+ * lado. Dos registros seguidos ponen sus controles en dos lugares distintos:
17
+ * eso no es un centro, es un resto.
18
+ *
19
+ * ── La regla: los dos lados PIDEN lo mismo ──────────────────────────
20
+ *
21
+ * Los lados piden el mismo ancho y crecen parejo, así que lo que sobra se
22
+ * reparte en dos mitades iguales y el centro cae en el medio de la línea, con
23
+ * o sin migas, con o sin paginador. Lo que no entra en una mitad se recorta
24
+ * adentro de su mitad —para eso `min-w-0`— en vez de empujar al vecino.
25
+ *
26
+ * ── Y se parte sola ─────────────────────────────────────────────────
27
+ *
28
+ * No hay ningún umbral acá: ni consulta de medios, ni de contenedor, ni una
29
+ * rama por densidad. Cada zona declara lo que PIDE y `flex-wrap` decide: en
30
+ * una banda angosta el centro ya no entra al lado de las migas y baja entero
31
+ * al renglón siguiente, con el paginador atrás. Es lo mismo que hace una fila
32
+ * de lista, y por la misma razón: un umbral no sabe si la línea trae tres
33
+ * contadores o nueve.
34
+ * ==================================================================== */
35
+ export function Line({ start, center, end,
36
+ /**
37
+ * Lo que PIDE cada lado antes de que la línea se parta. Los dos piden lo
38
+ * mismo —es lo que centra el centro— así que es un solo valor y no dos.
39
+ */
40
+ asks = "var(--container-trail)",
41
+ /** Lo que pide el centro. `auto` es «lo que mida»; un campo de búsqueda pide
42
+ * su ancho tope, que es lo que hace que no se estire a 700 px. */
43
+ centerAsks = "auto", gap = "gap-x-4 gap-y-2", align = "items-center", }) {
44
+ return (_jsxs("div", { className: `flex min-w-0 flex-wrap ${align} ${gap}`, children: [_jsx("div", { className: "flex min-w-0 flex-1 items-center", style: { flexBasis: asks }, children: start }), _jsx("div", { className: "flex min-w-0 shrink items-center justify-center", style: { flexBasis: centerAsks, flexGrow: 0 }, children: center }), _jsx("div", { className: "flex min-w-0 flex-1 items-center justify-end", style: { flexBasis: asks }, children: end })] }));
45
+ }
@@ -0,0 +1,30 @@
1
+ import type { ReactNode } from "react";
2
+ /**
3
+ * Context: the rule that decides whether two sections go side by side is
4
+ * DEPENDENCY, not space. Two that don't govern each other —the invoice lines
5
+ * and its payments— go side by side; two that do —choosing the customer and then
6
+ * its price list— go stacked, because the vertical order is the only thing that says which
7
+ * one comes first.
8
+ *
9
+ * That is why it is a grid and not a `flex-wrap`: wrapping arranges by available
10
+ * width, which is a decision about space.
11
+ *
12
+ * And it asks `@container` and not `md:`: with four panels open each one measures
13
+ * 380 px on a 1.600 screen, and a window rule would put two 190 px columns inside
14
+ * each panel. **Whoever mounts the view has to declare `@container` on its
15
+ * container** — the composer already does.
16
+ */
17
+ export declare function SectionGrid({ children,
18
+ /** A single column until the panel is truly large. For sections with a table
19
+ * inside: two 300 px tables don't read better than one 600 px one. */
20
+ wide, }: {
21
+ children: ReactNode;
22
+ wide?: boolean;
23
+ }): import("react").JSX.Element;
24
+ /** A section that takes up both columns: a wide table, the glance at twelve
25
+ * columns. Without this you would have to take it out of the grid and set up
26
+ * another one below, which is how a screen ends up with three grids and none of
27
+ * them aligned. */
28
+ export declare function FullWidth({ children }: {
29
+ children: ReactNode;
30
+ }): import("react").JSX.Element;
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * Context: the rule that decides whether two sections go side by side is
4
+ * DEPENDENCY, not space. Two that don't govern each other —the invoice lines
5
+ * and its payments— go side by side; two that do —choosing the customer and then
6
+ * its price list— go stacked, because the vertical order is the only thing that says which
7
+ * one comes first.
8
+ *
9
+ * That is why it is a grid and not a `flex-wrap`: wrapping arranges by available
10
+ * width, which is a decision about space.
11
+ *
12
+ * And it asks `@container` and not `md:`: with four panels open each one measures
13
+ * 380 px on a 1.600 screen, and a window rule would put two 190 px columns inside
14
+ * each panel. **Whoever mounts the view has to declare `@container` on its
15
+ * container** — the composer already does.
16
+ */
17
+ export function SectionGrid({ children,
18
+ /** A single column until the panel is truly large. For sections with a table
19
+ * inside: two 300 px tables don't read better than one 600 px one. */
20
+ wide = false, }) {
21
+ return (_jsx("div", { className: `grid min-w-0 gap-(--spacing-block) ${wide ? "@4xl:grid-cols-2" : "@2xl:grid-cols-2"}`, children: children }));
22
+ }
23
+ /** A section that takes up both columns: a wide table, the glance at twelve
24
+ * columns. Without this you would have to take it out of the grid and set up
25
+ * another one below, which is how a screen ends up with three grids and none of
26
+ * them aligned. */
27
+ export function FullWidth({ children }) {
28
+ return _jsx("div", { className: "min-w-0 @2xl:col-span-2", children: children });
29
+ }