@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,46 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { currentCopy, useUiCopy } from "../../foundations/copy.js";
4
+ import { Button } from "../../primitives/button/Button.js";
5
+ import { TextArea } from "../../primitives/field/Field.js";
6
+ import { Send, Users, X } from "lucide-react";
7
+ import { useState } from "react";
8
+ /**
9
+ * ESCRIBIR UNA NOTA, la manera que toda lista tiene.
10
+ *
11
+ * Es una función y no una constante porque sus palabras salen de la copia, y una
12
+ * constante las congelaría con las que hubiera al cargar el módulo —o sea, las
13
+ * de fábrica— por más que después se instale otra.
14
+ */
15
+ export function writeANote() {
16
+ const copy = currentCopy();
17
+ return {
18
+ id: "note",
19
+ label: copy.activity.writeNote,
20
+ internal: true,
21
+ placeholder: copy.activity.notePlaceholder,
22
+ };
23
+ }
24
+ export function MessageComposer({ kinds, onSend, sending = false, footer, }) {
25
+ const copy = useUiCopy();
26
+ /* La manera por default se arma acá adentro y no en la firma: un default de
27
+ parámetro se evalúa en cada render, sí, pero escrito como constante del
28
+ módulo congelaría las palabras de fábrica. */
29
+ const ways = kinds ?? [writeANote()];
30
+ const [writing, setWriting] = useState(undefined);
31
+ const [body, setBody] = useState("");
32
+ const ready = body.trim() !== "" && !sending;
33
+ function close() {
34
+ setWriting(undefined);
35
+ setBody("");
36
+ }
37
+ return (_jsxs("div", { className: "flex min-w-0 flex-col gap-2", children: [_jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-1.5", children: [ways.map((kind) => (_jsx(Button, {
38
+ /* Chosen is `secondary`, not `primary`: the gold is the record's one action,
39
+ and a way of writing that is merely selected is not an action. */
40
+ role: writing?.id === kind.id ? "secondary" : "ghost", size: "sm", onClick: () => (writing?.id === kind.id ? close() : setWriting(kind)), children: kind.label }, kind.id))), footer === undefined ? null : _jsx("div", { className: "ml-auto min-w-0", children: footer })] }), writing === undefined ? null : (_jsxs("div", { className: "flex min-w-0 flex-col gap-2", children: [writing.internal === true || writing.recipients === undefined ? null : (_jsxs("p", { className: "flex min-w-0 items-center gap-1.5 text-micro text-muted", title: copy.activity.recipients, children: [_jsx(Users, { className: "size-3.5 shrink-0", "aria-hidden": true }), _jsx("span", { className: "min-w-0 truncate", children: writing.recipients.length === 0
41
+ ? copy.activity.noRecipients
42
+ : writing.recipients.join(" · ") })] })), _jsx(TextArea, { value: body, onChange: setBody, placeholder: writing.placeholder ?? copy.activity.messagePlaceholder, rows: 3 }), _jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(Button, { role: "secondary", size: "sm", icon: Send, disabled: !ready, onClick: () => {
43
+ onSend(body.trim(), writing);
44
+ close();
45
+ }, children: sending ? copy.activity.sending : copy.activity.send }), _jsx(Button, { role: "ghost", size: "sm", icon: X, onClick: close, children: copy.activity.cancel })] })] }))] }));
46
+ }
@@ -0,0 +1,21 @@
1
+ import type { Surface, Tone } from "../../foundations/types.js";
2
+ import { type ReactNode } from "react";
3
+ export type TimelineItemProps = {
4
+ label: ReactNode;
5
+ at: Date | string | number;
6
+ tone?: Tone;
7
+ action?: ReactNode;
8
+ };
9
+ export type TimelineProps = {
10
+ children?: ReactNode;
11
+ empty?: {
12
+ sentence: string;
13
+ action?: ReactNode;
14
+ };
15
+ surface?: Surface;
16
+ };
17
+ /** Renders items in the order given — this kit's convention is newest first. */
18
+ export declare function Timeline({ children, empty, surface }: TimelineProps): import("react").JSX.Element | null;
19
+ export declare namespace Timeline {
20
+ var Item: ({ label, at, tone, action }: TimelineItemProps) => import("react").JSX.Element;
21
+ }
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { SurfaceProvider, useSurface } from "../../foundations/surface.js";
4
+ import { Empty } from "../../primitives/notice/Notice.js";
5
+ import { DateValue } from "../../primitives/value/Fecha.js";
6
+ import { Children } from "react";
7
+ const DOT_TONE = {
8
+ neutral: { canvas: "bg-muted", chrome: "bg-chrome-muted" },
9
+ info: { canvas: "bg-info", chrome: "bg-chrome-link" },
10
+ good: { canvas: "bg-good", chrome: "bg-chrome-good" },
11
+ warn: { canvas: "bg-warn", chrome: "bg-chrome-warn" },
12
+ bad: { canvas: "bg-bad", chrome: "bg-chrome-bad" },
13
+ accent: { canvas: "bg-accent", chrome: "bg-chrome-accent" },
14
+ };
15
+ function Item({ label, at, tone = "neutral", action }) {
16
+ const surface = useSurface();
17
+ const isChrome = surface === "chrome";
18
+ const text = isChrome ? "text-chrome-ink" : "text-ink";
19
+ const rail = isChrome ? "bg-chrome-ink/20" : "bg-line";
20
+ return (_jsxs("li", { className: "group/item relative flex gap-3 pb-4 last:pb-0", children: [_jsxs("span", { className: "relative flex w-2 shrink-0 justify-center", children: [_jsx("span", { className: `mt-1 size-2 shrink-0 rounded-pill ${DOT_TONE[tone][surface]}` }), _jsx("span", { className: `absolute top-3 bottom-0 w-px group-last/item:hidden ${rail}` })] }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex min-w-0 flex-wrap items-baseline gap-x-3 gap-y-0.5", children: [_jsx("span", { className: `min-w-0 text-meta ${text}`, children: label }), _jsx(DateValue, { when: at, format: "exact" })] }), action === undefined ? null : _jsx("div", { className: "mt-1", children: action })] })] }));
21
+ }
22
+ /** Renders items in the order given — this kit's convention is newest first. */
23
+ export function Timeline({ children, empty, surface }) {
24
+ const activeSurface = useSurface(surface);
25
+ if (Children.toArray(children).length === 0) {
26
+ return empty === undefined ? null : (_jsx(Empty, { sentence: empty.sentence, ...(empty.action === undefined ? {} : { action: empty.action }) }));
27
+ }
28
+ return (_jsx(SurfaceProvider, { value: activeSurface, children: _jsx("ol", { className: "flex flex-col", children: children }) }));
29
+ }
30
+ Timeline.Item = Item;
@@ -0,0 +1,3 @@
1
+ export { Activity, type ActivityAlert, type ActivityEvent, type ActivityLayout, type ActivityProps, useActivity, } from "./Activity.js";
2
+ export { type Message, MessageComposer, type MessageComposerProps, type MessageKind, writeANote, } from "./Messages.js";
3
+ export { Timeline, type TimelineItemProps, type TimelineProps, } from "./Timeline.js";
@@ -0,0 +1,4 @@
1
+ /* ACTIVITY — everything around a record: its notices, its conversation and its history. */
2
+ export { Activity, useActivity, } from "./Activity.js";
3
+ export { MessageComposer, writeANote, } from "./Messages.js";
4
+ export { Timeline, } from "./Timeline.js";
@@ -0,0 +1,64 @@
1
+ import type { ActivityEvent } from "../activity/Activity.js";
2
+ import { type AssistOrigin, type AssistSource } from "./assist.js";
3
+ import type { ReactNode } from "react";
4
+ /** The robot and the assistant's name: the header of a suggestion, a review, a pending
5
+ * state. `children` replaces the name — «Asistente sugiere». */
6
+ export declare function AssistLabel({ children, id }: {
7
+ children?: ReactNode;
8
+ id?: string;
9
+ }): import("react").JSX.Element;
10
+ /**
11
+ * Where the assistant got it: «Fuente: orden de compra PO/2026/0042».
12
+ *
13
+ * Context: a value without its source is a value nobody can check, and an unchecked value
14
+ * from a machine is the one people stop trusting after the first mistake. The source is a
15
+ * LINK to the record it was read from — with `href` a real `<a>` (middle-click, copy), with
16
+ * `onOpen` a link the screen answers — so checking it is one press, not a search.
17
+ */
18
+ export declare function AssistSourceLink({ source }: {
19
+ source: AssistSource;
20
+ }): import("react").JSX.Element;
21
+ export type AssistMarkProps = {
22
+ /** When, from what, and who accepted it. Each one that is present is said in the card. */
23
+ origin?: AssistOrigin;
24
+ };
25
+ /**
26
+ * The small robot next to a value the assistant set — provenance, after the fact.
27
+ *
28
+ * Context: once a suggestion is accepted the value looks like any other, and a week later
29
+ * nobody remembers whether «30 días» was typed or proposed. The mark keeps that answer next
30
+ * to the value: its tooltip says «Lo completó el asistente», and pressing it opens WHO
31
+ * (the assistant, and the person who accepted), WHEN and FROM WHAT — with the source as a
32
+ * link. It is a popover and not a tooltip because the source is a link, and a tooltip can
33
+ * never be entered with the keyboard.
34
+ *
35
+ * Next to a field, write it in the field's `action`; next to a read value, use
36
+ * `AssistedValue`.
37
+ */
38
+ export declare function AssistMark({ origin }: AssistMarkProps): import("react").JSX.Element;
39
+ /** A read value with the assistant's mark after it: a `Record.Facts` value, a table cell. */
40
+ export declare function AssistedValue({ children, origin, }: {
41
+ /** The value, drawn the way it would be without the mark. */
42
+ children: ReactNode;
43
+ origin?: AssistOrigin;
44
+ }): import("react").JSX.Element;
45
+ /**
46
+ * The assistant's entry in a record's history: the activity's event, with the robot as its
47
+ * node, the assistant (and who accepted) as its author, and the source as its detail.
48
+ *
49
+ * Context: provenance has two places. The mark answers «where did THIS value come from»
50
+ * while looking at it; the history answers «what has the assistant done on this record»,
51
+ * in the order it happened, next to what people did. Same mark in both, so the eye learns
52
+ * it once.
53
+ *
54
+ * Call it when the change happens (in the handler), not at module load: it reads the
55
+ * installed copy, like the formatters do.
56
+ */
57
+ export declare function assistEvent({ id, label, at, source, acceptedBy, }: {
58
+ id: string;
59
+ /** What happened, in the past: «completó 5 líneas desde la orden de compra». */
60
+ label: ReactNode;
61
+ at: Date | string | number;
62
+ source?: AssistSource;
63
+ acceptedBy?: string;
64
+ }): ActivityEvent;
@@ -0,0 +1,108 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { ASSIST_ICON, } from "./assist.js";
4
+ import { currentCopy, fillCopy, useUiCopy } from "../../foundations/copy.js";
5
+ import { cn, focusRing } from "../../foundations/variants.js";
6
+ import { PopoverTrigger } from "../../primitives/overlay/PopoverTrigger.js";
7
+ import { Tooltip, TooltipTrigger } from "../../primitives/overlay/Tooltip.js";
8
+ import { DateValue } from "../../primitives/value/Fecha.js";
9
+ import { Link } from "react-aria-components";
10
+ /* ==================================================================== *
11
+ * THE ASSISTANT'S MARK — how a screen says «this came from the assistant».
12
+ *
13
+ * Three pieces, one look:
14
+ *
15
+ * AssistLabel the robot and the word «Asistente», in the info tone:
16
+ * the header of anything the assistant proposes
17
+ * AssistSourceLink «Fuente: orden de compra PO/2026/0042», a real link
18
+ * AssistMark the small robot next to a value it SET, which opens
19
+ * who, when and from what
20
+ *
21
+ * ── Why the info tone, and never the gold ───────────────────────────
22
+ *
23
+ * The gold is the ONE main action of a screen (PRINCIPLES §2–3). The assistant
24
+ * is not an action, it is a source of information — and `info` already means
25
+ * «a fact that changes how you read what is below». It is also never the color
26
+ * alone: the robot and the word are always there, so a person who does not tell
27
+ * teal from navy still reads «Asistente».
28
+ *
29
+ * ── Why a robot and not sparkles ────────────────────────────────────
30
+ *
31
+ * Sparkles celebrate; a business screen states. «An automated assistant did
32
+ * this» is the fact a person needs to weigh a value, and the robot says exactly
33
+ * that. The icon lives in `ASSIST_ICON`, so changing it is one line.
34
+ * ==================================================================== */
35
+ /** The robot and the assistant's name: the header of a suggestion, a review, a pending
36
+ * state. `children` replaces the name — «Asistente sugiere». */
37
+ export function AssistLabel({ children, id }) {
38
+ const copy = useUiCopy();
39
+ const Icon = ASSIST_ICON;
40
+ return (_jsxs("span", { id: id, "data-assist": "label", className: "inline-flex shrink-0 items-center gap-1 text-micro font-medium text-info", children: [_jsx(Icon, { className: "size-(--size-icon-sm) shrink-0", strokeWidth: 2, "aria-hidden": true }), children ?? copy.assist.assistant] }));
41
+ }
42
+ /**
43
+ * Where the assistant got it: «Fuente: orden de compra PO/2026/0042».
44
+ *
45
+ * Context: a value without its source is a value nobody can check, and an unchecked value
46
+ * from a machine is the one people stop trusting after the first mistake. The source is a
47
+ * LINK to the record it was read from — with `href` a real `<a>` (middle-click, copy), with
48
+ * `onOpen` a link the screen answers — so checking it is one press, not a search.
49
+ */
50
+ export function AssistSourceLink({ source }) {
51
+ const copy = useUiCopy();
52
+ const goes = source.href !== undefined || source.onOpen !== undefined;
53
+ return (_jsxs("span", { className: "inline-flex max-w-full min-w-0 items-baseline gap-1 text-micro text-muted", children: [_jsxs("span", { className: "shrink-0", children: [copy.assist.source, ":"] }), goes ? (_jsx(Link, { ...(source.href === undefined ? {} : { href: source.href }), ...(source.onOpen === undefined ? {} : { onPress: source.onOpen }), className: ({ isFocusVisible }) => cn("min-w-0 cursor-pointer truncate rounded-mark text-primary underline-offset-2 hover:underline", focusRing({ isFocusVisible })), children: source.label })) : (_jsx("span", { className: "min-w-0 truncate text-ink", children: source.label }))] }));
54
+ }
55
+ /** The mark's own button. It forwards `ref` and spreads native props, so `PopoverTrigger`
56
+ * anchors to it and `TooltipTrigger` names it — the same contract as `IconButton`, in the
57
+ * assistant's tone instead of the three an icon button has. */
58
+ function MarkButton({ label, expanded, haspopup, ref, ...native }) {
59
+ const Icon = ASSIST_ICON;
60
+ return (_jsxs(TooltipTrigger, { children: [_jsx("button", { ...native, ref: ref, type: "button", "aria-label": label, ...(haspopup === undefined ? {} : { "aria-haspopup": haspopup }), ...(expanded === undefined ? {} : { "aria-expanded": expanded }), "data-assist": "mark", className: "inline-flex size-(--size-control-sm) shrink-0 items-center justify-center rounded-pill text-info transition-colors duration-(--duration-instant) hover:bg-info/10 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary", children: _jsx(Icon, { className: "size-(--size-icon-sm)", strokeWidth: 2, "aria-hidden": true }) }), _jsx(Tooltip, { children: label })] }));
61
+ }
62
+ /**
63
+ * The small robot next to a value the assistant set — provenance, after the fact.
64
+ *
65
+ * Context: once a suggestion is accepted the value looks like any other, and a week later
66
+ * nobody remembers whether «30 días» was typed or proposed. The mark keeps that answer next
67
+ * to the value: its tooltip says «Lo completó el asistente», and pressing it opens WHO
68
+ * (the assistant, and the person who accepted), WHEN and FROM WHAT — with the source as a
69
+ * link. It is a popover and not a tooltip because the source is a link, and a tooltip can
70
+ * never be entered with the keyboard.
71
+ *
72
+ * Next to a field, write it in the field's `action`; next to a read value, use
73
+ * `AssistedValue`.
74
+ */
75
+ export function AssistMark({ origin = {} }) {
76
+ const copy = useUiCopy();
77
+ return (_jsx(PopoverTrigger, { title: copy.assist.madeBy, placement: "bottom end", trigger: _jsx(MarkButton, { label: copy.assist.madeBy }), children: _jsxs("div", { className: "flex max-w-72 min-w-0 flex-col gap-1.5 text-micro text-muted", children: [origin.source === undefined ? null : _jsx(AssistSourceLink, { source: origin.source }), origin.at === undefined ? null : _jsx(DateValue, { when: origin.at, format: "exact" }), origin.acceptedBy === undefined ? null : (_jsx("span", { children: fillCopy(copy.assist.acceptedBy, { name: origin.acceptedBy }) }))] }) }));
78
+ }
79
+ /** A read value with the assistant's mark after it: a `Record.Facts` value, a table cell. */
80
+ export function AssistedValue({ children, origin, }) {
81
+ return (_jsxs("span", { className: "inline-flex max-w-full min-w-0 items-center gap-0.5", children: [_jsx("span", { className: "min-w-0 truncate", children: children }), _jsx(AssistMark, { ...(origin === undefined ? {} : { origin }) })] }));
82
+ }
83
+ /**
84
+ * The assistant's entry in a record's history: the activity's event, with the robot as its
85
+ * node, the assistant (and who accepted) as its author, and the source as its detail.
86
+ *
87
+ * Context: provenance has two places. The mark answers «where did THIS value come from»
88
+ * while looking at it; the history answers «what has the assistant done on this record»,
89
+ * in the order it happened, next to what people did. Same mark in both, so the eye learns
90
+ * it once.
91
+ *
92
+ * Call it when the change happens (in the handler), not at module load: it reads the
93
+ * installed copy, like the formatters do.
94
+ */
95
+ export function assistEvent({ id, label, at, source, acceptedBy, }) {
96
+ const copy = currentCopy();
97
+ const by = acceptedBy === undefined
98
+ ? copy.assist.assistant
99
+ : `${copy.assist.assistant} · ${fillCopy(copy.assist.acceptedBy, { name: acceptedBy })}`;
100
+ return {
101
+ id,
102
+ label,
103
+ at,
104
+ by,
105
+ icon: ASSIST_ICON,
106
+ ...(source === undefined ? {} : { detail: _jsx(AssistSourceLink, { source: source }) }),
107
+ };
108
+ }
@@ -0,0 +1,24 @@
1
+ export type AssistPendingProps = {
2
+ /** What the assistant is doing, in the screen's words: «Leyendo la orden de compra
3
+ * PO/2026/0042…». The copy's «El asistente está trabajando…» when absent. */
4
+ label?: string;
5
+ /** Stops it. Present = a «Cancelar» next to the sentence. */
6
+ onCancel?: () => void;
7
+ /** Skeleton bars under the sentence, standing in for the proposal that is coming —
8
+ * `0` (the default) is the one-line form, for under a field. */
9
+ rows?: number;
10
+ };
11
+ /**
12
+ * The assistant is working on a suggestion, and the screen goes on.
13
+ *
14
+ * Context: the assistant is slower than a form, and a screen that locks while it thinks
15
+ * teaches people to wait for it — or to close it. So this BLOCKS NOTHING: it is a line in
16
+ * the place where the suggestion will appear (under a field, above the lines), the fields
17
+ * stay editable, and «Cancelar» stops it. What the person types in the meantime wins; the
18
+ * screen decides whether a suggestion that arrives late still makes sense.
19
+ *
20
+ * The sentence is a polite live region (`role="status"`), so a screen reader hears that
21
+ * the assistant started without being interrupted; the bars are silent. The spinner and
22
+ * the bars' pulse stop under reduced motion, by the global rule in `tokens.css`.
23
+ */
24
+ export declare function AssistPending({ label, onCancel, rows }: AssistPendingProps): import("react").JSX.Element;
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { AssistLabel } from "./AssistMark.js";
4
+ import { useUiCopy } from "../../foundations/copy.js";
5
+ import { Button } from "../../primitives/button/Button.js";
6
+ import { LoaderCircle } from "lucide-react";
7
+ /** The widths of the skeleton's bars: uneven, so it reads as lines of content and not as
8
+ * a striped box. */
9
+ const BAR = ["w-2/3", "w-1/2", "w-3/4", "w-2/5"];
10
+ /**
11
+ * The assistant is working on a suggestion, and the screen goes on.
12
+ *
13
+ * Context: the assistant is slower than a form, and a screen that locks while it thinks
14
+ * teaches people to wait for it — or to close it. So this BLOCKS NOTHING: it is a line in
15
+ * the place where the suggestion will appear (under a field, above the lines), the fields
16
+ * stay editable, and «Cancelar» stops it. What the person types in the meantime wins; the
17
+ * screen decides whether a suggestion that arrives late still makes sense.
18
+ *
19
+ * The sentence is a polite live region (`role="status"`), so a screen reader hears that
20
+ * the assistant started without being interrupted; the bars are silent. The spinner and
21
+ * the bars' pulse stop under reduced motion, by the global rule in `tokens.css`.
22
+ */
23
+ export function AssistPending({ label, onCancel, rows = 0 }) {
24
+ const copy = useUiCopy();
25
+ return (_jsxs("div", { "data-assist": "pending", "aria-busy": "true", className: "flex min-w-0 flex-col gap-2", children: [_jsxs("span", { className: "flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1", children: [_jsx(LoaderCircle, { className: "size-(--size-icon-sm) shrink-0 animate-spin text-info", strokeWidth: 2, "aria-hidden": true }), _jsx(AssistLabel, {}), _jsx("span", { role: "status", className: "min-w-0 text-micro text-muted", children: label ?? copy.assist.working }), onCancel === undefined ? null : (_jsx(Button, { role: "ghost", size: "sm", onClick: onCancel, children: copy.assist.cancel }))] }), rows <= 0 ? null : (_jsx("span", { "aria-hidden": true, className: "flex flex-col gap-2 pl-5", children: Array.from({ length: rows }, (_, i) => (_jsx("span", { className: `h-3 rounded-control bg-ink/8 motion-safe:animate-pulse ${BAR[i % BAR.length]}` }, i))) }))] }));
26
+ }
@@ -0,0 +1,42 @@
1
+ import { type AssistApply, type AssistSource } from "./assist.js";
2
+ import { type ReactNode } from "react";
3
+ export type AssistSuggestionProps = {
4
+ /** The proposed value, drawn as it will read once applied: «30 días», «15/11/2026», a
5
+ * product with its code. */
6
+ value: ReactNode;
7
+ /** Where the assistant got it — a link to the record it read. */
8
+ source?: AssistSource;
9
+ /** Applies the value. Return the function that reverts it and the screen gets a
10
+ * «Deshacer» notice; the suggestion itself is the screen's to remove. */
11
+ onAccept: AssistApply;
12
+ /** «No, gracias»: the screen forgets the suggestion. */
13
+ onDismiss: () => void;
14
+ /** The field's name, for the notice after accepting. Inside a `Field` the accessible
15
+ * name already takes the field's label; the notice is read elsewhere, so it needs it. */
16
+ field?: string;
17
+ };
18
+ /**
19
+ * The assistant proposes a value for ONE field: the customer's payment term, the product of
20
+ * a scanned line, the due date. It goes right under the control it would change.
21
+ *
22
+ * Context: a suggestion has to be noticed and must not be mistaken for the value. So it is
23
+ * NOT written into the control — a pre-filled field reads as «someone already decided» and
24
+ * gets saved without a look. It sits under the control, in a dashed box (dashed: proposed,
25
+ * not yet real), with the robot and «Asistente sugiere», the value, and its source as a
26
+ * link. «Aceptar» applies it at once, and the notice carries «Deshacer» — undo over
27
+ * confirm, the system's rule. The × forgets it.
28
+ *
29
+ * Written inside a `Field`, after the control:
30
+ *
31
+ * <Field label="Plazo de pago">
32
+ * <NumberInput … />
33
+ * <AssistSuggestion value="30 días" source={…} onAccept={…} onDismiss={…} />
34
+ * </Field>
35
+ *
36
+ * It is a group named «Sugerencia del asistente» + the field's label, so a screen reader
37
+ * hears which field it is about before the value. Both buttons are plain buttons: Tab
38
+ * reaches them, Enter and Space press them. After pressing either, the focus goes back to
39
+ * the field's control — the suggestion that held it is gone, and the control is what the
40
+ * person was working on.
41
+ */
42
+ export declare function AssistSuggestion({ value, source, onAccept, onDismiss, field, }: AssistSuggestionProps): import("react").JSX.Element;
@@ -0,0 +1,55 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { acceptedMessage, applyWithUndo, } from "./assist.js";
4
+ import { AssistLabel, AssistSourceLink } from "./AssistMark.js";
5
+ import { useUiCopy } from "../../foundations/copy.js";
6
+ import { Button, IconButton } from "../../primitives/button/Button.js";
7
+ import { FieldIdsContext } from "../../primitives/field/context.js";
8
+ import { useToastIfAny } from "../../primitives/notice/Toast.js";
9
+ import { Check, X } from "lucide-react";
10
+ import { useContext, useId } from "react";
11
+ /**
12
+ * The assistant proposes a value for ONE field: the customer's payment term, the product of
13
+ * a scanned line, the due date. It goes right under the control it would change.
14
+ *
15
+ * Context: a suggestion has to be noticed and must not be mistaken for the value. So it is
16
+ * NOT written into the control — a pre-filled field reads as «someone already decided» and
17
+ * gets saved without a look. It sits under the control, in a dashed box (dashed: proposed,
18
+ * not yet real), with the robot and «Asistente sugiere», the value, and its source as a
19
+ * link. «Aceptar» applies it at once, and the notice carries «Deshacer» — undo over
20
+ * confirm, the system's rule. The × forgets it.
21
+ *
22
+ * Written inside a `Field`, after the control:
23
+ *
24
+ * <Field label="Plazo de pago">
25
+ * <NumberInput … />
26
+ * <AssistSuggestion value="30 días" source={…} onAccept={…} onDismiss={…} />
27
+ * </Field>
28
+ *
29
+ * It is a group named «Sugerencia del asistente» + the field's label, so a screen reader
30
+ * hears which field it is about before the value. Both buttons are plain buttons: Tab
31
+ * reaches them, Enter and Space press them. After pressing either, the focus goes back to
32
+ * the field's control — the suggestion that held it is gone, and the control is what the
33
+ * person was working on.
34
+ */
35
+ export function AssistSuggestion({ value, source, onAccept, onDismiss, field, }) {
36
+ const copy = useUiCopy();
37
+ const toasts = useToastIfAny();
38
+ const ids = useContext(FieldIdsContext);
39
+ const nameId = useId();
40
+ /* Back to the control once this box is gone. A frame later: the screen removes the
41
+ suggestion in the same update, and the control is only focusable after it. */
42
+ const refocus = () => {
43
+ const target = ids?.id;
44
+ if (target === undefined || typeof document === "undefined")
45
+ return;
46
+ requestAnimationFrame(() => document.getElementById(target)?.focus());
47
+ };
48
+ return (_jsxs("div", { role: "group", "aria-labelledby": ids === null ? nameId : `${nameId} ${ids.labelId}`, "data-assist": "suggestion", className: "flex min-w-0 flex-wrap items-center gap-x-3 gap-y-1.5 rounded-control border border-dashed border-info/40 bg-info/5 py-1 pr-1 pl-2.5", children: [_jsx("span", { id: nameId, hidden: true, children: copy.assist.suggestion }), _jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5 py-0.5", children: [_jsxs("span", { className: "flex min-w-0 flex-wrap items-baseline gap-x-1.5", children: [_jsxs(AssistLabel, { children: [copy.assist.assistant, " ", copy.assist.suggests] }), _jsx("span", { className: "min-w-0 text-meta font-semibold text-ink tabular-nums", children: value })] }), source === undefined ? null : _jsx(AssistSourceLink, { source: source })] }), _jsxs("span", { className: "flex shrink-0 items-center gap-0.5", children: [_jsx(Button, { role: "secondary", size: "sm", icon: Check, onClick: () => {
49
+ applyWithUndo(onAccept, toasts, acceptedMessage(copy, field), copy.assist.undo);
50
+ refocus();
51
+ }, children: copy.assist.accept }), _jsx(IconButton, { icon: X, label: copy.assist.dismiss, onClick: () => {
52
+ onDismiss();
53
+ refocus();
54
+ } })] })] }));
55
+ }
@@ -0,0 +1,56 @@
1
+ import { type AssistApply, type AssistSource, type ProposedChange } from "./assist.js";
2
+ import { type DialogContext } from "../../primitives/dialog/Dialog.js";
3
+ import { type ReactNode } from "react";
4
+ type GroupProps = {
5
+ /** «Campos», «Líneas». Without it the changes are listed without a heading. */
6
+ title?: string;
7
+ children?: ReactNode;
8
+ };
9
+ type ReviewProps = {
10
+ /** What the proposal is, as a heading. The copy's «Cambios propuestos» when absent. */
11
+ title?: string;
12
+ /** One sentence under the title: what the assistant read and what it would do. */
13
+ summary?: string;
14
+ /** Where the whole proposal comes from. A change may carry its own. */
15
+ source?: AssistSource;
16
+ /** Applies the chosen changes — their ids, in the listed order. Return the function that
17
+ * reverts them, and the screen gets «Deshacer». */
18
+ onApply: AssistApply<[ids: string[]]>;
19
+ /** Rejects the proposal. */
20
+ onDiscard: () => void;
21
+ /** The chosen ids, controlled. Uncontrolled from «all but the `unchosen` ones». */
22
+ chosen?: readonly string[];
23
+ onChosenChange?: (ids: string[]) => void;
24
+ /** `ChangeReview.Group` and `ChangeReview.Change`. */
25
+ children?: ReactNode;
26
+ };
27
+ export type ChangeReviewProps = ReviewProps & {
28
+ /** The role of «Aplicar». `primary` by default; `secondary` inside a record whose rail
29
+ * already shows the screen's one primary. */
30
+ emphasis?: "primary" | "secondary";
31
+ };
32
+ /** The review inside the page: a dashed card in the record it would change. */
33
+ export declare function ChangeReview(props: ChangeReviewProps): import("react").JSX.Element;
34
+ export declare namespace ChangeReview {
35
+ var Group: ((props: GroupProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"group">;
36
+ var Change: ((props: ProposedChange) => ReactNode) & import("../../foundations/slots.js").Slotted<"change">;
37
+ }
38
+ export type ChangeReviewDialogProps = ReviewProps & {
39
+ open: boolean;
40
+ /** Every way out ends here: ×, Escape, the scrim — «later», the proposal stays — and
41
+ * also after «Aplicar» and «Descartar». */
42
+ onClose: () => void;
43
+ /** What the dialog is about, in its header: «factura · FAC/2026/0120». */
44
+ context?: DialogContext;
45
+ };
46
+ /**
47
+ * The same review, in a `Dialog`: opened on demand — from a notice that says «el asistente
48
+ * encontró la orden de compra» — and a bottom sheet on a phone. «Aplicar» is the dialog's
49
+ * primary; closing without choosing keeps the proposal for later.
50
+ */
51
+ export declare function ChangeReviewDialog(props: ChangeReviewDialogProps): import("react").JSX.Element;
52
+ export declare namespace ChangeReviewDialog {
53
+ var Group: ((props: GroupProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"group">;
54
+ var Change: ((props: ProposedChange) => ReactNode) & import("../../foundations/slots.js").Slotted<"change">;
55
+ }
56
+ export {};
@@ -0,0 +1,121 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { appliedMessage, applyLabel, applyWithUndo, changeKind, chosenState, initiallyChosen, toggleChosen, } from "./assist.js";
4
+ import { AssistLabel, AssistSourceLink } from "./AssistMark.js";
5
+ import { fillCopy, useUiCopy } from "../../foundations/copy.js";
6
+ import { flatten, propsOf, slot, slotOf } from "../../foundations/slots.js";
7
+ import { Button } from "../../primitives/button/Button.js";
8
+ import { Dialog } from "../../primitives/dialog/Dialog.js";
9
+ import { Checkbox } from "../../primitives/field/Checks.js";
10
+ import { useToastIfAny } from "../../primitives/notice/Toast.js";
11
+ import { Tag } from "../../primitives/tag/Tag.js";
12
+ import { ArrowRight } from "lucide-react";
13
+ import { useId, useState } from "react";
14
+ const Group = slot("group", (_props) => null);
15
+ const Change = slot("change", (_props) => null);
16
+ /** The groups as written. Changes written outside a group form an untitled one in their
17
+ * place, so a short review is just its changes. */
18
+ function readTree(children) {
19
+ const out = [];
20
+ let loose = null;
21
+ for (const node of flatten(children)) {
22
+ const name = slotOf(node);
23
+ if (name === "group") {
24
+ loose = null;
25
+ const props = propsOf(node);
26
+ out.push({
27
+ ...(props.title === undefined ? {} : { title: props.title }),
28
+ changes: flatten(props.children)
29
+ .filter((one) => slotOf(one) === "change")
30
+ .map((one) => propsOf(one)),
31
+ });
32
+ }
33
+ else if (name === "change") {
34
+ if (loose === null) {
35
+ loose = { changes: [] };
36
+ out.push(loose);
37
+ }
38
+ loose.changes.push(propsOf(node));
39
+ }
40
+ }
41
+ return out;
42
+ }
43
+ /** What both faces share: the tree read once, the chosen ids, and «apply». */
44
+ function useReview({ children, chosen, onChosenChange, onApply }) {
45
+ const copy = useUiCopy();
46
+ const toasts = useToastIfAny();
47
+ const groups = readTree(children);
48
+ const all = groups.flatMap((g) => g.changes);
49
+ const order = all.map((c) => c.id);
50
+ const [own, setOwn] = useState(() => initiallyChosen(all));
51
+ const current = chosen === undefined ? own : order.filter((id) => chosen.includes(id));
52
+ const choose = (next) => {
53
+ if (chosen === undefined)
54
+ setOwn(next);
55
+ onChosenChange?.(next);
56
+ };
57
+ const apply = () => {
58
+ const ids = current;
59
+ applyWithUndo(() => onApply(ids), toasts, appliedMessage(copy, ids.length), copy.assist.undo);
60
+ };
61
+ return { groups, order, current, choose, apply };
62
+ }
63
+ /** One change: its check (named by its label), the kind in words, and before → after. */
64
+ function ChangeRow({ change, on, onToggle, }) {
65
+ const copy = useUiCopy();
66
+ const valuesId = useId();
67
+ const kind = changeKind(change);
68
+ const word = {
69
+ add: copy.assist.added,
70
+ remove: copy.assist.removed,
71
+ change: copy.assist.changed,
72
+ }[kind];
73
+ const empty = _jsx("span", { className: "text-muted italic", children: copy.assist.empty });
74
+ const before = change.before === null ? empty : change.before;
75
+ return (_jsxs("li", { "data-change": kind, className: "flex min-w-0 flex-col gap-1 border-b border-line px-4 py-2.5 last:border-b-0 @lg:flex-row @lg:items-start @lg:gap-4", children: [_jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [_jsxs("span", { className: "flex min-w-0 flex-wrap items-center gap-2", children: [_jsx(Checkbox, { checked: on, onChange: onToggle, label: change.label, describedBy: valuesId }), _jsx(Tag, { children: word })] }), change.detail === undefined ? null : (_jsx("span", { className: "pl-6.5 text-micro text-muted", children: change.detail })), change.source === undefined ? null : (_jsx("span", { className: "pl-6.5", children: _jsx(AssistSourceLink, { source: change.source }) }))] }), _jsxs("span", { id: valuesId, className: "flex min-w-0 flex-wrap items-baseline gap-x-1.5 pl-6.5 text-meta tabular-nums @lg:w-2/5 @lg:shrink-0 @lg:justify-end @lg:pl-0 @lg:text-right", children: [kind === "add" ? null : (_jsxs(_Fragment, { children: [_jsxs("span", { className: "sr-only", children: [copy.assist.from, " "] }), _jsx("span", { className: `text-muted ${kind === "remove" ? "line-through" : ""}`, children: before })] })), kind === "remove" ? null : (_jsxs(_Fragment, { children: [kind === "add" ? null : (_jsx(ArrowRight, { className: "size-(--size-icon-sm) shrink-0 self-center text-muted", strokeWidth: 2, "aria-hidden": true })), _jsxs("span", { className: "sr-only", children: [copy.assist.to, " "] }), _jsx("span", { className: "font-medium text-ink", children: change.after })] }))] })] }));
76
+ }
77
+ /** «Todos los cambios», the count, and the groups. */
78
+ function ReviewBody({ review }) {
79
+ const copy = useUiCopy();
80
+ const { groups, order, current, choose } = review;
81
+ const state = chosenState(order, current);
82
+ return (_jsxs("div", { className: "@container flex min-w-0 flex-col", children: [_jsxs("div", { className: "flex min-w-0 flex-wrap items-center justify-between gap-x-3 gap-y-1 border-b border-line px-4 py-2", children: [_jsx(Checkbox, { checked: state === "all", mixed: state === "some", label: copy.assist.all, onChange: (on) => choose(on ? [...order] : []) }), _jsx("span", { className: "text-micro text-muted tabular-nums", children: fillCopy(copy.assist.chosen, { count: current.length, total: order.length }) })] }), groups.map((group, i) => (_jsxs("section", { className: "flex min-w-0 flex-col", children: [group.title === undefined ? null : (_jsx("h4", { className: "px-4 pt-3 pb-1 text-micro font-medium text-muted", children: group.title })), _jsx("ul", { className: "flex min-w-0 flex-col", children: group.changes.map((change) => (_jsx(ChangeRow, { change: change, on: current.includes(change.id), onToggle: (on) => choose(toggleChosen(order, current, change.id, on)) }, change.id))) })] }, group.title ?? i)))] }));
83
+ }
84
+ /** «Elegí al menos un cambio.», «Descartar» and «Aplicar N cambios». */
85
+ function ReviewActions({ review, emphasis, onDiscard, after, }) {
86
+ const copy = useUiCopy();
87
+ const count = review.current.length;
88
+ return (_jsxs(_Fragment, { children: [count > 0 ? null : (
89
+ /* The reason next to the disabled button: a grey «Aplicar» with no explanation is a
90
+ dead end (the same rule as the wizard's «siguiente»). */
91
+ _jsx("span", { className: "mr-auto min-w-0 text-micro text-warn", children: copy.assist.noneChosen })), _jsx(Button, { role: "ghost", size: "sm", onClick: () => {
92
+ onDiscard();
93
+ after?.();
94
+ }, children: copy.assist.discard }), _jsx(Button, { role: emphasis, size: "sm", disabled: count === 0, onClick: () => {
95
+ review.apply();
96
+ after?.();
97
+ }, children: applyLabel(copy, count) })] }));
98
+ }
99
+ /** The review inside the page: a dashed card in the record it would change. */
100
+ export function ChangeReview(props) {
101
+ const { title, summary, source, onDiscard, emphasis = "primary" } = props;
102
+ const copy = useUiCopy();
103
+ const review = useReview(props);
104
+ const titleId = useId();
105
+ return (_jsxs("section", { "aria-labelledby": titleId, "data-assist": "review", className: "flex min-w-0 flex-col overflow-clip rounded-box border border-dashed border-info/40 bg-surface", children: [_jsxs("header", { className: "flex min-w-0 flex-col gap-1 border-b border-line px-4 py-3", children: [_jsxs("span", { className: "flex min-w-0 flex-wrap items-baseline gap-x-3 gap-y-1", children: [_jsx(AssistLabel, {}), source === undefined ? null : _jsx(AssistSourceLink, { source: source })] }), _jsx("h3", { id: titleId, className: "text-lead font-semibold text-ink", children: title ?? copy.assist.review }), summary === undefined ? null : (_jsx("p", { className: "max-w-prose text-meta text-muted", children: summary }))] }), _jsx(ReviewBody, { review: review }), _jsx("footer", { className: "flex min-w-0 flex-wrap items-center justify-end gap-2 border-t border-line bg-ground px-4 py-2.5", children: _jsx(ReviewActions, { review: review, emphasis: emphasis, onDiscard: onDiscard }) })] }));
106
+ }
107
+ ChangeReview.Group = Group;
108
+ ChangeReview.Change = Change;
109
+ /**
110
+ * The same review, in a `Dialog`: opened on demand — from a notice that says «el asistente
111
+ * encontró la orden de compra» — and a bottom sheet on a phone. «Aplicar» is the dialog's
112
+ * primary; closing without choosing keeps the proposal for later.
113
+ */
114
+ export function ChangeReviewDialog(props) {
115
+ const { open, onClose, context, title, summary, source, onDiscard } = props;
116
+ const copy = useUiCopy();
117
+ const review = useReview(props);
118
+ return (_jsx(Dialog, { open: open, onClose: onClose, title: title ?? copy.assist.review, ...(summary === undefined ? {} : { subtitle: summary }), ...(context === undefined ? {} : { context }), footer: _jsx(ReviewActions, { review: review, emphasis: "primary", onDiscard: onDiscard, after: onClose }), children: _jsxs("div", { className: "-mx-4 -my-4 flex min-w-0 flex-col", children: [_jsxs("span", { className: "flex min-w-0 flex-wrap items-baseline gap-x-3 gap-y-1 border-b border-line px-4 py-2.5", children: [_jsx(AssistLabel, {}), source === undefined ? null : _jsx(AssistSourceLink, { source: source })] }), _jsx(ReviewBody, { review: review })] }) }));
119
+ }
120
+ ChangeReviewDialog.Group = Group;
121
+ ChangeReviewDialog.Change = Change;