@cratis/scene.blueprint.components 0.1.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 (332) hide show
  1. package/.storybook/main.ts +61 -0
  2. package/.storybook/preview.tsx +42 -0
  3. package/BorrowedComponentName.ts +22 -0
  4. package/ComponentName.ts +27 -0
  5. package/CompositeName.ts +97 -0
  6. package/README.md +40 -0
  7. package/componentsBlueprint.ts +72 -0
  8. package/componentsBlueprintComponents.ts +23 -0
  9. package/dist/cjs/BorrowedComponentName.js +25 -0
  10. package/dist/cjs/BorrowedComponentName.js.map +1 -0
  11. package/dist/cjs/ComponentName.js +30 -0
  12. package/dist/cjs/ComponentName.js.map +1 -0
  13. package/dist/cjs/CompositeName.js +52 -0
  14. package/dist/cjs/CompositeName.js.map +1 -0
  15. package/dist/cjs/componentsBlueprint.js +93 -0
  16. package/dist/cjs/componentsBlueprint.js.map +1 -0
  17. package/dist/cjs/componentsBlueprintComponents.js +27 -0
  18. package/dist/cjs/componentsBlueprintComponents.js.map +1 -0
  19. package/dist/cjs/gallery/DialogTemplatePreview.js +46 -0
  20. package/dist/cjs/gallery/DialogTemplatePreview.js.map +1 -0
  21. package/dist/cjs/gallery/GalleryScreenPreview.js +65 -0
  22. package/dist/cjs/gallery/GalleryScreenPreview.js.map +1 -0
  23. package/dist/cjs/gallery/applicationChrome.js +137 -0
  24. package/dist/cjs/gallery/applicationChrome.js.map +1 -0
  25. package/dist/cjs/gallery/navigation.js +128 -0
  26. package/dist/cjs/gallery/navigation.js.map +1 -0
  27. package/dist/cjs/gallery/previewProfile.js +87 -0
  28. package/dist/cjs/gallery/previewProfile.js.map +1 -0
  29. package/dist/cjs/gallery/screens.js +80 -0
  30. package/dist/cjs/gallery/screens.js.map +1 -0
  31. package/dist/cjs/header/ArcPageHeader.js +65 -0
  32. package/dist/cjs/header/ArcPageHeader.js.map +1 -0
  33. package/dist/cjs/header/deriveArcHeading.js +51 -0
  34. package/dist/cjs/header/deriveArcHeading.js.map +1 -0
  35. package/dist/cjs/header/humanizeBindingName.js +36 -0
  36. package/dist/cjs/header/humanizeBindingName.js.map +1 -0
  37. package/dist/cjs/index.js +119 -0
  38. package/dist/cjs/index.js.map +1 -0
  39. package/dist/cjs/package.json +3 -0
  40. package/dist/cjs/packageName.js +15 -0
  41. package/dist/cjs/packageName.js.map +1 -0
  42. package/dist/cjs/templates/SampleBindingName.js +39 -0
  43. package/dist/cjs/templates/SampleBindingName.js.map +1 -0
  44. package/dist/cjs/templates/commandTemplates.js +82 -0
  45. package/dist/cjs/templates/commandTemplates.js.map +1 -0
  46. package/dist/cjs/templates/dataElements.js +131 -0
  47. package/dist/cjs/templates/dataElements.js.map +1 -0
  48. package/dist/cjs/templates/dialogElements.js +69 -0
  49. package/dist/cjs/templates/dialogElements.js.map +1 -0
  50. package/dist/cjs/templates/dialogTemplates.js +118 -0
  51. package/dist/cjs/templates/dialogTemplates.js.map +1 -0
  52. package/dist/cjs/templates/editorElements.js +81 -0
  53. package/dist/cjs/templates/editorElements.js.map +1 -0
  54. package/dist/cjs/templates/editorTemplates.js +172 -0
  55. package/dist/cjs/templates/editorTemplates.js.map +1 -0
  56. package/dist/cjs/templates/elements.js +101 -0
  57. package/dist/cjs/templates/elements.js.map +1 -0
  58. package/dist/cjs/templates/formElements.js +77 -0
  59. package/dist/cjs/templates/formElements.js.map +1 -0
  60. package/dist/cjs/templates/listTemplates.js +187 -0
  61. package/dist/cjs/templates/listTemplates.js.map +1 -0
  62. package/dist/cjs/templates/nesting.js +150 -0
  63. package/dist/cjs/templates/nesting.js.map +1 -0
  64. package/dist/cjs/templates/sampleData.js +141 -0
  65. package/dist/cjs/templates/sampleData.js.map +1 -0
  66. package/dist/cjs/templates/screenTemplates.js +41 -0
  67. package/dist/cjs/templates/screenTemplates.js.map +1 -0
  68. package/dist/cjs/templates/workspaceTemplates.js +212 -0
  69. package/dist/cjs/templates/workspaceTemplates.js.map +1 -0
  70. package/dist/esm/BorrowedComponentName.d.ts +4 -0
  71. package/dist/esm/BorrowedComponentName.d.ts.map +1 -0
  72. package/dist/esm/BorrowedComponentName.js +23 -0
  73. package/dist/esm/BorrowedComponentName.js.map +1 -0
  74. package/dist/esm/ComponentName.d.ts +4 -0
  75. package/dist/esm/ComponentName.d.ts.map +1 -0
  76. package/dist/esm/ComponentName.js +28 -0
  77. package/dist/esm/ComponentName.js.map +1 -0
  78. package/dist/esm/CompositeName.d.ts +28 -0
  79. package/dist/esm/CompositeName.d.ts.map +1 -0
  80. package/dist/esm/CompositeName.js +50 -0
  81. package/dist/esm/CompositeName.js.map +1 -0
  82. package/dist/esm/componentsBlueprint.d.ts +5 -0
  83. package/dist/esm/componentsBlueprint.d.ts.map +1 -0
  84. package/dist/esm/componentsBlueprint.js +90 -0
  85. package/dist/esm/componentsBlueprint.js.map +1 -0
  86. package/dist/esm/componentsBlueprintComponents.d.ts +3 -0
  87. package/dist/esm/componentsBlueprintComponents.d.ts.map +1 -0
  88. package/dist/esm/componentsBlueprintComponents.js +25 -0
  89. package/dist/esm/componentsBlueprintComponents.js.map +1 -0
  90. package/dist/esm/for_ArcPageHeader/when_rendering_a_gallery_screen.d.ts +2 -0
  91. package/dist/esm/for_ArcPageHeader/when_rendering_a_gallery_screen.d.ts.map +1 -0
  92. package/dist/esm/for_ArcPageHeader/when_rendering_a_gallery_screen.js +57 -0
  93. package/dist/esm/for_ArcPageHeader/when_rendering_a_gallery_screen.js.map +1 -0
  94. package/dist/esm/for_CompositeName/when_checking_the_names_against_the_packages_that_declare_them.d.ts +2 -0
  95. package/dist/esm/for_CompositeName/when_checking_the_names_against_the_packages_that_declare_them.d.ts.map +1 -0
  96. package/dist/esm/for_CompositeName/when_checking_the_names_against_the_packages_that_declare_them.js +26 -0
  97. package/dist/esm/for_CompositeName/when_checking_the_names_against_the_packages_that_declare_them.js.map +1 -0
  98. package/dist/esm/for_componentsBlueprint/when_resolving_its_dependencies.d.ts +2 -0
  99. package/dist/esm/for_componentsBlueprint/when_resolving_its_dependencies.d.ts.map +1 -0
  100. package/dist/esm/for_componentsBlueprint/when_resolving_its_dependencies.js +65 -0
  101. package/dist/esm/for_componentsBlueprint/when_resolving_its_dependencies.js.map +1 -0
  102. package/dist/esm/for_componentsBlueprint/when_validating_the_bundle.d.ts +2 -0
  103. package/dist/esm/for_componentsBlueprint/when_validating_the_bundle.d.ts.map +1 -0
  104. package/dist/esm/for_componentsBlueprint/when_validating_the_bundle.js +41 -0
  105. package/dist/esm/for_componentsBlueprint/when_validating_the_bundle.js.map +1 -0
  106. package/dist/esm/for_componentsGalleryScreens/when_checking_the_layouts_and_slots_they_fill.d.ts +2 -0
  107. package/dist/esm/for_componentsGalleryScreens/when_checking_the_layouts_and_slots_they_fill.d.ts.map +1 -0
  108. package/dist/esm/for_componentsGalleryScreens/when_checking_the_layouts_and_slots_they_fill.js +38 -0
  109. package/dist/esm/for_componentsGalleryScreens/when_checking_the_layouts_and_slots_they_fill.js.map +1 -0
  110. package/dist/esm/for_componentsScreenTemplates/when_checking_that_arrangements_reference_declared_slots.d.ts +2 -0
  111. package/dist/esm/for_componentsScreenTemplates/when_checking_that_arrangements_reference_declared_slots.d.ts.map +1 -0
  112. package/dist/esm/for_componentsScreenTemplates/when_checking_that_arrangements_reference_declared_slots.js +47 -0
  113. package/dist/esm/for_componentsScreenTemplates/when_checking_that_arrangements_reference_declared_slots.js.map +1 -0
  114. package/dist/esm/for_componentsScreenTemplates/when_following_the_nesting_chain.d.ts +2 -0
  115. package/dist/esm/for_componentsScreenTemplates/when_following_the_nesting_chain.d.ts.map +1 -0
  116. package/dist/esm/for_componentsScreenTemplates/when_following_the_nesting_chain.js +56 -0
  117. package/dist/esm/for_componentsScreenTemplates/when_following_the_nesting_chain.js.map +1 -0
  118. package/dist/esm/for_componentsScreenTemplates/when_placing_them_in_the_default_blueprint_layout.d.ts +2 -0
  119. package/dist/esm/for_componentsScreenTemplates/when_placing_them_in_the_default_blueprint_layout.d.ts.map +1 -0
  120. package/dist/esm/for_componentsScreenTemplates/when_placing_them_in_the_default_blueprint_layout.js +31 -0
  121. package/dist/esm/for_componentsScreenTemplates/when_placing_them_in_the_default_blueprint_layout.js.map +1 -0
  122. package/dist/esm/for_componentsScreenTemplates/when_resolving_the_component_names_they_reference.d.ts +2 -0
  123. package/dist/esm/for_componentsScreenTemplates/when_resolving_the_component_names_they_reference.d.ts.map +1 -0
  124. package/dist/esm/for_componentsScreenTemplates/when_resolving_the_component_names_they_reference.js +54 -0
  125. package/dist/esm/for_componentsScreenTemplates/when_resolving_the_component_names_they_reference.js.map +1 -0
  126. package/dist/esm/for_deriveArcHeading/when_no_binding_is_named.d.ts +2 -0
  127. package/dist/esm/for_deriveArcHeading/when_no_binding_is_named.d.ts.map +1 -0
  128. package/dist/esm/for_deriveArcHeading/when_no_binding_is_named.js +27 -0
  129. package/dist/esm/for_deriveArcHeading/when_no_binding_is_named.js.map +1 -0
  130. package/dist/esm/for_deriveArcHeading/when_the_binding_is_not_registered.d.ts +2 -0
  131. package/dist/esm/for_deriveArcHeading/when_the_binding_is_not_registered.d.ts.map +1 -0
  132. package/dist/esm/for_deriveArcHeading/when_the_binding_is_not_registered.js +18 -0
  133. package/dist/esm/for_deriveArcHeading/when_the_binding_is_not_registered.js.map +1 -0
  134. package/dist/esm/for_deriveArcHeading/when_the_binding_is_registered.d.ts +2 -0
  135. package/dist/esm/for_deriveArcHeading/when_the_binding_is_registered.d.ts.map +1 -0
  136. package/dist/esm/for_deriveArcHeading/when_the_binding_is_registered.js +26 -0
  137. package/dist/esm/for_deriveArcHeading/when_the_binding_is_registered.js.map +1 -0
  138. package/dist/esm/for_humanizeBindingName/when_reading_a_proxy_name.d.ts +2 -0
  139. package/dist/esm/for_humanizeBindingName/when_reading_a_proxy_name.d.ts.map +1 -0
  140. package/dist/esm/for_humanizeBindingName/when_reading_a_proxy_name.js +25 -0
  141. package/dist/esm/for_humanizeBindingName/when_reading_a_proxy_name.js.map +1 -0
  142. package/dist/esm/gallery/ArcPages.stories.d.ts +30 -0
  143. package/dist/esm/gallery/ArcPages.stories.d.ts.map +1 -0
  144. package/dist/esm/gallery/ArcPages.stories.js +34 -0
  145. package/dist/esm/gallery/ArcPages.stories.js.map +1 -0
  146. package/dist/esm/gallery/Bindings.stories.d.ts +22 -0
  147. package/dist/esm/gallery/Bindings.stories.d.ts.map +1 -0
  148. package/dist/esm/gallery/Bindings.stories.js +78 -0
  149. package/dist/esm/gallery/Bindings.stories.js.map +1 -0
  150. package/dist/esm/gallery/DialogTemplatePreview.d.ts +7 -0
  151. package/dist/esm/gallery/DialogTemplatePreview.d.ts.map +1 -0
  152. package/dist/esm/gallery/DialogTemplatePreview.js +44 -0
  153. package/dist/esm/gallery/DialogTemplatePreview.js.map +1 -0
  154. package/dist/esm/gallery/DialogTemplates.stories.d.ts +21 -0
  155. package/dist/esm/gallery/DialogTemplates.stories.d.ts.map +1 -0
  156. package/dist/esm/gallery/DialogTemplates.stories.js +23 -0
  157. package/dist/esm/gallery/DialogTemplates.stories.js.map +1 -0
  158. package/dist/esm/gallery/GalleryScreenPreview.d.ts +10 -0
  159. package/dist/esm/gallery/GalleryScreenPreview.d.ts.map +1 -0
  160. package/dist/esm/gallery/GalleryScreenPreview.js +62 -0
  161. package/dist/esm/gallery/GalleryScreenPreview.js.map +1 -0
  162. package/dist/esm/gallery/applicationChrome.d.ts +3 -0
  163. package/dist/esm/gallery/applicationChrome.d.ts.map +1 -0
  164. package/dist/esm/gallery/applicationChrome.js +135 -0
  165. package/dist/esm/gallery/applicationChrome.js.map +1 -0
  166. package/dist/esm/gallery/index.d.ts +7 -0
  167. package/dist/esm/gallery/index.d.ts.map +1 -0
  168. package/dist/esm/gallery/index.js +7 -0
  169. package/dist/esm/gallery/index.js.map +1 -0
  170. package/dist/esm/gallery/navigation.d.ts +9 -0
  171. package/dist/esm/gallery/navigation.d.ts.map +1 -0
  172. package/dist/esm/gallery/navigation.js +121 -0
  173. package/dist/esm/gallery/navigation.js.map +1 -0
  174. package/dist/esm/gallery/previewProfile.d.ts +6 -0
  175. package/dist/esm/gallery/previewProfile.d.ts.map +1 -0
  176. package/dist/esm/gallery/previewProfile.js +83 -0
  177. package/dist/esm/gallery/previewProfile.js.map +1 -0
  178. package/dist/esm/gallery/screens.d.ts +4 -0
  179. package/dist/esm/gallery/screens.d.ts.map +1 -0
  180. package/dist/esm/gallery/screens.js +77 -0
  181. package/dist/esm/gallery/screens.js.map +1 -0
  182. package/dist/esm/header/ArcHeading.d.ts +9 -0
  183. package/dist/esm/header/ArcHeading.d.ts.map +1 -0
  184. package/dist/esm/header/ArcHeading.js +2 -0
  185. package/dist/esm/header/ArcHeading.js.map +1 -0
  186. package/dist/esm/header/ArcPageHeader.d.ts +3 -0
  187. package/dist/esm/header/ArcPageHeader.d.ts.map +1 -0
  188. package/dist/esm/header/ArcPageHeader.js +63 -0
  189. package/dist/esm/header/ArcPageHeader.js.map +1 -0
  190. package/dist/esm/header/deriveArcHeading.d.ts +4 -0
  191. package/dist/esm/header/deriveArcHeading.d.ts.map +1 -0
  192. package/dist/esm/header/deriveArcHeading.js +49 -0
  193. package/dist/esm/header/deriveArcHeading.js.map +1 -0
  194. package/dist/esm/header/humanizeBindingName.d.ts +2 -0
  195. package/dist/esm/header/humanizeBindingName.d.ts.map +1 -0
  196. package/dist/esm/header/humanizeBindingName.js +34 -0
  197. package/dist/esm/header/humanizeBindingName.js.map +1 -0
  198. package/dist/esm/header/index.d.ts +5 -0
  199. package/dist/esm/header/index.d.ts.map +1 -0
  200. package/dist/esm/header/index.js +5 -0
  201. package/dist/esm/header/index.js.map +1 -0
  202. package/dist/esm/index.d.ts +10 -0
  203. package/dist/esm/index.d.ts.map +1 -0
  204. package/dist/esm/index.js +30 -0
  205. package/dist/esm/index.js.map +1 -0
  206. package/dist/esm/package.json +3 -0
  207. package/dist/esm/packageName.d.ts +2 -0
  208. package/dist/esm/packageName.d.ts.map +1 -0
  209. package/dist/esm/packageName.js +13 -0
  210. package/dist/esm/packageName.js.map +1 -0
  211. package/dist/esm/templates/ArcHeaderOptions.d.ts +8 -0
  212. package/dist/esm/templates/ArcHeaderOptions.d.ts.map +1 -0
  213. package/dist/esm/templates/ArcHeaderOptions.js +2 -0
  214. package/dist/esm/templates/ArcHeaderOptions.js.map +1 -0
  215. package/dist/esm/templates/ColumnDefinition.d.ts +5 -0
  216. package/dist/esm/templates/ColumnDefinition.d.ts.map +1 -0
  217. package/dist/esm/templates/ColumnDefinition.js +2 -0
  218. package/dist/esm/templates/ColumnDefinition.js.map +1 -0
  219. package/dist/esm/templates/SampleBindingName.d.ts +11 -0
  220. package/dist/esm/templates/SampleBindingName.d.ts.map +1 -0
  221. package/dist/esm/templates/SampleBindingName.js +37 -0
  222. package/dist/esm/templates/SampleBindingName.js.map +1 -0
  223. package/dist/esm/templates/TableOptions.d.ts +6 -0
  224. package/dist/esm/templates/TableOptions.d.ts.map +1 -0
  225. package/dist/esm/templates/TableOptions.js +2 -0
  226. package/dist/esm/templates/TableOptions.js.map +1 -0
  227. package/dist/esm/templates/commandTemplates.d.ts +4 -0
  228. package/dist/esm/templates/commandTemplates.d.ts.map +1 -0
  229. package/dist/esm/templates/commandTemplates.js +79 -0
  230. package/dist/esm/templates/commandTemplates.js.map +1 -0
  231. package/dist/esm/templates/dataElements.d.ts +11 -0
  232. package/dist/esm/templates/dataElements.d.ts.map +1 -0
  233. package/dist/esm/templates/dataElements.js +123 -0
  234. package/dist/esm/templates/dataElements.js.map +1 -0
  235. package/dist/esm/templates/dialogElements.d.ts +5 -0
  236. package/dist/esm/templates/dialogElements.d.ts.map +1 -0
  237. package/dist/esm/templates/dialogElements.js +65 -0
  238. package/dist/esm/templates/dialogElements.js.map +1 -0
  239. package/dist/esm/templates/dialogTemplates.d.ts +6 -0
  240. package/dist/esm/templates/dialogTemplates.d.ts.map +1 -0
  241. package/dist/esm/templates/dialogTemplates.js +113 -0
  242. package/dist/esm/templates/dialogTemplates.js.map +1 -0
  243. package/dist/esm/templates/editorElements.d.ts +11 -0
  244. package/dist/esm/templates/editorElements.d.ts.map +1 -0
  245. package/dist/esm/templates/editorElements.js +74 -0
  246. package/dist/esm/templates/editorElements.js.map +1 -0
  247. package/dist/esm/templates/editorTemplates.d.ts +5 -0
  248. package/dist/esm/templates/editorTemplates.d.ts.map +1 -0
  249. package/dist/esm/templates/editorTemplates.js +168 -0
  250. package/dist/esm/templates/editorTemplates.js.map +1 -0
  251. package/dist/esm/templates/elements.d.ts +11 -0
  252. package/dist/esm/templates/elements.d.ts.map +1 -0
  253. package/dist/esm/templates/elements.js +92 -0
  254. package/dist/esm/templates/elements.js.map +1 -0
  255. package/dist/esm/templates/formElements.d.ts +11 -0
  256. package/dist/esm/templates/formElements.d.ts.map +1 -0
  257. package/dist/esm/templates/formElements.js +70 -0
  258. package/dist/esm/templates/formElements.js.map +1 -0
  259. package/dist/esm/templates/index.d.ts +18 -0
  260. package/dist/esm/templates/index.d.ts.map +1 -0
  261. package/dist/esm/templates/index.js +18 -0
  262. package/dist/esm/templates/index.js.map +1 -0
  263. package/dist/esm/templates/listTemplates.d.ts +6 -0
  264. package/dist/esm/templates/listTemplates.d.ts.map +1 -0
  265. package/dist/esm/templates/listTemplates.js +182 -0
  266. package/dist/esm/templates/listTemplates.js.map +1 -0
  267. package/dist/esm/templates/nesting.d.ts +6 -0
  268. package/dist/esm/templates/nesting.d.ts.map +1 -0
  269. package/dist/esm/templates/nesting.js +145 -0
  270. package/dist/esm/templates/nesting.js.map +1 -0
  271. package/dist/esm/templates/sampleData.d.ts +10 -0
  272. package/dist/esm/templates/sampleData.d.ts.map +1 -0
  273. package/dist/esm/templates/sampleData.js +134 -0
  274. package/dist/esm/templates/sampleData.js.map +1 -0
  275. package/dist/esm/templates/screenTemplates.d.ts +4 -0
  276. package/dist/esm/templates/screenTemplates.d.ts.map +1 -0
  277. package/dist/esm/templates/screenTemplates.js +38 -0
  278. package/dist/esm/templates/screenTemplates.js.map +1 -0
  279. package/dist/esm/templates/workspaceTemplates.d.ts +5 -0
  280. package/dist/esm/templates/workspaceTemplates.d.ts.map +1 -0
  281. package/dist/esm/templates/workspaceTemplates.js +208 -0
  282. package/dist/esm/templates/workspaceTemplates.js.map +1 -0
  283. package/dist/esm/tsconfig.tsbuildinfo +1 -0
  284. package/for_ArcPageHeader/when_rendering_a_gallery_screen.tsx +79 -0
  285. package/for_CompositeName/when_checking_the_names_against_the_packages_that_declare_them.ts +41 -0
  286. package/for_componentsBlueprint/when_resolving_its_dependencies.ts +85 -0
  287. package/for_componentsBlueprint/when_validating_the_bundle.ts +55 -0
  288. package/for_componentsGalleryScreens/when_checking_the_layouts_and_slots_they_fill.ts +56 -0
  289. package/for_componentsScreenTemplates/when_checking_that_arrangements_reference_declared_slots.ts +66 -0
  290. package/for_componentsScreenTemplates/when_following_the_nesting_chain.ts +83 -0
  291. package/for_componentsScreenTemplates/when_placing_them_in_the_default_blueprint_layout.ts +51 -0
  292. package/for_componentsScreenTemplates/when_resolving_the_component_names_they_reference.ts +72 -0
  293. package/for_deriveArcHeading/when_no_binding_is_named.ts +42 -0
  294. package/for_deriveArcHeading/when_the_binding_is_not_registered.ts +25 -0
  295. package/for_deriveArcHeading/when_the_binding_is_registered.ts +35 -0
  296. package/for_humanizeBindingName/when_reading_a_proxy_name.ts +34 -0
  297. package/gallery/ArcPages.stories.tsx +80 -0
  298. package/gallery/Bindings.stories.tsx +134 -0
  299. package/gallery/DialogTemplatePreview.tsx +49 -0
  300. package/gallery/DialogTemplates.stories.tsx +44 -0
  301. package/gallery/GalleryScreenPreview.tsx +70 -0
  302. package/gallery/applicationChrome.ts +108 -0
  303. package/gallery/index.ts +9 -0
  304. package/gallery/navigation.ts +63 -0
  305. package/gallery/previewProfile.ts +68 -0
  306. package/gallery/screens.ts +75 -0
  307. package/header/ArcHeading.ts +39 -0
  308. package/header/ArcPageHeader.tsx +44 -0
  309. package/header/deriveArcHeading.ts +47 -0
  310. package/header/humanizeBindingName.ts +36 -0
  311. package/header/index.ts +7 -0
  312. package/index.ts +12 -0
  313. package/package.json +71 -0
  314. package/packageName.ts +12 -0
  315. package/templates/ArcHeaderOptions.ts +27 -0
  316. package/templates/ColumnDefinition.ts +18 -0
  317. package/templates/SampleBindingName.ts +50 -0
  318. package/templates/TableOptions.ts +22 -0
  319. package/templates/commandTemplates.ts +59 -0
  320. package/templates/dataElements.ts +97 -0
  321. package/templates/dialogElements.ts +53 -0
  322. package/templates/dialogTemplates.ts +105 -0
  323. package/templates/editorElements.ts +69 -0
  324. package/templates/editorTemplates.ts +129 -0
  325. package/templates/elements.ts +81 -0
  326. package/templates/formElements.ts +61 -0
  327. package/templates/index.ts +20 -0
  328. package/templates/listTemplates.ts +142 -0
  329. package/templates/nesting.ts +118 -0
  330. package/templates/sampleData.ts +81 -0
  331. package/templates/screenTemplates.ts +35 -0
  332. package/templates/workspaceTemplates.ts +163 -0
@@ -0,0 +1,142 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { ScreenTemplate, WidthSizeClass } from '@cratis/scene.model';
5
+ import { SlotName, TemplateSlotName, column, row, slotLeaf } from '@cratis/scene.blueprint.default';
6
+ import { dataPage, invoiceColumns, invoiceTableOptions, observableDataTable } from './dataElements';
7
+ import { objectContentEditor, objectNavigationalBar, timeMachine } from './editorElements';
8
+ import { arcPageHeader, page, toolbar, toolbarButton, toolbarGroup, toolbarSeparator } from './elements';
9
+ import { SampleBindingName } from './SampleBindingName';
10
+
11
+ /**
12
+ * The three list shapes an Arc application repeats: a list, a live list, and a list with the selected
13
+ * record beside it.
14
+ *
15
+ * All three fill the application shell's `content` slot, which is the only slot the default blueprint's
16
+ * `AppShell` layout declares for a screen - so an application that has picked the default blueprint can
17
+ * drop any of these in without arranging anything.
18
+ *
19
+ * What makes them worth shipping is what is *already wired*. A list page is not "a table in a slot"; it is
20
+ * a query name, a set of columns, an empty message, a data key, a filter field list, a header that states
21
+ * what the page is bound to, and an action bar. Every one of those is a decision, and repeating all seven
22
+ * per screen is how a list page ends up subtly different on every screen of an application.
23
+ */
24
+
25
+ /**
26
+ * The archetype: a `dataPage` filling the body, under a header that says what it is bound to.
27
+ *
28
+ * `dataPage` is the single highest-leverage name `Cratis.Components` exposes - the library's whole
29
+ * list-screen composite, with its title bar, menubar, filterable table and optional details pane driven
30
+ * from one query. Building the same thing out of a `table` and a `toolbar` in a screen is pages of
31
+ * modeling for a worse result, and this template is the answer to that: an application supplies a query
32
+ * name and has a working list page.
33
+ */
34
+ export const dataListPageTemplate: ScreenTemplate = {
35
+ name: 'DataListPage',
36
+ fitsSlot: SlotName.Content,
37
+ slots: [{ name: TemplateSlotName.Header }, { name: TemplateSlotName.Body }],
38
+ content: {
39
+ [TemplateSlotName.Header]: [
40
+ arcPageHeader(
41
+ 'data-list-header',
42
+ { title: 'Invoices', subtitle: 'Every invoice, filterable and paged against the server', section: 'Billing', query: SampleBindingName.AllInvoices },
43
+ [
44
+ toolbar('data-list-actions', [
45
+ toolbarButton('data-list-new', 'Register an invoice', 'pi pi-plus', 'New'),
46
+ toolbarButton('data-list-refresh', 'Refresh', 'pi pi-refresh'),
47
+ toolbarSeparator('data-list-separator'),
48
+ toolbarGroup('data-list-export', [
49
+ toolbarButton('data-list-download', 'Download as CSV', 'pi pi-download'),
50
+ toolbarButton('data-list-print', 'Print', 'pi pi-print'),
51
+ ]),
52
+ ]),
53
+ ],
54
+ ),
55
+ ],
56
+ [TemplateSlotName.Body]: [dataPage('data-list-body', SampleBindingName.AllInvoices, invoiceTableOptions, invoiceColumns)],
57
+ },
58
+ displayName: 'Data list page',
59
+ description: 'A dataPage bound to one query, under a header that states the binding - the whole list screen in two elements.',
60
+ };
61
+
62
+ /**
63
+ * The live variant: the same page shape over an observable query.
64
+ *
65
+ * A separate template rather than a flag, for the same reason `observableDataTable` is a separate name
66
+ * from `dataTable`: the difference lives in the *proxy* a host registers, not in how the page is
67
+ * configured. An observable query opens a subscription and the page re-renders when the read model
68
+ * changes on the server. Choosing this template is an application saying its data is live, and that is a
69
+ * decision worth being able to read off the screen rather than infer from a property.
70
+ */
71
+ export const observableDataListPageTemplate: ScreenTemplate = {
72
+ name: 'ObservableDataListPage',
73
+ fitsSlot: SlotName.Content,
74
+ slots: [{ name: TemplateSlotName.Header }, { name: TemplateSlotName.Body }],
75
+ content: {
76
+ [TemplateSlotName.Header]: [
77
+ arcPageHeader('observable-list-header', {
78
+ title: 'Invoices in flight',
79
+ subtitle: 'Updates as the read model changes - no refresh button, because there is nothing to refresh',
80
+ section: 'Billing',
81
+ query: SampleBindingName.InvoicesInFlight,
82
+ }),
83
+ ],
84
+ [TemplateSlotName.Body]: [
85
+ page('observable-list-body', 'In flight', [
86
+ observableDataTable('observable-list-table', SampleBindingName.InvoicesInFlight, invoiceTableOptions, invoiceColumns),
87
+ ]),
88
+ ],
89
+ },
90
+ displayName: 'Observable data list page',
91
+ description: 'A live list over an observable query, which re-renders when the read model changes on the server.',
92
+ };
93
+
94
+ /**
95
+ * List plus detail: the whole list screen, with the selected record's document and history beside it.
96
+ *
97
+ * The detail region is built from the library's Arc-free editors, which is the interesting part. They read
98
+ * their content out of the property bag rather than from a query, so this half of the page renders fully
99
+ * at design time while the list half is still a placeholder - and in an event-sourced application the
100
+ * record's *history* is as natural a thing to show as its current values, which is why the time machine is
101
+ * here rather than in some optional extra.
102
+ *
103
+ * Its arrangement drops the detail column below the list at a compact width, because a document editor and
104
+ * a paged table side by side on a phone are two unreadable slivers.
105
+ */
106
+ export const dataListWithDetailPageTemplate: ScreenTemplate = {
107
+ name: 'DataListWithDetailPage',
108
+ fitsSlot: SlotName.Content,
109
+ slots: [{ name: TemplateSlotName.Header }, { name: TemplateSlotName.Body }, { name: TemplateSlotName.SidePanel }],
110
+ arrangement: {
111
+ root: column([slotLeaf(TemplateSlotName.Header), row([slotLeaf(TemplateSlotName.Body, { grow: 2 }), slotLeaf(TemplateSlotName.SidePanel, { grow: 1 })], 16)]),
112
+ overrides: [
113
+ {
114
+ width: WidthSizeClass.Compact,
115
+ root: column([slotLeaf(TemplateSlotName.Header), slotLeaf(TemplateSlotName.Body), slotLeaf(TemplateSlotName.SidePanel)], 16),
116
+ },
117
+ ],
118
+ },
119
+ content: {
120
+ [TemplateSlotName.Header]: [
121
+ arcPageHeader('list-detail-header', {
122
+ title: 'Invoices',
123
+ subtitle: 'The list, with the selected invoice beside it',
124
+ section: 'Billing',
125
+ query: SampleBindingName.AllInvoices,
126
+ }),
127
+ ],
128
+ [TemplateSlotName.Body]: [dataPage('list-detail-body', SampleBindingName.AllInvoices, invoiceTableOptions, invoiceColumns)],
129
+ [TemplateSlotName.SidePanel]: [
130
+ page('list-detail-panel', 'Selected invoice', [
131
+ objectNavigationalBar('list-detail-trail'),
132
+ objectContentEditor('list-detail-document', false),
133
+ timeMachine('list-detail-history'),
134
+ ]),
135
+ ],
136
+ },
137
+ displayName: 'Data list with detail page',
138
+ description: 'A dataPage beside a detail region showing the selected record document and its history.',
139
+ };
140
+
141
+ /** The three list-shaped templates. */
142
+ export const listTemplates: ScreenTemplate[] = [dataListPageTemplate, observableDataListPageTemplate, dataListWithDetailPageTemplate];
@@ -0,0 +1,118 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { ScreenTemplate } from '@cratis/scene.model';
5
+ import { SlotName, TemplateSlotName } from '@cratis/scene.blueprint.default';
6
+ import { invoiceColumns, invoiceTableOptions, observableDataTable } from './dataElements';
7
+ import { filterPanel } from './editorElements';
8
+ import { arcPageHeader, page, toolbar, toolbarButton, toolbarSeparator } from './elements';
9
+ import { SampleBindingName } from './SampleBindingName';
10
+
11
+ /**
12
+ * A worked three-level chain, from the application layout down to one behavior.
13
+ *
14
+ * The nesting rule is one rule applied at every depth: a template names, in `fitsSlot`, a slot declared by
15
+ * whatever contains it. A module's template fits the application layout's `content`; a feature's fits a
16
+ * slot the module's declares; a slice's fits one the feature's declares. Nothing here is a special case
17
+ * for a particular level, which is exactly why the hierarchy can be arbitrarily deep with no second
18
+ * mechanism.
19
+ *
20
+ * The slot names are chosen so that each fitted name is declared by exactly one container in the chain -
21
+ * `body` only by the module, `primary` only by the feature. That is not decoration: `resolveScreenTemplates`
22
+ * places a template only when the containers in scope agree on exactly one home for it, and reports it as
23
+ * unplaced rather than guessing when two of them declare the same name. A chain that reused `body` at
24
+ * three levels would read fine and resolve to nothing.
25
+ *
26
+ * The whole chain is Arc-bound, which is the point of it living in *this* blueprint rather than being a
27
+ * second copy of the default one's. It ends where a Cratis slice really ends: a button that summons the
28
+ * command dialog.
29
+ */
30
+
31
+ /**
32
+ * Module level: fits the application shell's `content` slot.
33
+ *
34
+ * A module always has a name and a description, so it brings its own header, and it offers a body for the
35
+ * feature inside it plus a side panel for the filters that apply across the whole module.
36
+ */
37
+ export const dataModulePageTemplate: ScreenTemplate = {
38
+ name: 'DataModulePage',
39
+ fitsSlot: SlotName.Content,
40
+ slots: [{ name: TemplateSlotName.Header }, { name: TemplateSlotName.Body }, { name: TemplateSlotName.SidePanel }],
41
+ content: {
42
+ [TemplateSlotName.Header]: [
43
+ arcPageHeader('module-header', {
44
+ title: 'Billing',
45
+ subtitle: 'Everything the billing module owns',
46
+ section: 'Operations',
47
+ }),
48
+ ],
49
+ [TemplateSlotName.SidePanel]: [page('module-filters', 'Filters', [filterPanel('module-filter-panel', 'Filter the module')])],
50
+ },
51
+ displayName: 'Data module page',
52
+ description: 'Module level: fits the application layout content slot and offers a body for one feature.',
53
+ };
54
+
55
+ /**
56
+ * Feature level: fits the module page's `body` slot.
57
+ *
58
+ * A feature is where actions belong - a module is a grouping and a slice is one behavior, and the feature
59
+ * in between is what a user thinks of as "the screen with the buttons on it". It offers a primary region
60
+ * for the slice and a secondary one for the live view of what that slice is doing.
61
+ */
62
+ export const dataFeatureSectionTemplate: ScreenTemplate = {
63
+ name: 'DataFeatureSection',
64
+ fitsSlot: TemplateSlotName.Body,
65
+ slots: [{ name: TemplateSlotName.Toolbar }, { name: TemplateSlotName.Primary }, { name: TemplateSlotName.Secondary }],
66
+ content: {
67
+ [TemplateSlotName.Toolbar]: [
68
+ toolbar('feature-toolbar', [
69
+ toolbarButton('feature-new', 'Register an invoice', 'pi pi-plus', 'New'),
70
+ toolbarButton('feature-adjust', 'Record an adjustment', 'pi pi-pencil', 'Adjust'),
71
+ toolbarSeparator('feature-separator'),
72
+ toolbarButton('feature-export', 'Export the feature data', 'pi pi-download'),
73
+ ]),
74
+ ],
75
+ [TemplateSlotName.Secondary]: [
76
+ page('feature-live', 'In flight', [
77
+ observableDataTable('feature-live-table', SampleBindingName.InvoicesInFlight, invoiceTableOptions, invoiceColumns),
78
+ ]),
79
+ ],
80
+ },
81
+ displayName: 'Data feature section',
82
+ description: 'Feature level: fits a module page body slot, brings the action toolbar and a live view.',
83
+ };
84
+
85
+ /**
86
+ * Slice level: fits the feature section's `primary` slot.
87
+ *
88
+ * The end of the chain, and deliberately the thinnest thing in it. A slice is one behavior, and in a
89
+ * Cratis application that behavior is one command - so its surface is a header saying what the command is
90
+ * and whether it is wired, and the action that summons it. The capture itself happens in the `CommandDialog`
91
+ * dialog template, which is why this template has no form on it and does not need one.
92
+ */
93
+ export const commandSliceSectionTemplate: ScreenTemplate = {
94
+ name: 'CommandSliceSection',
95
+ fitsSlot: TemplateSlotName.Primary,
96
+ slots: [{ name: TemplateSlotName.Header }, { name: TemplateSlotName.Actions }],
97
+ content: {
98
+ [TemplateSlotName.Header]: [
99
+ arcPageHeader('slice-header', {
100
+ title: 'Record an adjustment',
101
+ subtitle: 'One behavior, one command, one button',
102
+ section: 'Adjustments',
103
+ command: SampleBindingName.RecordAdjustment,
104
+ }),
105
+ ],
106
+ [TemplateSlotName.Actions]: [
107
+ toolbar('slice-actions', [
108
+ toolbarButton('slice-record', 'Record an adjustment', 'pi pi-check', 'Record'),
109
+ toolbarButton('slice-cancel', 'Leave the invoice as it is', 'pi pi-times', 'Cancel'),
110
+ ]),
111
+ ],
112
+ },
113
+ displayName: 'Command slice section',
114
+ description: 'Slice level: fits a feature section primary slot and hosts one command behavior.',
115
+ };
116
+
117
+ /** The chain, outermost first - what a spec walks to prove `fitsSlot` resolves at every level. */
118
+ export const nestingChainTemplates: ScreenTemplate[] = [dataModulePageTemplate, dataFeatureSectionTemplate, commandSliceSectionTemplate];
@@ -0,0 +1,81 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /**
5
+ * The seeded content the Arc-free composites in this package's templates render.
6
+ *
7
+ * There is a real split running through this blueprint, and it is worth naming rather than hiding. Most of
8
+ * `@cratis/components` is Arc-bound: a data page, a table, a command form and a command dialog all need a
9
+ * registered proxy and a live backend before they show anything, so at design time they are placeholders,
10
+ * and that is correct.
11
+ *
12
+ * The editors are not. A schema editor, a document editor, a navigational bar and a time machine all take
13
+ * their content from the property bag, so a template that seeds them renders as a working page with no
14
+ * backend at all. That is why the editor templates carry this data: it makes two of this package's pages
15
+ * genuinely usable in a preview, rather than eight pages of dashed boxes.
16
+ *
17
+ * The shape is an invoice throughout, matching the query and command names the other templates bind to, so
18
+ * the whole package reads as one small application rather than eight unrelated demonstrations.
19
+ */
20
+
21
+ /** A JSON schema in the shape Chronicle emits for an event type - what `schemaEditor` edits. */
22
+ export const invoiceSchema: Record<string, unknown> = {
23
+ title: 'InvoiceRegistered',
24
+ type: 'object',
25
+ properties: {
26
+ number: { type: 'string', description: 'The invoice number as printed on the document.' },
27
+ customer: { type: 'string', description: 'The customer the invoice is addressed to.' },
28
+ issued: { type: 'string', format: 'date-time', description: 'When the invoice was issued.' },
29
+ amount: { type: 'number', description: 'The gross amount, in the invoice currency.' },
30
+ currency: { type: 'string', description: 'The ISO currency code.' },
31
+ },
32
+ };
33
+
34
+ /** One invoice as a plain document - what `objectContentEditor` renders against {@link invoiceSchema}. */
35
+ export const invoiceDocument: Record<string, unknown> = {
36
+ number: 'INV-2043',
37
+ customer: 'Northwind Traders',
38
+ issued: '2026-01-05T09:30:00Z',
39
+ amount: 4200,
40
+ currency: 'USD',
41
+ };
42
+
43
+ /** Where in the document the navigational bar currently is. */
44
+ export const invoiceNavigationPath: string[] = ['lines', 'shipping'];
45
+
46
+ /**
47
+ * Successive versions of the invoice, for the time machine.
48
+ *
49
+ * Every entry has an id, a label and a parseable timestamp, because the adapter drops any that does not -
50
+ * a version invented at the epoch would not be a slightly wrong entry, it would silently reorder every
51
+ * real one around it.
52
+ */
53
+ export const invoiceVersions: Record<string, unknown>[] = [
54
+ { id: 'v3', label: 'Adjustment recorded', timestamp: '2026-01-12T14:05:00Z', content: 'Amount reduced by 120.00 - damaged goods' },
55
+ { id: 'v2', label: 'Approved', timestamp: '2026-01-07T08:15:00Z', content: 'Approved by Amelia Nyquist' },
56
+ { id: 'v1', label: 'Registered', timestamp: '2026-01-05T09:30:00Z', content: 'Registered from the supplier portal' },
57
+ ];
58
+
59
+ /** The filters the list templates offer, in the shape `filterPanel` reads. */
60
+ export const invoiceFilters: Record<string, unknown>[] = [
61
+ {
62
+ key: 'status',
63
+ label: 'Status',
64
+ type: 'string',
65
+ multi: true,
66
+ options: [
67
+ { key: 'draft', label: 'Draft', count: 12 },
68
+ { key: 'approved', label: 'Approved', count: 44 },
69
+ { key: 'paid', label: 'Paid', count: 108 },
70
+ ],
71
+ },
72
+ { key: 'amount', label: 'Amount', type: 'number', buckets: 4 },
73
+ { key: 'issued', label: 'Issued', type: 'date' },
74
+ ];
75
+
76
+ /** The status choices a command form's dropdown offers. */
77
+ export const statusOptions: { label: string; value: string }[] = [
78
+ { label: 'Draft', value: 'draft' },
79
+ { label: 'Approved', value: 'approved' },
80
+ { label: 'Paid', value: 'paid' },
81
+ ];
@@ -0,0 +1,35 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { ScreenTemplate } from '@cratis/scene.model';
5
+ import { commandTemplates } from './commandTemplates';
6
+ import { editorTemplates } from './editorTemplates';
7
+ import { listTemplates } from './listTemplates';
8
+ import { nestingChainTemplates } from './nesting';
9
+ import { workspaceTemplates } from './workspaceTemplates';
10
+
11
+ /**
12
+ * The screen templates this blueprint provides.
13
+ *
14
+ * Eight whole pages that fill the application shell's `content` slot, plus the three-level chain that
15
+ * demonstrates how `fitsSlot` composes at module, feature and slice level. The list is what the manifest's
16
+ * `screenTemplates` names and what the bundle provides; `validatePackageBundle` proves the two agree.
17
+ */
18
+ export const componentsScreenTemplates: ScreenTemplate[] = [
19
+ ...listTemplates,
20
+ ...workspaceTemplates,
21
+ ...commandTemplates,
22
+ ...editorTemplates,
23
+ ...nestingChainTemplates,
24
+ ];
25
+
26
+ /**
27
+ * The eight templates that fill the application layout's own `content` slot directly.
28
+ *
29
+ * Kept apart from the nesting chain because `fitsSlot` is resolved against *the containers in scope*, and
30
+ * these two groups are never in scope together. Each of these is a whole page an application places on its
31
+ * own; the chain's three are one page assembled from three levels. Resolving them as one set would ask
32
+ * `resolveScreenTemplates` which of eight `body`-declaring templates the feature section belongs to, and it
33
+ * would rightly answer that it cannot tell.
34
+ */
35
+ export const componentsPageTemplates: ScreenTemplate[] = [...listTemplates, ...workspaceTemplates, ...commandTemplates, ...editorTemplates];
@@ -0,0 +1,163 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { ScreenTemplate, WidthSizeClass } from '@cratis/scene.model';
5
+ import { SlotName, TemplateSlotName, column, grid, slotLeaf } from '@cratis/scene.blueprint.default';
6
+ import { ColumnDefinition } from './ColumnDefinition';
7
+ import { adjustmentColumns, dataTable, invoiceColumns, invoiceTableOptions, observableDataTable } from './dataElements';
8
+ import { objectContentEditor, timeMachine } from './editorElements';
9
+ import { arcPageHeader, page } from './elements';
10
+ import { SampleBindingName } from './SampleBindingName';
11
+ import { TableOptions } from './TableOptions';
12
+
13
+ /**
14
+ * The two whole-workspace shapes: a master-detail arrangement, and a dashboard of data widgets.
15
+ *
16
+ * Both are arrangements of *several* bindings rather than one, which is what separates them from the list
17
+ * templates. That is also what makes them the templates most worth shipping: an application can wire one
18
+ * query without help, and gets a page that looks like every other page in the product only if something
19
+ * has already decided how four of them sit together.
20
+ */
21
+
22
+ /** The columns of the revenue widget's query. */
23
+ const revenueColumns: ColumnDefinition[] = [
24
+ { field: 'month', header: 'Month' },
25
+ { field: 'invoiced', header: 'Invoiced' },
26
+ { field: 'collected', header: 'Collected' },
27
+ ];
28
+
29
+ /** The columns of the open-tickets widget's query. */
30
+ const ticketColumns: ColumnDefinition[] = [
31
+ { field: 'reference', header: 'Reference' },
32
+ { field: 'subject', header: 'Subject' },
33
+ { field: 'age', header: 'Age' },
34
+ ];
35
+
36
+ /** Table options for a widget-sized table, where there is no search box to filter across. */
37
+ const widgetTableOptions: TableOptions = { emptyMessage: 'Nothing to show yet', dataKey: 'id' };
38
+
39
+ /**
40
+ * Master and detail: the list in the larger column, the selected record in the narrower one.
41
+ *
42
+ * The difference from `DataListWithDetailPage` is real and worth having both. That template is a whole
43
+ * `dataPage` - its own title bar, menubar and filtering - with a detail region added beside it. This one is
44
+ * a plain `dataTable` next to a detail region, which is the right shape when the page's chrome comes from
45
+ * the *feature* around it rather than from the list itself. Reaching for the wrong one shows up as a page
46
+ * with two toolbars.
47
+ *
48
+ * The grid collapses to a single column at a compact width, because a master and a detail side by side on a
49
+ * phone is the arrangement that made "master-detail does not work on mobile" a truism.
50
+ */
51
+ export const masterDetailPageTemplate: ScreenTemplate = {
52
+ name: 'MasterDetailPage',
53
+ fitsSlot: SlotName.Content,
54
+ slots: [{ name: TemplateSlotName.Header }, { name: TemplateSlotName.Primary }, { name: TemplateSlotName.Secondary }],
55
+ arrangement: {
56
+ root: column([slotLeaf(TemplateSlotName.Header), grid([slotLeaf(TemplateSlotName.Primary, { span: 2 }), slotLeaf(TemplateSlotName.Secondary)], 3, 16)]),
57
+ overrides: [
58
+ {
59
+ width: WidthSizeClass.Compact,
60
+ root: column([slotLeaf(TemplateSlotName.Header), slotLeaf(TemplateSlotName.Primary), slotLeaf(TemplateSlotName.Secondary)], 16),
61
+ },
62
+ ],
63
+ },
64
+ content: {
65
+ [TemplateSlotName.Header]: [
66
+ arcPageHeader('master-detail-header', {
67
+ title: 'Invoices',
68
+ subtitle: 'Pick an invoice on the left to inspect it on the right',
69
+ section: 'Billing',
70
+ query: SampleBindingName.AllInvoices,
71
+ }),
72
+ ],
73
+ [TemplateSlotName.Primary]: [
74
+ page('master-detail-master', 'Invoices', [dataTable('master-detail-table', SampleBindingName.AllInvoices, invoiceTableOptions, invoiceColumns)]),
75
+ ],
76
+ [TemplateSlotName.Secondary]: [
77
+ page('master-detail-detail', 'Selected invoice', [
78
+ objectContentEditor('master-detail-document', false),
79
+ timeMachine('master-detail-history'),
80
+ ]),
81
+ ],
82
+ },
83
+ displayName: 'Master-detail page',
84
+ description: 'A queried list in the larger column with the selected record and its history in the narrower one.',
85
+ };
86
+
87
+ /**
88
+ * A dashboard of data widgets - four queries arranged so the page reads in the order people already read it.
89
+ *
90
+ * The composition is the one every template line settles on: a row of figures across the top, then a wide
91
+ * column and a narrow one. Copying it is the point rather than a shortcut - it is the arrangement the eye
92
+ * already knows how to scan, and a dashboard that invents its own costs the reader a moment on every visit.
93
+ *
94
+ * What this blueprint adds is that every widget is a *query*, not a picture. Each one names a proxy a host
95
+ * registers, so the dashboard is live the moment the application wires it, with nothing to replace.
96
+ */
97
+ export const dashboardPageTemplate: ScreenTemplate = {
98
+ name: 'DashboardPage',
99
+ fitsSlot: SlotName.Content,
100
+ slots: [
101
+ { name: TemplateSlotName.Header },
102
+ { name: TemplateSlotName.Stats },
103
+ { name: TemplateSlotName.Primary },
104
+ { name: TemplateSlotName.Secondary },
105
+ ],
106
+ arrangement: {
107
+ root: column([
108
+ slotLeaf(TemplateSlotName.Header),
109
+ slotLeaf(TemplateSlotName.Stats),
110
+ grid([slotLeaf(TemplateSlotName.Primary, { span: 2 }), slotLeaf(TemplateSlotName.Secondary)], 3, 16),
111
+ ]),
112
+ overrides: [
113
+ {
114
+ width: WidthSizeClass.Compact,
115
+ root: column(
116
+ [
117
+ slotLeaf(TemplateSlotName.Header),
118
+ slotLeaf(TemplateSlotName.Stats),
119
+ slotLeaf(TemplateSlotName.Primary),
120
+ slotLeaf(TemplateSlotName.Secondary),
121
+ ],
122
+ 16,
123
+ ),
124
+ },
125
+ ],
126
+ },
127
+ content: {
128
+ [TemplateSlotName.Header]: [
129
+ arcPageHeader('dashboard-header', {
130
+ title: 'Billing',
131
+ subtitle: 'Four queries, arranged the way people already read a dashboard',
132
+ section: 'Operations',
133
+ query: SampleBindingName.RevenueByMonth,
134
+ }),
135
+ ],
136
+ [TemplateSlotName.Stats]: [
137
+ page('dashboard-stat-revenue', 'Revenue by month', [
138
+ dataTable('dashboard-stat-revenue-table', SampleBindingName.RevenueByMonth, widgetTableOptions, revenueColumns),
139
+ ]),
140
+ page('dashboard-stat-flight', 'In flight', [
141
+ observableDataTable('dashboard-stat-flight-table', SampleBindingName.InvoicesInFlight, widgetTableOptions, invoiceColumns),
142
+ ]),
143
+ page('dashboard-stat-tickets', 'Open tickets', [
144
+ dataTable('dashboard-stat-tickets-table', SampleBindingName.OpenTickets, widgetTableOptions, ticketColumns),
145
+ ]),
146
+ ],
147
+ [TemplateSlotName.Primary]: [
148
+ page('dashboard-invoices', 'Recent invoices', [
149
+ dataTable('dashboard-invoices-table', SampleBindingName.AllInvoices, invoiceTableOptions, invoiceColumns),
150
+ ]),
151
+ ],
152
+ [TemplateSlotName.Secondary]: [
153
+ page('dashboard-adjustments', 'Adjustments', [
154
+ dataTable('dashboard-adjustments-table', SampleBindingName.AllAdjustments, widgetTableOptions, adjustmentColumns),
155
+ ]),
156
+ ],
157
+ },
158
+ displayName: 'Dashboard page',
159
+ description: 'A row of query-backed widgets over a wide and a narrow column, each bound to its own query.',
160
+ };
161
+
162
+ /** The two workspace-shaped templates. */
163
+ export const workspaceTemplates: ScreenTemplate[] = [masterDetailPageTemplate, dashboardPageTemplate];