@happyvertical/smrt-svelte 0.55.6 → 0.55.8

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 (318) hide show
  1. package/AGENTS.md +9 -31
  2. package/README.md +195 -5
  3. package/agents/browser-ai.md +47 -0
  4. package/agents/command-palette.md +85 -0
  5. package/agents/import-export.md +62 -0
  6. package/agents/overview-surfaces.md +255 -0
  7. package/agents/screens.md +57 -0
  8. package/agents/workspace.md +202 -5
  9. package/dist/browser-ai/adapters/stt/dictation-source.d.ts.map +1 -1
  10. package/dist/browser-ai/adapters/stt/dictation-source.js +8 -2
  11. package/dist/browser-ai/adapters/stt/factory.d.ts +6 -3
  12. package/dist/browser-ai/adapters/stt/factory.d.ts.map +1 -1
  13. package/dist/browser-ai/adapters/stt/factory.js +19 -9
  14. package/dist/browser-ai/adapters/stt/index.d.ts +3 -1
  15. package/dist/browser-ai/adapters/stt/index.d.ts.map +1 -1
  16. package/dist/browser-ai/adapters/stt/index.js +3 -1
  17. package/dist/browser-ai/adapters/stt/local-speech-model.d.ts +111 -0
  18. package/dist/browser-ai/adapters/stt/local-speech-model.d.ts.map +1 -0
  19. package/dist/browser-ai/adapters/stt/local-speech-model.js +377 -0
  20. package/dist/browser-ai/adapters/stt/local-speech.d.ts +82 -0
  21. package/dist/browser-ai/adapters/stt/local-speech.d.ts.map +1 -0
  22. package/dist/browser-ai/adapters/stt/local-speech.js +317 -0
  23. package/dist/browser-ai/adapters/stt/local-speech.worker.d.ts +2 -0
  24. package/dist/browser-ai/adapters/stt/local-speech.worker.d.ts.map +1 -0
  25. package/dist/browser-ai/adapters/stt/local-speech.worker.js +32 -0
  26. package/dist/browser-ai/adapters/stt/transformers-env.d.ts +8 -0
  27. package/dist/browser-ai/adapters/stt/transformers-env.d.ts.map +1 -0
  28. package/dist/browser-ai/adapters/stt/transformers-env.js +17 -0
  29. package/dist/browser-ai/adapters/stt/types.d.ts +54 -9
  30. package/dist/browser-ai/adapters/stt/types.d.ts.map +1 -1
  31. package/dist/browser-ai/adapters/tts/browser-synthesis.d.ts +5 -0
  32. package/dist/browser-ai/adapters/tts/browser-synthesis.d.ts.map +1 -1
  33. package/dist/browser-ai/adapters/tts/browser-synthesis.js +83 -55
  34. package/dist/browser-ai/capabilities/speech-probe.d.ts +29 -0
  35. package/dist/browser-ai/capabilities/speech-probe.d.ts.map +1 -0
  36. package/dist/browser-ai/capabilities/speech-probe.js +19 -0
  37. package/dist/browser-ai/core/errors.d.ts +9 -0
  38. package/dist/browser-ai/core/errors.d.ts.map +1 -1
  39. package/dist/browser-ai/core/errors.js +12 -0
  40. package/dist/browser-ai/index.d.ts +1 -0
  41. package/dist/browser-ai/index.d.ts.map +1 -1
  42. package/dist/browser-ai/index.js +1 -0
  43. package/dist/components/app/AppShell.svelte +587 -33
  44. package/dist/components/app/AppShell.svelte.d.ts +75 -4
  45. package/dist/components/app/AppShell.svelte.d.ts.map +1 -1
  46. package/dist/components/app/DockToggles.svelte +0 -1
  47. package/dist/components/app/dock-toggle.d.ts +7 -1
  48. package/dist/components/app/dock-toggle.d.ts.map +1 -1
  49. package/dist/components/app/index.d.ts +2 -1
  50. package/dist/components/app/index.d.ts.map +1 -1
  51. package/dist/components/app/slot-item.d.ts +21 -0
  52. package/dist/components/app/slot-item.d.ts.map +1 -0
  53. package/dist/components/app/slot-item.js +1 -0
  54. package/dist/components/command-palette/CommandPalette.svelte +75 -0
  55. package/dist/components/command-palette/CommandPalette.svelte.d.ts +22 -0
  56. package/dist/components/command-palette/CommandPalette.svelte.d.ts.map +1 -0
  57. package/dist/components/command-palette/CommandPaletteDialog.svelte +406 -0
  58. package/dist/components/command-palette/CommandPaletteDialog.svelte.d.ts +18 -0
  59. package/dist/components/command-palette/CommandPaletteDialog.svelte.d.ts.map +1 -0
  60. package/dist/components/command-palette/CommandPaletteTrigger.svelte +91 -0
  61. package/dist/components/command-palette/CommandPaletteTrigger.svelte.d.ts +17 -0
  62. package/dist/components/command-palette/CommandPaletteTrigger.svelte.d.ts.map +1 -0
  63. package/dist/components/command-palette/context.d.ts +18 -0
  64. package/dist/components/command-palette/context.d.ts.map +1 -0
  65. package/dist/components/command-palette/context.js +38 -0
  66. package/dist/components/command-palette/controller.svelte.d.ts +70 -0
  67. package/dist/components/command-palette/controller.svelte.d.ts.map +1 -0
  68. package/dist/components/command-palette/controller.svelte.js +379 -0
  69. package/dist/components/command-palette/hotkeys.d.ts +30 -0
  70. package/dist/components/command-palette/hotkeys.d.ts.map +1 -0
  71. package/dist/components/command-palette/hotkeys.js +161 -0
  72. package/dist/components/command-palette/index.d.ts +19 -0
  73. package/dist/components/command-palette/index.d.ts.map +1 -0
  74. package/dist/components/command-palette/index.js +17 -0
  75. package/dist/components/command-palette/match.d.ts +38 -0
  76. package/dist/components/command-palette/match.d.ts.map +1 -0
  77. package/dist/components/command-palette/match.js +172 -0
  78. package/dist/components/command-palette/providers.d.ts +159 -0
  79. package/dist/components/command-palette/providers.d.ts.map +1 -0
  80. package/dist/components/command-palette/providers.js +345 -0
  81. package/dist/components/command-palette/rank.d.ts +20 -0
  82. package/dist/components/command-palette/rank.d.ts.map +1 -0
  83. package/dist/components/command-palette/rank.js +74 -0
  84. package/dist/components/command-palette/types.d.ts +119 -0
  85. package/dist/components/command-palette/types.d.ts.map +1 -0
  86. package/dist/components/command-palette/types.js +10 -0
  87. package/dist/components/command-palette/use-provider.svelte.d.ts +14 -0
  88. package/dist/components/command-palette/use-provider.svelte.d.ts.map +1 -0
  89. package/dist/components/command-palette/use-provider.svelte.js +23 -0
  90. package/dist/components/forms/AddressInput.svelte +2 -15
  91. package/dist/components/forms/AddressInput.svelte.d.ts.map +1 -1
  92. package/dist/components/forms/DateRangeInput.svelte +2 -15
  93. package/dist/components/forms/DateRangeInput.svelte.d.ts.map +1 -1
  94. package/dist/components/forms/DateTimeInput.svelte +8 -15
  95. package/dist/components/forms/DateTimeInput.svelte.d.ts.map +1 -1
  96. package/dist/components/forms/MeasurementInput.svelte +2 -15
  97. package/dist/components/forms/MeasurementInput.svelte.d.ts.map +1 -1
  98. package/dist/components/forms/MoneyInput.svelte +8 -25
  99. package/dist/components/forms/MoneyInput.svelte.d.ts.map +1 -1
  100. package/dist/components/forms/NumberInput.svelte +7 -15
  101. package/dist/components/forms/NumberInput.svelte.d.ts.map +1 -1
  102. package/dist/components/forms/PhoneInput.svelte +7 -15
  103. package/dist/components/forms/PhoneInput.svelte.d.ts.map +1 -1
  104. package/dist/components/forms/SelectInput.svelte +34 -40
  105. package/dist/components/forms/SelectInput.svelte.d.ts.map +1 -1
  106. package/dist/components/forms/TextInput.svelte +20 -37
  107. package/dist/components/forms/TextInput.svelte.d.ts.map +1 -1
  108. package/dist/components/forms/TextareaInput.svelte +19 -35
  109. package/dist/components/forms/TextareaInput.svelte.d.ts.map +1 -1
  110. package/dist/components/import-export/ImportExport.svelte +678 -0
  111. package/dist/components/import-export/ImportExport.svelte.d.ts +5 -0
  112. package/dist/components/import-export/ImportExport.svelte.d.ts.map +1 -0
  113. package/dist/components/import-export/collection-adapter.d.ts +35 -0
  114. package/dist/components/import-export/collection-adapter.d.ts.map +1 -0
  115. package/dist/components/import-export/collection-adapter.js +42 -0
  116. package/dist/components/import-export/csv.d.ts +60 -0
  117. package/dist/components/import-export/csv.d.ts.map +1 -0
  118. package/dist/components/import-export/csv.js +192 -0
  119. package/dist/components/import-export/download.d.ts +4 -0
  120. package/dist/components/import-export/download.d.ts.map +1 -0
  121. package/dist/components/import-export/download.js +17 -0
  122. package/dist/components/import-export/export.d.ts +25 -0
  123. package/dist/components/import-export/export.d.ts.map +1 -0
  124. package/dist/components/import-export/export.js +68 -0
  125. package/dist/components/import-export/fields.d.ts +48 -0
  126. package/dist/components/import-export/fields.d.ts.map +1 -0
  127. package/dist/components/import-export/fields.js +103 -0
  128. package/dist/components/import-export/index.d.ts +12 -0
  129. package/dist/components/import-export/index.d.ts.map +1 -0
  130. package/dist/components/import-export/index.js +9 -0
  131. package/dist/components/import-export/mapping.d.ts +12 -0
  132. package/dist/components/import-export/mapping.d.ts.map +1 -0
  133. package/dist/components/import-export/mapping.js +38 -0
  134. package/dist/components/import-export/props.d.ts +34 -0
  135. package/dist/components/import-export/props.d.ts.map +1 -0
  136. package/dist/components/import-export/props.js +1 -0
  137. package/dist/components/import-export/report.d.ts +13 -0
  138. package/dist/components/import-export/report.d.ts.map +1 -0
  139. package/dist/components/import-export/report.js +50 -0
  140. package/dist/components/import-export/runner.d.ts +17 -0
  141. package/dist/components/import-export/runner.d.ts.map +1 -0
  142. package/dist/components/import-export/runner.js +39 -0
  143. package/dist/components/import-export/types.d.ts +100 -0
  144. package/dist/components/import-export/types.d.ts.map +1 -0
  145. package/dist/components/import-export/types.js +6 -0
  146. package/dist/components/import-export/validate.d.ts +39 -0
  147. package/dist/components/import-export/validate.d.ts.map +1 -0
  148. package/dist/components/import-export/validate.js +268 -0
  149. package/dist/components/overview/OverviewGrid.svelte +579 -0
  150. package/dist/components/overview/OverviewGrid.svelte.d.ts +5 -0
  151. package/dist/components/overview/OverviewGrid.svelte.d.ts.map +1 -0
  152. package/dist/components/overview/WidgetOptionsForm.svelte +193 -0
  153. package/dist/components/overview/WidgetOptionsForm.svelte.d.ts +5 -0
  154. package/dist/components/overview/WidgetOptionsForm.svelte.d.ts.map +1 -0
  155. package/dist/components/overview/controller.svelte.d.ts +92 -0
  156. package/dist/components/overview/controller.svelte.d.ts.map +1 -0
  157. package/dist/components/overview/controller.svelte.js +336 -0
  158. package/dist/components/overview/format.d.ts +13 -0
  159. package/dist/components/overview/format.d.ts.map +1 -0
  160. package/dist/components/overview/format.js +45 -0
  161. package/dist/components/overview/grid-types.d.ts +52 -0
  162. package/dist/components/overview/grid-types.d.ts.map +1 -0
  163. package/dist/components/overview/grid-types.js +1 -0
  164. package/dist/components/overview/index.d.ts +24 -0
  165. package/dist/components/overview/index.d.ts.map +1 -0
  166. package/dist/components/overview/index.js +22 -0
  167. package/dist/components/overview/load.d.ts +30 -0
  168. package/dist/components/overview/load.d.ts.map +1 -0
  169. package/dist/components/overview/load.js +92 -0
  170. package/dist/components/overview/markdown.d.ts +53 -0
  171. package/dist/components/overview/markdown.d.ts.map +1 -0
  172. package/dist/components/overview/markdown.js +203 -0
  173. package/dist/components/overview/model.d.ts +100 -0
  174. package/dist/components/overview/model.d.ts.map +1 -0
  175. package/dist/components/overview/model.js +460 -0
  176. package/dist/components/overview/recipe-widgets.d.ts +77 -0
  177. package/dist/components/overview/recipe-widgets.d.ts.map +1 -0
  178. package/dist/components/overview/recipe-widgets.js +151 -0
  179. package/dist/components/overview/registry.d.ts +45 -0
  180. package/dist/components/overview/registry.d.ts.map +1 -0
  181. package/dist/components/overview/registry.js +112 -0
  182. package/dist/components/overview/resize.d.ts +25 -0
  183. package/dist/components/overview/resize.d.ts.map +1 -0
  184. package/dist/components/overview/resize.js +41 -0
  185. package/dist/components/overview/schema.d.ts +34 -0
  186. package/dist/components/overview/schema.d.ts.map +1 -0
  187. package/dist/components/overview/schema.js +180 -0
  188. package/dist/components/overview/server.d.ts +14 -0
  189. package/dist/components/overview/server.d.ts.map +1 -0
  190. package/dist/components/overview/server.js +13 -0
  191. package/dist/components/overview/types.d.ts +235 -0
  192. package/dist/components/overview/types.d.ts.map +1 -0
  193. package/dist/components/overview/types.js +17 -0
  194. package/dist/components/overview/widgets/ChartWidget.svelte +111 -0
  195. package/dist/components/overview/widgets/ChartWidget.svelte.d.ts +6 -0
  196. package/dist/components/overview/widgets/ChartWidget.svelte.d.ts.map +1 -0
  197. package/dist/components/overview/widgets/MetricWidget.svelte +86 -0
  198. package/dist/components/overview/widgets/MetricWidget.svelte.d.ts +6 -0
  199. package/dist/components/overview/widgets/MetricWidget.svelte.d.ts.map +1 -0
  200. package/dist/components/overview/widgets/NoteWidget.svelte +61 -0
  201. package/dist/components/overview/widgets/NoteWidget.svelte.d.ts +5 -0
  202. package/dist/components/overview/widgets/NoteWidget.svelte.d.ts.map +1 -0
  203. package/dist/components/overview/widgets/RecordListWidget.svelte +91 -0
  204. package/dist/components/overview/widgets/RecordListWidget.svelte.d.ts +6 -0
  205. package/dist/components/overview/widgets/RecordListWidget.svelte.d.ts.map +1 -0
  206. package/dist/components/overview/widgets/ShortcutsWidget.svelte +80 -0
  207. package/dist/components/overview/widgets/ShortcutsWidget.svelte.d.ts +6 -0
  208. package/dist/components/overview/widgets/ShortcutsWidget.svelte.d.ts.map +1 -0
  209. package/dist/components/overview/widgets/core.d.ts +44 -0
  210. package/dist/components/overview/widgets/core.d.ts.map +1 -0
  211. package/dist/components/overview/widgets/core.js +222 -0
  212. package/dist/components/overview/widgets/data.d.ts +76 -0
  213. package/dist/components/overview/widgets/data.d.ts.map +1 -0
  214. package/dist/components/overview/widgets/data.js +40 -0
  215. package/dist/components/screens/DetailScreen.svelte +220 -0
  216. package/dist/components/screens/DetailScreen.svelte.d.ts +5 -0
  217. package/dist/components/screens/DetailScreen.svelte.d.ts.map +1 -0
  218. package/dist/components/screens/EditForm.svelte +313 -0
  219. package/dist/components/screens/EditForm.svelte.d.ts +5 -0
  220. package/dist/components/screens/EditForm.svelte.d.ts.map +1 -0
  221. package/dist/components/screens/ListScreen.svelte +191 -0
  222. package/dist/components/screens/ListScreen.svelte.d.ts +5 -0
  223. package/dist/components/screens/ListScreen.svelte.d.ts.map +1 -0
  224. package/dist/components/screens/RecipeScreens.svelte +237 -0
  225. package/dist/components/screens/RecipeScreens.svelte.d.ts +5 -0
  226. package/dist/components/screens/RecipeScreens.svelte.d.ts.map +1 -0
  227. package/dist/components/screens/fields.d.ts +54 -0
  228. package/dist/components/screens/fields.d.ts.map +1 -0
  229. package/dist/components/screens/fields.js +229 -0
  230. package/dist/components/screens/index.d.ts +8 -0
  231. package/dist/components/screens/index.d.ts.map +1 -0
  232. package/dist/components/screens/index.js +6 -0
  233. package/dist/components/screens/types.d.ts +215 -0
  234. package/dist/components/screens/types.d.ts.map +1 -0
  235. package/dist/components/screens/types.js +1 -0
  236. package/dist/components/screens/values.d.ts +62 -0
  237. package/dist/components/screens/values.d.ts.map +1 -0
  238. package/dist/components/screens/values.js +289 -0
  239. package/dist/components/sortable/Sortable.svelte +6 -33
  240. package/dist/components/sortable/Sortable.svelte.d.ts.map +1 -1
  241. package/dist/components/sortable/announce.d.ts +5 -0
  242. package/dist/components/sortable/announce.d.ts.map +1 -0
  243. package/dist/components/sortable/announce.js +33 -0
  244. package/dist/components/sortable/controller.svelte.d.ts +10 -0
  245. package/dist/components/sortable/controller.svelte.d.ts.map +1 -1
  246. package/dist/components/sortable/controller.svelte.js +29 -7
  247. package/dist/components/workspace/admin-shell/AdminShell.svelte +424 -58
  248. package/dist/components/workspace/admin-shell/AdminShell.svelte.d.ts +27 -2
  249. package/dist/components/workspace/admin-shell/AdminShell.svelte.d.ts.map +1 -1
  250. package/dist/components/workspace/admin-shell/ShellBrand.svelte +86 -0
  251. package/dist/components/workspace/admin-shell/ShellBrand.svelte.d.ts +18 -0
  252. package/dist/components/workspace/admin-shell/ShellBrand.svelte.d.ts.map +1 -0
  253. package/dist/components/workspace/admin-shell/ShellIconButton.svelte +77 -0
  254. package/dist/components/workspace/admin-shell/ShellIconButton.svelte.d.ts +26 -0
  255. package/dist/components/workspace/admin-shell/ShellIconButton.svelte.d.ts.map +1 -0
  256. package/dist/components/workspace/admin-shell/ShellLayoutEditor.svelte +88 -16
  257. package/dist/components/workspace/admin-shell/ShellLayoutEditor.svelte.d.ts.map +1 -1
  258. package/dist/components/workspace/admin-shell/ShellNavEditor.svelte +531 -0
  259. package/dist/components/workspace/admin-shell/ShellNavEditor.svelte.d.ts +26 -0
  260. package/dist/components/workspace/admin-shell/ShellNavEditor.svelte.d.ts.map +1 -0
  261. package/dist/components/workspace/admin-shell/ShellSectionIcon.svelte +57 -0
  262. package/dist/components/workspace/admin-shell/ShellSectionIcon.svelte.d.ts +22 -0
  263. package/dist/components/workspace/admin-shell/ShellSectionIcon.svelte.d.ts.map +1 -0
  264. package/dist/components/workspace/admin-shell/ShellSectionMenu.svelte +290 -0
  265. package/dist/components/workspace/admin-shell/ShellSectionMenu.svelte.d.ts +32 -0
  266. package/dist/components/workspace/admin-shell/ShellSectionMenu.svelte.d.ts.map +1 -0
  267. package/dist/components/workspace/admin-shell/TenantNav.svelte +67 -2
  268. package/dist/components/workspace/admin-shell/TenantNav.svelte.d.ts +8 -0
  269. package/dist/components/workspace/admin-shell/TenantNav.svelte.d.ts.map +1 -1
  270. package/dist/components/workspace/admin-shell/layout-controller.svelte.d.ts +67 -0
  271. package/dist/components/workspace/admin-shell/layout-controller.svelte.d.ts.map +1 -1
  272. package/dist/components/workspace/admin-shell/layout-controller.svelte.js +129 -1
  273. package/dist/components/workspace/admin-shell/layout.d.ts +122 -0
  274. package/dist/components/workspace/admin-shell/layout.d.ts.map +1 -1
  275. package/dist/components/workspace/admin-shell/layout.js +410 -10
  276. package/dist/components/workspace/admin-shell/settings.js +4 -4
  277. package/dist/components/workspace/admin-shell/shell-icons.d.ts +45 -0
  278. package/dist/components/workspace/admin-shell/shell-icons.d.ts.map +1 -0
  279. package/dist/components/workspace/admin-shell/shell-icons.js +66 -0
  280. package/dist/components/workspace/admin-shell/slot-labels.d.ts +33 -0
  281. package/dist/components/workspace/admin-shell/slot-labels.d.ts.map +1 -0
  282. package/dist/components/workspace/admin-shell/slot-labels.js +33 -0
  283. package/dist/components/workspace/admin-shell/slots.d.ts +50 -0
  284. package/dist/components/workspace/admin-shell/slots.d.ts.map +1 -0
  285. package/dist/components/workspace/admin-shell/slots.js +77 -0
  286. package/dist/components/workspace/admin-shell/state.svelte.d.ts +35 -0
  287. package/dist/components/workspace/admin-shell/state.svelte.d.ts.map +1 -1
  288. package/dist/components/workspace/admin-shell/state.svelte.js +111 -0
  289. package/dist/components/workspace/admin-shell/types.d.ts +101 -1
  290. package/dist/components/workspace/admin-shell/types.d.ts.map +1 -1
  291. package/dist/components/workspace/index.d.ts +9 -2
  292. package/dist/components/workspace/index.d.ts.map +1 -1
  293. package/dist/components/workspace/index.js +6 -0
  294. package/dist/components/workspace/manifest-nav.d.ts +20 -0
  295. package/dist/components/workspace/manifest-nav.d.ts.map +1 -1
  296. package/dist/components/workspace/manifest-nav.js +42 -13
  297. package/dist/i18n/server.d.ts +6 -0
  298. package/dist/i18n/server.d.ts.map +1 -1
  299. package/dist/i18n/server.js +6 -0
  300. package/dist/i18n/strings.import-export.d.ts +88 -0
  301. package/dist/i18n/strings.import-export.d.ts.map +1 -0
  302. package/dist/i18n/strings.import-export.js +88 -0
  303. package/dist/i18n/strings.overview.d.ts +100 -0
  304. package/dist/i18n/strings.overview.d.ts.map +1 -0
  305. package/dist/i18n/strings.overview.js +107 -0
  306. package/dist/i18n/strings.palette.d.ts +18 -0
  307. package/dist/i18n/strings.palette.d.ts.map +1 -0
  308. package/dist/i18n/strings.palette.js +18 -0
  309. package/dist/i18n/strings.screens.d.ts +31 -0
  310. package/dist/i18n/strings.screens.d.ts.map +1 -0
  311. package/dist/i18n/strings.screens.js +31 -0
  312. package/dist/i18n/strings.workspace.d.ts +49 -0
  313. package/dist/i18n/strings.workspace.d.ts.map +1 -1
  314. package/dist/i18n/strings.workspace.js +49 -0
  315. package/package.json +59 -19
  316. package/dist/browser-ai/adapters/stt/whisper-wasm.d.ts +0 -51
  317. package/dist/browser-ai/adapters/stt/whisper-wasm.d.ts.map +0 -1
  318. package/dist/browser-ai/adapters/stt/whisper-wasm.js +0 -380
@@ -0,0 +1,191 @@
1
+ <script lang="ts">
2
+ /**
3
+ * ListScreen - a searchable, sortable, paged table for any model, derived from
4
+ * its manifest definition and resolved field policy (#3718).
5
+ *
6
+ * Columns are the policy's basic-tier scalar fields in policy order (override
7
+ * with `columns`). Hidden fields, fields outside the policy, and long text /
8
+ * JSON / raw reference columns never appear by default. The screen is
9
+ * transport-neutral: the caller supplies `rows` and handles `onselect`,
10
+ * `oncreate` and `onretry`.
11
+ */
12
+ import { DataTable, type DataTableColumn } from '@happyvertical/smrt-ui/data';
13
+ import { Alert } from '@happyvertical/smrt-ui/feedback';
14
+ import { SearchInput } from '@happyvertical/smrt-ui/forms';
15
+ import { useI18n } from '@happyvertical/smrt-ui/i18n';
16
+ import { EmptyState, PageHeader } from '@happyvertical/smrt-ui/layout';
17
+ import { Button } from '@happyvertical/smrt-ui/ui';
18
+ import { M } from '../../i18n/strings.screens.js';
19
+ import {
20
+ deriveScreenFields,
21
+ screenSourceError,
22
+ screenTitles,
23
+ } from './fields.js';
24
+ import type {
25
+ ListScreenProps,
26
+ ScreenCollectionDefinition,
27
+ ScreenPolicy,
28
+ ScreenRecord,
29
+ } from './types.js';
30
+ import { compareScreenValues, formatScreenValue } from './values.js';
31
+
32
+ let {
33
+ definition,
34
+ policy = null,
35
+ rows,
36
+ title,
37
+ description,
38
+ columns,
39
+ maxColumns,
40
+ pageSize = 25,
41
+ searchable = true,
42
+ loading = false,
43
+ error = null,
44
+ currency,
45
+ locale,
46
+ showHeader = true,
47
+ onselect,
48
+ oncreate,
49
+ onretry,
50
+ extraActions,
51
+ }: ListScreenProps = $props();
52
+
53
+ const { t } = useI18n();
54
+
55
+ const titles = $derived(screenTitles(definition));
56
+ const heading = $derived(title ?? titles.plural);
57
+ const sourceError = $derived(screenSourceError(definition, policy));
58
+ const idField = $derived(definition.idField ?? 'id');
59
+
60
+ const fields = $derived(
61
+ sourceError
62
+ ? []
63
+ : deriveScreenFields(definition, policy, {
64
+ mode: 'list',
65
+ include: columns,
66
+ maxListColumns: maxColumns,
67
+ }),
68
+ );
69
+
70
+ type DisplayRow = Record<string, unknown> & { __raw: ScreenRecord };
71
+
72
+ const formatContext = $derived({
73
+ currency,
74
+ locale,
75
+ yes: t(M['ui.screens.yes']),
76
+ no: t(M['ui.screens.no']),
77
+ });
78
+
79
+ const displayRows = $derived<DisplayRow[]>(
80
+ rows.map((row) => {
81
+ const display: DisplayRow = { __raw: row };
82
+ for (const field of fields) {
83
+ display[field.name] = formatScreenValue(
84
+ field,
85
+ row[field.name],
86
+ formatContext,
87
+ );
88
+ }
89
+ return display;
90
+ }),
91
+ );
92
+
93
+ const tableColumns = $derived<DataTableColumn<DisplayRow>[]>(
94
+ fields.map((field) => ({
95
+ id: field.name,
96
+ label: field.label,
97
+ accessor: field.name,
98
+ sortable: true,
99
+ align:
100
+ field.kind === 'integer' ||
101
+ field.kind === 'decimal' ||
102
+ field.kind === 'money'
103
+ ? ('right' as const)
104
+ : ('left' as const),
105
+ sortFn: (a, b, direction) =>
106
+ compareScreenValues(a.__raw[field.name], b.__raw[field.name], direction),
107
+ })),
108
+ );
109
+
110
+ let query = $state('');
111
+ const needle = $derived(query.trim().toLowerCase());
112
+ function matches(row: DisplayRow): boolean {
113
+ if (!needle) return true;
114
+ return fields.some((field) =>
115
+ String(row[field.name] ?? '')
116
+ .toLowerCase()
117
+ .includes(needle),
118
+ );
119
+ }
120
+ </script>
121
+
122
+ {#if showHeader}
123
+ <PageHeader title={heading} subtitle={description}>
124
+ {#snippet actions()}
125
+ {#if extraActions}{@render extraActions()}{/if}
126
+ {#if oncreate}
127
+ <Button variant="primary" onclick={oncreate}>
128
+ {t(M['ui.screens.create_action'], { name: titles.singular.toLowerCase() })}
129
+ </Button>
130
+ {/if}
131
+ {/snippet}
132
+ </PageHeader>
133
+ {/if}
134
+
135
+ <section class="smrt-list-screen" aria-label={heading}>
136
+ {#if sourceError}
137
+ <Alert variant="error">{sourceError}</Alert>
138
+ {:else}
139
+ {#if searchable}
140
+ <div class="smrt-list-screen__search">
141
+ <SearchInput
142
+ value={query}
143
+ onsearch={(next) => {
144
+ query = next;
145
+ }}
146
+ label={t(M['ui.screens.search'], { name: heading.toLowerCase() })}
147
+ placeholder={t(M['ui.screens.search'], { name: heading.toLowerCase() })}
148
+ />
149
+ </div>
150
+ {/if}
151
+
152
+ <DataTable
153
+ data={displayRows}
154
+ columns={tableColumns}
155
+ rowKey={(row: DisplayRow) => String(row.__raw[idField])}
156
+ sortable
157
+ {pageSize}
158
+ {loading}
159
+ error={error ?? undefined}
160
+ onRetry={onretry}
161
+ filterFn={matches}
162
+ caption={heading}
163
+ phoneLayout="cards"
164
+ hoverable
165
+ onRowClick={onselect ? (row: DisplayRow) => onselect(row.__raw) : undefined}
166
+ >
167
+ {#snippet empty()}
168
+ <EmptyState
169
+ title={needle
170
+ ? t(M['ui.screens.empty_search'])
171
+ : t(M['ui.screens.empty_title'], { name: heading.toLowerCase() })}
172
+ actionLabel={!needle && oncreate
173
+ ? t(M['ui.screens.create_action'], { name: titles.singular.toLowerCase() })
174
+ : undefined}
175
+ onaction={!needle ? oncreate : undefined}
176
+ />
177
+ {/snippet}
178
+ </DataTable>
179
+ {/if}
180
+ </section>
181
+
182
+ <style>
183
+ .smrt-list-screen {
184
+ display: flex;
185
+ flex-direction: column;
186
+ gap: var(--smrt-spacing-md, 1rem);
187
+ }
188
+ .smrt-list-screen__search {
189
+ max-width: 24rem;
190
+ }
191
+ </style>
@@ -0,0 +1,5 @@
1
+ import type { ListScreenProps } from './types.js';
2
+ declare const ListScreen: import("svelte").Component<ListScreenProps, {}, "">;
3
+ type ListScreen = ReturnType<typeof ListScreen>;
4
+ export default ListScreen;
5
+ //# sourceMappingURL=ListScreen.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListScreen.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/screens/ListScreen.svelte.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,YAAY,CAAC;AAmJpB,QAAA,MAAM,UAAU,qDAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -0,0 +1,237 @@
1
+ <script lang="ts">
2
+ /**
3
+ * RecipeScreens - list, view, create and edit for any model, derived from its
4
+ * manifest definition and resolved field policy (#3718). It is the default
5
+ * screen set for a package that ships models but no consumer UI: tags, facts,
6
+ * secrets, profiles, reports, prompts and the like.
7
+ *
8
+ * It composes `ListScreen`, `DetailScreen` and `EditForm` over a
9
+ * transport-neutral `source` (list / get / create / update / delete). The
10
+ * `view` and `recordId` props are bindable so an app can mirror them into its
11
+ * router (`onnavigate` fires on every user navigation); left unbound, the
12
+ * component keeps its own state. An operation is offered only when the source
13
+ * implements it and `can` has not turned it off, so a read-only source yields
14
+ * a read-only screen set.
15
+ */
16
+ import { Alert } from '@happyvertical/smrt-ui/feedback';
17
+ import { useI18n } from '@happyvertical/smrt-ui/i18n';
18
+ import { Button } from '@happyvertical/smrt-ui/ui';
19
+ import { untrack } from 'svelte';
20
+ import { M } from '../../i18n/strings.screens.js';
21
+ import DetailScreen from './DetailScreen.svelte';
22
+ import EditForm from './EditForm.svelte';
23
+ import { screenTitles } from './fields.js';
24
+ import ListScreen from './ListScreen.svelte';
25
+ import type {
26
+ RecipeScreensProps,
27
+ RecipeScreensSource,
28
+ RecipeScreenView,
29
+ ScreenCollectionDefinition,
30
+ ScreenPolicy,
31
+ ScreenRecord,
32
+ } from './types.js';
33
+
34
+ let {
35
+ definition,
36
+ policy = null,
37
+ source,
38
+ view = $bindable<RecipeScreenView>('list'),
39
+ recordId = $bindable<string | null>(null),
40
+ title,
41
+ columns,
42
+ fields,
43
+ currency,
44
+ locale,
45
+ can = {},
46
+ onnavigate,
47
+ }: RecipeScreensProps = $props();
48
+
49
+ const { t } = useI18n();
50
+
51
+ const titles = $derived(screenTitles(definition));
52
+ const idField = $derived(definition.idField ?? 'id');
53
+ const allowCreate = $derived(can.create !== false && !!source.create);
54
+ const allowUpdate = $derived(can.update !== false && !!source.update);
55
+ const allowDelete = $derived(can.delete !== false && !!source.delete);
56
+
57
+ let rows = $state<readonly ScreenRecord[]>([]);
58
+ let loading = $state(true);
59
+ let loadFailed = $state(false);
60
+ let saving = $state(false);
61
+ let deleting = $state(false);
62
+ let fetched = $state<ScreenRecord | undefined>(undefined);
63
+ let fetchSettled = $state(false);
64
+
65
+ async function refresh(): Promise<void> {
66
+ loading = true;
67
+ loadFailed = false;
68
+ try {
69
+ rows = await source.list();
70
+ } catch {
71
+ loadFailed = true;
72
+ } finally {
73
+ loading = false;
74
+ }
75
+ }
76
+
77
+ $effect(() => {
78
+ // Reload whenever the source (or object) changes; mutations call refresh().
79
+ void source;
80
+ void definition.objectRef;
81
+ untrack(() => void refresh());
82
+ });
83
+
84
+ // Resolve the record for view / edit: `source.get` when provided, else the
85
+ // loaded list. A token drops answers for a record the user already left.
86
+ let fetchToken = 0;
87
+ $effect(() => {
88
+ const id = recordId;
89
+ const wanted = view === 'view' || view === 'edit';
90
+ const get = source.get;
91
+ const token = ++fetchToken;
92
+ fetched = undefined;
93
+ fetchSettled = false;
94
+ if (!wanted || id === null || !get) return;
95
+ void get
96
+ .call(source, id)
97
+ .then((found) => {
98
+ if (token === fetchToken) fetched = found;
99
+ })
100
+ .catch(() => {
101
+ if (token === fetchToken) fetched = undefined;
102
+ })
103
+ .finally(() => {
104
+ if (token === fetchToken) fetchSettled = true;
105
+ });
106
+ });
107
+
108
+ const current = $derived<ScreenRecord | undefined>(
109
+ recordId === null
110
+ ? undefined
111
+ : (fetched ??
112
+ (source.get && !fetchSettled
113
+ ? undefined
114
+ : rows.find((row) => String(row[idField]) === recordId))),
115
+ );
116
+ const resolving = $derived(
117
+ (view === 'view' || view === 'edit') &&
118
+ recordId !== null &&
119
+ !current &&
120
+ (loading || (!!source.get && !fetchSettled)),
121
+ );
122
+
123
+ function navigate(next: RecipeScreenView, id: string | null = null): void {
124
+ view = next;
125
+ recordId = id;
126
+ onnavigate?.(next, id);
127
+ }
128
+
129
+ function idOf(record: ScreenRecord | undefined): string | null {
130
+ const value = record?.[idField];
131
+ return value === undefined || value === null ? null : String(value);
132
+ }
133
+
134
+ async function create(values: Record<string, unknown>): Promise<void> {
135
+ saving = true;
136
+ try {
137
+ const created = await source.create?.(values);
138
+ await refresh();
139
+ const id = idOf(created);
140
+ if (id) navigate('view', id);
141
+ else navigate('list');
142
+ } finally {
143
+ saving = false;
144
+ }
145
+ }
146
+
147
+ async function update(values: Record<string, unknown>): Promise<void> {
148
+ if (recordId === null) return;
149
+ saving = true;
150
+ try {
151
+ await source.update?.(recordId, values);
152
+ await refresh();
153
+ navigate('view', recordId);
154
+ } finally {
155
+ saving = false;
156
+ }
157
+ }
158
+
159
+ async function remove(): Promise<void> {
160
+ if (recordId === null) return;
161
+ deleting = true;
162
+ try {
163
+ await source.delete?.(recordId);
164
+ await refresh();
165
+ navigate('list');
166
+ } finally {
167
+ deleting = false;
168
+ }
169
+ }
170
+ </script>
171
+
172
+ <div class="smrt-recipe-screens">
173
+ {#if view === 'create' && allowCreate}
174
+ <EditForm
175
+ {definition}
176
+ {policy}
177
+ {currency}
178
+ {fields}
179
+ submitting={saving}
180
+ onsubmit={create}
181
+ oncancel={() => navigate('list')}
182
+ />
183
+ {:else if (view === 'view' || view === 'edit') && recordId !== null}
184
+ {#if current}
185
+ {#if view === 'edit' && allowUpdate}
186
+ {#key recordId}
187
+ <EditForm
188
+ {definition}
189
+ {policy}
190
+ {currency}
191
+ {fields}
192
+ record={current}
193
+ submitting={saving}
194
+ onsubmit={update}
195
+ oncancel={() => navigate('view', recordId)}
196
+ />
197
+ {/key}
198
+ {:else}
199
+ <DetailScreen
200
+ {definition}
201
+ {policy}
202
+ {currency}
203
+ {locale}
204
+ {fields}
205
+ record={current}
206
+ {deleting}
207
+ onback={() => navigate('list')}
208
+ onedit={allowUpdate ? () => navigate('edit', recordId) : undefined}
209
+ ondelete={allowDelete ? remove : undefined}
210
+ />
211
+ {/if}
212
+ {:else if !resolving}
213
+ <Alert variant="warning">{t(M['ui.screens.not_found'])}</Alert>
214
+ <Button variant="ghost" onclick={() => navigate('list')}>
215
+ {t(M['ui.screens.back'], { name: titles.plural.toLowerCase() })}
216
+ </Button>
217
+ {/if}
218
+ {:else}
219
+ <ListScreen
220
+ {definition}
221
+ {policy}
222
+ {rows}
223
+ {title}
224
+ {columns}
225
+ {currency}
226
+ {locale}
227
+ {loading}
228
+ error={loadFailed ? t(M['ui.screens.load_failed']) : null}
229
+ onretry={() => void refresh()}
230
+ onselect={(row) => {
231
+ const id = idOf(row);
232
+ if (id) navigate('view', id);
233
+ }}
234
+ oncreate={allowCreate ? () => navigate('create') : undefined}
235
+ />
236
+ {/if}
237
+ </div>
@@ -0,0 +1,5 @@
1
+ import type { RecipeScreensProps } from './types.js';
2
+ declare const RecipeScreens: import("svelte").Component<RecipeScreensProps, {}, "view" | "recordId">;
3
+ type RecipeScreens = ReturnType<typeof RecipeScreens>;
4
+ export default RecipeScreens;
5
+ //# sourceMappingURL=RecipeScreens.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecipeScreens.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/screens/RecipeScreens.svelte.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EACV,kBAAkB,EAMnB,MAAM,YAAY,CAAC;AAqLpB,QAAA,MAAM,aAAa,yEAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Pure derivation of list / view / edit fields from a manifest-derived
3
+ * collection definition and its resolved field policy (#3718).
4
+ *
5
+ * Mirrors smrt-fields' `ObjectForm` selection rule: a field renders only when
6
+ * it is in BOTH the generated web definition and the resolved policy, so
7
+ * sensitive, transient and read-permission-gated fields (which the policy
8
+ * resolver omits) can never appear on a generated screen. Without a policy the
9
+ * code seed applies: the manifest `ui` hints and the cold-start rule (no
10
+ * `basic` markers anywhere => everything basic; any marker => unmarked fields
11
+ * advanced).
12
+ */
13
+ import type { ScreenCollectionDefinition, ScreenField, ScreenFieldDefinition, ScreenInputKind, ScreenMode, ScreenPolicy } from './types.js';
14
+ /** Columns shown by default on a list when the policy marks many basic. */
15
+ export declare const DEFAULT_MAX_LIST_COLUMNS = 6;
16
+ export interface DeriveScreenFieldsOptions {
17
+ mode: ScreenMode;
18
+ /**
19
+ * Explicit field names, in the order given. Hidden fields, fields outside
20
+ * the policy, and non-editable system fields are still dropped.
21
+ */
22
+ include?: readonly string[];
23
+ /** Field names to drop. */
24
+ exclude?: readonly string[];
25
+ /** List mode only: cap on default columns (`include` is never capped). */
26
+ maxListColumns?: number;
27
+ }
28
+ /** `dueDate` -> `Due date`; reference fields drop a trailing `Id`. */
29
+ export declare function humanizeFieldName(name: string): string;
30
+ /** Singular and plural display names derived from the class name. */
31
+ export declare function screenTitles(definition: ScreenCollectionDefinition): {
32
+ singular: string;
33
+ plural: string;
34
+ };
35
+ /** Which control renders a field, from its widget hint and wire type. */
36
+ export declare function inputKindFor(definition: ScreenFieldDefinition): ScreenInputKind;
37
+ /**
38
+ * Mismatch between a definition and a policy, or `null` when they belong
39
+ * together. Components surface this instead of rendering the wrong object.
40
+ */
41
+ export declare function screenSourceError(definition: ScreenCollectionDefinition, policy: ScreenPolicy | undefined | null): string | null;
42
+ /**
43
+ * Select and decorate the fields one screen shows.
44
+ *
45
+ * - `edit`: basic and advanced tiers, system fields never.
46
+ * - `view`: basic and advanced tiers, then `createdAt`/`updatedAt` as
47
+ * read-only advanced meta when the definition has them.
48
+ * - `list`: basic tier only, without long text, JSON or raw reference columns,
49
+ * capped at {@link DEFAULT_MAX_LIST_COLUMNS}; `include` overrides all of it.
50
+ */
51
+ export declare function deriveScreenFields(definition: ScreenCollectionDefinition, policy: ScreenPolicy | undefined | null, options: DeriveScreenFieldsOptions): ScreenField[];
52
+ /** Group fields preserving first-seen group order; ungrouped is `null`. */
53
+ export declare function groupScreenFields(fields: readonly ScreenField[]): Array<[string | null, ScreenField[]]>;
54
+ //# sourceMappingURL=fields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../../src/components/screens/fields.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EACV,0BAA0B,EAC1B,WAAW,EACX,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,YAAY,EACb,MAAM,YAAY,CAAC;AAepB,2EAA2E;AAC3E,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,UAAU,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,2BAA2B;IAC3B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,sEAAsE;AACtE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAStD;AAaD,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,UAAU,EAAE,0BAA0B,GAAG;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,CAWA;AAED,yEAAyE;AACzE,wBAAgB,YAAY,CAC1B,UAAU,EAAE,qBAAqB,GAChC,eAAe,CA0BjB;AAUD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,0BAA0B,EACtC,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI,GACtC,MAAM,GAAG,IAAI,CAKf;AAiCD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,0BAA0B,EACtC,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI,EACvC,OAAO,EAAE,yBAAyB,GACjC,WAAW,EAAE,CA6Gf;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,WAAW,EAAE,GAC7B,KAAK,CAAC,CAAC,MAAM,GAAG,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,CAQvC"}