@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,2 @@
1
+ export * from "./list/index.js";
2
+ export * from "./record/index.js";
@@ -0,0 +1,3 @@
1
+ /* VIEWS — the two macros, and nothing else: one record, or N records. */
2
+ export * from "./list/index.js";
3
+ export * from "./record/index.js";
@@ -0,0 +1,119 @@
1
+ import type { ListIdentity } from "../../components/listing/ListingBar.js";
2
+ import type { SortField } from "../../components/listing/SortMenu.js";
3
+ import type { Surface } from "../../foundations/types.js";
4
+ import type { DataColumn, DataTableCreate } from "../../primitives/table/DataTable.js";
5
+ import type { RowAction } from "../../primitives/table/RowActions.js";
6
+ import type { SortState } from "../../primitives/table/Table.js";
7
+ import { type ListCrumb, type ListEmpty, type ListGroup, type ListPivot, type ListPresent, type ListReport, type ListSheet, type RowOf } from "./types.js";
8
+ import type { ReactNode } from "react";
9
+ type BarProps = {
10
+ children?: ReactNode;
11
+ };
12
+ type CrumbsProps = {
13
+ crumbs: readonly ListCrumb[];
14
+ };
15
+ type NodeProps = {
16
+ children?: ReactNode;
17
+ };
18
+ type RowsProps<T> = {
19
+ row: (item: T) => RowOf;
20
+ /**
21
+ * Los rótulos de las zonas de una fila, arriba de todas. Sin esto no hay
22
+ * encabezado: una lista de cinco archivos con el nombre y nada más no lo
23
+ * necesita.
24
+ *
25
+ * No son columnas. Una fila tiene un nombre, UNA cadena de `meta` ya formateada
26
+ * y una columna de fichas: eso es lo que se rotula.
27
+ */
28
+ header?: {
29
+ name: string;
30
+ meta?: string;
31
+ tags?: string;
32
+ };
33
+ };
34
+ type TableProps<T extends object> = {
35
+ columns: readonly DataColumn<T>[];
36
+ /** Cuáles están en pantalla. Las obligatorias se quedan aunque se omitan. */
37
+ visibleColumnIds?: readonly string[];
38
+ onVisibleColumnIdsChange?: (ids: readonly string[]) => void;
39
+ /** El pie con los agregados de las columnas que declararon uno. */
40
+ totals?: boolean;
41
+ /** Lo que se le hace a UNA fila sin entrar. Se dibujan escondidas y aparecen
42
+ * sobre la fila que se está apuntando. */
43
+ rowActions?: (item: T) => readonly RowAction[];
44
+ /** Escribir un registro nuevo como una fila más de la tabla (la lista editable de
45
+ * Odoo). Ver la cabecera de `DataTable`. */
46
+ create?: DataTableCreate<T>;
47
+ };
48
+ /** El tablero. Sin `card`, la tarjeta sale de lo que ya dice `List.Rows`: el
49
+ * nombre, el `meta` y las fichas. Escribirla igual es declarar que ESTA lista
50
+ * se puede ver como tablero. */
51
+ type BoardProps<T> = {
52
+ card?: (item: T) => ReactNode;
53
+ };
54
+ /** La planilla. Sin columnas propias, sale de las que declaró `List.Table` — la
55
+ * de datos CRUDOS sí las trae, porque ahí salen del archivo y el código no sabe
56
+ * cuáles son. */
57
+ type SheetProps<T> = Partial<ListSheet<T>>;
58
+ export type ListProps<T extends object> = {
59
+ items: readonly T[];
60
+ keyOf: (item: T) => string;
61
+ /** The list is a FIELD of a record — a one2many / many2many — and not a screen: a
62
+ * one-line bar that does not stick. See «A list INSIDE a record» above. */
63
+ embedded?: boolean;
64
+ /** En qué superficie se apoya la BARRA. `canvas` (el default) es una barra
65
+ * de control clara; `chrome` la convierte en una banda oscura, una opción
66
+ * explícita: la barra de la aplicación es la única banda oscura de la
67
+ * pantalla, igual que el riel de un registro. */
68
+ surface?: Surface;
69
+ /** Cómo se parte el conjunto. Es del CONJUNTO y no de una cara: cambiar de
70
+ * presentación no puede perderlo. */
71
+ group?: ListGroup<T>;
72
+ selection?: {
73
+ has: (id: string) => boolean;
74
+ toggle: (id: string) => void;
75
+ count: number;
76
+ clear: () => void;
77
+ actions?: ReactNode;
78
+ };
79
+ /** El orden, que también es del conjunto. */
80
+ sort?: SortState | null;
81
+ onSortChange?: (next: SortState | null) => void;
82
+ /** Por qué campos se puede ordenar en las caras que NO tienen encabezados
83
+ * donde hacer clic. */
84
+ sortable?: readonly SortField<T>[];
85
+ /** Cuál cara se está mirando. Sin esto, la primera que esté escrita. */
86
+ present?: ListPresent;
87
+ onPresentChange?: (next: ListPresent) => void;
88
+ onOpen?: (item: T) => void;
89
+ onPeek?: (item: T) => void;
90
+ isPeeked?: (item: T) => boolean;
91
+ /** Los tres estados, en un solo lugar. */
92
+ state?: {
93
+ loading?: boolean;
94
+ error?: string | null;
95
+ };
96
+ /** Vacía POR UN FILTRO es otra situación: no falta contenido, sobra un
97
+ * recorte. */
98
+ filtered?: boolean;
99
+ empty?: ListEmpty;
100
+ children?: ReactNode;
101
+ };
102
+ export declare function List<T extends object>({ items, keyOf, embedded, surface, group, selection, sort, onSortChange, sortable, present, onPresentChange, onOpen, onPeek, isPeeked, state, filtered, empty, children, }: ListProps<T>): import("react").JSX.Element;
103
+ export declare namespace List {
104
+ var Bar: ((props: BarProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"bar">;
105
+ var Crumbs: ((props: CrumbsProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"crumbs">;
106
+ var Identity: ((props: ListIdentity) => ReactNode) & import("../../foundations/slots.js").Slotted<"identity">;
107
+ var Search: ((props: NodeProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"search">;
108
+ var Actions: ((props: NodeProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"actions">;
109
+ var Pagination: ((props: NodeProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"pagination">;
110
+ var Views: ((props: NodeProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"views">;
111
+ var Metrics: ((props: NodeProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"metrics">;
112
+ var Rows: <T>(props: RowsProps<T>) => ReactNode;
113
+ var Table: <T extends object>(props: TableProps<T>) => ReactNode;
114
+ var Board: <T>(props: BoardProps<T>) => ReactNode;
115
+ var Sheet: <T>(props: SheetProps<T>) => ReactNode;
116
+ var Report: ((props: ListReport) => ReactNode) & import("../../foundations/slots.js").Slotted<"report">;
117
+ var Pivot: <T>(props: ListPivot<T>) => ReactNode;
118
+ }
119
+ export {};
@@ -0,0 +1,101 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { flatten, loose, pick, propsOf, slot, slotOf, } from "../../foundations/slots.js";
3
+ import { ListView } from "./ListView.js";
4
+ import {} from "./types.js";
5
+ /** La barra: todo lo que es del CONJUNTO y no de una fila. Sin ella no hay
6
+ * banda — que es lo que quiere una lista metida adentro de un diálogo. */
7
+ const Bar = slot("bar", (_props) => null);
8
+ /** De dónde vengo. Va arriba de la barra, y sólo cuando la barra es cromo. */
9
+ const Crumbs = slot("crumbs", (_props) => null);
10
+ /** Cómo se llama esta lista y cuánto tiene. */
11
+ const Identity = slot("identity", (_props) => null);
12
+ /** El campo de búsqueda, ya armado: lo arma quien tiene las declaraciones del
13
+ * dominio — el sistema no sabe qué es un NIT. */
14
+ const Search = slot("search", (_props) => null);
15
+ /** Lo que EMPIEZA algo nuevo. Sigue visible cuando hay una selección. */
16
+ const Actions = slot("actions", (_props) => null);
17
+ const Pagination = slot("pagination", (_props) => null);
18
+ /** La escotilla del conmutador: un selector propio. Casi nunca hace falta —
19
+ * las caras escritas ya lo dibujan. */
20
+ const Views = slot("views", (_props) => null);
21
+ /** Las medidas que además RECORTAN: «2 por confirmar». Van debajo de la barra y
22
+ * arriba de las filas, porque son del conjunto y no del marco. */
23
+ const Metrics = slot("metrics", (_props) => null);
24
+ const Rows = slot("rows", (_props) => null);
25
+ /* Through `unknown`: `create` both receives and hands back a `T` (`onChange`, `draft`),
26
+ so `TableProps` is invariant in `T` and `TableProps<never>` no longer narrows to it. The
27
+ slot only carries the props; `List` reads them back typed against the list's `T`. */
28
+ const TableSlot = slot("table", (_props) => null);
29
+ const Board = slot("board", (_props) => null);
30
+ const SheetSlot = slot("sheet", (_props) => null);
31
+ const Report = slot("report", (_props) => null);
32
+ const Pivot = slot("pivot", (_props) => null);
33
+ /* El orden en que se OFRECEN cuando están escritas de otra manera. El conmutador
34
+ respeta el orden del árbol; esto sólo nombra a qué presentación corresponde
35
+ cada ranura. */
36
+ const PRESENT_OF = {
37
+ rows: "rows",
38
+ table: "table",
39
+ board: "board",
40
+ sheet: "sheet",
41
+ report: "report",
42
+ pivot: "pivot",
43
+ };
44
+ const FACES = ["rows", "table", "board", "sheet", "report", "pivot"];
45
+ export function List({ items, keyOf, embedded, surface, group, selection, sort, onSortChange, sortable, present, onPresentChange, onOpen, onPeek, isPeeked, state, filtered, empty, children, }) {
46
+ const top = flatten(children);
47
+ const bar = flatten(propsOf(pick(top, "bar"))?.children);
48
+ const crumbs = propsOf(pick(bar, "crumbs"))?.crumbs;
49
+ const identity = propsOf(pick(bar, "identity"));
50
+ const search = propsOf(pick(bar, "search"))?.children;
51
+ const actions = propsOf(pick(bar, "actions"))?.children;
52
+ const pagination = propsOf(pick(bar, "pagination"))?.children;
53
+ const views = propsOf(pick(bar, "views"))?.children;
54
+ const metrics = propsOf(pick(top, "metrics"))?.children;
55
+ const rows = propsOf(pick(top, "rows"));
56
+ const table = propsOf(pick(top, "table"));
57
+ const board = propsOf(pick(top, "board"));
58
+ const sheet = propsOf(pick(top, "sheet"));
59
+ const report = propsOf(pick(top, "report"));
60
+ const pivot = propsOf(pick(top, "pivot"));
61
+ /* Las caras que hay son las que están escritas, EN ESE ORDEN. El conmutador
62
+ no puede ofrecer una que no se pueda dibujar, porque la que se dibuja y la
63
+ que se ofrece son el mismo nodo. */
64
+ const presents = top
65
+ .map((node) => FACES.find((face) => slotOf(node) === face))
66
+ .filter((face) => face !== undefined)
67
+ .map((face) => PRESENT_OF[face]);
68
+ /* La escotilla: lo que el arquetipo no previó se dibuja igual, debajo. Que
69
+ aparezca algo acá es la señal de que al arquetipo le falta una pieza. */
70
+ const rest = loose(top, ["bar", "metrics", ...FACES]);
71
+ return (_jsx(ListView, { items: items, keyOf: keyOf, row: rows?.row ?? (() => ({ name: "" })), ...(rows?.header === undefined ? {} : { rowHeader: rows.header }), ...(identity === undefined ? {} : { identity }), ...(crumbs === undefined ? {} : { crumbs }), ...(embedded === undefined ? {} : { embedded }), ...(surface === undefined ? {} : { surface }), ...(search === undefined ? {} : { search }), ...(actions === undefined ? {} : { actions }), ...(pagination === undefined ? {} : { pagination }), ...(views === undefined ? {} : { views }), ...(metrics === undefined ? {} : { metrics }), ...(table === undefined
72
+ ? {}
73
+ : {
74
+ columns: table.columns,
75
+ ...(table.totals === undefined ? {} : { totals: table.totals }),
76
+ ...(table.rowActions === undefined ? {} : { rowActions: table.rowActions }),
77
+ ...(table.create === undefined ? {} : { create: table.create }),
78
+ ...(table.visibleColumnIds === undefined
79
+ ? {}
80
+ : { visibleColumnIds: table.visibleColumnIds }),
81
+ ...(table.onVisibleColumnIdsChange === undefined
82
+ ? {}
83
+ : { onVisibleColumnIdsChange: table.onVisibleColumnIdsChange }),
84
+ }), ...(board?.card === undefined ? {} : { card: board.card }), ...(sheet?.columns === undefined || sheet.cell === undefined
85
+ ? {}
86
+ : { sheet: sheet }), ...(report === undefined ? {} : { report }), ...(pivot === undefined ? {} : { pivot }), ...(presents.length === 0 ? {} : { presents }), ...(present === undefined ? {} : { present }), ...(onPresentChange === undefined ? {} : { onPresentChange }), ...(group === undefined ? {} : { group }), ...(selection === undefined ? {} : { selection }), ...(sort === undefined ? {} : { sort }), ...(onSortChange === undefined ? {} : { onSortChange }), ...(sortable === undefined ? {} : { sortable }), ...(onOpen === undefined ? {} : { onOpen }), ...(onPeek === undefined ? {} : { onPeek }), ...(isPeeked === undefined ? {} : { isPeeked }), ...(state === undefined ? {} : { state }), ...(filtered === undefined ? {} : { filtered }), ...(empty === undefined ? {} : { empty }), children: rest.length === 0 ? undefined : rest }));
87
+ }
88
+ List.Bar = Bar;
89
+ List.Crumbs = Crumbs;
90
+ List.Identity = Identity;
91
+ List.Search = Search;
92
+ List.Actions = Actions;
93
+ List.Pagination = Pagination;
94
+ List.Views = Views;
95
+ List.Metrics = Metrics;
96
+ List.Rows = Rows;
97
+ List.Table = TableSlot;
98
+ List.Board = Board;
99
+ List.Sheet = SheetSlot;
100
+ List.Report = Report;
101
+ List.Pivot = Pivot;
@@ -0,0 +1,6 @@
1
+ import type { ListViewProps } from "./types.js";
2
+ export declare function ListView<T extends object>({ items, keyOf, identity, crumbs, embedded, surface: requestedSurface, metrics, search, pagination, views, actions, row, rowHeader, columns, visibleColumnIds, onVisibleColumnIdsChange, card, sheet, report, pivot, present: requested, presents, onPresentChange, sort, onSortChange, sortable, totals, rowActions, create, group, selection, onOpen, onPeek, state, filtered, empty, children, }: ListViewProps<T>): import("react").JSX.Element;
3
+ /** What a list offers when it fails and can be retried. */
4
+ export declare function RetryAction({ onRetry }: {
5
+ onRetry: () => void;
6
+ }): import("react").JSX.Element;
@@ -0,0 +1,295 @@
1
+ "use client";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useColumnControl, visibleColumns } from "../../components/listing/columns.js";
4
+ import { ColumnsMenu, specsFromColumns, } from "../../components/listing/ColumnsMenu.js";
5
+ import { Listing } from "../../components/listing/Listing.js";
6
+ import { ListingBar } from "../../components/listing/ListingBar.js";
7
+ import { RecordCard } from "../../components/listing/RecordCard.js";
8
+ import { GroupHeader, Row, RowHeader } from "../../components/listing/Row.js";
9
+ import { sortItems, SortMenu, } from "../../components/listing/SortMenu.js";
10
+ import { ViewSwitcher } from "../../components/listing/ViewSwitcher.js";
11
+ import { Breadcrumb } from "../../components/record/Breadcrumb.js";
12
+ import { useUiCopy } from "../../foundations/copy.js";
13
+ import { useDensity } from "../../foundations/density.js";
14
+ import { pathKey, pileIsOpen, pilesOf, } from "../../foundations/grouping.js";
15
+ import { pivotFrom, pivotIsEmpty } from "../../foundations/pivot.js";
16
+ import { Button } from "../../primitives/button/Button.js";
17
+ import { Empty, Failed, Skeleton } from "../../primitives/notice/Notice.js";
18
+ import { PivotTable } from "../../primitives/table/PivotTable.js";
19
+ import { ReportTable } from "../../primitives/table/ReportTable.js";
20
+ import { groupedColumnIds } from "./columns.js";
21
+ import { groupLevelsOf, reportColumnsOf, reportRowsOf, sheetFromColumns, sheetRowsOf, } from "./derive.js";
22
+ import { SheetPresentation, TablePresentation, } from "./presentations.js";
23
+ import { useNarrowList } from "./useNarrowList.js";
24
+ import { Grid3x3, LayoutGrid, List, Sheet, Sigma, Table2 } from "lucide-react";
25
+ import { Fragment, useCallback, useMemo } from "react";
26
+ /**
27
+ * EL DIBUJO de una lista. **La puerta es `List`**, que se escribe como árbol y
28
+ * traduce las ranuras a esto — acá todo entra como props porque acá ya se
29
+ * decidió todo: quién compone no elige entre dos maneras de escribir lo mismo,
30
+ * porque esto no se publica.
31
+ *
32
+ * Context: `invoices.view.tsx` has 349 lines and about 120 of them are
33
+ * re-assembling this: the bar, the search field, the grouping and the three
34
+ * states. Ten views with their own copy are 1,200 lines that drift apart one at
35
+ * a time, one per week — and it already happened: Facturas had a text
36
+ * `<input>` while the modal explorer had facets, filters and grouping. The same
37
+ * list, in two places, with two sets of capabilities.
38
+ *
39
+ * **Grouping, sorting and which columns are on screen belong to the SET;
40
+ * rows, table and board are three PRESENTATIONS of the same set.** Until now
41
+ * grouping only existed inside `DataTable`, so switching presentation lost
42
+ * the grouping; the columns submenu existed only on FrameView, and every
43
+ * column could hide. Odoo splits required vs optional — that split lives in
44
+ * `useColumnControl`. Collapse lives in `useTreeControl`.
45
+ *
46
+ * The escape hatch is `children`: whatever the archetype did not foresee gets
47
+ * drawn anyway, and its appearing there is the signal that the archetype is
48
+ * missing something.
49
+ */
50
+ const PRESENT_ICONS = [
51
+ { id: "rows", icon: List },
52
+ { id: "table", icon: Table2 },
53
+ { id: "board", icon: LayoutGrid },
54
+ { id: "sheet", icon: Sheet },
55
+ /* La sigma y no un ícono de tabla: lo que distingue a un informe de las otras
56
+ cuatro es que SUMA. */
57
+ { id: "report", icon: Sigma },
58
+ /* La cuadrícula: dos ejes, y lo que importa está adentro. */
59
+ { id: "pivot", icon: Grid3x3 },
60
+ ];
61
+ export function ListView({ items, keyOf, identity, crumbs, embedded = false, surface: requestedSurface, metrics, search, pagination, views, actions, row, rowHeader, columns, visibleColumnIds, onVisibleColumnIdsChange, card, sheet, report, pivot, present: requested = "rows", presents, onPresentChange, sort, onSortChange, sortable, totals = false, rowActions, create, group, selection, onOpen, onPeek, state, filtered = false, empty, children, }) {
62
+ const { frame, offered, present } = useNarrowList(presents, requested);
63
+ /* Embedded, the list sits on the record's paper: there is no dark band to inherit, and a
64
+ navy switcher inside a white sheet would be a second chrome on the screen. */
65
+ const surface = embedded ? undefined : requestedSurface;
66
+ const density = useDensity();
67
+ const copy = useUiCopy();
68
+ const loading = state?.loading === true;
69
+ const error = state?.error ?? null;
70
+ const columnSpecs = useMemo(() => specsFromColumns(columns ?? [], false), [columns]);
71
+ const columnControl = useColumnControl(columnSpecs, {
72
+ ...(visibleColumnIds === undefined ? {} : { visibleIds: visibleColumnIds }),
73
+ /* El nombre tiene que ser el que `useColumnControl` lee. Decía
74
+ `onVisibleColumnIdsChange` —el nombre de la prop de ACÁ— y el hook busca
75
+ `onVisibleIdsChange`, así que nunca entraba en modo controlado: la lista
76
+ ignoraba en silencio las columnas que le pasaran. */
77
+ ...(onVisibleColumnIdsChange === undefined
78
+ ? {}
79
+ : { onVisibleIdsChange: onVisibleColumnIdsChange }),
80
+ });
81
+ /* Agrupar por una columna escondida dejaría montones cuyo criterio no se ve.
82
+ Con N niveles son N columnas, y se reponen todas. Es lo ÚNICO para lo que
83
+ hace falta saber qué columna contesta por un campo: la tabla ya no agrupa
84
+ por columnas, agrupa por niveles. */
85
+ const groupedIds = group === undefined ? [] : groupedColumnIds(group, columns);
86
+ const tableIds = groupedIds.every((id) => columnControl.visibleIds.includes(id))
87
+ ? columnControl.visibleIds
88
+ : [
89
+ ...columnControl.visibleIds,
90
+ ...groupedIds.filter((id) => !columnControl.visibleIds.includes(id)),
91
+ ];
92
+ const shownColumns = columns === undefined ? undefined : visibleColumns(columns, tableIds);
93
+ const groupLevels = useMemo(() => groupLevelsOf(group, columns), [group, columns]);
94
+ const switcher = views ??
95
+ (offered.length > 1 ? (_jsx(ViewSwitcher, { options: PRESENT_ICONS.filter((option) => offered.includes(option.id)).map((option) => ({
96
+ id: option.id,
97
+ label: copy.present[option.id],
98
+ icon: option.icon,
99
+ })), current: present, ...(onPresentChange === undefined
100
+ ? {}
101
+ : { onSelect: (id) => onPresentChange(id) }), ...(surface === undefined ? {} : { surface }) })) : undefined);
102
+ const sheetFromDeclared = useMemo(() => sheetFromColumns(shownColumns), [shownColumns]);
103
+ const sheetSpec = sheet ?? sheetFromDeclared;
104
+ /* El menú de columnas vale en `table` y en la planilla DERIVADA —las dos
105
+ dibujan las columnas que declaró el código—, y no en la planilla de datos
106
+ crudos ni en el informe: ahí las columnas salen del archivo o son los
107
+ períodos, y no hay ninguna que el código pueda ofrecer esconder. */
108
+ const columnsMenu = (present === "table" || (present === "sheet" && sheet === undefined)) &&
109
+ columnControl.hasOptional ? (_jsx(ColumnsMenu, { control: columnControl, ...(surface === undefined ? {} : { surface }) })) : null;
110
+ /* ORDENAR. El control va en la barra y no adentro de la tabla porque el orden
111
+ es del CONJUNTO, igual que los niveles y que lo plegado: cambiar de
112
+ presentación no puede perderlo, y en filas, tablero y planilla no hay
113
+ encabezados donde hacer clic.
114
+
115
+ Lo único que NO se ordena es un informe cuyas filas DECLARÓ el dominio: ahí
116
+ el orden es el informe —«Total activos» tiene que quedar después de los
117
+ activos— y reordenarlo por importe lo destruye.
118
+
119
+ Un informe armado a partir de los montones sí se ordena, porque no es una
120
+ jerarquía que alguien escribió: es este mismo conjunto, contado. La regla
121
+ mira `report.rows` y no la presentación, que era la versión gruesa de esto y
122
+ le sacaba el orden a un informe que sí podía tenerlo. */
123
+ const declaredReport = present === "report" && report?.rows !== undefined;
124
+ /* El pivote tampoco se ordena desde la barra, y por una razón propia: sus
125
+ filas no son las filas del conjunto. Cada eje está en el orden de sus
126
+ claves, y ordenar los registros de abajo no ordena los montones de arriba —
127
+ ofrecerlo sería un control que se mueve y no cambia nada. */
128
+ const sortMenu = sortable === undefined ||
129
+ sortable.length === 0 ||
130
+ declaredReport ||
131
+ present === "pivot" ? null : (_jsx(SortMenu, { fields: sortable, sort: sort ?? null, onSortChange: (next) => onSortChange?.(next), ...(surface === undefined ? {} : { surface }) }));
132
+ const rightViews = views ?? switcher;
133
+ const viewsSlot = columnsMenu === null && sortMenu === null && rightViews === undefined ? undefined : (_jsxs(_Fragment, { children: [sortMenu, columnsMenu, rightViews] }));
134
+ /* Embedded, the line is drawn only if it has something to OFFER: a count alone repeats
135
+ what the rows (and the footer) already say. */
136
+ const barHasControls = !embedded ||
137
+ search !== undefined ||
138
+ viewsSlot !== undefined ||
139
+ actions !== undefined ||
140
+ pagination !== undefined ||
141
+ (selection?.count ?? 0) > 0;
142
+ const bar = !barHasControls ? undefined : (_jsx(ListingBar, { surface: surface, ...(embedded ? { inline: true, count: items.length } : {}), ...(embedded || crumbs === undefined || crumbs.length === 0 || density === "compact"
143
+ ? {}
144
+ : {
145
+ crumbs: (_jsx(Breadcrumb, { crumbs: crumbs, ...(surface === undefined ? {} : { surface }) })),
146
+ }), ...(actions === undefined ? {} : { actions }), ...(identity?.title === undefined ? {} : { title: identity.title }), ...(identity?.description === undefined ? {} : { description: identity.description }), ...(identity?.counters === undefined ? {} : { counters: identity.counters }), ...(selection === undefined
147
+ ? {}
148
+ : {
149
+ selection: {
150
+ count: selection.count,
151
+ onClear: selection.clear,
152
+ ...(selection.actions === undefined ? {} : { actions: selection.actions }),
153
+ },
154
+ }), ...(search === undefined ? {} : { search }), ...(pagination === undefined ? {} : { pagination }), ...(viewsSlot === undefined ? {} : { views: viewsSlot }) }));
155
+ const renderRow = (item) => {
156
+ const d = row(item);
157
+ const id = keyOf(item);
158
+ return (_jsx(Row, { ...(d.icon === undefined ? {} : { icon: d.icon }), name: d.name, ...(d.tags === undefined ? {} : { tags: d.tags }), ...(d.meta === undefined ? {} : { meta: d.meta }), ...(d.actions === undefined ? {} : { actions: d.actions }), ...(onOpen === undefined ? {} : { onOpen: () => onOpen(item) }), ...(onPeek === undefined ? {} : { onPeek: () => onPeek(item) }), ...(selection === undefined
159
+ ? {}
160
+ : { selected: selection.has(id), onSelectedChange: () => selection.toggle(id) }), children: d.children }, id));
161
+ };
162
+ /* El orden va ANTES de agrupar y no después, y no es indistinto: agrupar
163
+ preserva el orden de aparición dentro de cada montón, así que ordenar
164
+ primero ordena las filas de cada montón. Al revés habría que reordenar N
165
+ montones y el orden entre ellos quedaría al azar.
166
+
167
+ La tabla ordena adentro —es TanStack— así que ahí se deja pasar: ordenar dos
168
+ veces no rompe nada, pero es trabajo al pedo sobre cada render. */
169
+ const ordered = useMemo(() => present === "table" || sortable === undefined
170
+ ? items
171
+ : sortItems(items, sortable, sort ?? null), [items, present, sortable, sort]);
172
+ /**
173
+ * La grilla que hay que dibujar: la que le pasaron plegada, o la que se arma
174
+ * con las filas en la mano.
175
+ *
176
+ * Es la misma decisión que `pilesOf` toma para los montones, y por el mismo
177
+ * motivo: quién plegó no es asunto de esta capa.
178
+ */
179
+ const pivotShown = useMemo(() => {
180
+ if (pivot?.folded !== undefined)
181
+ return pivot.folded;
182
+ if (pivot?.spec === undefined)
183
+ return undefined;
184
+ return pivotFrom(ordered, pivot.spec);
185
+ }, [pivot, ordered]);
186
+ /**
187
+ * Vacío es no tener NADA que dibujar, y en el pivote eso no se pregunta
188
+ * contando `items`: cuando la grilla la plegó quien guarda los datos, las
189
+ * filas de la pantalla son montones y el conjunto puede no haber bajado
190
+ * nunca. Contar los registros ahí es tapar una grilla entera con «todavía no
191
+ * hay datos».
192
+ */
193
+ const isEmpty = !loading &&
194
+ error === null &&
195
+ (present === "pivot" && pivotShown !== undefined
196
+ ? pivotIsEmpty(pivotShown)
197
+ : items.length === 0) &&
198
+ /* The first record of an empty list is written in the table, not under a sentence
199
+ saying there is nothing. */
200
+ !(present === "table" && create?.draft != null);
201
+ /* La única línea que hace agrupable a una vista: el árbol que le pasaron, o el
202
+ que se arma con las filas en la mano. */
203
+ const piles = useMemo(() => pilesOf(ordered, group), [group, ordered]);
204
+ const isOpen = useCallback((pile) => pileIsOpen(pile, group), [group]);
205
+ const sheetRows = useMemo(() => sheetRowsOf(piles, isOpen, columns), [piles, isOpen, columns]);
206
+ /* La forma de una fila de ESTA lista, para que el encabezado reserve los
207
+ mismos espaciadores. Se mira la primera y no todas: el ícono y las acciones
208
+ los decide la vista para la lista entera. */
209
+ const first = items[0];
210
+ const firstRow = first === undefined ? undefined : row(first);
211
+ /** Los montones, con sus filas adentro. Se llama a sí misma porque el árbol
212
+ * tiene N niveles: un montón dibuja su encabezado y, adentro, o bien los
213
+ * montones de abajo o bien las filas — nunca las dos cosas. */
214
+ function renderPiles(list, nodes) {
215
+ return list.map((pile) => {
216
+ const key = pathKey(pile.path);
217
+ const open = isOpen(pile);
218
+ return (_jsxs(Fragment, { children: [_jsx(GroupHeader, { field: pile.field, label: pile.label, count: pile.count, depth: pile.depth, open: open, ...(group?.onToggle === undefined
219
+ ? {}
220
+ : { onToggle: () => group.onToggle?.(key) }) }), !open
221
+ ? null
222
+ : pile.piles.length > 0
223
+ ? renderPiles(pile.piles, nodes)
224
+ : nodes(pile.items)] }, key));
225
+ });
226
+ }
227
+ const reportRows = useMemo(() => reportRowsOf(piles, columns, row), [piles, columns, row]);
228
+ function wrapGroups(nodes) {
229
+ if (piles === null)
230
+ return nodes(ordered);
231
+ return renderPiles(piles, nodes);
232
+ }
233
+ const renderCard = (item) => {
234
+ if (card !== undefined) {
235
+ return _jsx(Fragment, { children: card(item) }, keyOf(item));
236
+ }
237
+ const d = row(item);
238
+ return (_jsx(RecordCard, { title: d.name, ...(d.tags === undefined ? {} : { tags: d.tags }), ...(d.meta === undefined ? {} : { meta: d.meta }), ...(onOpen === undefined ? {} : { onOpen: () => onOpen(item) }) }, keyOf(item)));
239
+ };
240
+ const body = present === "table" && shownColumns !== undefined ? (
241
+ /* The table receives EVERYTHING that belongs to the set: see `TablePresentation`. */
242
+ _jsx(TablePresentation, { items: items, columns: shownColumns, keyOf: keyOf, levels: groupLevels, ...(sort === undefined ? {} : { sort }), ...(onSortChange === undefined ? {} : { onSortChange }), ...(group === undefined ? {} : { group }), ...(selection === undefined ? {} : { selection }), totals: totals, ...(rowActions === undefined ? {} : { rowActions }), ...(create === undefined ? {} : { create }), ...(onPeek === undefined ? {} : { onPeek }), ...(onOpen === undefined ? {} : { onOpen }) })) : present === "sheet" && sheetSpec !== undefined ? (
243
+ /* La planilla recibe el conjunto por ÍNDICE y no una matriz ya armada: ver `SheetPresentation`. */
244
+ _jsx(SheetPresentation, { spec: sheetSpec, entries: sheetRows, ordered: ordered, ...(group === undefined ? {} : { group }) })) : present === "report" && report !== undefined ? (
245
+ /* El informe declarado por el dominio no se ORDENA desde la barra: el
246
+ orden ES el informe, y ordenar un balance por importe deja «Total
247
+ Activos» en el medio. Pero sí se AGRUPA cuando las líneas no vienen
248
+ declaradas: ahí el informe es este conjunto contado por los niveles que
249
+ estén puestos. */
250
+ _jsx(ReportTable
251
+ /* Built from the piles, the numbers are the list's columns' — and so is how they
252
+ are written. Declared by the domain, the columns are the domain's. */
253
+ , {
254
+ /* Built from the piles, the numbers are the list's columns' — and so is how they
255
+ are written. Declared by the domain, the columns are the domain's. */
256
+ columns: report.rows === undefined
257
+ ? reportColumnsOf(report.columns, columns)
258
+ : report.columns, rows: report.rows ?? reportRows, ...(report.defaultOpen === undefined ? {} : { defaultOpen: report.defaultOpen }), ...(report.height === undefined ? {} : { height: report.height }) })) : present === "pivot" && pivotShown !== undefined ? (
259
+ /* El pivote recibe la grilla y nada más: no hay selección que pasarle
260
+ —una casilla por montón elegiría cosas que no son registros—, no hay
261
+ orden —cada eje viene en el orden de sus claves— y no hay menú de
262
+ columnas, porque las columnas son un eje y no una lista de campos que
263
+ se puedan esconder de a uno. */
264
+ _jsx(PivotTable, { pivot: pivotShown, ...(pivot?.onCell === undefined ? {} : { onCell: pivot.onCell }), ...(pivot?.height === undefined ? {} : { height: pivot.height }) })) : present === "board" ? (_jsx("div", { className: "flex flex-col", children: wrapGroups((inside) => (_jsx("div", { className: "grid gap-3 p-3 @2xl:grid-cols-2 @5xl:grid-cols-3", children: inside.map(renderCard) }))) })) : (
265
+ /* El encabezado va ANTES de los montones y no adentro de cada uno:
266
+ rotula la fila, y la fila es la misma en los cinco montones. */
267
+ _jsxs(_Fragment, { children: [rowHeader === undefined || items.length === 0 ? null : (_jsx(RowHeader, { name: rowHeader.name, ...(rowHeader.meta === undefined ? {} : { meta: rowHeader.meta }), ...(rowHeader.tags === undefined ? {} : { tags: rowHeader.tags }), withSelection: selection !== undefined,
268
+ /* Los espaciadores se preguntan por la PRIMERA fila: el ícono y las
269
+ acciones son de la lista entera, no de una fila — si la primera no
270
+ tiene ícono, ninguna lo tiene. */
271
+ withIcon: firstRow?.icon !== undefined, withActions: onOpen !== undefined || firstRow?.actions !== undefined })), wrapGroups((inside) => inside.map(renderRow))] }));
272
+ return (
273
+ /* The list is its own container (`@container`: the presentations adapt to the width
274
+ the LIST has, not the window) and fills the space it is given. Before, every page
275
+ wrapped it in a `div` to get both. */
276
+ _jsxs("div", { ref: frame, className: "@container flex min-w-0 flex-1 flex-col bg-surface", children: [_jsxs(Listing, { bar: bar,
277
+ /* La barra se queda arriba: con 187 filas, scrollear para ver la última
278
+ dejaba sin buscador, sin paginador y sin el conmutador.
279
+ Embedded it does NOT: the record has its own sticky parts (its rail, its tabs),
280
+ and a second band stuck under them — or carried up into the frame's header slot,
281
+ which is what a sticky list bar does under a sidebar — would cover the record
282
+ for a collection of a dozen rows. */
283
+ sticky: !embedded, ...(surface === undefined ? {} : { surface }), ...(metrics === undefined
284
+ ? {}
285
+ : {
286
+ metrics: _jsx("div", { className: "px-3.5", children: metrics }),
287
+ }), children: [loading ? _jsx(Skeleton, { label: copy.failed.loading }) : null, isEmpty ? (filtered ? (_jsx(Empty, { sentence: empty?.whenFiltered?.sentence ?? copy.list.emptyFiltered, ...(empty?.whenFiltered?.action === undefined
288
+ ? {}
289
+ : { action: empty.whenFiltered.action }) })) : (_jsx(Empty, { sentence: empty?.sentence ?? copy.list.empty, ...(empty?.action === undefined ? {} : { action: empty.action }) }))) : null, loading || isEmpty ? null : body] }), error === null ? null : (_jsx("div", { className: "px-3 pt-(--spacing-block)", children: _jsx(Failed, { heading: copy.failed.list, sentence: error }) })), children] }));
290
+ }
291
+ /** What a list offers when it fails and can be retried. */
292
+ export function RetryAction({ onRetry }) {
293
+ const copy = useUiCopy();
294
+ return (_jsx(Button, { role: "secondary", size: "sm", onClick: onRetry, children: copy.failed.retry }));
295
+ }
@@ -0,0 +1,18 @@
1
+ import type { ListPresent } from "../../components/listing/set.js";
2
+ import type { DataColumn } from "../../primitives/table/DataTable.js";
3
+ import type { ListGroup } from "./types.js";
4
+ /** Las columnas que una tabla agrupada tiene que MOSTRAR, en orden.
5
+ *
6
+ * No son por las que agrupa —eso lo hacen los niveles, con la clave del motor—
7
+ * sino las que no pueden quedar escondidas: un montón «Septiembre» con la
8
+ * columna «registrado» apagada es un corte cuyo criterio no está en la
9
+ * pantalla.
10
+ *
11
+ * **El nombre de una columna y el de un campo no son el mismo, y suponerlo fue
12
+ * lo que rompió la tabla.** Una columna puede llamarse `registered` y contestar
13
+ * por el `registered_at` del modelo — que es justo lo que declara
14
+ * `DataColumn.field`. Lee las columnas en orden —la que SE LLAMA como el campo,
15
+ * después la que lo declara— y `columnOf` gana si la vista sabe más. */
16
+ export declare function groupedColumnIds<T extends object>(group: ListGroup<T>, columns: readonly DataColumn<T>[] | undefined): string[];
17
+ /** The presentations that need width: a grid of columns. */
18
+ export declare const WIDE_PRESENTS: readonly ListPresent[];
@@ -0,0 +1,27 @@
1
+ /** Las columnas que una tabla agrupada tiene que MOSTRAR, en orden.
2
+ *
3
+ * No son por las que agrupa —eso lo hacen los niveles, con la clave del motor—
4
+ * sino las que no pueden quedar escondidas: un montón «Septiembre» con la
5
+ * columna «registrado» apagada es un corte cuyo criterio no está en la
6
+ * pantalla.
7
+ *
8
+ * **El nombre de una columna y el de un campo no son el mismo, y suponerlo fue
9
+ * lo que rompió la tabla.** Una columna puede llamarse `registered` y contestar
10
+ * por el `registered_at` del modelo — que es justo lo que declara
11
+ * `DataColumn.field`. Lee las columnas en orden —la que SE LLAMA como el campo,
12
+ * después la que lo declara— y `columnOf` gana si la vista sabe más. */
13
+ export function groupedColumnIds(group, columns) {
14
+ return group.levels
15
+ .map((level) => group.columnOf?.(level) ?? columnAnswering(level.field, columns))
16
+ .filter((id) => id !== undefined);
17
+ }
18
+ /** The presentations that need width: a grid of columns. */
19
+ export const WIDE_PRESENTS = ["table", "sheet", "report", "pivot"];
20
+ /** The id of the column that answers for a model field, when there is one. */
21
+ function columnAnswering(field, columns) {
22
+ if (columns === undefined)
23
+ return field;
24
+ return (columns.find((one) => one.id === field)?.id ??
25
+ columns.find((one) => one.field === field)?.id ??
26
+ field);
27
+ }