@salsita-ai/sdk 0.50.0-develop.5a0bcdee42 → 0.50.0-develop.61e519cfcc

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 (1191) hide show
  1. package/README.md +3 -3
  2. package/dist/admin/create-admin-pages-from-spec.d.ts +1 -1
  3. package/dist/application-spec/core/components/component-filter.d.ts +53 -0
  4. package/dist/application-spec/core/components/component-filter.js +1 -0
  5. package/dist/application-spec/core/components/index.d.ts +2 -0
  6. package/dist/application-spec/core/components/index.js +1 -0
  7. package/dist/application-spec/core/components/sdk-code-ref.d.ts +9 -0
  8. package/dist/application-spec/core/components/sdk-code-ref.js +1 -0
  9. package/dist/application-spec/core/enhanced-json-value.d.ts +0 -68
  10. package/dist/application-spec/core/enhanced-json-value.js +1 -1
  11. package/dist/application-spec/core/expressions/index.d.ts +2 -0
  12. package/dist/application-spec/core/expressions/index.js +1 -0
  13. package/dist/application-spec/core/expressions/relation-expression-params.d.ts +11 -0
  14. package/dist/application-spec/core/expressions/sdk-expression-implementation.d.ts +24 -0
  15. package/dist/application-spec/core/expressions/sdk-expression-implementation.js +1 -0
  16. package/dist/application-spec/core/index.d.ts +2 -0
  17. package/dist/application-spec/core/index.js +1 -1
  18. package/dist/application-spec/core/json-value.d.ts +1 -1
  19. package/dist/application-spec/{core → enhanced-json}/eval-to-constant.d.ts +1 -1
  20. package/dist/application-spec/enhanced-json/index.d.ts +4 -0
  21. package/dist/application-spec/enhanced-json/index.js +1 -0
  22. package/dist/application-spec/enhanced-json/is-enhanced-json-array.d.ts +2 -0
  23. package/dist/application-spec/enhanced-json/is-enhanced-json-array.js +1 -0
  24. package/dist/application-spec/enhanced-json/resolve-enhanced-json-value.d.ts +18 -0
  25. package/dist/application-spec/enhanced-json/resolve-enhanced-json-value.js +1 -0
  26. package/dist/application-spec/enhanced-json/schema-from-value.d.ts +24 -0
  27. package/dist/application-spec/enhanced-json/schema-from-value.js +1 -0
  28. package/dist/application-spec/enhanced-json/stringify-enhanced-json-value.d.ts +14 -0
  29. package/dist/application-spec/enhanced-json/stringify-enhanced-json-value.js +1 -0
  30. package/dist/application-spec/enhanced-json/validate-enhanced-json-value-caps.d.ts +12 -0
  31. package/dist/application-spec/enhanced-json/validate-enhanced-json-value-caps.js +1 -0
  32. package/dist/application-spec/enhanced-json/validate-no-legacy-code-ref.d.ts +13 -0
  33. package/dist/application-spec/enhanced-json/validate-no-legacy-code-ref.js +1 -0
  34. package/dist/application-spec/errors/diagnostic-codes.d.ts +9 -0
  35. package/dist/application-spec/errors/diagnostic-codes.js +1 -1
  36. package/dist/application-spec/errors/diagnostic-messages.d.ts +12 -0
  37. package/dist/application-spec/errors/diagnostic-messages.js +1 -1
  38. package/dist/application-spec/generate-application/code/common/index.d.ts +1 -0
  39. package/dist/application-spec/generate-application/code/common/index.js +1 -1
  40. package/dist/application-spec/generate-application/code/common/project-module-list.d.ts +8 -0
  41. package/dist/application-spec/generate-application/code/common/project-module-list.js +3 -0
  42. package/dist/application-spec/generate-application/code/domain-runtime-files.js +1 -1
  43. package/dist/application-spec/generate-application/code/project-scaffolding.d.ts +8 -1
  44. package/dist/application-spec/generate-application/code/project-scaffolding.js +2 -2
  45. package/dist/application-spec/generate-application/code/standalone-app-files.d.ts +2 -2
  46. package/dist/application-spec/generate-application/code/standalone-app-files.js +1 -1
  47. package/dist/application-spec/generate-application/code/templates/admin-domain-code.d.ts +1 -2
  48. package/dist/application-spec/generate-application/code/templates/admin-domain-code.js +6 -14
  49. package/dist/application-spec/generate-application/code/templates/admin-frontend-code.d.ts +1 -2
  50. package/dist/application-spec/generate-application/code/templates/admin-frontend-code.js +4 -4
  51. package/dist/application-spec/generate-application/code/templates/configurator-config.js +6 -4
  52. package/dist/application-spec/generate-application/code/templates/configurator-domain-code.d.ts +1 -2
  53. package/dist/application-spec/generate-application/code/templates/configurator-domain-code.js +7 -16
  54. package/dist/application-spec/generate-application/code/templates/configurator-frontend-code.d.ts +1 -2
  55. package/dist/application-spec/generate-application/code/templates/configurator-frontend-code.js +7 -9
  56. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-assistant.d.ts +2 -2
  57. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-assistant.js +1 -1
  58. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-component-optics.js +4 -4
  59. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-defaults.d.ts +4 -2
  60. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-defaults.js +1 -1
  61. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-domain-block.js +56 -56
  62. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-invariants.d.ts +1 -1
  63. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-invariants.js +1 -1
  64. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-phx-globals.js +3 -0
  65. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-relation-expressions.js +1 -1
  66. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-resources.d.ts +6 -8
  67. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-resources.js +11 -11
  68. package/dist/application-spec/generate-application/code/templates/domain-spec/index.d.ts +1 -1
  69. package/dist/application-spec/generate-application/code/templates/domain-spec/index.js +1 -1
  70. package/dist/application-spec/generate-application/code/templates/domain-spec.js +12 -12
  71. package/dist/application-spec/generate-application/code/templates/domain.js +5 -5
  72. package/dist/application-spec/generate-application/code/templates/globals.js +5 -4
  73. package/dist/application-spec/generate-application/code/templates/index.d.ts +0 -8
  74. package/dist/application-spec/generate-application/code/templates/index.js +1 -1
  75. package/dist/application-spec/generate-application/code/templates/package-json.js +1 -1
  76. package/dist/application-spec/generate-application/code/templates/skills/phoenix-create-configurator-skill.js +66 -42
  77. package/dist/application-spec/generate-application/code/templates/skills/phoenix-review-skill.js +9 -3
  78. package/dist/application-spec/generate-application/code/templates/skills/phoenix-skill.js +1 -1
  79. package/dist/application-spec/generate-application/code/templates/skills/sdk-content.d.ts +22 -16
  80. package/dist/application-spec/generate-application/code/templates/skills/sdk-content.js +6 -9
  81. package/dist/application-spec/generate-application/code/templates/webhook-builders.js +9 -4
  82. package/dist/application-spec/generate-application/code/templates/webhook-index.d.ts +6 -1
  83. package/dist/application-spec/generate-application/code/templates/webhook-index.js +10 -1
  84. package/dist/application-spec/generate-application/code/templates/webhooks-config.js +2 -2
  85. package/dist/application-spec/generate-application/index.d.ts +2 -0
  86. package/dist/application-spec/generate-application/index.js +1 -1
  87. package/dist/application-spec/generate-application/runtime/admin-runtime/admin-runtime.d.ts +6 -2
  88. package/dist/application-spec/generate-application/runtime/admin-runtime/admin-runtime.js +1 -1
  89. package/dist/application-spec/generate-application/runtime/application-runtime.d.ts +8 -3
  90. package/dist/application-spec/generate-application/runtime/application-runtime.js +1 -1
  91. package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-runtime.d.ts +5 -3
  92. package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-runtime.js +1 -1
  93. package/dist/application-spec/generate-application/runtime/factory-data/factory-data-runtime.d.ts +43 -0
  94. package/dist/application-spec/generate-application/runtime/factory-data/factory-data-runtime.js +1 -0
  95. package/dist/application-spec/generate-application/runtime/factory-data/index.d.ts +3 -0
  96. package/dist/application-spec/generate-application/runtime/factory-data/index.js +1 -0
  97. package/dist/application-spec/generate-application/runtime/factory-data/recipe-defaults.d.ts +13 -0
  98. package/dist/application-spec/generate-application/runtime/factory-data/recipe-defaults.js +1 -0
  99. package/dist/application-spec/generate-application/runtime/factory-data/static-violations.d.ts +16 -0
  100. package/dist/application-spec/generate-application/runtime/factory-data/static-violations.js +1 -0
  101. package/dist/application-spec/generate-application/runtime/migrations/index.d.ts +1 -0
  102. package/dist/application-spec/generate-application/runtime/migrations/index.js +1 -0
  103. package/dist/application-spec/generate-application/runtime/migrations/migration-runtime.d.ts +53 -0
  104. package/dist/application-spec/generate-application/runtime/migrations/migration-runtime.js +1 -0
  105. package/dist/application-spec/generate-application/runtime/sections/assistant-runtime.d.ts +4 -3
  106. package/dist/application-spec/generate-application/runtime/sections/assistant-runtime.js +1 -1
  107. package/dist/application-spec/generate-application/runtime/sections/build-sdk-optic.d.ts +1 -1
  108. package/dist/application-spec/generate-application/runtime/sections/build-sdk-optic.js +1 -1
  109. package/dist/application-spec/generate-application/runtime/sections/component-optic.d.ts +2 -1
  110. package/dist/application-spec/generate-application/runtime/sections/expression-runtime.js +1 -1
  111. package/dist/application-spec/generate-application/runtime/sections/transformers-runtime.d.ts +2 -4
  112. package/dist/application-spec/index.d.ts +1 -0
  113. package/dist/application-spec/index.js +1 -1
  114. package/dist/application-spec/parse-application-files/categorize/categorize-files.d.ts +6 -0
  115. package/dist/application-spec/parse-application-files/categorize/categorize-files.js +1 -1
  116. package/dist/application-spec/parse-application-files/categorize/module-analysis.d.ts +1 -1
  117. package/dist/application-spec/parse-application-files/categorize/module-analysis.js +1 -1
  118. package/dist/application-spec/parse-application-files/raw-spec/raw-assistant.d.ts +16 -3
  119. package/dist/application-spec/parse-application-files/raw-spec/raw-assistant.js +1 -1
  120. package/dist/application-spec/parse-application-files/raw-spec/raw-spec-file.js +1 -1
  121. package/dist/application-spec/parse-application-files/spec/application/admin-spec/admin-spec.js +1 -1
  122. package/dist/application-spec/parse-application-files/spec/application/configurator-spec/configurator-spec.js +1 -1
  123. package/dist/application-spec/parse-application-files/spec/components/component-entry.d.ts +1 -9
  124. package/dist/application-spec/parse-application-files/spec/components/component-entry.js +1 -1
  125. package/dist/application-spec/parse-application-files/spec/components/component-filter.d.ts +1 -54
  126. package/dist/application-spec/parse-application-files/spec/components/component-filter.js +1 -1
  127. package/dist/application-spec/parse-application-files/spec/components/index.d.ts +1 -1
  128. package/dist/application-spec/parse-application-files/spec/components/index.js +1 -1
  129. package/dist/application-spec/parse-application-files/spec/expressions/expression.d.ts +1 -28
  130. package/dist/application-spec/parse-application-files/spec/expressions/expression.js +1 -1
  131. package/dist/application-spec/parse-application-files/spec/expressions/expressions.d.ts +1 -1
  132. package/dist/application-spec/parse-application-files/spec/expressions/expressions.js +1 -1
  133. package/dist/application-spec/parse-application-files/spec/expressions/index.d.ts +0 -1
  134. package/dist/application-spec/parse-application-files/spec/expressions/index.js +1 -1
  135. package/dist/application-spec/parse-application-files/spec/expressions/memo-eval-plan.js +1 -1
  136. package/dist/application-spec/parse-application-files/spec/expressions/user-expressions.js +1 -1
  137. package/dist/application-spec/parse-application-files/spec/model/defaults.d.ts +7 -2
  138. package/dist/application-spec/parse-application-files/spec/model/defaults.js +1 -1
  139. package/dist/application-spec/parse-application-files/spec/relations/reference-field-type.d.ts +25 -0
  140. package/dist/application-spec/parse-application-files/spec/relations/reference-field-type.js +1 -0
  141. package/dist/application-spec/parse-application-files/spec/relations/relation-field-mismatch.d.ts +46 -0
  142. package/dist/application-spec/parse-application-files/spec/relations/relation-field-mismatch.js +1 -0
  143. package/dist/application-spec/parse-application-files/spec/relations/relations.d.ts +4 -3
  144. package/dist/application-spec/parse-application-files/spec/relations/relations.js +1 -1
  145. package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-field-type.d.ts +3 -8
  146. package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-field-type.js +1 -1
  147. package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-schema.d.ts +9 -43
  148. package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-schema.js +1 -1
  149. package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-server-settings.d.ts +2 -2
  150. package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant.d.ts +5 -21
  151. package/dist/application-spec/parse-application-files/spec/sections/infra.d.ts +2 -0
  152. package/dist/application-spec/parse-application-files/spec/sections/infra.js +1 -1
  153. package/dist/client/authorized-client.d.ts +3 -1
  154. package/dist/client/authorized-client.js +1 -1
  155. package/dist/client/contract.d.ts +34 -0
  156. package/dist/client/contract.js +1 -1
  157. package/dist/client/index.d.ts +2 -2
  158. package/dist/client/index.js +1 -1
  159. package/dist/client/local-authorized-client.d.ts +3 -1
  160. package/dist/client/local-authorized-client.js +1 -1
  161. package/dist/client/memory-authorized-client.d.ts +3 -1
  162. package/dist/client/memory-authorized-client.js +1 -1
  163. package/dist/client/phoenix-api.d.ts +367 -30
  164. package/dist/configurator/application-runtime/extensions/create-configurator-extensions.js +1 -1
  165. package/dist/configurator/application-runtime/extensions/selectors.d.ts +3 -1
  166. package/dist/configurator/application-runtime/extensions/selectors.js +1 -1
  167. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.d.ts +136 -6
  168. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.js +1 -1
  169. package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.d.ts +7 -1
  170. package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.js +1 -1
  171. package/dist/configurator/application-runtime/extensions/systems/drag-and-drop-system/drag-and-drop-system.d.ts +3 -3
  172. package/dist/configurator/application-runtime/extensions/systems/graphql-system/entity-meta.js +1 -1
  173. package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.d.ts +20 -4
  174. package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.js +1 -1
  175. package/dist/configurator/application-runtime/extensions/systems/graphql-system/inject-assistant-lenses.d.ts +11 -0
  176. package/dist/configurator/application-runtime/extensions/systems/graphql-system/inject-assistant-lenses.js +1 -0
  177. package/dist/configurator/application-runtime/extensions/systems/index.d.ts +1 -1
  178. package/dist/configurator/application-runtime/extensions/systems/layout-system/layout-system.d.ts +2 -2
  179. package/dist/configurator/application-runtime/extensions/systems/layout-system/layout-system.js +1 -1
  180. package/dist/configurator/common/configurator-interface.d.ts +26 -1
  181. package/dist/configurator/common/configurator-interface.js +1 -1
  182. package/dist/configurator/common/frontend-analytics.d.ts +2 -0
  183. package/dist/configurator/common/frontend-analytics.js +1 -1
  184. package/dist/configurator/common/index.d.ts +2 -0
  185. package/dist/configurator/common/index.js +1 -1
  186. package/dist/configurator/common/use-finalize-action.d.ts +31 -0
  187. package/dist/configurator/common/use-finalize-action.js +1 -0
  188. package/dist/configurator/common/use-reset-camera.d.ts +6 -0
  189. package/dist/configurator/common/use-reset-camera.js +1 -0
  190. package/dist/configurator/configurator-context/configurator-hooks/layout-hooks.d.ts +1 -1
  191. package/dist/configurator/pages/DefaultConfiguratorLayout.d.ts +6 -0
  192. package/dist/configurator/pages/DefaultConfiguratorLayout.js +1 -0
  193. package/dist/configurator/pages/LoadedConfiguratorDetailPage.js +1 -1
  194. package/dist/configurator/pages/configurator-layout-name.d.ts +2 -0
  195. package/dist/configurator/pages/configurator-layout-name.js +1 -0
  196. package/dist/configurator/pages/default-configurator-elements.d.ts +7 -0
  197. package/dist/configurator/pages/default-configurator-elements.js +1 -0
  198. package/dist/configurator/pages/index.d.ts +1 -0
  199. package/dist/configurator/pages/index.js +1 -1
  200. package/dist/configurator/scene/scene-controls/hotspot-drag-handle/HotspotDragHandle.d.ts +1 -1
  201. package/dist/configurator/scene/scene-controls/hotspot-drag-handle/HotspotDragSceneHandle.d.ts +1 -1
  202. package/dist/configurator/scene/scene-entity/dimension-indicators/DimensionIndicator.d.ts +1 -1
  203. package/dist/configurator/scene/scene-entity/dimension-indicators/DimensionIndicatorInternal.d.ts +1 -1
  204. package/dist/configurator/scene/scene-entity/drag-and-drop/shared.d.ts +2 -2
  205. package/dist/configurator/scene/scene-entity/drag-and-drop/use-drag-object.d.ts +1 -1
  206. package/dist/configurator/scene/scene-entity/materials/RemoteReplacedMaterial.js +1 -1
  207. package/dist/configurator/scene/scene-entity/objects/SceneEntityObjectTextDecal.d.ts +1 -1
  208. package/dist/configurator/ui/assistant/AssistantChips.d.ts +8 -2
  209. package/dist/configurator/ui/assistant/AssistantChips.js +1 -1
  210. package/dist/configurator/ui/assistant/AssistantComposer.d.ts +2 -1
  211. package/dist/configurator/ui/assistant/AssistantComposer.js +1 -1
  212. package/dist/configurator/ui/assistant/AssistantMarkdown.d.ts +1 -1
  213. package/dist/configurator/ui/assistant/AssistantMarkdown.js +1 -1
  214. package/dist/configurator/ui/assistant/AssistantThread.d.ts +6 -2
  215. package/dist/configurator/ui/assistant/AssistantThread.js +1 -1
  216. package/dist/configurator/ui/assistant/entity-link/AssistantEntityLink.d.ts +13 -0
  217. package/dist/configurator/ui/assistant/entity-link/AssistantEntityLink.js +1 -0
  218. package/dist/configurator/ui/assistant/entity-link/entity-link-selection.d.ts +22 -0
  219. package/dist/configurator/ui/assistant/entity-link/entity-link-selection.js +1 -0
  220. package/dist/configurator/ui/assistant/entity-link/entity-link-state.d.ts +27 -0
  221. package/dist/configurator/ui/assistant/entity-link/entity-link-state.js +1 -0
  222. package/dist/configurator/ui/assistant/entity-link/entity-link-target.d.ts +5 -0
  223. package/dist/configurator/ui/assistant/entity-link/entity-link-target.js +1 -0
  224. package/dist/configurator/ui/assistant/entity-link/index.d.ts +3 -0
  225. package/dist/configurator/ui/assistant/entity-link/index.js +1 -0
  226. package/dist/configurator/ui/assistant/thread-items.d.ts +13 -2
  227. package/dist/configurator/ui/assistant/thread-items.js +1 -1
  228. package/dist/configurator/ui/assistant/tool-chip.d.ts +8 -1
  229. package/dist/configurator/ui/assistant/tool-chip.js +1 -1
  230. package/dist/configurator/ui/configurator-layout/sidebar-keys/index.d.ts +1 -0
  231. package/dist/configurator/ui/configurator-layout/sidebar-keys/index.js +1 -0
  232. package/dist/configurator/ui/configurator-layout/sidebar-keys/sidebar-keys.d.ts +11 -0
  233. package/dist/configurator/ui/configurator-layout/sidebar-keys/sidebar-keys.js +1 -0
  234. package/dist/configurator/ui/configurator-layout/slots/desktop-sidebar/DesktopSidebar.d.ts +101 -0
  235. package/dist/configurator/ui/configurator-layout/slots/desktop-sidebar/DesktopSidebar.js +16 -0
  236. package/dist/configurator/ui/configurator-layout/slots/desktop-sidebar/index.d.ts +1 -0
  237. package/dist/configurator/ui/configurator-layout/slots/desktop-sidebar/index.js +1 -0
  238. package/dist/configurator/ui/configurator-layout/slots/services/InvariantViolations.d.ts +4 -4
  239. package/dist/configurator/ui/configurator-layout/slots/services/InvariantViolations.js +1 -1
  240. package/dist/configurator/ui/configurator-layout/slots/services/SideEffects.d.ts +3 -6
  241. package/dist/configurator/ui/configurator-layout/slots/services/SideEffects.js +1 -1
  242. package/dist/configurator/ui/configurator-layout/slots/slots.d.ts +1 -0
  243. package/dist/configurator/ui/configurator-layout/slots/slots.js +1 -1
  244. package/dist/configurator/ui/configurator-layout/universal/DesktopLayout.d.ts +0 -74
  245. package/dist/configurator/ui/configurator-layout/universal/DesktopLayout.js +5 -20
  246. package/dist/configurator/ui/configurator-layout/universal/DesktopPreview.js +1 -1
  247. package/dist/configurator/ui/configurator-layout/universal/MobileLayout.js +4 -4
  248. package/dist/configurator/ui/configurator-layout/universal/MobilePreview.js +1 -1
  249. package/dist/configurator/ui/configurator-layout/universal/use-layout-scene-safe-area.d.ts +47 -0
  250. package/dist/configurator/ui/configurator-layout/universal/use-layout-scene-safe-area.js +1 -0
  251. package/dist/configurator/ui/configurator-layout/universal/use-scene-safe-area.d.ts +11 -26
  252. package/dist/configurator/ui/configurator-layout/universal/use-scene-safe-area.js +1 -1
  253. package/dist/configurator/ui/legacy/layout/steps/StepsNavigation.d.ts +2 -2
  254. package/dist/configurator/ui/phoenix-layout-elements/header/common/step-navigation/StepsNavigation.d.ts +2 -2
  255. package/dist/docs/complex-use-cases/filtered-controls-with-fix-dialog.mdx +100 -117
  256. package/dist/docs/complex-use-cases/navigation-reset-selection.mdx +18 -12
  257. package/dist/docs/complex-use-cases/sketching.mdx +0 -38
  258. package/dist/docs/controls/select-attribute/cardselect.mdx +9 -13
  259. package/dist/docs/dimensions/3d-scene-integration/dimension-indicators.mdx +2 -2
  260. package/dist/docs/dimensions/3d-scene-integration/editable-angle-indicator.mdx +1 -1
  261. package/dist/docs/dimensions/3d-scene-integration/editable-distance-dimension-indicator.mdx +1 -1
  262. package/dist/docs/dimensions/3d-scene-integration/list-selector-dimension-indicator.mdx +1 -1
  263. package/dist/docs/drag-and-drop/drag-handle.mdx +1 -1
  264. package/dist/docs/drag-and-drop/hotspot-handle.mdx +1 -1
  265. package/dist/docs/drag-and-drop/planes.mdx +1 -1
  266. package/dist/docs/drag-and-drop/rotatable.mdx +2 -2
  267. package/dist/docs/index.json +42 -1
  268. package/dist/docs/integrations/woocommerce/local-development.mdx +1 -1
  269. package/dist/docs/layouts/custom-layout.mdx +1404 -0
  270. package/dist/docs/layouts/custom-price.mdx +14 -16
  271. package/dist/docs/layouts/header/fixed.mdx +2 -2
  272. package/dist/docs/layouts/header/floating.mdx +2 -2
  273. package/dist/docs/layouts/sidebar/in-a-custom-layout.mdx +380 -0
  274. package/dist/docs/layouts/sidebar/tabs.mdx +24 -21
  275. package/dist/docs/layouts/sidebar-footer/basic.mdx +32 -77
  276. package/dist/docs/other-features/client-side-rendering/declarative.mdx +1 -1
  277. package/dist/docs/other-features/domain-actions.mdx +1 -1
  278. package/dist/docs/other-features/side-effects.mdx +50 -45
  279. package/dist/docs/other-features/transformers.mdx +5 -1
  280. package/dist/docs/other-features/violation-messages.mdx +52 -56
  281. package/dist/docs/phoenix/admin.mdx +9 -24
  282. package/dist/docs/phoenix/application-states.mdx +9 -7
  283. package/dist/docs/phoenix/configurator-interface.mdx +237 -80
  284. package/dist/docs/phoenix/deployments.mdx +1 -1
  285. package/dist/docs/phoenix/domain-model.mdx +4 -0
  286. package/dist/docs/phoenix/expression-context.mdx +11 -3
  287. package/dist/docs/phoenix/finalization.mdx +1 -1
  288. package/dist/docs/phoenix/getting-started.mdx +1 -1
  289. package/dist/docs/phoenix/layout-slots.mdx +116 -0
  290. package/dist/docs/phoenix/localization.mdx +3 -22
  291. package/dist/docs/phoenix/phoenix-cli.mdx +52 -50
  292. package/dist/docs/phoenix/project-structure.mdx +27 -11
  293. package/dist/docs/phoenix/quickstart.mdx +2 -2
  294. package/dist/docs/phoenix/sdk-builder-workflow.mdx +12 -11
  295. package/dist/docs/phoenix/testing.mdx +140 -0
  296. package/dist/docs/phoenix/webhook-membership.mdx +10 -9
  297. package/dist/docs/phoenix/webhooks.mdx +19 -2
  298. package/dist/docs/recipes-and-delete/recipe-hierarchy-selection.mdx +15 -13
  299. package/dist/docs/relations/hierarchy.mdx +13 -2
  300. package/dist/docs/ux-guidelines/choosing-a-control.mdx +11 -0
  301. package/dist/domain/admin-domain/__generated/enhanced-model.d.ts +1 -2
  302. package/dist/domain/admin-domain/__generated/model/versions/v1.d.ts +1 -1
  303. package/dist/domain/admin-domain/__generated/model/versions/v2.d.ts +1 -1
  304. package/dist/domain/admin-domain/__generated/model/versions/v3.d.ts +1 -1
  305. package/dist/domain/admin-domain/__generated/model/versions/v4.d.ts +1 -1
  306. package/dist/domain/admin-domain/__generated/model/versions/v5.d.ts +1 -1
  307. package/dist/domain/admin-domain/__generated/model/versions/v6.d.ts +2 -2
  308. package/dist/domain/admin-domain/__generated/model/versions/v6.js +1 -1
  309. package/dist/domain/admin-domain/implementation/common-admin-expressions.d.ts +26 -14
  310. package/dist/domain/admin-domain/implementation/common-admin-migrations.d.ts +1 -1
  311. package/dist/domain/admin-domain/implementation/common-admin-publish.d.ts +1 -2
  312. package/dist/domain/admin-domain/index.d.ts +9 -5
  313. package/dist/domain/admin-domain/index.js +1 -1
  314. package/dist/domain/application/GetApplicationWrapperHandler.d.ts +2 -2
  315. package/dist/domain/application/GetThemeHandler.d.ts +1 -1
  316. package/dist/domain/application/GetWebComponentOptions.d.ts +1 -1
  317. package/dist/domain/application/admin-page-factories.d.ts +1 -2
  318. package/dist/domain/application/application-config.d.ts +30 -97
  319. package/dist/domain/application/assistant/assistant-fields.d.ts +12 -0
  320. package/dist/domain/application/assistant/assistant-fields.js +1 -0
  321. package/dist/domain/application/assistant/assistant-manifest.d.ts +71 -0
  322. package/dist/domain/application/assistant/assistant-resolved-manifest.d.ts +131 -0
  323. package/dist/domain/application/assistant/assistant-resolved-manifest.js +1 -0
  324. package/dist/domain/application/assistant/assistant-value-type.d.ts +9 -0
  325. package/dist/domain/application/assistant/assistant-value-type.js +1 -0
  326. package/dist/domain/application/assistant/build-assistant-lenses.d.ts +14 -0
  327. package/dist/domain/application/assistant/build-assistant-lenses.js +5 -0
  328. package/dist/domain/application/assistant/build-assistant-manifest.d.ts +4 -0
  329. package/dist/domain/application/assistant/build-assistant-manifest.js +1 -0
  330. package/dist/domain/application/assistant/create-assistant-execution-schema.d.ts +32 -0
  331. package/dist/domain/application/assistant/create-assistant-execution-schema.js +1 -0
  332. package/dist/domain/application/assistant/generate-assistant-prompt.d.ts +3 -0
  333. package/dist/domain/application/assistant/generate-assistant-prompt.js +1 -0
  334. package/dist/domain/application/assistant/index.d.ts +9 -0
  335. package/dist/domain/application/assistant/index.js +1 -0
  336. package/dist/domain/application/assistant/session-setup/AssistantSetupHandler.d.ts +20 -0
  337. package/dist/domain/application/assistant/session-setup/AssistantSetupHandler.js +1 -0
  338. package/dist/domain/application/assistant/session-setup/apply-assistant-setup.d.ts +10 -0
  339. package/dist/domain/application/assistant/session-setup/apply-assistant-setup.js +1 -0
  340. package/dist/domain/application/assistant/session-setup/assistant-setup-manifest.d.ts +48 -0
  341. package/dist/domain/application/assistant/session-setup/assistant-setup-manifest.js +1 -0
  342. package/dist/domain/application/assistant/session-setup/create-session-assistant.d.ts +15 -0
  343. package/dist/domain/application/assistant/session-setup/create-session-assistant.js +1 -0
  344. package/dist/domain/application/assistant/session-setup/index.d.ts +4 -0
  345. package/dist/domain/application/assistant/session-setup/index.js +1 -0
  346. package/dist/domain/application/assistant-field-options.d.ts +2 -3
  347. package/dist/domain/application/assistant-mutations.d.ts +3 -5
  348. package/dist/domain/application/assistant-mutations.js +1 -1
  349. package/dist/domain/application/assistant-recipe-groups.d.ts +3 -7
  350. package/dist/domain/application/configurator-builder.d.ts +36 -18
  351. package/dist/domain/application/configurator-builder.js +1 -1
  352. package/dist/domain/application/create-initial-published-data.d.ts +6 -7
  353. package/dist/domain/application/index.d.ts +3 -6
  354. package/dist/domain/application/index.js +1 -1
  355. package/dist/domain/application/published-data/DataRowValidatorHandler.d.ts +1 -1
  356. package/dist/domain/application/published-data/FilterPublishedChunksHandler.d.ts +1 -1
  357. package/dist/domain/application/published-data/MapPublishedChunkedDataHandler.d.ts +1 -1
  358. package/dist/domain/application/published-data/MapPublishedRevisionDataHandler.d.ts +1 -1
  359. package/dist/domain/application/published-data/SheetValidatorHandler.d.ts +1 -1
  360. package/dist/domain/application/published-data/build-legend-data.d.ts +1 -1
  361. package/dist/domain/application/published-data/create-finalize-admin-domain.d.ts +1 -2
  362. package/dist/domain/application/published-data/format-field-type.d.ts +1 -1
  363. package/dist/domain/application/published-data/map-data-to-sheet.d.ts +1 -1
  364. package/dist/domain/application/published-data/map-published-chunked-data.d.ts +3 -3
  365. package/dist/domain/application/published-data/map-published-data.d.ts +7 -4
  366. package/dist/domain/application/published-data/validate-sheet-data.d.ts +1 -1
  367. package/dist/domain/available-system-components.js +1 -1
  368. package/dist/domain/core/action/action-factory.d.ts +11 -0
  369. package/dist/domain/core/{action.d.ts → action/action.d.ts} +22 -18
  370. package/dist/domain/core/action/index.d.ts +2 -0
  371. package/dist/domain/core/action/index.js +1 -0
  372. package/dist/domain/{components → core/component}/component-reader-types.d.ts +1 -2
  373. package/dist/domain/{components → core/component}/debug-state-component.d.ts +1 -1
  374. package/dist/domain/core/component/debug-state-component.js +1 -0
  375. package/dist/domain/core/component/domain-component-optic.d.ts +65 -0
  376. package/dist/domain/core/component/domain-component-optic.js +16 -0
  377. package/dist/domain/{components → core/component}/drag-state-component.d.ts +1 -1
  378. package/dist/domain/core/component/drag-state-component.js +1 -0
  379. package/dist/domain/{components → core/component}/export-state-component.d.ts +1 -1
  380. package/dist/domain/core/component/export-state-component.js +1 -0
  381. package/dist/domain/{components → core/component}/fullscreen-state-component.d.ts +1 -1
  382. package/dist/domain/core/component/fullscreen-state-component.js +1 -0
  383. package/dist/domain/{components → core/component}/group-components-by-entity-id-and-name.d.ts +1 -2
  384. package/dist/domain/core/component/group-components-by-entity-id-and-name.js +1 -0
  385. package/dist/domain/{components → core/component}/hover-state-component.d.ts +1 -1
  386. package/dist/domain/core/component/hover-state-component.js +1 -0
  387. package/dist/domain/core/component/index.d.ts +18 -0
  388. package/dist/domain/core/component/index.js +1 -0
  389. package/dist/domain/{components → core/component}/legacy-filter.d.ts +4 -19
  390. package/dist/domain/{components → core/component}/navigation-state-component.d.ts +1 -1
  391. package/dist/domain/core/component/navigation-state-component.js +1 -0
  392. package/dist/domain/{components → core/component}/selection-state-component.d.ts +1 -1
  393. package/dist/domain/core/component/selection-state-component.js +1 -0
  394. package/dist/domain/{components → core/component}/system-component-builder.d.ts +1 -2
  395. package/dist/domain/core/component/system-component-builder.js +1 -0
  396. package/dist/domain/{components → core/component}/system-component-filter.d.ts +38 -20
  397. package/dist/domain/core/component/system-virtual-entity.js +1 -0
  398. package/dist/domain/{components → core/component}/tool-state-component.d.ts +1 -1
  399. package/dist/domain/core/component/tool-state-component.js +1 -0
  400. package/dist/domain/{components → core/component}/updates.d.ts +1 -2
  401. package/dist/domain/{components → core/component}/view-state-component.d.ts +1 -1
  402. package/dist/domain/core/component/view-state-component.js +1 -0
  403. package/dist/domain/{components → core/component}/viewport-state-component.d.ts +1 -1
  404. package/dist/domain/core/component/viewport-state-component.js +1 -0
  405. package/dist/domain/core/data-schema/data-cell-value.d.ts +4 -0
  406. package/dist/domain/core/data-schema/data-schema-array-field.d.ts +5 -0
  407. package/dist/domain/core/data-schema/data-schema-field-object.d.ts +4 -0
  408. package/dist/domain/core/data-schema/data-schema-field.d.ts +2 -0
  409. package/dist/domain/core/data-schema/data-schema-field.js +1 -0
  410. package/dist/domain/core/data-schema/data-schema-localized-field.d.ts +4 -0
  411. package/dist/domain/core/data-schema/data-schema-localized-field.js +1 -0
  412. package/dist/domain/core/data-schema/data-schema-primitive-field.d.ts +5 -0
  413. package/dist/domain/core/data-schema/data-schema-primitive-field.js +1 -0
  414. package/dist/domain/core/data-schema/data-schema.d.ts +2 -0
  415. package/dist/domain/core/data-schema/data-schema.js +1 -0
  416. package/dist/domain/core/data-schema/index.d.ts +7 -0
  417. package/dist/domain/core/data-schema/index.js +1 -0
  418. package/dist/domain/core/decoder/create-decoder.d.ts +6 -0
  419. package/dist/domain/core/decoder/create-decoder.js +1 -0
  420. package/dist/domain/core/decoder/decoder.d.ts +6 -0
  421. package/dist/domain/core/decoder/decoder.js +1 -0
  422. package/dist/domain/core/decoder/index.d.ts +2 -0
  423. package/dist/domain/core/decoder/index.js +1 -0
  424. package/dist/domain/core/domain-factory.d.ts +4 -5
  425. package/dist/domain/core/domain-factory.js +1 -1
  426. package/dist/domain/core/domain.d.ts +4 -5
  427. package/dist/domain/core/domain.js +1 -1
  428. package/dist/domain/core/emission/index.d.ts +8 -0
  429. package/dist/domain/core/emission/index.js +1 -0
  430. package/dist/domain/core/emission/reset-state-emission.d.ts +12 -0
  431. package/dist/domain/core/emission/reset-state-emission.js +1 -0
  432. package/dist/domain/core/emission/state-emission.d.ts +4 -0
  433. package/dist/domain/core/emission/state-emission.js +1 -0
  434. package/dist/domain/core/emission/state-update-emission.d.ts +14 -0
  435. package/dist/domain/core/emission/state-update-emission.js +1 -0
  436. package/dist/domain/core/emission/state-validation-result.d.ts +18 -0
  437. package/dist/domain/core/emission/state-validation-result.js +1 -0
  438. package/dist/domain/core/emission/transformation-log.d.ts +2 -0
  439. package/dist/domain/core/emission/transformation-log.js +1 -0
  440. package/dist/domain/core/emission/transformer-log-entry.d.ts +6 -0
  441. package/dist/domain/core/emission/transformer-log-entry.js +1 -0
  442. package/dist/domain/core/emission/transformer-log.d.ts +11 -0
  443. package/dist/domain/core/emission/transformer-log.js +1 -0
  444. package/dist/domain/core/emission/transformer-phase.d.ts +1 -0
  445. package/dist/domain/core/emission/transformer-phase.js +1 -0
  446. package/dist/domain/core/expression/aliased-expressions.d.ts +10 -0
  447. package/dist/domain/core/expression/aliased-expressions.js +1 -0
  448. package/dist/domain/core/expression/constant-expressions.d.ts +16 -0
  449. package/dist/domain/core/expression/constant-expressions.js +1 -0
  450. package/dist/domain/core/expression/custom-expression.d.ts +25 -0
  451. package/dist/domain/core/expression/custom-expression.js +1 -0
  452. package/dist/domain/core/expression/expression.d.ts +46 -0
  453. package/dist/domain/core/expression/expression.js +1 -0
  454. package/dist/domain/core/expression/index.d.ts +4 -0
  455. package/dist/domain/core/expression/index.js +1 -0
  456. package/dist/domain/core/index.d.ts +13 -17
  457. package/dist/domain/core/index.js +1 -1
  458. package/dist/domain/{invariants → core/invariant}/builtin-invariant.d.ts +2 -2
  459. package/dist/domain/core/invariant/custom-invariants.d.ts +13 -0
  460. package/dist/domain/core/invariant/custom-invariants.js +1 -0
  461. package/dist/domain/core/invariant/index.d.ts +5 -0
  462. package/dist/domain/core/invariant/index.js +1 -0
  463. package/dist/domain/core/invariant/invariants.d.ts +10 -0
  464. package/dist/domain/core/invariant/invariants.js +1 -0
  465. package/dist/domain/core/invariant/violation-component.js +1 -0
  466. package/dist/domain/{invariants → core/invariant}/violation.d.ts +52 -4
  467. package/dist/domain/core/invariant/violation.js +1 -0
  468. package/dist/domain/core/{component.d.ts → model/component.d.ts} +1 -1
  469. package/dist/domain/core/model/index.d.ts +6 -0
  470. package/dist/domain/core/model/index.js +1 -0
  471. package/dist/domain/core/{model.d.ts → model/model.d.ts} +1 -1
  472. package/dist/domain/core/{reflection.d.ts → model/reflection.d.ts} +1 -1
  473. package/dist/domain/core/model/reflection.js +1 -0
  474. package/dist/domain/core/recipe/index.d.ts +1 -0
  475. package/dist/domain/core/recipe/index.js +1 -0
  476. package/dist/domain/core/recipe/recipes.d.ts +23 -0
  477. package/dist/domain/core/recipe/recipes.js +1 -0
  478. package/dist/domain/core/relation/all-of-type-relation.d.ts +19 -0
  479. package/dist/domain/core/relation/all-of-type-relation.js +1 -0
  480. package/dist/domain/{relations → core/relation}/component-factories.d.ts +1 -2
  481. package/dist/domain/core/relation/component-factories.js +1 -0
  482. package/dist/domain/{relations → core/relation}/composed-of.d.ts +1 -1
  483. package/dist/domain/core/relation/composed-of.js +1 -0
  484. package/dist/domain/core/relation/direct-relation.d.ts +17 -0
  485. package/dist/domain/core/relation/index.d.ts +8 -0
  486. package/dist/domain/core/relation/index.js +1 -0
  487. package/dist/domain/core/relation/indirect-relation.d.ts +25 -0
  488. package/dist/domain/core/relation/indirect-relation.js +1 -0
  489. package/dist/domain/{relations → core/relation}/reference-component.d.ts +4 -5
  490. package/dist/domain/core/relation/reference-component.js +1 -0
  491. package/dist/domain/{relations → core/relation}/reference-field.d.ts +1 -1
  492. package/dist/domain/core/relation/reference-field.js +1 -0
  493. package/dist/domain/core/relation/relation-factory.d.ts +22 -0
  494. package/dist/domain/core/relation/relation-factory.js +1 -0
  495. package/dist/domain/core/schema/enhanced-json-schema.js +1 -0
  496. package/dist/domain/core/schema/extended-schema-validator.js +1 -0
  497. package/dist/domain/core/schema/index.d.ts +3 -0
  498. package/dist/domain/core/schema/index.js +1 -0
  499. package/dist/domain/core/schema/schema-validator.js +1 -0
  500. package/dist/domain/core/state/id-sequence.d.ts +15 -0
  501. package/dist/domain/core/state/id-sequence.js +1 -0
  502. package/dist/domain/core/state/index.d.ts +3 -0
  503. package/dist/domain/core/state/index.js +1 -0
  504. package/dist/domain/core/{migrations.d.ts → state/migrations.d.ts} +15 -47
  505. package/dist/domain/core/state/migrations.js +1 -0
  506. package/dist/domain/core/{state.d.ts → state/state.d.ts} +2 -3
  507. package/dist/domain/domain-builder.d.ts +11 -11
  508. package/dist/domain/domain-builder.js +1 -1
  509. package/dist/domain/domain-context/action-system/action-system.d.ts +2 -4
  510. package/dist/domain/domain-context/action-system/action-system.js +1 -1
  511. package/dist/domain/domain-context/action-system/index.d.ts +1 -0
  512. package/dist/domain/domain-context/action-system/index.js +1 -0
  513. package/dist/domain/domain-context/analytics-system/index.d.ts +2 -0
  514. package/dist/domain/domain-context/analytics-system/index.js +1 -0
  515. package/dist/domain/domain-context/create-transformer.d.ts +2 -2
  516. package/dist/domain/domain-context/dimension-system/dimension-state.js +1 -1
  517. package/dist/domain/domain-context/dimension-system/dimension-system.d.ts +3 -4
  518. package/dist/domain/domain-context/dimension-system/dimension-system.js +1 -1
  519. package/dist/domain/domain-context/dimension-system/index.d.ts +1 -0
  520. package/dist/domain/domain-context/dimension-system/index.js +1 -0
  521. package/dist/domain/domain-context/domain-context-systems.d.ts +8 -10
  522. package/dist/domain/domain-context/index.d.ts +8 -18
  523. package/dist/domain/domain-context/index.js +1 -1
  524. package/dist/domain/domain-context/navigation-system/index.d.ts +3 -0
  525. package/dist/domain/domain-context/navigation-system/index.js +1 -0
  526. package/dist/domain/domain-context/navigation-system/navigation-system.d.ts +5 -8
  527. package/dist/domain/domain-context/navigation-system/navigation-system.js +1 -1
  528. package/dist/domain/domain-context/navigation-system/navigation-updates.d.ts +1 -12
  529. package/dist/domain/domain-context/navigation-system/navigation-updates.js +1 -1
  530. package/dist/domain/domain-context/navigation-system/selection-transformers.d.ts +2 -2
  531. package/dist/domain/domain-context/navigation-system/selection-transformers.js +1 -1
  532. package/dist/domain/domain-context/recipe-system/index.d.ts +1 -0
  533. package/dist/domain/domain-context/recipe-system/index.js +1 -0
  534. package/dist/domain/domain-context/recipe-system/recipe-cooker-system.d.ts +2 -4
  535. package/dist/domain/domain-context/recipe-system/recipe-cooker-system.js +1 -1
  536. package/dist/domain/domain-context/relation-transformers/cascade-deletes.d.ts +3 -3
  537. package/dist/domain/domain-context/relation-transformers/cascade-deletes.js +1 -1
  538. package/dist/domain/domain-context/relation-transformers/cascade-ref-pruning.d.ts +3 -3
  539. package/dist/domain/domain-context/relation-transformers/cascade-ref-pruning.js +1 -1
  540. package/dist/domain/domain-context/relation-transformers/create-entity-refs.d.ts +3 -3
  541. package/dist/domain/domain-context/relation-transformers/create-entity-refs.js +2 -2
  542. package/dist/domain/domain-context/relation-transformers/index.d.ts +4 -0
  543. package/dist/domain/domain-context/relation-transformers/index.js +1 -0
  544. package/dist/domain/domain-context/relation-transformers/replace-refs.d.ts +3 -3
  545. package/dist/domain/domain-context/relation-transformers/replace-refs.js +1 -1
  546. package/dist/domain/domain-context/store-system/apply-updates.d.ts +1 -3
  547. package/dist/domain/domain-context/store-system/apply-updates.js +1 -1
  548. package/dist/domain/domain-context/store-system/index.d.ts +4 -0
  549. package/dist/domain/domain-context/store-system/index.js +1 -0
  550. package/dist/domain/domain-context/store-system/next-domain-entity-id.d.ts +1 -13
  551. package/dist/domain/domain-context/store-system/next-domain-entity-id.js +1 -1
  552. package/dist/domain/domain-context/store-system/reconcile-projected-entities.d.ts +1 -2
  553. package/dist/domain/domain-context/store-system/reconcile-projected-entities.js +1 -1
  554. package/dist/domain/domain-context/store-system/store-system.d.ts +2 -39
  555. package/dist/domain/domain-context/store-system/store-system.js +2 -2
  556. package/dist/domain/domain-context/store-system/system-state.d.ts +2 -4
  557. package/dist/domain/domain-context/store-system/system-state.js +1 -1
  558. package/dist/domain/domain-context/transformers/actions-builder.d.ts +1 -2
  559. package/dist/domain/domain-context/transformers/actions-builder.js +1 -1
  560. package/dist/domain/domain-context/transformers/auto-snap-transformer.d.ts +6 -10
  561. package/dist/domain/domain-context/transformers/auto-snap-transformer.js +1 -1
  562. package/dist/domain/domain-context/transformers/chain-builder.d.ts +3 -3
  563. package/dist/domain/domain-context/transformers/context.d.ts +2 -7
  564. package/dist/domain/domain-context/transformers/context.js +1 -1
  565. package/dist/domain/domain-context/transformers/entity-builder.d.ts +1 -5
  566. package/dist/domain/domain-context/transformers/entity-builder.js +1 -1
  567. package/dist/domain/domain-context/transformers/index.d.ts +1 -1
  568. package/dist/domain/domain-context/transformers/index.js +1 -1
  569. package/dist/domain/domain-context/transformers/then-builder.d.ts +1 -2
  570. package/dist/domain/domain-context/transformers/then-builder.js +1 -1
  571. package/dist/domain/domain-context/transformers/when-builder.d.ts +3 -9
  572. package/dist/domain/domain-context/transformers/when-builder.js +1 -1
  573. package/dist/domain/domain-context/undo-system.d.ts +29 -3
  574. package/dist/domain/domain-context/undo-system.js +1 -1
  575. package/dist/domain/domain-runtime/access/selectors.d.ts +9 -0
  576. package/dist/domain/domain-runtime/access/selectors.js +1 -1
  577. package/dist/domain/domain-runtime/access/types.d.ts +2 -0
  578. package/dist/domain/domain-runtime/access/types.js +1 -1
  579. package/dist/domain/domain-runtime/domain-context/action-context.d.ts +11 -0
  580. package/dist/domain/domain-runtime/domain-context/action-context.js +1 -0
  581. package/dist/domain/domain-runtime/domain-context/component-reader.d.ts +1 -4
  582. package/dist/domain/domain-runtime/domain-context/component-reader.js +1 -1
  583. package/dist/domain/domain-runtime/domain-context/domain-context.js +1 -1
  584. package/dist/domain/domain-runtime/domain-context/expression-context.d.ts +8 -0
  585. package/dist/domain/domain-runtime/domain-context/expression-context.js +1 -0
  586. package/dist/domain/domain-runtime/domain-context/index.d.ts +3 -0
  587. package/dist/domain/domain-runtime/domain-context/runtime-expression-context.d.ts +18 -0
  588. package/dist/domain/domain-runtime/domain-context/runtime-expression-context.js +1 -0
  589. package/dist/domain/domain-runtime/domain-context/selectors.d.ts +19 -25
  590. package/dist/domain/domain-runtime/domain-context/selectors.js +1 -1
  591. package/dist/domain/domain-runtime/domain-context/types.d.ts +4 -1
  592. package/dist/domain/domain-runtime/domain-runtime.d.ts +88 -72
  593. package/dist/domain/domain-runtime/errors/implementation-error-collector.d.ts +19 -0
  594. package/dist/domain/domain-runtime/errors/implementation-error-collector.js +1 -0
  595. package/dist/domain/domain-runtime/errors/implementation-error.d.ts +46 -0
  596. package/dist/domain/domain-runtime/errors/implementation-error.js +1 -0
  597. package/dist/domain/domain-runtime/errors/implementation-errors.d.ts +13 -0
  598. package/dist/domain/domain-runtime/errors/implementation-errors.js +1 -0
  599. package/dist/domain/domain-runtime/errors/index.d.ts +4 -0
  600. package/dist/domain/domain-runtime/errors/index.js +1 -0
  601. package/dist/domain/domain-runtime/errors/to-implementation-errors.d.ts +10 -0
  602. package/dist/domain/domain-runtime/errors/to-implementation-errors.js +1 -0
  603. package/dist/domain/domain-runtime/index.d.ts +1 -0
  604. package/dist/domain/domain-runtime/index.js +1 -1
  605. package/dist/domain/domain-runtime/spec/create-violation-expressions.d.ts +24 -0
  606. package/dist/domain/domain-runtime/spec/create-violation-expressions.js +1 -0
  607. package/dist/domain/domain-runtime/spec/index.d.ts +5 -0
  608. package/dist/domain/domain-runtime/spec/index.js +1 -1
  609. package/dist/domain/domain-runtime/spec/initialize.d.ts +11 -0
  610. package/dist/domain/domain-runtime/spec/initialize.js +1 -1
  611. package/dist/domain/{expressions → domain-runtime/spec}/memoize-expression.d.ts +1 -2
  612. package/dist/domain/{application → domain-runtime/spec/module-checks}/element-registration.d.ts +6 -1
  613. package/dist/domain/domain-runtime/spec/module-checks/element-registration.js +1 -0
  614. package/dist/domain/{application → domain-runtime/spec/module-checks}/handler-registration.d.ts +5 -0
  615. package/dist/domain/domain-runtime/spec/module-checks/handler-registration.js +1 -0
  616. package/dist/domain/domain-runtime/spec/module-checks/index.d.ts +8 -0
  617. package/dist/domain/domain-runtime/spec/module-checks/index.js +1 -0
  618. package/dist/domain/domain-runtime/spec/module-checks/project-modules.d.ts +32 -0
  619. package/dist/domain/domain-runtime/spec/module-checks/project-modules.js +1 -0
  620. package/dist/domain/domain-runtime/spec/module-checks/resolve-action-modules.d.ts +4 -0
  621. package/dist/domain/domain-runtime/spec/module-checks/resolve-action-modules.js +1 -0
  622. package/dist/domain/domain-runtime/spec/module-checks/resolve-component-optic-modules.d.ts +4 -0
  623. package/dist/domain/domain-runtime/spec/module-checks/resolve-component-optic-modules.js +1 -0
  624. package/dist/domain/domain-runtime/spec/module-checks/resolve-expression-modules.d.ts +15 -0
  625. package/dist/domain/domain-runtime/spec/module-checks/resolve-expression-modules.js +1 -0
  626. package/dist/domain/domain-runtime/spec/module-checks/resolve-imported-transformers.d.ts +22 -0
  627. package/dist/domain/domain-runtime/spec/module-checks/resolve-imported-transformers.js +1 -0
  628. package/dist/domain/domain-runtime/spec/module-checks/resolve-invariant-modules.d.ts +6 -0
  629. package/dist/domain/domain-runtime/spec/module-checks/resolve-invariant-modules.js +1 -0
  630. package/dist/domain/{actions → domain-runtime/spec}/prepare-action-implementations.d.ts +1 -1
  631. package/dist/domain/domain-runtime/spec/prepare-action-implementations.js +5 -0
  632. package/dist/domain/{expressions → domain-runtime/spec}/prepare-domain-expressions.d.ts +1 -1
  633. package/dist/domain/domain-runtime/spec/selectors.d.ts +7 -8
  634. package/dist/domain/domain-runtime/spec/selectors.js +1 -1
  635. package/dist/domain/domain-runtime/spec/types.d.ts +8 -6
  636. package/dist/domain/{system-components → extensions}/angle-indicator.d.ts +1 -1
  637. package/dist/domain/extensions/angle-indicator.js +1 -0
  638. package/dist/domain/{system-components → extensions}/attribute-switch.d.ts +1 -1
  639. package/dist/domain/extensions/attribute-switch.js +1 -0
  640. package/dist/domain/{system-components → extensions}/autorotate-camera-component.d.ts +1 -1
  641. package/dist/domain/extensions/autorotate-camera-component.js +1 -0
  642. package/dist/domain/{system-components → extensions}/basic-sidebar-footer.d.ts +1 -1
  643. package/dist/domain/extensions/basic-sidebar-footer.js +1 -0
  644. package/dist/domain/extensions/camera-based-hidden-entity-object.js +1 -0
  645. package/dist/domain/extensions/camera-based-hidden-entity.js +1 -0
  646. package/dist/domain/{system-components → extensions}/canvas-config.d.ts +2 -2
  647. package/dist/domain/extensions/canvas-config.js +1 -0
  648. package/dist/domain/extensions/canvas-custom-environment.js +1 -0
  649. package/dist/domain/{system-components → extensions}/canvas-padding.d.ts +1 -1
  650. package/dist/domain/extensions/canvas-padding.js +1 -0
  651. package/dist/domain/{system-components → extensions}/canvas-preset-environment.d.ts +1 -1
  652. package/dist/domain/extensions/canvas-preset-environment.js +1 -0
  653. package/dist/domain/{system-components → extensions}/child-entity-recipe-hierarchy.d.ts +2 -2
  654. package/dist/domain/extensions/child-entity-recipe-hierarchy.js +1 -0
  655. package/dist/domain/{system-components → extensions}/client-side-image.d.ts +2 -2
  656. package/dist/domain/extensions/client-side-image.js +1 -0
  657. package/dist/domain/extensions/color-value.js +1 -0
  658. package/dist/domain/{system-components → extensions}/common/angle-indicator-schema.d.ts +3 -3
  659. package/dist/domain/extensions/common/angle-indicator-schema.js +1 -0
  660. package/dist/domain/{system-components → extensions}/common/dimension-indicator-schema.d.ts +3 -3
  661. package/dist/domain/extensions/common/dimension-indicator-schema.js +1 -0
  662. package/dist/domain/extensions/common/index.d.ts +4 -0
  663. package/dist/domain/extensions/common/index.js +1 -0
  664. package/dist/domain/{system-components → extensions}/custom-header.d.ts +2 -2
  665. package/dist/domain/{system-components → extensions}/custom-header.js +1 -1
  666. package/dist/domain/extensions/custom-price-footer.js +1 -0
  667. package/dist/domain/{system-components → extensions}/custom-sidebar-footer.d.ts +2 -2
  668. package/dist/domain/{system-components → extensions}/custom-sidebar-footer.js +1 -1
  669. package/dist/domain/{system-components → extensions}/dimension-indicator.d.ts +1 -1
  670. package/dist/domain/extensions/dimension-indicator.js +1 -0
  671. package/dist/domain/{system-components → extensions}/editable-angle-indicator.d.ts +4 -3
  672. package/dist/domain/extensions/editable-angle-indicator.js +1 -0
  673. package/dist/domain/{system-components → extensions}/editable-distance-dimension-indicator.d.ts +4 -3
  674. package/dist/domain/extensions/editable-distance-dimension-indicator.js +1 -0
  675. package/dist/domain/{system-components → extensions}/editable-offset-indicator.d.ts +4 -3
  676. package/dist/domain/extensions/editable-offset-indicator.js +1 -0
  677. package/dist/domain/{system-components → extensions}/editable-size-indicator.d.ts +3 -2
  678. package/dist/domain/extensions/editable-size-indicator.js +1 -0
  679. package/dist/domain/{system-components → extensions}/entity-header.d.ts +1 -1
  680. package/dist/domain/extensions/entity-header.js +1 -0
  681. package/dist/domain/{system-components → extensions}/exit-tool-mode-fab.d.ts +1 -1
  682. package/dist/domain/extensions/exit-tool-mode-fab.js +1 -0
  683. package/dist/domain/{system-components → extensions}/finalize-action.d.ts +1 -1
  684. package/dist/domain/extensions/finalize-action.js +1 -0
  685. package/dist/domain/extensions/finalize-component.js +1 -0
  686. package/dist/domain/extensions/fit-selection-orthographic-camera-component.js +1 -0
  687. package/dist/domain/extensions/fit-selection-perspective-camera-component.js +1 -0
  688. package/dist/domain/{system-components → extensions}/fixed-header.d.ts +1 -1
  689. package/dist/domain/extensions/fixed-header.js +1 -0
  690. package/dist/domain/{system-components → extensions}/floating-header.d.ts +1 -1
  691. package/dist/domain/extensions/floating-header.js +1 -0
  692. package/dist/domain/{system-components → extensions}/hidden-header.d.ts +1 -1
  693. package/dist/domain/extensions/hidden-header.js +1 -0
  694. package/dist/domain/{system-components → extensions}/hidden-sidebar-footer.d.ts +1 -1
  695. package/dist/domain/extensions/hidden-sidebar-footer.js +1 -0
  696. package/dist/domain/{system-components → extensions}/horizontal-tabs.d.ts +3 -3
  697. package/dist/domain/extensions/horizontal-tabs.js +1 -0
  698. package/dist/domain/extensions/index.d.ts +69 -0
  699. package/dist/domain/extensions/index.js +1 -0
  700. package/dist/domain/{system-components → extensions}/list-selector-dimension-indicator.d.ts +4 -3
  701. package/dist/domain/extensions/list-selector-dimension-indicator.js +1 -0
  702. package/dist/domain/extensions/multilingual-text-value.js +1 -0
  703. package/dist/domain/{system-components → extensions}/navigation-steps.d.ts +2 -2
  704. package/dist/domain/extensions/navigation-steps.js +1 -0
  705. package/dist/domain/{system-components → extensions}/offset-anchors.d.ts +1 -1
  706. package/dist/domain/extensions/offset-anchors.js +1 -0
  707. package/dist/domain/{system-components → extensions}/offset-indicator.d.ts +1 -2
  708. package/dist/domain/extensions/offset-indicator.js +1 -0
  709. package/dist/domain/{system-components → extensions}/offset.d.ts +1 -1
  710. package/dist/domain/extensions/offset.js +1 -0
  711. package/dist/domain/{system-components → extensions}/other-action.d.ts +1 -1
  712. package/dist/domain/extensions/other-action.js +1 -0
  713. package/dist/domain/{system-components → extensions}/property-page.d.ts +2 -2
  714. package/dist/domain/extensions/property-page.js +1 -0
  715. package/dist/domain/{system-components → extensions}/read-sidebar-footer.d.ts +1 -1
  716. package/dist/domain/extensions/read-sidebar-footer.js +1 -0
  717. package/dist/domain/{system-components → extensions}/replace-entity-recipe-hierarchy.d.ts +2 -2
  718. package/dist/domain/extensions/replace-entity-recipe-hierarchy.js +1 -0
  719. package/dist/domain/extensions/rotatable.js +1 -0
  720. package/dist/domain/{system-components → extensions}/rotation-handle.d.ts +2 -2
  721. package/dist/domain/extensions/rotation-handle.js +1 -0
  722. package/dist/domain/{system-components → extensions}/save-template-thumbnail.d.ts +2 -2
  723. package/dist/domain/extensions/save-template-thumbnail.js +1 -0
  724. package/dist/domain/{system-components → extensions}/scene-entity-add-fab.d.ts +1 -1
  725. package/dist/domain/extensions/scene-entity-add-fab.js +1 -0
  726. package/dist/domain/extensions/scene-entity-animation.js +1 -0
  727. package/dist/domain/extensions/scene-entity-control.js +1 -0
  728. package/dist/domain/{system-components → extensions}/scene-entity-delete-fab.d.ts +1 -1
  729. package/dist/domain/extensions/scene-entity-delete-fab.js +1 -0
  730. package/dist/domain/extensions/scene-entity-floor-object.js +1 -0
  731. package/dist/domain/{system-components → extensions}/scene-entity-html-hotspot.d.ts +1 -1
  732. package/dist/domain/extensions/scene-entity-html-hotspot.js +1 -0
  733. package/dist/domain/{system-components → extensions}/scene-entity-navigation-hotspot.d.ts +1 -1
  734. package/dist/domain/extensions/scene-entity-navigation-hotspot.js +1 -0
  735. package/dist/domain/{system-components → extensions}/scene-entity-object-html-hotspot.d.ts +1 -1
  736. package/dist/domain/extensions/scene-entity-object-html-hotspot.js +1 -0
  737. package/dist/domain/{system-components → extensions}/scene-entity-select-hotspot.d.ts +1 -1
  738. package/dist/domain/extensions/scene-entity-select-hotspot.js +1 -0
  739. package/dist/domain/extensions/scene-entity-wall-object.js +1 -0
  740. package/dist/domain/extensions/selectable-component.js +1 -0
  741. package/dist/domain/{system-components → extensions}/sidebar-tabs.d.ts +1 -1
  742. package/dist/domain/extensions/sidebar-tabs.js +1 -0
  743. package/dist/domain/extensions/simple-summary.js +1 -0
  744. package/dist/domain/{system-components → extensions}/size.d.ts +1 -1
  745. package/dist/domain/extensions/size.js +1 -0
  746. package/dist/domain/{system-components → extensions}/sketching-draw.d.ts +1 -1
  747. package/dist/domain/extensions/sketching-draw.js +1 -0
  748. package/dist/domain/{system-components → extensions}/sketching-edit.d.ts +2 -2
  749. package/dist/domain/extensions/sketching-edit.js +1 -0
  750. package/dist/domain/extensions/summary-component.js +1 -0
  751. package/dist/domain/extensions/text-value.js +1 -0
  752. package/dist/domain/extensions/tool-controls.js +1 -0
  753. package/dist/domain/{system-components → extensions}/tool-menu-fab.d.ts +2 -2
  754. package/dist/domain/extensions/tool-menu-fab.js +1 -0
  755. package/dist/domain/{system-components → extensions}/toolbar.d.ts +2 -2
  756. package/dist/domain/{system-components → extensions}/toolbar.js +1 -1
  757. package/dist/domain/{system-components → extensions}/universal-sidebar-footer.d.ts +1 -1
  758. package/dist/domain/extensions/universal-sidebar-footer.js +1 -0
  759. package/dist/domain/extensions/view-controls.js +1 -0
  760. package/dist/domain/index.d.ts +2 -32
  761. package/dist/domain/index.js +1 -1
  762. package/dist/domain/mocks/create-mock-domain-context.d.ts +1 -1
  763. package/dist/domain/mocks/create-mock-domain-runtime-services.d.ts +1 -1
  764. package/dist/domain/mocks/create-mock-domain-runtime.d.ts +30 -21
  765. package/dist/domain/mocks/create-mock-domain-runtime.js +1 -1
  766. package/dist/domain/mocks/create-mock-domain.d.ts +1 -1
  767. package/dist/domain/mocks/create-mock-domain.js +1 -1
  768. package/dist/domain/mocks/create-mock-state.d.ts +2 -2
  769. package/dist/domain/mocks/create-test-application-config.d.ts +59 -0
  770. package/dist/domain/mocks/create-test-application-config.js +1 -0
  771. package/dist/domain/mocks/index.d.ts +1 -0
  772. package/dist/domain/mocks/index.js +1 -1
  773. package/dist/domain/projections/blender-projections/blender-projections.d.ts +2 -3
  774. package/dist/domain/projections/blender-projections/blender-projections.js +1 -1
  775. package/dist/domain/projections/blender-projections/camera.d.ts +2 -2
  776. package/dist/domain/projections/collision-projections.d.ts +1 -1
  777. package/dist/domain/projections/composition-projections.d.ts +1 -1
  778. package/dist/domain/projections/composition-projections.js +1 -1
  779. package/dist/domain/projections/constraint-projections.d.ts +1 -1
  780. package/dist/domain/projections/index.d.ts +1 -1
  781. package/dist/domain/projections/position-projections.d.ts +1 -1
  782. package/dist/domain/projections/projected-entities-projections.d.ts +2 -3
  783. package/dist/domain/projections/snap-matching.d.ts +1 -2
  784. package/dist/domain/projections/snap-utils.d.ts +1 -2
  785. package/dist/domain/projections/snapping-projections.d.ts +1 -1
  786. package/dist/domain/projections/validation-projections.d.ts +3 -20
  787. package/dist/domain/projections/validation-projections.js +1 -1
  788. package/dist/domain/sketching/sketching-projections.d.ts +1 -1
  789. package/dist/domain/system-components/admin-sidebar.d.ts +1 -1
  790. package/dist/domain/system-components/admin-sidebar.js +1 -1
  791. package/dist/domain/system-components/angle-dimension.js +1 -1
  792. package/dist/domain/system-components/application-config.d.ts +3 -3
  793. package/dist/domain/system-components/application-config.js +1 -1
  794. package/dist/domain/system-components/attribute-selection.js +1 -1
  795. package/dist/domain/system-components/bounding-box-component.d.ts +1 -1
  796. package/dist/domain/system-components/bounding-box-component.js +1 -1
  797. package/dist/domain/system-components/bounding-sphere-component.d.ts +1 -1
  798. package/dist/domain/system-components/bounding-sphere-component.js +1 -1
  799. package/dist/domain/system-components/child-entity-recipes.d.ts +1 -1
  800. package/dist/domain/system-components/child-entity-recipes.js +1 -1
  801. package/dist/domain/system-components/child-entity-selection.d.ts +1 -2
  802. package/dist/domain/system-components/child-entity-selection.js +1 -1
  803. package/dist/domain/system-components/collision-box-geometry.d.ts +5 -3
  804. package/dist/domain/system-components/collision-box-geometry.js +1 -1
  805. package/dist/domain/system-components/collision-geometries.d.ts +1 -1
  806. package/dist/domain/system-components/collision-geometry.d.ts +5 -3
  807. package/dist/domain/system-components/collision-geometry.js +1 -1
  808. package/dist/domain/system-components/collision-point-geometry.d.ts +5 -3
  809. package/dist/domain/system-components/collision-point-geometry.js +1 -1
  810. package/dist/domain/system-components/common/index.d.ts +0 -4
  811. package/dist/domain/system-components/common/index.js +1 -1
  812. package/dist/domain/system-components/common/material-override-schema.d.ts +2 -2
  813. package/dist/domain/system-components/common/recipes.d.ts +21 -4
  814. package/dist/domain/system-components/common/recipes.js +1 -1
  815. package/dist/domain/system-components/constraint.d.ts +11 -24
  816. package/dist/domain/system-components/constraint.js +1 -1
  817. package/dist/domain/system-components/create-blueprint.d.ts +1 -1
  818. package/dist/domain/system-components/custom-scene-entity.d.ts +1 -1
  819. package/dist/domain/system-components/custom-scene-entity.js +1 -1
  820. package/dist/domain/system-components/detail.js +1 -1
  821. package/dist/domain/system-components/distance-dimension-select.d.ts +1 -1
  822. package/dist/domain/system-components/distance-dimension-select.js +1 -1
  823. package/dist/domain/system-components/distance-dimension.d.ts +1 -1
  824. package/dist/domain/system-components/distance-dimension.js +1 -1
  825. package/dist/domain/system-components/drag-handle.d.ts +2 -2
  826. package/dist/domain/system-components/drag-handle.js +1 -1
  827. package/dist/domain/system-components/fit-entity-orthographic-camera-component.js +1 -1
  828. package/dist/domain/system-components/fit-entity-perspective-camera-component.js +1 -1
  829. package/dist/domain/system-components/fit-root-orthographic-camera-component.js +1 -1
  830. package/dist/domain/system-components/fit-root-perspective-camera-component.js +1 -1
  831. package/dist/domain/system-components/generic-dimension.d.ts +1 -1
  832. package/dist/domain/system-components/generic-dimension.js +1 -1
  833. package/dist/domain/system-components/hidden-entity.js +1 -1
  834. package/dist/domain/system-components/hotspot-drag-handle.d.ts +2 -3
  835. package/dist/domain/system-components/hotspot-drag-handle.js +1 -1
  836. package/dist/domain/system-components/index.d.ts +0 -68
  837. package/dist/domain/system-components/index.js +1 -1
  838. package/dist/domain/system-components/material-override-property-transition.js +1 -1
  839. package/dist/domain/system-components/material-override-transformer.js +1 -1
  840. package/dist/domain/system-components/material-swatch.js +1 -1
  841. package/dist/domain/system-components/navigation-page.js +1 -1
  842. package/dist/domain/system-components/navigation-panel-list.js +1 -1
  843. package/dist/domain/system-components/phoenix-entity-elements/admin-data-table-sidebar.d.ts +1 -1
  844. package/dist/domain/system-components/phoenix-layout-elements/admin-connected-resource-page.d.ts +1 -1
  845. package/dist/domain/system-components/phoenix-layout-elements/admin-data-table-actions.d.ts +1 -1
  846. package/dist/domain/system-components/phoenix-layout-elements/admin-data-table-page.d.ts +1 -1
  847. package/dist/domain/system-components/pivot-point.d.ts +1 -1
  848. package/dist/domain/system-components/pivot-point.js +1 -1
  849. package/dist/domain/system-components/price.js +1 -1
  850. package/dist/domain/system-components/projected-entities.d.ts +1 -1
  851. package/dist/domain/system-components/projected-entities.js +1 -1
  852. package/dist/domain/system-components/replace-entity-recipes.d.ts +1 -1
  853. package/dist/domain/system-components/replace-entity-recipes.js +1 -1
  854. package/dist/domain/system-components/scene-entity-ambient-light.js +1 -1
  855. package/dist/domain/system-components/scene-entity-box-object.js +1 -1
  856. package/dist/domain/system-components/scene-entity-directional-light.js +1 -1
  857. package/dist/domain/system-components/scene-entity-local-material-override.js +1 -1
  858. package/dist/domain/system-components/scene-entity-material-override.d.ts +1 -1
  859. package/dist/domain/system-components/scene-entity-material-override.js +1 -1
  860. package/dist/domain/system-components/scene-entity-object-clip.js +1 -1
  861. package/dist/domain/system-components/scene-entity-object-decal.js +1 -1
  862. package/dist/domain/system-components/scene-entity-object-group.js +1 -1
  863. package/dist/domain/system-components/scene-entity-object-local-material-override.js +1 -1
  864. package/dist/domain/system-components/scene-entity-object-material-override.d.ts +1 -1
  865. package/dist/domain/system-components/scene-entity-object-material-override.js +1 -1
  866. package/dist/domain/system-components/scene-entity-object-properties.js +1 -1
  867. package/dist/domain/system-components/scene-entity-object-remote-material-override.js +1 -1
  868. package/dist/domain/system-components/scene-entity-object-text-decal.d.ts +1 -1
  869. package/dist/domain/system-components/scene-entity-object-text-decal.js +1 -1
  870. package/dist/domain/system-components/scene-entity-object-transformer.js +1 -1
  871. package/dist/domain/system-components/scene-entity-object-transimissive-material-override.d.ts +1 -1
  872. package/dist/domain/system-components/scene-entity-object-transimissive-material-override.js +1 -1
  873. package/dist/domain/system-components/scene-entity-object.js +1 -1
  874. package/dist/domain/system-components/scene-entity-point-light.js +1 -1
  875. package/dist/domain/system-components/scene-entity-properties.js +1 -1
  876. package/dist/domain/system-components/scene-entity-rect-area-light.js +1 -1
  877. package/dist/domain/system-components/scene-entity-remote-material-override.js +1 -1
  878. package/dist/domain/system-components/scene-entity-remote-object.js +1 -1
  879. package/dist/domain/system-components/scene-entity-spot-light.js +1 -1
  880. package/dist/domain/system-components/scene-entity-transimissive-material-override.d.ts +1 -1
  881. package/dist/domain/system-components/scene-entity-transimissive-material-override.js +1 -1
  882. package/dist/domain/system-components/sketching-line.d.ts +1 -1
  883. package/dist/domain/system-components/sketching-line.js +1 -1
  884. package/dist/domain/system-components/sketching-rectangle.d.ts +1 -1
  885. package/dist/domain/system-components/sketching-rectangle.js +1 -1
  886. package/dist/domain/system-components/sketching.d.ts +1 -1
  887. package/dist/domain/system-components/sketching.js +1 -1
  888. package/dist/domain/system-components/snap-axis.d.ts +1 -1
  889. package/dist/domain/system-components/snap-axis.js +1 -1
  890. package/dist/domain/system-components/snap-edge.d.ts +1 -1
  891. package/dist/domain/system-components/snap-edge.js +1 -1
  892. package/dist/domain/system-components/snap-plane.d.ts +1 -1
  893. package/dist/domain/system-components/snap-plane.js +1 -1
  894. package/dist/domain/system-components/snap-point.d.ts +1 -1
  895. package/dist/domain/system-components/snap-point.js +1 -1
  896. package/dist/domain/system-components/static-orthographic-camera-component.d.ts +1 -1
  897. package/dist/domain/system-components/static-orthographic-camera-component.js +1 -1
  898. package/dist/domain/system-components/static-perspective-camera-component.d.ts +1 -1
  899. package/dist/domain/system-components/static-perspective-camera-component.js +1 -1
  900. package/dist/domain/utils/eval-cache.d.ts +2 -3
  901. package/dist/domain/utils/map-nested-object.d.ts +1 -1
  902. package/dist/domain/utils/memo-eval.d.ts +2 -4
  903. package/dist/editor/domain-editors/use-implementation-files.d.ts +8 -8
  904. package/dist/editor/domain-editors/use-implementation-files.js +1 -1
  905. package/dist/editor/mocks/EditorMockContext.js +1 -1
  906. package/dist/i18n/locales/cs/messages.js +1 -1
  907. package/dist/i18n/locales/da/messages.js +1 -1
  908. package/dist/i18n/locales/de/messages.js +1 -1
  909. package/dist/i18n/locales/de-AT/messages.js +1 -1
  910. package/dist/i18n/locales/en/messages.js +1 -1
  911. package/dist/i18n/locales/en-AU/messages.js +1 -1
  912. package/dist/i18n/locales/en-GB/messages.js +1 -1
  913. package/dist/i18n/locales/es/messages.js +1 -1
  914. package/dist/i18n/locales/fr/messages.js +1 -1
  915. package/dist/i18n/locales/hu/messages.js +1 -1
  916. package/dist/i18n/locales/it/messages.js +1 -1
  917. package/dist/i18n/locales/nl/messages.js +1 -1
  918. package/dist/i18n/locales/pl/messages.js +1 -1
  919. package/dist/i18n/locales/pt/messages.js +1 -1
  920. package/dist/i18n/locales/ro/messages.js +1 -1
  921. package/dist/i18n/locales/sk/messages.js +1 -1
  922. package/dist/i18n/locales/tr/messages.js +1 -1
  923. package/dist/legacy/domain-cli/gen/configurator-builder.js +30 -16
  924. package/dist/legacy/domain-cli/gen/constant-expressions.js +1 -3
  925. package/dist/legacy/domain-cli/gen/defaults.js +1 -7
  926. package/dist/legacy/domain-cli/gen/implementation.js +7 -11
  927. package/dist/legacy/domain-cli/gen/invariants.js +7 -6
  928. package/dist/legacy/domain-cli/gen/relations.js +1 -1
  929. package/dist/legacy/domain-cli/utils/cache.d.ts +1 -1
  930. package/dist/legacy/domain-cli/utils/cache.js +1 -1
  931. package/dist/legacy/domain-spec/__generated/domain-schema.d.ts +81 -68
  932. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/agents/claude-md.d.ts +1 -1
  933. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/agents/cursor-rules.d.ts +1 -1
  934. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/agents/shared-sdk-content.d.ts +1 -1
  935. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/agents/shared-sdk-content.js +7 -0
  936. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/domain-index.js +17 -15
  937. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/env-example.d.ts +1 -1
  938. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/env-example.js +4 -0
  939. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/frontend-admin.js +16 -15
  940. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/frontend-configurator.js +16 -15
  941. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/frontend-embedded-admin.js +23 -22
  942. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/frontend-embedded-configurator.js +16 -15
  943. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/generator-shared.d.ts +7 -2
  944. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/generator-shared.js +8 -12
  945. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/index.d.ts +1 -1
  946. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/index.js +1 -1
  947. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/webhook-builders.js +7 -7
  948. package/dist/phoenix/application-spec/application-spec-builder.js +1 -1
  949. package/dist/phoenix/application-spec/resolve-deployment-data.d.ts +4 -3
  950. package/dist/phoenix/application-spec/resolve-deployment-data.js +2 -2
  951. package/dist/phoenix/commands/check.js +1 -1
  952. package/dist/phoenix/commands/deploy.js +1 -1
  953. package/dist/phoenix/commands/fix.js +1 -1
  954. package/dist/phoenix/commands/init.d.ts +4 -4
  955. package/dist/phoenix/commands/init.js +1 -1
  956. package/dist/phoenix/commands/prepare-deployment-command.js +2 -2
  957. package/dist/phoenix/commands/prepare-local-environment-command.js +1 -1
  958. package/dist/phoenix/commands/prettier.js +1 -1
  959. package/dist/phoenix/scripts/build-admin.js +1 -1
  960. package/dist/phoenix/services/application-spec-project-watcher.js +3 -3
  961. package/dist/phoenix/services/prepare-development-environment.js +1 -1
  962. package/dist/phoenix/services/source-archive.d.ts +1 -0
  963. package/dist/phoenix/services/source-archive.js +1 -1
  964. package/dist/phoenix/services/variant-file-session.js +1 -1
  965. package/dist/phoenix/utils/git/index.d.ts +1 -0
  966. package/dist/phoenix/utils/git/index.js +1 -0
  967. package/dist/phoenix/utils/git/is-inside-git-repository.d.ts +6 -0
  968. package/dist/phoenix/utils/git/is-inside-git-repository.js +1 -0
  969. package/dist/phoenix/utils/index.d.ts +1 -0
  970. package/dist/phoenix/utils/index.js +1 -1
  971. package/dist/react-sdk/application-runtime/hooks/use-access-service.d.ts +2 -0
  972. package/dist/react-sdk/application-runtime/hooks/use-domain-application-props.d.ts +5 -2
  973. package/dist/react-sdk/application-runtime/hooks/use-spec.d.ts +1 -1
  974. package/dist/react-sdk/application-runtime/mocks/create-mock-application-runtime.d.ts +1 -1
  975. package/dist/react-sdk/application-runtime/mocks/create-mock-application-runtime.js +1 -1
  976. package/dist/react-sdk/application-runtime/routing/access-service.d.ts +1 -0
  977. package/dist/react-sdk/application-runtime/runtime/create-application-runtime.d.ts +57 -40
  978. package/dist/react-sdk/application-runtime/runtime/create-application-runtime.js +1 -1
  979. package/dist/react-sdk/domain-context/common-hooks/use-configurator-messages.d.ts +30 -0
  980. package/dist/react-sdk/domain-context/common-hooks/use-configurator-messages.js +1 -0
  981. package/dist/react-sdk/domain-context/common-hooks/use-domain-context.d.ts +9 -9
  982. package/dist/react-sdk/domain-context/index.d.ts +2 -1
  983. package/dist/react-sdk/domain-context/index.js +1 -1
  984. package/dist/react-sdk/domain-context/system-hooks/navigation-hooks.d.ts +11 -0
  985. package/dist/react-sdk/domain-context/system-hooks/navigation-hooks.js +1 -1
  986. package/dist/react-sdk/domain-controls/hooks/use-angle-dimension.d.ts +1 -1
  987. package/dist/ui-sdk/theme/types.d.ts +1 -1
  988. package/dist/webhook/builders/common.d.ts +8 -0
  989. package/dist/webhook/builders/webhook-builder.d.ts +1 -1
  990. package/dist/webhook/builders/webhook-builder.js +1 -1
  991. package/package.json +3 -3
  992. package/schema/domain-spec.json +1115 -209
  993. package/dist/application-spec/generate-application/code/templates/env-ci.d.ts +0 -1
  994. package/dist/application-spec/generate-application/code/templates/env-ci.js +0 -25
  995. package/dist/application-spec/generate-application/code/templates/env-example.d.ts +0 -1
  996. package/dist/application-spec/generate-application/code/templates/env-example.js +0 -90
  997. package/dist/application-spec/generate-application/code/templates/prettier-ignore.d.ts +0 -1
  998. package/dist/application-spec/generate-application/code/templates/prettier-ignore.js +0 -6
  999. package/dist/application-spec/generate-application/code/templates/private-assets-readme.d.ts +0 -1
  1000. package/dist/application-spec/generate-application/code/templates/private-assets-readme.js +0 -24
  1001. package/dist/application-spec/generate-application/code/templates/public-assets-readme.d.ts +0 -1
  1002. package/dist/application-spec/generate-application/code/templates/public-assets-readme.js +0 -24
  1003. package/dist/application-spec/generate-application/code/templates/readme.d.ts +0 -1
  1004. package/dist/application-spec/generate-application/code/templates/readme.js +0 -23
  1005. package/dist/application-spec/generate-application/code/templates/skills/agents-md.d.ts +0 -1
  1006. package/dist/application-spec/generate-application/code/templates/skills/agents-md.js +0 -2
  1007. package/dist/application-spec/generate-application/code/templates/webhook-implementation.d.ts +0 -1
  1008. package/dist/application-spec/generate-application/code/templates/webhook-implementation.js +0 -7
  1009. package/dist/domain/actions/action-factory.d.ts +0 -10
  1010. package/dist/domain/actions/prepare-action-implementations.js +0 -5
  1011. package/dist/domain/application/element-registration.js +0 -1
  1012. package/dist/domain/application/handler-registration.js +0 -1
  1013. package/dist/domain/application/resolve-imported-transformers.d.ts +0 -13
  1014. package/dist/domain/application/resolve-imported-transformers.js +0 -1
  1015. package/dist/domain/application/resource-builder.d.ts +0 -13
  1016. package/dist/domain/application/resource-builder.js +0 -1
  1017. package/dist/domain/components/debug-state-component.js +0 -1
  1018. package/dist/domain/components/domain-component-optic.d.ts +0 -76
  1019. package/dist/domain/components/domain-component-optic.js +0 -16
  1020. package/dist/domain/components/drag-state-component.js +0 -1
  1021. package/dist/domain/components/export-state-component.js +0 -1
  1022. package/dist/domain/components/fullscreen-state-component.js +0 -1
  1023. package/dist/domain/components/group-components-by-entity-id-and-name.js +0 -1
  1024. package/dist/domain/components/hover-state-component.js +0 -1
  1025. package/dist/domain/components/index.d.ts +0 -2
  1026. package/dist/domain/components/index.js +0 -1
  1027. package/dist/domain/components/navigation-state-component.js +0 -1
  1028. package/dist/domain/components/selection-state-component.js +0 -1
  1029. package/dist/domain/components/system-component-builder.js +0 -1
  1030. package/dist/domain/components/system-virtual-entity.js +0 -1
  1031. package/dist/domain/components/tool-state-component.js +0 -1
  1032. package/dist/domain/components/view-state-component.js +0 -1
  1033. package/dist/domain/components/viewport-state-component.js +0 -1
  1034. package/dist/domain/core/expression.d.ts +0 -50
  1035. package/dist/domain/core/json-schema.js +0 -1
  1036. package/dist/domain/core/migrations.js +0 -1
  1037. package/dist/domain/core/reflection.js +0 -1
  1038. package/dist/domain/domain-context/recipe-system/recipes.d.ts +0 -57
  1039. package/dist/domain/domain-context/recipe-system/recipes.js +0 -1
  1040. package/dist/domain/expressions/constant-expressions.d.ts +0 -9
  1041. package/dist/domain/expressions/constant-expressions.js +0 -1
  1042. package/dist/domain/expressions/custom-expression.d.ts +0 -13
  1043. package/dist/domain/expressions/custom-expression.js +0 -1
  1044. package/dist/domain/expressions/index.d.ts +0 -1
  1045. package/dist/domain/expressions/index.js +0 -1
  1046. package/dist/domain/invariants/custom-invariants.d.ts +0 -22
  1047. package/dist/domain/invariants/custom-invariants.js +0 -1
  1048. package/dist/domain/invariants/invariants.d.ts +0 -68
  1049. package/dist/domain/invariants/invariants.js +0 -1
  1050. package/dist/domain/invariants/violation-component.js +0 -1
  1051. package/dist/domain/invariants/violation.js +0 -1
  1052. package/dist/domain/relations/all-of-type-relation.d.ts +0 -33
  1053. package/dist/domain/relations/all-of-type-relation.js +0 -1
  1054. package/dist/domain/relations/component-factories.js +0 -1
  1055. package/dist/domain/relations/composed-of.js +0 -1
  1056. package/dist/domain/relations/direct-relation.d.ts +0 -29
  1057. package/dist/domain/relations/indirect-relation.d.ts +0 -81
  1058. package/dist/domain/relations/indirect-relation.js +0 -1
  1059. package/dist/domain/relations/reference-component.js +0 -1
  1060. package/dist/domain/relations/relation-factory.d.ts +0 -19
  1061. package/dist/domain/relations/relation-factory.js +0 -1
  1062. package/dist/domain/relations/relation-implementation.d.ts +0 -8
  1063. package/dist/domain/system-components/angle-indicator.js +0 -1
  1064. package/dist/domain/system-components/attribute-switch.js +0 -1
  1065. package/dist/domain/system-components/autorotate-camera-component.js +0 -1
  1066. package/dist/domain/system-components/basic-sidebar-footer.js +0 -1
  1067. package/dist/domain/system-components/camera-based-hidden-entity-object.js +0 -1
  1068. package/dist/domain/system-components/camera-based-hidden-entity.js +0 -1
  1069. package/dist/domain/system-components/canvas-config.js +0 -1
  1070. package/dist/domain/system-components/canvas-custom-environment.js +0 -1
  1071. package/dist/domain/system-components/canvas-padding.js +0 -1
  1072. package/dist/domain/system-components/canvas-preset-environment.js +0 -1
  1073. package/dist/domain/system-components/child-entity-recipe-hierarchy.js +0 -1
  1074. package/dist/domain/system-components/client-side-image.js +0 -1
  1075. package/dist/domain/system-components/color-value.js +0 -1
  1076. package/dist/domain/system-components/common/angle-indicator-schema.js +0 -1
  1077. package/dist/domain/system-components/common/dimension-indicator-schema.js +0 -1
  1078. package/dist/domain/system-components/custom-price-footer.js +0 -1
  1079. package/dist/domain/system-components/dimension-indicator.js +0 -1
  1080. package/dist/domain/system-components/editable-angle-indicator.js +0 -1
  1081. package/dist/domain/system-components/editable-distance-dimension-indicator.js +0 -1
  1082. package/dist/domain/system-components/editable-offset-indicator.js +0 -1
  1083. package/dist/domain/system-components/editable-size-indicator.js +0 -1
  1084. package/dist/domain/system-components/entity-header.js +0 -1
  1085. package/dist/domain/system-components/exit-tool-mode-fab.js +0 -1
  1086. package/dist/domain/system-components/finalize-action.js +0 -1
  1087. package/dist/domain/system-components/finalize-component.js +0 -1
  1088. package/dist/domain/system-components/fit-selection-orthographic-camera-component.js +0 -1
  1089. package/dist/domain/system-components/fit-selection-perspective-camera-component.js +0 -1
  1090. package/dist/domain/system-components/fixed-header.js +0 -1
  1091. package/dist/domain/system-components/floating-header.js +0 -1
  1092. package/dist/domain/system-components/hidden-header.js +0 -1
  1093. package/dist/domain/system-components/hidden-sidebar-footer.js +0 -1
  1094. package/dist/domain/system-components/horizontal-tabs.js +0 -1
  1095. package/dist/domain/system-components/list-selector-dimension-indicator.js +0 -1
  1096. package/dist/domain/system-components/multilingual-text-value.js +0 -1
  1097. package/dist/domain/system-components/navigation-steps.js +0 -1
  1098. package/dist/domain/system-components/offset-anchors.js +0 -1
  1099. package/dist/domain/system-components/offset-indicator.js +0 -1
  1100. package/dist/domain/system-components/offset.js +0 -1
  1101. package/dist/domain/system-components/other-action.js +0 -1
  1102. package/dist/domain/system-components/property-page.js +0 -1
  1103. package/dist/domain/system-components/read-sidebar-footer.js +0 -1
  1104. package/dist/domain/system-components/replace-entity-recipe-hierarchy.js +0 -1
  1105. package/dist/domain/system-components/rotatable.js +0 -1
  1106. package/dist/domain/system-components/rotation-handle.js +0 -1
  1107. package/dist/domain/system-components/save-template-thumbnail.js +0 -1
  1108. package/dist/domain/system-components/scene-entity-add-fab.js +0 -1
  1109. package/dist/domain/system-components/scene-entity-animation.js +0 -1
  1110. package/dist/domain/system-components/scene-entity-control.js +0 -1
  1111. package/dist/domain/system-components/scene-entity-delete-fab.js +0 -1
  1112. package/dist/domain/system-components/scene-entity-floor-object.js +0 -1
  1113. package/dist/domain/system-components/scene-entity-html-hotspot.js +0 -1
  1114. package/dist/domain/system-components/scene-entity-navigation-hotspot.js +0 -1
  1115. package/dist/domain/system-components/scene-entity-object-html-hotspot.js +0 -1
  1116. package/dist/domain/system-components/scene-entity-select-hotspot.js +0 -1
  1117. package/dist/domain/system-components/scene-entity-wall-object.js +0 -1
  1118. package/dist/domain/system-components/selectable-component.js +0 -1
  1119. package/dist/domain/system-components/sidebar-tabs.js +0 -1
  1120. package/dist/domain/system-components/simple-summary.js +0 -1
  1121. package/dist/domain/system-components/size.js +0 -1
  1122. package/dist/domain/system-components/sketching-draw.js +0 -1
  1123. package/dist/domain/system-components/sketching-edit.js +0 -1
  1124. package/dist/domain/system-components/summary-component.js +0 -1
  1125. package/dist/domain/system-components/text-value.js +0 -1
  1126. package/dist/domain/system-components/tool-controls.js +0 -1
  1127. package/dist/domain/system-components/tool-menu-fab.js +0 -1
  1128. package/dist/domain/system-components/universal-sidebar-footer.js +0 -1
  1129. package/dist/domain/system-components/view-controls.js +0 -1
  1130. package/dist/phoenix/application-spec/generate-assistant-prompt.d.ts +0 -13
  1131. package/dist/phoenix/application-spec/generate-assistant-prompt.js +0 -1
  1132. /package/dist/{domain/components/component-reader-types.js → application-spec/core/expressions/relation-expression-params.js} +0 -0
  1133. /package/dist/application-spec/{core → enhanced-json}/eval-code-uses-self.d.ts +0 -0
  1134. /package/dist/application-spec/{core → enhanced-json}/eval-code-uses-self.js +0 -0
  1135. /package/dist/application-spec/{core → enhanced-json}/eval-to-constant.js +0 -0
  1136. /package/dist/domain/{core/action.js → application/assistant/assistant-manifest.js} +0 -0
  1137. /package/dist/domain/{actions → core/action}/action-factory.js +0 -0
  1138. /package/dist/domain/core/{enhanced-json-schema.js → action/action.js} +0 -0
  1139. /package/dist/domain/core/{expression.js → component/component-reader-types.js} +0 -0
  1140. /package/dist/domain/{components → core/component}/legacy-filter.js +0 -0
  1141. /package/dist/domain/{components → core/component}/system-component-filter.js +0 -0
  1142. /package/dist/domain/{components → core/component}/system-virtual-entity.d.ts +0 -0
  1143. /package/dist/domain/{components → core/component}/updates.js +0 -0
  1144. /package/dist/domain/core/{schema-validator.js → data-schema/data-cell-value.js} +0 -0
  1145. /package/dist/domain/{relations/reference-field.js → core/data-schema/data-schema-array-field.js} +0 -0
  1146. /package/dist/domain/{relations/relation-implementation.js → core/data-schema/data-schema-field-object.js} +0 -0
  1147. /package/dist/domain/{invariants → core/invariant}/builtin-invariant.js +0 -0
  1148. /package/dist/domain/{invariants → core/invariant}/violation-component.d.ts +0 -0
  1149. /package/dist/domain/core/{alias.d.ts → model/alias.d.ts} +0 -0
  1150. /package/dist/domain/core/{alias.js → model/alias.js} +0 -0
  1151. /package/dist/domain/core/{common-definitions.d.ts → model/common-definitions.d.ts} +0 -0
  1152. /package/dist/domain/core/{common-definitions.js → model/common-definitions.js} +0 -0
  1153. /package/dist/domain/core/{component.js → model/component.js} +0 -0
  1154. /package/dist/domain/core/{model.js → model/model.js} +0 -0
  1155. /package/dist/domain/core/{preset.d.ts → model/preset.d.ts} +0 -0
  1156. /package/dist/domain/core/{preset.js → model/preset.js} +0 -0
  1157. /package/dist/domain/{relations → core/relation}/direct-relation.js +0 -0
  1158. /package/dist/domain/core/{schema-validator-ajv.d.ts → schema/create-ajv-schema-validator.d.ts} +0 -0
  1159. /package/dist/domain/core/{schema-validator-ajv.js → schema/create-ajv-schema-validator.js} +0 -0
  1160. /package/dist/domain/core/{schema-validator-csp.d.ts → schema/create-csp-schema-validator.d.ts} +0 -0
  1161. /package/dist/domain/core/{schema-validator-csp.js → schema/create-csp-schema-validator.js} +0 -0
  1162. /package/dist/domain/core/{enhanced-json-schema.d.ts → schema/enhanced-json-schema.d.ts} +0 -0
  1163. /package/dist/domain/core/{json-schema.d.ts → schema/extended-schema-validator.d.ts} +0 -0
  1164. /package/dist/domain/core/{schema-validator.d.ts → schema/schema-validator.d.ts} +0 -0
  1165. /package/dist/domain/core/{state.js → state/state.js} +0 -0
  1166. /package/dist/domain/{expressions → domain-runtime/spec}/memoize-expression.js +0 -0
  1167. /package/dist/domain/{expressions → domain-runtime/spec}/prepare-domain-expressions.js +0 -0
  1168. /package/dist/domain/{system-components → extensions}/camera-based-hidden-entity-object.d.ts +0 -0
  1169. /package/dist/domain/{system-components → extensions}/camera-based-hidden-entity.d.ts +0 -0
  1170. /package/dist/domain/{system-components → extensions}/canvas-custom-environment.d.ts +0 -0
  1171. /package/dist/domain/{system-components → extensions}/color-value.d.ts +0 -0
  1172. /package/dist/domain/{system-components → extensions}/common/dimension-indicators.d.ts +0 -0
  1173. /package/dist/domain/{system-components → extensions}/common/dimension-indicators.js +0 -0
  1174. /package/dist/domain/{system-components → extensions}/common/editable-indicator-button-variant.d.ts +0 -0
  1175. /package/dist/domain/{system-components → extensions}/common/editable-indicator-button-variant.js +0 -0
  1176. /package/dist/domain/{system-components → extensions}/custom-price-footer.d.ts +0 -0
  1177. /package/dist/domain/{system-components → extensions}/finalize-component.d.ts +0 -0
  1178. /package/dist/domain/{system-components → extensions}/fit-selection-orthographic-camera-component.d.ts +0 -0
  1179. /package/dist/domain/{system-components → extensions}/fit-selection-perspective-camera-component.d.ts +0 -0
  1180. /package/dist/domain/{system-components → extensions}/multilingual-text-value.d.ts +0 -0
  1181. /package/dist/domain/{system-components → extensions}/rotatable.d.ts +0 -0
  1182. /package/dist/domain/{system-components → extensions}/scene-entity-animation.d.ts +0 -0
  1183. /package/dist/domain/{system-components → extensions}/scene-entity-control.d.ts +0 -0
  1184. /package/dist/domain/{system-components → extensions}/scene-entity-floor-object.d.ts +0 -0
  1185. /package/dist/domain/{system-components → extensions}/scene-entity-wall-object.d.ts +0 -0
  1186. /package/dist/domain/{system-components → extensions}/selectable-component.d.ts +0 -0
  1187. /package/dist/domain/{system-components → extensions}/simple-summary.d.ts +0 -0
  1188. /package/dist/domain/{system-components → extensions}/summary-component.d.ts +0 -0
  1189. /package/dist/domain/{system-components → extensions}/text-value.d.ts +0 -0
  1190. /package/dist/domain/{system-components → extensions}/tool-controls.d.ts +0 -0
  1191. /package/dist/domain/{system-components → extensions}/view-controls.d.ts +0 -0
@@ -0,0 +1,1404 @@
1
+ # Custom Layout
2
+
3
+ Make the configurator look like the brand's own product page. A furniture shop wants its table configurator to read like the rest of its site: a floating panel on the left with the product's name, the edge finishes as picture cards, the price in large type and one clear call to action, and the table in the space beside it. The project writes that page as one React component. Phoenix supplies the 3D scene, the product's state and a few hooks; every pixel around the scene is the project's own.
4
+
5
+ - [Choose this approach](#choose-this-approach)
6
+ - [Register the layout](#register-the-layout)
7
+ - [What the layout has to do](#what-the-layout-has-to-do)
8
+ - [Read and change the product](#read-and-change-the-product)
9
+ - [Draw the choices](#draw-the-choices)
10
+ - [Offer fullscreen](#offer-fullscreen)
11
+ - [Show messages](#show-messages)
12
+ - [Request a quote](#request-a-quote)
13
+ - [Serve read mode](#serve-read-mode)
14
+ - [The spec the layout reads](#the-spec-the-layout-reads)
15
+ - [Try the example](#try-the-example)
16
+ - [Test cases](#test-cases)
17
+ - [Known gaps](#known-gaps)
18
+ - [Related pages](#related-pages)
19
+ - [Complete Implementation](#complete-implementation)
20
+
21
+ ## Choose this approach
22
+
23
+ Write your own layout when the configurator has to follow a design the built-in layout cannot take on: the brand's typography, controls and spacing, a panel on the left, a top bar with the price, an area the built-in layout has no place for.
24
+
25
+ Stay with the built-in layout when its structure fits and only its parts change. [Universal](?path=/docs/layouts-universal--docs) demonstrates that layout, and the pages of its parts describe what the spec configures: [Header](?path=/docs/layouts-header-floating--docs), [Sidebar](?path=/docs/layouts-sidebar-general--docs), [Sidebar Footer](?path=/docs/layouts-sidebar-footer-basic--docs), [Toolbar](?path=/docs/layouts-toolbar--docs) and [View Controls](?path=/docs/layouts-view-controls--docs).
26
+
27
+ A project layout replaces all of that. None of the built-in sidebar, footer, toolbar or property pages is rendered for it, so the layout builds every control the user needs. This example uses no SDK component that draws UI: only the scene, the safe-area hook and hooks that read and change the product's state. A layout may also mount the SDK's own pieces where it wants them, see [Configurator Interface → Loaded Configuration UI](?path=/docs/phoenix-configurator-interface--docs#loaded-configuration-ui).
28
+
29
+ ## Register the layout
30
+
31
+ Create `src/elements/ConfiguratorLayout.tsx` with a default export made by `phx.frontend.createCustomPhoenixLayoutElement`. The name `ConfiguratorLayout` is what makes it the layout: Phoenix renders the element registered under that name for every loaded configuration, in owner and in read mode, whatever `layout` the spec sets. Nothing in the YAML refers to it.
32
+
33
+ ```tsx
34
+ import { Box } from '@mui/material'
35
+
36
+ import { LayoutSlots, useSceneSafeArea } from '@salsita-ai/sdk/configurator'
37
+
38
+ import { phx } from '../../.phoenix/phx.js'
39
+ import { FullscreenToggle } from '../_shared/FullscreenToggle.js'
40
+ import { MessageToast } from '../_shared/MessageToast.js'
41
+ import { ProductPanel } from '../_shared/ProductPanel.js'
42
+
43
+ const GUTTER = 24
44
+ const PANEL_WIDTH = 380
45
+
46
+ const ConfiguratorLayout = () => {
47
+ const { containerRef, safeAreaRef } = useSceneSafeArea()
48
+ const isFullscreen = phx.frontend.useIsFullscreenActive()
49
+
50
+ return (
51
+ <Box component="div" ref={containerRef} sx={{ position: 'absolute', inset: 0 }}>
52
+ <LayoutSlots.SharedCanvas />
53
+
54
+ {!isFullscreen && (
55
+ <Box
56
+ component="aside"
57
+ sx={{
58
+ position: 'absolute',
59
+ insetBlockStart: GUTTER,
60
+ insetInlineStart: GUTTER,
61
+ inlineSize: PANEL_WIDTH,
62
+ maxBlockSize: `calc(100% - ${2 * GUTTER}px)`,
63
+ display: 'flex',
64
+ flexDirection: 'column',
65
+ borderRadius: 5,
66
+ bgcolor: 'background.paper',
67
+ boxShadow: '0 12px 40px rgba(0, 0, 0, 0.12)',
68
+ overflow: 'hidden',
69
+ }}
70
+ >
71
+ <ProductPanel />
72
+ </Box>
73
+ )}
74
+
75
+ <Box
76
+ component="div"
77
+ ref={safeAreaRef}
78
+ sx={{
79
+ position: 'absolute',
80
+ insetBlock: 0,
81
+ insetInlineStart: isFullscreen ? 0 : PANEL_WIDTH + 2 * GUTTER,
82
+ insetInlineEnd: 0,
83
+ pointerEvents: 'none',
84
+ }}
85
+ >
86
+ <Box
87
+ component="div"
88
+ sx={{ position: 'absolute', insetBlockStart: GUTTER, insetInlineEnd: GUTTER, pointerEvents: 'auto' }}
89
+ >
90
+ <FullscreenToggle />
91
+ </Box>
92
+ <Box
93
+ component="div"
94
+ sx={{ position: 'absolute', insetBlockEnd: GUTTER, insetInlineStart: GUTTER, pointerEvents: 'auto' }}
95
+ >
96
+ <MessageToast />
97
+ </Box>
98
+ </Box>
99
+ </Box>
100
+ )
101
+ }
102
+
103
+ export default phx.frontend.createCustomPhoenixLayoutElement('ConfiguratorLayout', ConfiguratorLayout)
104
+ ```
105
+
106
+ The components it uses live in `src/_shared/`, which Phoenix does not import by convention, so the layout imports them itself. Application projects receive `phx` as a global. Storybook examples cannot rely on that project environment, so these files import it from `../../.phoenix/phx.js`; leave that import out in a project.
107
+
108
+ ## What the layout has to do
109
+
110
+ - **Position the root and cover the page.** `LayoutSlots.SharedCanvas` is absolutely positioned and fills its nearest positioned ancestor. The root here is `position: absolute; inset: 0`.
111
+ - **Mount the shared canvas.** The app loader stays on screen until the scene has loaded. A layout without `LayoutSlots.SharedCanvas` never gets past the loader unless the project sets `appLoader: legacy`.
112
+ - **Put the UI above the canvas.** The canvas is opaque. Content that is positioned and comes after it in the markup is painted above it; unpositioned content is painted under it and cannot be seen.
113
+ - **Tell the camera where the free area is.** `useSceneSafeArea()` returns two refs. `containerRef` goes on the element that covers the whole canvas, `safeAreaRef` on the region the product should stay visible in, here everything right of the panel. The camera then frames the product in that region. The hook measures again whenever either of the two elements resizes; for a change no resize reports, such as a `transform` on an ancestor settling at the end of an animation, it also returns `update` to call. Without the two refs the product is centred in the whole canvas and sits against the panel.
114
+ - **Let the pointer through.** The safe-area element lies over the canvas, so it sets `pointerEvents: 'none'`; otherwise the scene cannot be orbited. The fullscreen button inside it switches pointer events back on.
115
+ - **Honour fullscreen.** Fullscreen is a flag in the product's state, not a browser feature. The layout reads it with `phx.frontend.useIsFullscreenActive()`, removes the panel and lets the safe area start at the left edge, so the camera frames the product in the whole canvas.
116
+ - **Serve read mode.** The same element renders a configuration shared for viewing, and the layout decides what a viewer sees.
117
+
118
+ ## Read and change the product
119
+
120
+ The panel reads everything it shows from hooks and writes the customer's choice back through one of them. The table lists the hooks the whole layout uses:
121
+
122
+ ```tsx
123
+ import { Box, Button, Typography } from '@mui/material'
124
+
125
+ import { detailComponent, finalizeActionComponent } from '@salsita-ai/sdk/domain'
126
+ import { PhoenixHandlerBoundary, useResolveLocalizable } from '@salsita-ai/sdk/react'
127
+
128
+ import { phx } from '../../.phoenix/phx.js'
129
+ import { EdgeFinishCards } from './EdgeFinishCards.js'
130
+ import { ReviewActions } from './ReviewActions.js'
131
+
132
+ const BUTTON_SX = { minBlockSize: 48, borderRadius: 999, textTransform: 'none', fontWeight: 600 } as const
133
+
134
+ export const ProductPanel = () => {
135
+ const resolve = useResolveLocalizable()
136
+ const detail = phx.frontend.useFirstRootComponent(detailComponent)
137
+ const price = phx.frontend.useRootEntityPrice()
138
+ const tableId = phx.frontend.useRootEntityId()
139
+ const edgeFinish = phx.frontend.useAttributeSelection(tableId, 'edgeFinish')
140
+ const { accessInfo } = phx.frontend.useAccessService()
141
+ const navigationState = phx.frontend.useActiveNavigationState()
142
+ const pushNavigate = phx.frontend.usePushNavigate()
143
+ const popNavigate = phx.frontend.usePopNavigate()
144
+ const navigate = phx.frontend.useNavigate()
145
+ const finalizeActions = phx.frontend.useComponents({ componentTypes: [finalizeActionComponent] }) ?? []
146
+
147
+ const isReadMode = accessInfo.viewMode
148
+ const isReview = isReadMode || navigationState !== 'configure'
149
+ // The spec's primary finalize action, or its first one
150
+ const quoteAction = finalizeActions.find(action => action.state.variant === 'primary') ?? finalizeActions[0]
151
+ const chosenEdge = edgeFinish.options.find(option => option.value === edgeFinish.value)
152
+
153
+ return (
154
+ <>
155
+ <Box component="header" sx={{ display: 'grid', gap: 1, padding: 3, paddingBlockEnd: 2 }}>
156
+ {isReadMode ? (
157
+ <Typography
158
+ variant="overline"
159
+ sx={{ justifySelf: 'start', paddingInline: 1.5, borderRadius: 999, bgcolor: 'action.selected' }}
160
+ >
161
+ View only
162
+ </Typography>
163
+ ) : (
164
+ <Typography variant="overline" color="text.secondary">
165
+ {resolve(detail?.state.subtitle)}
166
+ </Typography>
167
+ )}
168
+ <Typography variant="h5" component="h2" fontWeight={700}>
169
+ {resolve(detail?.state.title)}
170
+ </Typography>
171
+ <Typography variant="body2" color="text.secondary">
172
+ {resolve(detail?.state.description)}
173
+ </Typography>
174
+ </Box>
175
+
176
+ <Box component="div" sx={{ display: 'grid', gap: 1.5, paddingInline: 3, paddingBlockEnd: 3, overflowY: 'auto' }}>
177
+ <Typography variant="subtitle2" component="h3">
178
+ Edge finish
179
+ </Typography>
180
+ {isReview ? (
181
+ <Box component="div" sx={{ padding: 2, borderRadius: 3, bgcolor: 'action.hover' }}>
182
+ <Typography variant="body2" fontWeight={600}>
183
+ {resolve(chosenEdge?.title)}
184
+ </Typography>
185
+ <Typography variant="caption" color="text.secondary">
186
+ {resolve(chosenEdge?.description)}
187
+ </Typography>
188
+ </Box>
189
+ ) : (
190
+ <EdgeFinishCards selection={edgeFinish} />
191
+ )}
192
+ </Box>
193
+
194
+ <Box component="footer" sx={{ display: 'grid', gap: 2, padding: 3, borderTop: 1, borderColor: 'divider' }}>
195
+ <Box component="div" sx={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between' }}>
196
+ <Typography variant="body2" color="text.secondary">
197
+ Total price
198
+ </Typography>
199
+ <Typography variant="h5" component="p" fontWeight={700}>
200
+ {price}
201
+ </Typography>
202
+ </Box>
203
+ {!isReadMode && navigationState === 'configure' && (
204
+ <Button size="large" variant="contained" onClick={() => pushNavigate('checkout')} sx={BUTTON_SX}>
205
+ Review and request a quote
206
+ </Button>
207
+ )}
208
+ {!isReadMode && navigationState === 'checkout' && (
209
+ <>
210
+ <Typography variant="body2" color="text.secondary">
211
+ Your table is ready for a quote. A real shop collects the contact details here.
212
+ </Typography>
213
+ {quoteAction ? (
214
+ <PhoenixHandlerBoundary name={quoteAction.state.handler}>
215
+ <ReviewActions
216
+ handler={quoteAction.state.handler}
217
+ label={resolve(quoteAction.state.label)}
218
+ onBack={popNavigate}
219
+ />
220
+ </PhoenixHandlerBoundary>
221
+ ) : (
222
+ <Button size="large" variant="outlined" onClick={popNavigate} sx={BUTTON_SX}>
223
+ Back to the configuration
224
+ </Button>
225
+ )}
226
+ </>
227
+ )}
228
+ {!isReadMode && navigationState === 'requested' && (
229
+ <>
230
+ <Typography variant="body2" role="status">
231
+ Thank you. Your quote request is on its way, and the shop replies within two working days.
232
+ </Typography>
233
+ <Button size="large" variant="outlined" onClick={() => navigate('configure')} sx={BUTTON_SX}>
234
+ Back to the configuration
235
+ </Button>
236
+ </>
237
+ )}
238
+ </Box>
239
+ </>
240
+ )
241
+ }
242
+ ```
243
+
244
+ | Hook | What the layout uses it for |
245
+ | ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
246
+ | `phx.frontend.useFirstRootComponent(detailComponent)` | The `detail` component of the root entity: name, subtitle and description. `detailComponent` comes from `@salsita-ai/sdk/domain`; the hook returns `null` without one. |
247
+ | `phx.frontend.useRootEntityId()` | The id of the table, which the control hooks take. |
248
+ | `phx.frontend.useAttributeSelection(entityId, instanceName)` | The `attributeSelection` component named `edgeFinish`: the current `value` and the `options`, each with `title`, `description`, `value`, `disabled` and `onSelect`. |
249
+ | `phx.frontend.useRootEntityPrice()` | The root entity's `price` component, formatted for the current locale and currency, or `null` without one. |
250
+ | `phx.frontend.useAccessService()` | `accessInfo.viewMode` is `true` while a configuration shared for viewing is open, and also while the host sets the `readonly` property. |
251
+ | `phx.frontend.useActiveNavigationState()` | The active navigation state; the panel shows its review step while it is `checkout`. |
252
+ | `phx.frontend.usePushNavigate()` and `phx.frontend.usePopNavigate()` | Enter the review step and leave it again. |
253
+ | `phx.frontend.useNavigate()` | Return from the confirmation to the configuration, forgetting the review step. |
254
+ | `phx.frontend.useComponents({ componentTypes: [finalizeActionComponent] })` | The spec's `finalizeAction` components; the panel offers the primary one in its review step. `finalizeActionComponent` comes from `@salsita-ai/sdk/domain`. |
255
+ | `phx.frontend.useFinalizeAction(handler)` | Run the finalize action's handler, with its pending state, its error and whether finalizing is possible; see [Request a quote](#request-a-quote). |
256
+ | `phx.frontend.useIsFullscreenActive()` and `phx.frontend.useSetFullscreen()` | Read the fullscreen flag, and set it from the layout's own button. |
257
+ | `phx.frontend.useConfiguratorMessages(onMessage)` | Receive violations, side-effect hints and errors one by one, with their text resolved, for the layout's own toast; see [Show messages](#show-messages). |
258
+ | `useResolveLocalizable()` from `@salsita-ai/sdk/react` | Turns the localizable texts of the spec into strings in the current language. [Localization](?path=/docs/phoenix-localization--docs) describes it and `LocalizableMessage`. |
259
+ | `PhoenixHandlerBoundary` from `@salsita-ai/sdk/react` | Wraps the review step's buttons, so an edited handler takes effect without a reload. |
260
+
261
+ Calling an option's `onSelect` is the whole write: it changes `edgeFinish` on the table, the scene morphs the edge and the price expression recalculates. The option fields are named for display: the spec's `label` arrives as `title`, its `img` as `imageSrc`.
262
+
263
+ The review step is the layout's own: the button pushes the `checkout` navigation state, and the panel shows a summary instead of the cards. There **Request a quote** runs the spec's finalize action, whose handler moves the panel on to the `requested` state and its confirmation; see [Request a quote](#request-a-quote). A real shop collects the contact details in the review step before it sends the request.
264
+
265
+ ## Draw the choices
266
+
267
+ The edge finish is a visual choice, so the panel shows it as cards with a drawing of each profile, as [Choosing a Control](?path=/docs/ux-guidelines-choosing-a-control--docs) recommends for shapes. The selected card has a border in the theme's primary colour, a tinted background and a check mark, so the state does not depend on colour alone. The cards form a radio group: the group has `role="radiogroup"` and a label, each card `role="radio"` and `aria-checked`, only the selected card is in the tab order, and the arrow keys move the selection, skipping disabled options, as in a native radio group. Each card is at least 44 pixels high and shows a focus ring for keyboard users.
268
+
269
+ ```tsx
270
+ import { Box, ButtonBase, type SxProps, type Theme, Typography } from '@mui/material'
271
+ import type { KeyboardEvent } from 'react'
272
+
273
+ import { type UseAttributeSelection, useResolveLocalizable } from '@salsita-ai/sdk/react'
274
+
275
+ // Cross-sections of the tabletop's edge, keyed by the option values of the spec.
276
+ const EDGE_PROFILES: Readonly<Record<string, string>> = {
277
+ None: 'M0 4H32V20H0Z',
278
+ Facet: 'M0 4H26L32 10V14L26 20H0Z',
279
+ Round: 'M0 4H24A8 8 0 0 1 24 20H0Z',
280
+ TreeTrunk: 'M0 4H27C33 5 28 9 34 11C29 13 34 17 27 20H0Z',
281
+ }
282
+
283
+ const CHECK_BADGE: SxProps<Theme> = {
284
+ position: 'absolute',
285
+ insetBlockStart: 10,
286
+ insetInlineEnd: 10,
287
+ display: 'grid',
288
+ placeItems: 'center',
289
+ inlineSize: 22,
290
+ blockSize: 22,
291
+ borderRadius: '50%',
292
+ bgcolor: 'primary.main',
293
+ color: 'primary.contrastText',
294
+ fontSize: 13,
295
+ }
296
+
297
+ // Arrow keys move the selection between the cards, as in a native radio group.
298
+ const ARROW_STEPS: Readonly<Record<string, number | undefined>> = {
299
+ ArrowRight: 1,
300
+ ArrowDown: 1,
301
+ ArrowLeft: -1,
302
+ ArrowUp: -1,
303
+ }
304
+
305
+ interface EdgeFinishCardsProps {
306
+ readonly selection: ReturnType<UseAttributeSelection>
307
+ }
308
+
309
+ export const EdgeFinishCards = ({ selection }: EdgeFinishCardsProps) => {
310
+ const resolve = useResolveLocalizable()
311
+ const { options } = selection
312
+ // The card in the tab order: the selected one, or the first enabled one. Disabled cards are never in it.
313
+ const selectedIndex = options.findIndex(option => option.value === selection.value && !option.disabled)
314
+ const focusIndex = selectedIndex >= 0 ? selectedIndex : options.findIndex(option => !option.disabled)
315
+
316
+ const handleKeyDown = (event: KeyboardEvent<HTMLElement>, index: number) => {
317
+ const step = ARROW_STEPS[event.key]
318
+
319
+ if (step === undefined) {
320
+ return
321
+ }
322
+
323
+ event.preventDefault()
324
+ // The next enabled option in the arrow's direction, wrapping around; disabled options are skipped.
325
+ const count = options.length
326
+ const next = Array.from(
327
+ { length: count - 1 },
328
+ (_, offset) => (((index + step * (offset + 1)) % count) + count) % count
329
+ ).find(candidate => !options[candidate]?.disabled)
330
+
331
+ if (next === undefined) {
332
+ return
333
+ }
334
+
335
+ options[next]?.onSelect()
336
+ event.currentTarget.parentElement?.querySelectorAll<HTMLElement>('[role="radio"]')[next]?.focus()
337
+ }
338
+
339
+ return (
340
+ <Box
341
+ component="div"
342
+ role="radiogroup"
343
+ aria-label="Edge finish"
344
+ sx={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 1.5 }}
345
+ >
346
+ {options.map((option, index) => {
347
+ const isSelected = option.value === selection.value
348
+
349
+ return (
350
+ <ButtonBase
351
+ key={String(option.value)}
352
+ role="radio"
353
+ aria-checked={isSelected}
354
+ tabIndex={index === focusIndex ? 0 : -1}
355
+ disabled={option.disabled}
356
+ onClick={option.onSelect}
357
+ onKeyDown={event => handleKeyDown(event, index)}
358
+ sx={{
359
+ position: 'relative',
360
+ display: 'grid',
361
+ justifyItems: 'start',
362
+ gap: 0.5,
363
+ padding: 2,
364
+ borderRadius: 3,
365
+ border: 2,
366
+ borderColor: isSelected ? 'primary.main' : 'divider',
367
+ bgcolor: isSelected ? 'action.hover' : 'transparent',
368
+ textAlign: 'start',
369
+ transition: 'border-color 150ms, background-color 150ms',
370
+ '&:hover': { borderColor: isSelected ? 'primary.main' : 'text.disabled' },
371
+ '&.Mui-focusVisible': { outline: 2, outlineColor: 'primary.main', outlineOffset: 2 },
372
+ '&.Mui-disabled': { opacity: 0.4 },
373
+ }}
374
+ >
375
+ {isSelected && (
376
+ <Box component="span" aria-hidden sx={CHECK_BADGE}>
377
+ ✓
378
+ </Box>
379
+ )}
380
+ <Box
381
+ component="svg"
382
+ viewBox="0 0 36 24"
383
+ aria-hidden
384
+ sx={{ inlineSize: 60, blockSize: 40, color: '#b98b5e' }}
385
+ >
386
+ <path d={EDGE_PROFILES[String(option.value)]} fill="currentColor" />
387
+ </Box>
388
+ <Typography variant="body2" fontWeight={600}>
389
+ {resolve(option.title)}
390
+ </Typography>
391
+ <Typography variant="caption" color="text.secondary">
392
+ {resolve(option.description)}
393
+ </Typography>
394
+ </ButtonBase>
395
+ )
396
+ })}
397
+ </Box>
398
+ )
399
+ }
400
+ ```
401
+
402
+ The drawings are keyed by the option values of the spec. A spec can carry a picture per option instead, as `img`, which the hook returns as `imageSrc`; [CardSelect](?path=/docs/controls-select-attribute-cardselect--docs) shows the SDK's own card control.
403
+
404
+ ## Offer fullscreen
405
+
406
+ Fullscreen is a flag in the configurator's state, not the browser's fullscreen mode. `phx.frontend.useIsFullscreenActive()` reads it and `phx.frontend.useSetFullscreen()` returns a function that sets it: `setFullscreen(true)` turns it on, `setFullscreen(false)` off. The layout's own button flips it, and the layout decides what to hide.
407
+
408
+ ```tsx
409
+ import { Button } from '@mui/material'
410
+
411
+ import { phx } from '../../.phoenix/phx.js'
412
+
413
+ const ENTER_ICON = 'M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5'
414
+ const EXIT_ICON = 'M9 4v5H4M15 4v5h5M15 20v-5h5M9 20v-5H4'
415
+
416
+ export const FullscreenToggle = () => {
417
+ const isFullscreen = phx.frontend.useIsFullscreenActive()
418
+ const setFullscreen = phx.frontend.useSetFullscreen()
419
+
420
+ return (
421
+ <Button
422
+ onClick={() => setFullscreen(!isFullscreen)}
423
+ startIcon={
424
+ <svg viewBox="0 0 24 24" width={20} height={20} fill="none" stroke="currentColor" strokeWidth={2}>
425
+ <path d={isFullscreen ? EXIT_ICON : ENTER_ICON} />
426
+ </svg>
427
+ }
428
+ sx={{
429
+ minBlockSize: 44,
430
+ paddingInline: 2.5,
431
+ borderRadius: 999,
432
+ bgcolor: 'background.paper',
433
+ color: 'text.primary',
434
+ boxShadow: '0 4px 16px rgba(0, 0, 0, 0.12)',
435
+ textTransform: 'none',
436
+ fontWeight: 600,
437
+ '&:hover': { bgcolor: 'background.paper', boxShadow: '0 6px 20px rgba(0, 0, 0, 0.18)' },
438
+ }}
439
+ >
440
+ {isFullscreen ? 'Exit fullscreen' : 'Fullscreen'}
441
+ </Button>
442
+ )
443
+ }
444
+ ```
445
+
446
+ The button stays in the free area in both states, so the way back is always where the user left it. [Interaction Modes](?path=/docs/ux-guidelines-interaction-modes--docs#full-screen-preview) describes what fullscreen hides.
447
+
448
+ ## Show messages
449
+
450
+ When a change is rejected because it breaks an invariant, when a committed change carries a hint, or when an error is thrown while a change is validated, the configurator has a message for the customer. `phx.frontend.useConfiguratorMessages(onMessage)` calls `onMessage` once for each, with the text already in the customer's language, and the layout shows it its own way. Here a toast at the bottom of the free area shows a message for six seconds, colored by its severity:
451
+
452
+ ```tsx
453
+ import { Alert } from '@mui/material'
454
+ import { useEffect, useState } from 'react'
455
+
456
+ import type { ConfiguratorMessage } from '@salsita-ai/sdk/react'
457
+
458
+ import { phx } from '../../.phoenix/phx.js'
459
+
460
+ const VIOLATION_SEVERITY = { fatal: 'error', fixable: 'error', warning: 'warning', notice: 'info' } as const
461
+ const RANK = { info: 0, warning: 1, error: 2 } as const
462
+ const VISIBLE_MS = 6000
463
+
464
+ const severityOf = (message: ConfiguratorMessage) => {
465
+ if (message.kind === 'violation') {
466
+ return VIOLATION_SEVERITY[message.violation.severity]
467
+ }
468
+
469
+ return message.kind === 'error' ? 'error' : 'info'
470
+ }
471
+
472
+ export const MessageToast = () => {
473
+ const [message, setMessage] = useState<ConfiguratorMessage | null>(null)
474
+
475
+ // A rejected change also reports the notices already present; keep the worst message while it is shown
476
+ phx.frontend.useConfiguratorMessages(next => {
477
+ setMessage(shown => (shown !== null && RANK[severityOf(next)] < RANK[severityOf(shown)] ? shown : next))
478
+ })
479
+
480
+ useEffect(() => {
481
+ if (message === null) {
482
+ return
483
+ }
484
+
485
+ const timeout = setTimeout(() => setMessage(null), VISIBLE_MS)
486
+
487
+ return () => clearTimeout(timeout)
488
+ }, [message])
489
+
490
+ if (message === null) {
491
+ return null
492
+ }
493
+
494
+ return (
495
+ <Alert
496
+ severity={severityOf(message)}
497
+ onClose={() => setMessage(null)}
498
+ sx={{ maxInlineSize: 420, borderRadius: 3, boxShadow: '0 12px 40px rgba(0, 0, 0, 0.12)' }}
499
+ >
500
+ {message.text}
501
+ </Alert>
502
+ )
503
+ }
504
+ ```
505
+
506
+ The hook takes a new function on every render without missing a message, so passing the state setter, or an inline function, is fine. `message.kind` is `'violation'`, `'sideEffect'` or `'error'`; a violation also carries `entityId` and the `violation` itself, with its `severity`. A rejected change brings one message for each violation of the rejected state, including notices and warnings that were already present, so the toast keeps the most severe message while it is shown instead of letting a later notice replace the reason for the rejection. The layout mounts the toast in the safe-area element, which sets `pointerEvents: 'none'`, so the toast's wrapper switches pointer events back on for the close button.
507
+
508
+ To give the toast something to show, the spec registers one transformer. Choosing **Tree trunk** keeps the change and adds a hint to it, which arrives as a `sideEffect` message:
509
+
510
+ ```ts
511
+ import { msg } from '@lingui/core/macro'
512
+
513
+ import { phx } from '../../.phoenix/phx.js'
514
+
515
+ // A tree-trunk edge is cut by hand; choosing it carries a hint, which reaches the layout as a side-effect message
516
+ export default phx.frontend.transformerBuilder.when
517
+ .entity(['Table'])
518
+ .modified({ atFields: ['edgeFinish'] })
519
+ .then.overrideMatchingUpdate(({ update }) => {
520
+ if (update.stateDelta.edgeFinish !== 'TreeTrunk') {
521
+ return [update]
522
+ }
523
+
524
+ return [{ ...update, hint: msg`Tree trunk edges are cut by hand, so delivery takes three weeks longer.` }]
525
+ })
526
+ .build('tree-trunk-delivery')
527
+ ```
528
+
529
+ [Configurator Interface → Loaded Configuration UI](?path=/docs/phoenix-configurator-interface--docs#loaded-configuration-ui) lists the messages the hook does not deliver: a failure to save, errors of the built-in finalize and other actions, and preset errors stay snackbars.
530
+
531
+ ## Request a quote
532
+
533
+ The spec declares what finalizing means for this product as a `finalizeAction` component, and the project registers the handler it names:
534
+
535
+ ```yaml
536
+ components:
537
+ Table:
538
+ finalizeAction:
539
+ quote:
540
+ variant: primary
541
+ label: Request a quote
542
+ title: Send the configuration to the shop for a quote
543
+ icon: PaperPlaneTilt
544
+ handler: requestQuote
545
+ ```
546
+
547
+ ```ts
548
+ import { useCallback } from 'react'
549
+
550
+ import { phx } from '../../.phoenix/phx.js'
551
+
552
+ // Stands in for the shop's quote service: the request takes a moment, then the panel shows the confirmation
553
+ export default phx.frontend.createPhoenixHandler('requestQuote', () => {
554
+ const navigate = phx.frontend.useNavigate()
555
+
556
+ return {
557
+ handler: useCallback(async () => {
558
+ await new Promise(resolve => setTimeout(resolve, 1500))
559
+ navigate('requested')
560
+ }, [navigate]),
561
+ }
562
+ })
563
+ ```
564
+
565
+ The handler stands in for the shop's quote service: it waits a moment, as a request would, and then enters the `requested` navigation state, in which the panel thanks the customer. A handler is a hook factory, so it can use any hook, here `phx.frontend.useNavigate()`.
566
+
567
+ The panel lists the finalize actions with `phx.frontend.useComponents({ componentTypes: [finalizeActionComponent] })` and offers the primary one, or the first when none is primary, in its review step. It renders the review step's buttons in a component of their own inside `<PhoenixHandlerBoundary name={handler}>`, because `phx.frontend.useFinalizeAction(handler)` runs the project's handler factory: it is called once per component, never in a loop, and the boundary remounts the buttons when the handler is edited. **Back to the configuration** lives in the same component, so it can be disabled while the request is pending.
568
+
569
+ ```tsx
570
+ import { Alert, Box, Button, CircularProgress, Typography } from '@mui/material'
571
+
572
+ import { phx } from '../../.phoenix/phx.js'
573
+
574
+ const BUTTON_SX = { minBlockSize: 48, borderRadius: 999, textTransform: 'none', fontWeight: 600 } as const
575
+
576
+ interface ReviewActionsProps {
577
+ readonly handler: string
578
+ readonly label: string
579
+ readonly onBack: () => void
580
+ }
581
+
582
+ // The review step's buttons: one finalize action and the way back. `useFinalizeAction` runs the action's handler,
583
+ // so this component calls it exactly once and is rendered inside a `PhoenixHandlerBoundary` for that handler.
584
+ // Back is disabled while the request is pending, so the customer cannot change the configuration while it is sent.
585
+ // The pending state belongs to this component: when the panel unmounts, as in fullscreen, the request goes on and
586
+ // the remounted buttons are enabled again.
587
+ export const ReviewActions = ({ handler, label, onBack }: ReviewActionsProps) => {
588
+ const { run, isPending, error, disabled, hints } = phx.frontend.useFinalizeAction(handler)
589
+
590
+ return (
591
+ <Box component="div" sx={{ display: 'grid', gap: 2 }}>
592
+ <Box component="div" sx={{ display: 'grid', gap: 1 }}>
593
+ <Button
594
+ size="large"
595
+ variant="contained"
596
+ disabled={disabled || isPending}
597
+ onClick={run}
598
+ startIcon={isPending ? <CircularProgress size={18} color="inherit" /> : undefined}
599
+ sx={BUTTON_SX}
600
+ >
601
+ {isPending ? 'Sending the request…' : label}
602
+ </Button>
603
+ {disabled && hints && (
604
+ <Typography variant="caption" color="text.secondary">
605
+ {hints}
606
+ </Typography>
607
+ )}
608
+ {error && <Alert severity="error">The request could not be sent: {error.message}</Alert>}
609
+ </Box>
610
+ <Button size="large" variant="outlined" disabled={isPending} onClick={onBack} sx={BUTTON_SX}>
611
+ Back to the configuration
612
+ </Button>
613
+ </Box>
614
+ )
615
+ }
616
+ ```
617
+
618
+ - `run()` records the finalize-button click for analytics and runs the handler; it does nothing while `disabled` or `isPending`.
619
+ - While `isPending` the button shows a spinner and cannot be clicked again, and **Back to the configuration** is disabled, so the customer cannot change the configuration while it is sent. `isPending` and `error` belong to the mounted component: entering fullscreen unmounts the panel, the request goes on, and the panel shown after fullscreen starts with both buttons enabled. A layout that must rule that out keeps the review step mounted, or hides its fullscreen button while a request runs.
620
+ - `error` is what the handler rejected with. The layout shows it under the button; no snackbar is raised. It is cleared when the customer tries again.
621
+ - `disabled` and `hints` come from the configuration's violations: while a `warning` or worse holds, or the configuration failed to save, finalizing is not possible and `hints` says why.
622
+
623
+ The review step stays: a quote request is a commitment, so the customer sees the summary first, and a real shop collects the contact details there. A product that finalizes without a review offers the button in place of **Review and request a quote**. [Configurator Interface → Hooks for a Project Layout](?path=/docs/phoenix-configurator-interface--docs#hooks-for-a-project-layout) describes the hook, and [Finalization](?path=/docs/phoenix-finalization--docs) what a real flow does on the server.
624
+
625
+ ## Serve read mode
626
+
627
+ While `accessInfo.viewMode` is `true` the panel marks the view as view only, replaces the cards with the chosen finish and shows the price without an action; the finalize action is not offered, since `useFinalizeAction` does not check read mode itself. The hooks do not hide or disable anything in read mode: what a viewer can change is decided by what the layout renders. Rotating and zooming the scene, and fullscreen, stay available, as [Interaction Modes](?path=/docs/ux-guidelines-interaction-modes--docs#view-only-mode) recommends.
628
+
629
+ ## The spec the layout reads
630
+
631
+ The layout reads four components of the root entity and its navigation states; the scene components are in the complete implementation below.
632
+
633
+ ```yaml
634
+ navigationStates:
635
+ - configure
636
+ - checkout
637
+ - requested
638
+
639
+ components:
640
+ Table:
641
+ detail:
642
+ main:
643
+ title: Linden dining table
644
+ subtitle: Solid oak, seats six
645
+ description: A solid oak top on slender steel legs, finished with the edge profile of your choice.
646
+ price:
647
+ main:
648
+ price:
649
+ $read: $price
650
+ attributeSelection:
651
+ edgeFinish:
652
+ value:
653
+ $bind: edgeFinish
654
+ options:
655
+ - label: Square
656
+ description: Crisp and modern
657
+ value: None
658
+ - label: Facet
659
+ description: A light bevel
660
+ value: Facet
661
+ - label: Round
662
+ description: Soft to the touch
663
+ value: Round
664
+ - label: Tree trunk
665
+ description: The natural edge
666
+ value: TreeTrunk
667
+ finalizeAction:
668
+ quote:
669
+ variant: primary
670
+ label: Request a quote
671
+ title: Send the configuration to the shop for a quote
672
+ icon: PaperPlaneTilt
673
+ handler: requestQuote
674
+
675
+ transformers:
676
+ - name: tree-trunk-delivery
677
+ ```
678
+
679
+ `$price` is a custom expression in `src/expressions/table.ts` that adds a surcharge per finish, and `tree-trunk-delivery` is the transformer in `src/transformers/tree-trunk-delivery.ts` that adds the hint shown in [Show messages](#show-messages), and `requestQuote` is the handler in `src/handlers/request-quote.ts`. The example sets no `applicationConfig` and no layout components: `layout`, the header, the sidebar footer, the toolbar, `viewControls` and property pages configure the built-in layout and have no effect on this one. The `finalizeAction` is not one of them: it describes the product's own finalizing, which this layout offers itself.
680
+
681
+ ## Try the example
682
+
683
+ To see read mode, open **Mocks** in the editor rail on the left and apply the **Read User** template.
684
+
685
+ ## Test cases
686
+
687
+ - The panel is on the left and the table is centred in the area to the right of it, not in the whole canvas.
688
+ - Choosing **Tree trunk** moves the check mark to that card, changes the edge of the tabletop and raises the price from $1,290.00 to $1,630.00.
689
+ - Choosing **Tree trunk** also shows "Tree trunk edges are cut by hand, so delivery takes three weeks longer." at the bottom of the free area, until its close button is clicked or six seconds pass. Choosing another finish shows nothing.
690
+ - Tab reaches the selected card, and the arrow keys move the selection to the next or previous card.
691
+ - Dragging in the area to the right of the panel orbits the camera.
692
+ - **Review and request a quote** replaces the cards with the chosen finish and offers **Request a quote**; **Back to the configuration** brings the cards back.
693
+ - **Request a quote** shows a spinner and "Sending the request…" for about a second and a half, with **Back to the configuration** disabled, then "Thank you. Your quote request is on its way, and the shop replies within two working days."; **Back to the configuration** then returns to the cards.
694
+ - **Fullscreen** removes the panel and the table moves to the centre of the canvas; **Exit fullscreen** brings both back.
695
+ - With the **Read User** mock the panel says **View only**, shows the chosen finish and the price, and has no button, so no quote can be requested.
696
+
697
+ ## Known gaps
698
+
699
+ A project layout has only what it renders. This one leaves out the following, each of which a product may need. [Layout Slots](?path=/docs/phoenix-layout-slots--docs) describes every `LayoutSlots` member named here.
700
+
701
+ - **Phone width.** The panel is written for desktop: on a narrow screen it covers the scene. A phone layout puts the panel in a bottom sheet and moves the safe area above it.
702
+ - **Messages that stay snackbars.** The toast shows violations, side effects and errors, and the finalize button shows its own error. A failure to save the configuration is still raised as a snackbar, which renders into `LayoutSlots.DesktopSnackbarsRoot`; this layout mounts no snackbar root, so it appears outside the configurator. A layout that wants it inside mounts the root.
703
+ - **Toolbar actions.** Undo and redo, camera reset, measurements, sharing and language switching are not offered. A layout can mount `LayoutSlots.DesktopToolbar` for the toolbar the spec configures, or build its own buttons.
704
+ - **View controls, tool controls and leaving a tool mode.** A spec can configure view controls and tool controls, and a tool mode has a button that leaves it. The built-in layout places them with `LayoutSlots.DesktopViewControls`, `LayoutSlots.DesktopToolControls` and `LayoutSlots.DesktopCallToAction`; this layout mounts none of them, so they do not appear.
705
+ - **A project's layout dialog.** A dialog the project registers with `phx.frontend.createLayoutDialog` is shown by `LayoutDialog`, which the built-in layout mounts. This layout does not; a layout that needs the dialog mounts `LayoutDialog` from `@salsita-ai/sdk/configurator`.
706
+ - **Selection.** The table has no parts to select. A product with selectable parts reads `phx.frontend.useSelectedDomainEntityId()` and shows the controls of the selected part.
707
+ - **Clone to edit in read mode.** With `shareCloneToEdit` set, the built-in layout's `LayoutSlots.DesktopReadonlyBanner` offers **Edit configuration** to a viewer; this layout's "View only" label offers nothing. A layout mounts the banner, or builds its own action with `LayoutSlots.useIsCloningAllowed()` and `LayoutSlots.CloneToEditDialog`.
708
+ - **Back and close.** The built-in header's back button returns to the product choice, runs the host's close action or leaves the expanded view, whichever applies. This layout has none of them. `useCloseAction()` from `@salsita-ai/sdk/configurator` returns the host's close action, or `null` when there is none; the hook that chooses among the three is not exported.
709
+ - **Analytics.** The finalize button records `FinalizeButtonClicked` through `useFinalizeAction`. The built-in fullscreen button records `FullScreenModeToggled`; this layout's fullscreen and other buttons record nothing. A layout that wants the events pushes `FrontendAnalyticsFactory.FullScreenModeToggled()` and the like, from `@salsita-ai/sdk/configurator`, with `phx.frontend.useAnalytics().push(...)`.
710
+ - **Preview start screen.** The built-in layout shows a preview while `usePreview().isPreview` is set, which `preview: auto` does on phones without the project opting in. This layout ignores it and always renders the interface.
711
+ - **Assistant panel.** A project layout gets it only with `LayoutSlots.DesktopSidebar`, the built-in sidebar as one piece, see [Sidebar in a Custom Layout](?path=/docs/layouts-sidebar-in-a-custom-layout--docs); this layout does not use it.
712
+ - **"Powered by Salsita" mark.** The built-in layout shows it; a project layout decides whether to mount `LayoutSlots.DesktopPoweredBy`, and this one does not.
713
+
714
+ ## Related pages
715
+
716
+ - [Configurator Interface → Loaded Configuration UI](?path=/docs/phoenix-configurator-interface--docs#loaded-configuration-ui) is the reference for the element name, the minimal layout, the SDK pieces a layout can mount and the hooks it reads.
717
+ - [Universal](?path=/docs/layouts-universal--docs) is the built-in layout this one replaces.
718
+ - [Header / Custom](?path=/docs/layouts-header-custom--docs) replaces only the header, with the price from `useRootEntityPrice()`.
719
+ - [Canvas Padding](?path=/docs/layouts-canvas-padding--docs) scales the gaps `useSceneSafeArea()` measures.
720
+ - [Presets / Custom](?path=/docs/layouts-presets-custom--docs) replaces the preset screen the same way.
721
+
722
+ ## Complete Implementation
723
+
724
+ {/* AUTO-GENERATED SECTION: This section is automatically updated by 'phoenix story build' */}
725
+
726
+ <details>
727
+ <summary>Click to view the complete implementation files</summary>
728
+
729
+ ### ./spec/domain.yaml
730
+
731
+ ```yaml
732
+ model:
733
+ latest:
734
+ entityTypes:
735
+ - Table
736
+ aliases:
737
+ RootEntity:
738
+ - Table
739
+ commonTypes:
740
+ EdgeFinish:
741
+ enum:
742
+ - None
743
+ - Facet
744
+ - Round
745
+ - TreeTrunk
746
+ shapes:
747
+ Table:
748
+ edgeFinish:
749
+ $ref: '#/model/latest/commonTypes/EdgeFinish'
750
+
751
+ presets:
752
+ - rootEntityType: Table
753
+ initialDomainEntities:
754
+ - id: Table-1
755
+ type: Table
756
+ edgeFinish: None
757
+
758
+ navigationStates:
759
+ - configure
760
+ - checkout
761
+ - requested
762
+
763
+ components:
764
+ Table:
765
+ detail:
766
+ main:
767
+ title: Linden dining table
768
+ subtitle: Solid oak, seats six
769
+ description: A solid oak top on slender steel legs, finished with the edge profile of your choice.
770
+ price:
771
+ main:
772
+ price:
773
+ $read: $price
774
+ attributeSelection:
775
+ edgeFinish:
776
+ value:
777
+ $bind: edgeFinish
778
+ options:
779
+ - label: Square
780
+ description: Crisp and modern
781
+ value: None
782
+ - label: Facet
783
+ description: A light bevel
784
+ value: Facet
785
+ - label: Round
786
+ description: Soft to the touch
787
+ value: Round
788
+ - label: Tree trunk
789
+ description: The natural edge
790
+ value: TreeTrunk
791
+ finalizeAction:
792
+ quote:
793
+ variant: primary
794
+ label: Request a quote
795
+ title: Send the configuration to the shop for a quote
796
+ icon: PaperPlaneTilt
797
+ handler: requestQuote
798
+ fitRootPerspectiveCamera:
799
+ main:
800
+ priority: 1
801
+ fov: 35
802
+ near: 100
803
+ far: 10000
804
+ minDistance: 1000
805
+ maxDistance: 9000
806
+ distance: 5000
807
+ azimuthAngle: 1.5
808
+ polarAngle: 1.1
809
+ fitMeshChanges: true
810
+ sceneEntityRemoteObject:
811
+ top:
812
+ fileUrl: /models/tables.gltf
813
+ objectName: RECHTHOEK_RECTANGLE
814
+ dimensionUnit: m
815
+ leg:
816
+ fileUrl: /models/tables.gltf
817
+ objectName: AXL_LEG
818
+ dimensionUnit: m
819
+ sceneEntityObjectProperties:
820
+ top:
821
+ offsetY: 820
822
+ morphTargetInfluences:
823
+ Facet:
824
+ value:
825
+ $read: $edgeFinishFacet
826
+ scaleOne: 1
827
+ scaleZero: 0
828
+ Bol:
829
+ value:
830
+ $read: $edgeFinishRound
831
+ scaleOne: 1
832
+ scaleZero: 0
833
+ Boomstamrand:
834
+ value:
835
+ $read: $edgeFinishTreeTrunk
836
+ scaleOne: 1
837
+ scaleZero: 0
838
+ leg:
839
+ morphTargetInfluences:
840
+ Length:
841
+ value: 1000
842
+ scaleOne: 3000
843
+ scaleZero: 1400
844
+ Width:
845
+ value: 700
846
+ scaleOne: 1300
847
+ scaleZero: 600
848
+ Height:
849
+ value: 780
850
+ scaleOne: 780
851
+ scaleZero: 740
852
+
853
+ transformers:
854
+ - name: tree-trunk-delivery
855
+ ```
856
+
857
+ ### ./src/\_shared/EdgeFinishCards.tsx
858
+
859
+ ```tsx
860
+ import { Box, ButtonBase, type SxProps, type Theme, Typography } from '@mui/material'
861
+ import type { KeyboardEvent } from 'react'
862
+
863
+ import { type UseAttributeSelection, useResolveLocalizable } from '@salsita-ai/sdk/react'
864
+
865
+ // Cross-sections of the tabletop's edge, keyed by the option values of the spec.
866
+ const EDGE_PROFILES: Readonly<Record<string, string>> = {
867
+ None: 'M0 4H32V20H0Z',
868
+ Facet: 'M0 4H26L32 10V14L26 20H0Z',
869
+ Round: 'M0 4H24A8 8 0 0 1 24 20H0Z',
870
+ TreeTrunk: 'M0 4H27C33 5 28 9 34 11C29 13 34 17 27 20H0Z',
871
+ }
872
+
873
+ const CHECK_BADGE: SxProps<Theme> = {
874
+ position: 'absolute',
875
+ insetBlockStart: 10,
876
+ insetInlineEnd: 10,
877
+ display: 'grid',
878
+ placeItems: 'center',
879
+ inlineSize: 22,
880
+ blockSize: 22,
881
+ borderRadius: '50%',
882
+ bgcolor: 'primary.main',
883
+ color: 'primary.contrastText',
884
+ fontSize: 13,
885
+ }
886
+
887
+ // Arrow keys move the selection between the cards, as in a native radio group.
888
+ const ARROW_STEPS: Readonly<Record<string, number | undefined>> = {
889
+ ArrowRight: 1,
890
+ ArrowDown: 1,
891
+ ArrowLeft: -1,
892
+ ArrowUp: -1,
893
+ }
894
+
895
+ interface EdgeFinishCardsProps {
896
+ readonly selection: ReturnType<UseAttributeSelection>
897
+ }
898
+
899
+ export const EdgeFinishCards = ({ selection }: EdgeFinishCardsProps) => {
900
+ const resolve = useResolveLocalizable()
901
+ const { options } = selection
902
+ // The card in the tab order: the selected one, or the first enabled one. Disabled cards are never in it.
903
+ const selectedIndex = options.findIndex(option => option.value === selection.value && !option.disabled)
904
+ const focusIndex = selectedIndex >= 0 ? selectedIndex : options.findIndex(option => !option.disabled)
905
+
906
+ const handleKeyDown = (event: KeyboardEvent<HTMLElement>, index: number) => {
907
+ const step = ARROW_STEPS[event.key]
908
+
909
+ if (step === undefined) {
910
+ return
911
+ }
912
+
913
+ event.preventDefault()
914
+ // The next enabled option in the arrow's direction, wrapping around; disabled options are skipped.
915
+ const count = options.length
916
+ const next = Array.from(
917
+ { length: count - 1 },
918
+ (_, offset) => (((index + step * (offset + 1)) % count) + count) % count
919
+ ).find(candidate => !options[candidate]?.disabled)
920
+
921
+ if (next === undefined) {
922
+ return
923
+ }
924
+
925
+ options[next]?.onSelect()
926
+ event.currentTarget.parentElement?.querySelectorAll<HTMLElement>('[role="radio"]')[next]?.focus()
927
+ }
928
+
929
+ return (
930
+ <Box
931
+ component="div"
932
+ role="radiogroup"
933
+ aria-label="Edge finish"
934
+ sx={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 1.5 }}
935
+ >
936
+ {options.map((option, index) => {
937
+ const isSelected = option.value === selection.value
938
+
939
+ return (
940
+ <ButtonBase
941
+ key={String(option.value)}
942
+ role="radio"
943
+ aria-checked={isSelected}
944
+ tabIndex={index === focusIndex ? 0 : -1}
945
+ disabled={option.disabled}
946
+ onClick={option.onSelect}
947
+ onKeyDown={event => handleKeyDown(event, index)}
948
+ sx={{
949
+ position: 'relative',
950
+ display: 'grid',
951
+ justifyItems: 'start',
952
+ gap: 0.5,
953
+ padding: 2,
954
+ borderRadius: 3,
955
+ border: 2,
956
+ borderColor: isSelected ? 'primary.main' : 'divider',
957
+ bgcolor: isSelected ? 'action.hover' : 'transparent',
958
+ textAlign: 'start',
959
+ transition: 'border-color 150ms, background-color 150ms',
960
+ '&:hover': { borderColor: isSelected ? 'primary.main' : 'text.disabled' },
961
+ '&.Mui-focusVisible': { outline: 2, outlineColor: 'primary.main', outlineOffset: 2 },
962
+ '&.Mui-disabled': { opacity: 0.4 },
963
+ }}
964
+ >
965
+ {isSelected && (
966
+ <Box component="span" aria-hidden sx={CHECK_BADGE}>
967
+ ✓
968
+ </Box>
969
+ )}
970
+ <Box
971
+ component="svg"
972
+ viewBox="0 0 36 24"
973
+ aria-hidden
974
+ sx={{ inlineSize: 60, blockSize: 40, color: '#b98b5e' }}
975
+ >
976
+ <path d={EDGE_PROFILES[String(option.value)]} fill="currentColor" />
977
+ </Box>
978
+ <Typography variant="body2" fontWeight={600}>
979
+ {resolve(option.title)}
980
+ </Typography>
981
+ <Typography variant="caption" color="text.secondary">
982
+ {resolve(option.description)}
983
+ </Typography>
984
+ </ButtonBase>
985
+ )
986
+ })}
987
+ </Box>
988
+ )
989
+ }
990
+ ```
991
+
992
+ ### ./src/\_shared/FullscreenToggle.tsx
993
+
994
+ ```tsx
995
+ import { Button } from '@mui/material'
996
+
997
+ import { phx } from '../../.phoenix/phx.js'
998
+
999
+ const ENTER_ICON = 'M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5'
1000
+ const EXIT_ICON = 'M9 4v5H4M15 4v5h5M15 20v-5h5M9 20v-5H4'
1001
+
1002
+ export const FullscreenToggle = () => {
1003
+ const isFullscreen = phx.frontend.useIsFullscreenActive()
1004
+ const setFullscreen = phx.frontend.useSetFullscreen()
1005
+
1006
+ return (
1007
+ <Button
1008
+ onClick={() => setFullscreen(!isFullscreen)}
1009
+ startIcon={
1010
+ <svg viewBox="0 0 24 24" width={20} height={20} fill="none" stroke="currentColor" strokeWidth={2}>
1011
+ <path d={isFullscreen ? EXIT_ICON : ENTER_ICON} />
1012
+ </svg>
1013
+ }
1014
+ sx={{
1015
+ minBlockSize: 44,
1016
+ paddingInline: 2.5,
1017
+ borderRadius: 999,
1018
+ bgcolor: 'background.paper',
1019
+ color: 'text.primary',
1020
+ boxShadow: '0 4px 16px rgba(0, 0, 0, 0.12)',
1021
+ textTransform: 'none',
1022
+ fontWeight: 600,
1023
+ '&:hover': { bgcolor: 'background.paper', boxShadow: '0 6px 20px rgba(0, 0, 0, 0.18)' },
1024
+ }}
1025
+ >
1026
+ {isFullscreen ? 'Exit fullscreen' : 'Fullscreen'}
1027
+ </Button>
1028
+ )
1029
+ }
1030
+ ```
1031
+
1032
+ ### ./src/\_shared/MessageToast.tsx
1033
+
1034
+ ```tsx
1035
+ import { Alert } from '@mui/material'
1036
+ import { useEffect, useState } from 'react'
1037
+
1038
+ import type { ConfiguratorMessage } from '@salsita-ai/sdk/react'
1039
+
1040
+ import { phx } from '../../.phoenix/phx.js'
1041
+
1042
+ const VIOLATION_SEVERITY = { fatal: 'error', fixable: 'error', warning: 'warning', notice: 'info' } as const
1043
+ const RANK = { info: 0, warning: 1, error: 2 } as const
1044
+ const VISIBLE_MS = 6000
1045
+
1046
+ const severityOf = (message: ConfiguratorMessage) => {
1047
+ if (message.kind === 'violation') {
1048
+ return VIOLATION_SEVERITY[message.violation.severity]
1049
+ }
1050
+
1051
+ return message.kind === 'error' ? 'error' : 'info'
1052
+ }
1053
+
1054
+ export const MessageToast = () => {
1055
+ const [message, setMessage] = useState<ConfiguratorMessage | null>(null)
1056
+
1057
+ // A rejected change also reports the notices already present; keep the worst message while it is shown
1058
+ phx.frontend.useConfiguratorMessages(next => {
1059
+ setMessage(shown => (shown !== null && RANK[severityOf(next)] < RANK[severityOf(shown)] ? shown : next))
1060
+ })
1061
+
1062
+ useEffect(() => {
1063
+ if (message === null) {
1064
+ return
1065
+ }
1066
+
1067
+ const timeout = setTimeout(() => setMessage(null), VISIBLE_MS)
1068
+
1069
+ return () => clearTimeout(timeout)
1070
+ }, [message])
1071
+
1072
+ if (message === null) {
1073
+ return null
1074
+ }
1075
+
1076
+ return (
1077
+ <Alert
1078
+ severity={severityOf(message)}
1079
+ onClose={() => setMessage(null)}
1080
+ sx={{ maxInlineSize: 420, borderRadius: 3, boxShadow: '0 12px 40px rgba(0, 0, 0, 0.12)' }}
1081
+ >
1082
+ {message.text}
1083
+ </Alert>
1084
+ )
1085
+ }
1086
+ ```
1087
+
1088
+ ### ./src/\_shared/ProductPanel.tsx
1089
+
1090
+ ```tsx
1091
+ import { Box, Button, Typography } from '@mui/material'
1092
+
1093
+ import { detailComponent, finalizeActionComponent } from '@salsita-ai/sdk/domain'
1094
+ import { PhoenixHandlerBoundary, useResolveLocalizable } from '@salsita-ai/sdk/react'
1095
+
1096
+ import { phx } from '../../.phoenix/phx.js'
1097
+ import { EdgeFinishCards } from './EdgeFinishCards.js'
1098
+ import { ReviewActions } from './ReviewActions.js'
1099
+
1100
+ const BUTTON_SX = { minBlockSize: 48, borderRadius: 999, textTransform: 'none', fontWeight: 600 } as const
1101
+
1102
+ export const ProductPanel = () => {
1103
+ const resolve = useResolveLocalizable()
1104
+ const detail = phx.frontend.useFirstRootComponent(detailComponent)
1105
+ const price = phx.frontend.useRootEntityPrice()
1106
+ const tableId = phx.frontend.useRootEntityId()
1107
+ const edgeFinish = phx.frontend.useAttributeSelection(tableId, 'edgeFinish')
1108
+ const { accessInfo } = phx.frontend.useAccessService()
1109
+ const navigationState = phx.frontend.useActiveNavigationState()
1110
+ const pushNavigate = phx.frontend.usePushNavigate()
1111
+ const popNavigate = phx.frontend.usePopNavigate()
1112
+ const navigate = phx.frontend.useNavigate()
1113
+ const finalizeActions = phx.frontend.useComponents({ componentTypes: [finalizeActionComponent] }) ?? []
1114
+
1115
+ const isReadMode = accessInfo.viewMode
1116
+ const isReview = isReadMode || navigationState !== 'configure'
1117
+ // The spec's primary finalize action, or its first one
1118
+ const quoteAction = finalizeActions.find(action => action.state.variant === 'primary') ?? finalizeActions[0]
1119
+ const chosenEdge = edgeFinish.options.find(option => option.value === edgeFinish.value)
1120
+
1121
+ return (
1122
+ <>
1123
+ <Box component="header" sx={{ display: 'grid', gap: 1, padding: 3, paddingBlockEnd: 2 }}>
1124
+ {isReadMode ? (
1125
+ <Typography
1126
+ variant="overline"
1127
+ sx={{ justifySelf: 'start', paddingInline: 1.5, borderRadius: 999, bgcolor: 'action.selected' }}
1128
+ >
1129
+ View only
1130
+ </Typography>
1131
+ ) : (
1132
+ <Typography variant="overline" color="text.secondary">
1133
+ {resolve(detail?.state.subtitle)}
1134
+ </Typography>
1135
+ )}
1136
+ <Typography variant="h5" component="h2" fontWeight={700}>
1137
+ {resolve(detail?.state.title)}
1138
+ </Typography>
1139
+ <Typography variant="body2" color="text.secondary">
1140
+ {resolve(detail?.state.description)}
1141
+ </Typography>
1142
+ </Box>
1143
+
1144
+ <Box component="div" sx={{ display: 'grid', gap: 1.5, paddingInline: 3, paddingBlockEnd: 3, overflowY: 'auto' }}>
1145
+ <Typography variant="subtitle2" component="h3">
1146
+ Edge finish
1147
+ </Typography>
1148
+ {isReview ? (
1149
+ <Box component="div" sx={{ padding: 2, borderRadius: 3, bgcolor: 'action.hover' }}>
1150
+ <Typography variant="body2" fontWeight={600}>
1151
+ {resolve(chosenEdge?.title)}
1152
+ </Typography>
1153
+ <Typography variant="caption" color="text.secondary">
1154
+ {resolve(chosenEdge?.description)}
1155
+ </Typography>
1156
+ </Box>
1157
+ ) : (
1158
+ <EdgeFinishCards selection={edgeFinish} />
1159
+ )}
1160
+ </Box>
1161
+
1162
+ <Box component="footer" sx={{ display: 'grid', gap: 2, padding: 3, borderTop: 1, borderColor: 'divider' }}>
1163
+ <Box component="div" sx={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between' }}>
1164
+ <Typography variant="body2" color="text.secondary">
1165
+ Total price
1166
+ </Typography>
1167
+ <Typography variant="h5" component="p" fontWeight={700}>
1168
+ {price}
1169
+ </Typography>
1170
+ </Box>
1171
+ {!isReadMode && navigationState === 'configure' && (
1172
+ <Button size="large" variant="contained" onClick={() => pushNavigate('checkout')} sx={BUTTON_SX}>
1173
+ Review and request a quote
1174
+ </Button>
1175
+ )}
1176
+ {!isReadMode && navigationState === 'checkout' && (
1177
+ <>
1178
+ <Typography variant="body2" color="text.secondary">
1179
+ Your table is ready for a quote. A real shop collects the contact details here.
1180
+ </Typography>
1181
+ {quoteAction ? (
1182
+ <PhoenixHandlerBoundary name={quoteAction.state.handler}>
1183
+ <ReviewActions
1184
+ handler={quoteAction.state.handler}
1185
+ label={resolve(quoteAction.state.label)}
1186
+ onBack={popNavigate}
1187
+ />
1188
+ </PhoenixHandlerBoundary>
1189
+ ) : (
1190
+ <Button size="large" variant="outlined" onClick={popNavigate} sx={BUTTON_SX}>
1191
+ Back to the configuration
1192
+ </Button>
1193
+ )}
1194
+ </>
1195
+ )}
1196
+ {!isReadMode && navigationState === 'requested' && (
1197
+ <>
1198
+ <Typography variant="body2" role="status">
1199
+ Thank you. Your quote request is on its way, and the shop replies within two working days.
1200
+ </Typography>
1201
+ <Button size="large" variant="outlined" onClick={() => navigate('configure')} sx={BUTTON_SX}>
1202
+ Back to the configuration
1203
+ </Button>
1204
+ </>
1205
+ )}
1206
+ </Box>
1207
+ </>
1208
+ )
1209
+ }
1210
+ ```
1211
+
1212
+ ### ./src/\_shared/ReviewActions.tsx
1213
+
1214
+ ```tsx
1215
+ import { Alert, Box, Button, CircularProgress, Typography } from '@mui/material'
1216
+
1217
+ import { phx } from '../../.phoenix/phx.js'
1218
+
1219
+ const BUTTON_SX = { minBlockSize: 48, borderRadius: 999, textTransform: 'none', fontWeight: 600 } as const
1220
+
1221
+ interface ReviewActionsProps {
1222
+ readonly handler: string
1223
+ readonly label: string
1224
+ readonly onBack: () => void
1225
+ }
1226
+
1227
+ // The review step's buttons: one finalize action and the way back. `useFinalizeAction` runs the action's handler,
1228
+ // so this component calls it exactly once and is rendered inside a `PhoenixHandlerBoundary` for that handler.
1229
+ // Back is disabled while the request is pending, so the customer cannot change the configuration while it is sent.
1230
+ // The pending state belongs to this component: when the panel unmounts, as in fullscreen, the request goes on and
1231
+ // the remounted buttons are enabled again.
1232
+ export const ReviewActions = ({ handler, label, onBack }: ReviewActionsProps) => {
1233
+ const { run, isPending, error, disabled, hints } = phx.frontend.useFinalizeAction(handler)
1234
+
1235
+ return (
1236
+ <Box component="div" sx={{ display: 'grid', gap: 2 }}>
1237
+ <Box component="div" sx={{ display: 'grid', gap: 1 }}>
1238
+ <Button
1239
+ size="large"
1240
+ variant="contained"
1241
+ disabled={disabled || isPending}
1242
+ onClick={run}
1243
+ startIcon={isPending ? <CircularProgress size={18} color="inherit" /> : undefined}
1244
+ sx={BUTTON_SX}
1245
+ >
1246
+ {isPending ? 'Sending the request…' : label}
1247
+ </Button>
1248
+ {disabled && hints && (
1249
+ <Typography variant="caption" color="text.secondary">
1250
+ {hints}
1251
+ </Typography>
1252
+ )}
1253
+ {error && <Alert severity="error">The request could not be sent: {error.message}</Alert>}
1254
+ </Box>
1255
+ <Button size="large" variant="outlined" disabled={isPending} onClick={onBack} sx={BUTTON_SX}>
1256
+ Back to the configuration
1257
+ </Button>
1258
+ </Box>
1259
+ )
1260
+ }
1261
+ ```
1262
+
1263
+ ### ./src/elements/ConfiguratorLayout.tsx
1264
+
1265
+ ```tsx
1266
+ import { Box } from '@mui/material'
1267
+
1268
+ import { LayoutSlots, useSceneSafeArea } from '@salsita-ai/sdk/configurator'
1269
+
1270
+ import { phx } from '../../.phoenix/phx.js'
1271
+ import { FullscreenToggle } from '../_shared/FullscreenToggle.js'
1272
+ import { MessageToast } from '../_shared/MessageToast.js'
1273
+ import { ProductPanel } from '../_shared/ProductPanel.js'
1274
+
1275
+ const GUTTER = 24
1276
+ const PANEL_WIDTH = 380
1277
+
1278
+ const ConfiguratorLayout = () => {
1279
+ const { containerRef, safeAreaRef } = useSceneSafeArea()
1280
+ const isFullscreen = phx.frontend.useIsFullscreenActive()
1281
+
1282
+ return (
1283
+ <Box component="div" ref={containerRef} sx={{ position: 'absolute', inset: 0 }}>
1284
+ <LayoutSlots.SharedCanvas />
1285
+
1286
+ {!isFullscreen && (
1287
+ <Box
1288
+ component="aside"
1289
+ sx={{
1290
+ position: 'absolute',
1291
+ insetBlockStart: GUTTER,
1292
+ insetInlineStart: GUTTER,
1293
+ inlineSize: PANEL_WIDTH,
1294
+ maxBlockSize: `calc(100% - ${2 * GUTTER}px)`,
1295
+ display: 'flex',
1296
+ flexDirection: 'column',
1297
+ borderRadius: 5,
1298
+ bgcolor: 'background.paper',
1299
+ boxShadow: '0 12px 40px rgba(0, 0, 0, 0.12)',
1300
+ overflow: 'hidden',
1301
+ }}
1302
+ >
1303
+ <ProductPanel />
1304
+ </Box>
1305
+ )}
1306
+
1307
+ <Box
1308
+ component="div"
1309
+ ref={safeAreaRef}
1310
+ sx={{
1311
+ position: 'absolute',
1312
+ insetBlock: 0,
1313
+ insetInlineStart: isFullscreen ? 0 : PANEL_WIDTH + 2 * GUTTER,
1314
+ insetInlineEnd: 0,
1315
+ pointerEvents: 'none',
1316
+ }}
1317
+ >
1318
+ <Box
1319
+ component="div"
1320
+ sx={{ position: 'absolute', insetBlockStart: GUTTER, insetInlineEnd: GUTTER, pointerEvents: 'auto' }}
1321
+ >
1322
+ <FullscreenToggle />
1323
+ </Box>
1324
+ <Box
1325
+ component="div"
1326
+ sx={{ position: 'absolute', insetBlockEnd: GUTTER, insetInlineStart: GUTTER, pointerEvents: 'auto' }}
1327
+ >
1328
+ <MessageToast />
1329
+ </Box>
1330
+ </Box>
1331
+ </Box>
1332
+ )
1333
+ }
1334
+
1335
+ export default phx.frontend.createCustomPhoenixLayoutElement('ConfiguratorLayout', ConfiguratorLayout)
1336
+ ```
1337
+
1338
+ ### ./src/expressions/table.ts
1339
+
1340
+ ```ts
1341
+ import { phx } from '../../.phoenix/phx.js'
1342
+
1343
+ const EDGE_FINISH_SURCHARGE = { None: 0, Facet: 90, Round: 120, TreeTrunk: 340 }
1344
+
1345
+ export default phx.domain.implementCustomExpressions({
1346
+ Table: {
1347
+ $price: s => {
1348
+ return 1290 + EDGE_FINISH_SURCHARGE[s.edgeFinish]
1349
+ },
1350
+ $edgeFinishFacet: s => {
1351
+ return s.edgeFinish === 'Facet' ? 1 : 0
1352
+ },
1353
+ $edgeFinishRound: s => {
1354
+ return s.edgeFinish === 'Round' ? 1 : 0
1355
+ },
1356
+ $edgeFinishTreeTrunk: s => {
1357
+ return s.edgeFinish === 'TreeTrunk' ? 1 : 0
1358
+ },
1359
+ },
1360
+ })
1361
+ ```
1362
+
1363
+ ### ./src/handlers/request-quote.ts
1364
+
1365
+ ```ts
1366
+ import { useCallback } from 'react'
1367
+
1368
+ import { phx } from '../../.phoenix/phx.js'
1369
+
1370
+ // Stands in for the shop's quote service: the request takes a moment, then the panel shows the confirmation
1371
+ export default phx.frontend.createPhoenixHandler('requestQuote', () => {
1372
+ const navigate = phx.frontend.useNavigate()
1373
+
1374
+ return {
1375
+ handler: useCallback(async () => {
1376
+ await new Promise(resolve => setTimeout(resolve, 1500))
1377
+ navigate('requested')
1378
+ }, [navigate]),
1379
+ }
1380
+ })
1381
+ ```
1382
+
1383
+ ### ./src/transformers/tree-trunk-delivery.ts
1384
+
1385
+ ```ts
1386
+ import { msg } from '@lingui/core/macro'
1387
+
1388
+ import { phx } from '../../.phoenix/phx.js'
1389
+
1390
+ // A tree-trunk edge is cut by hand; choosing it carries a hint, which reaches the layout as a side-effect message
1391
+ export default phx.frontend.transformerBuilder.when
1392
+ .entity(['Table'])
1393
+ .modified({ atFields: ['edgeFinish'] })
1394
+ .then.overrideMatchingUpdate(({ update }) => {
1395
+ if (update.stateDelta.edgeFinish !== 'TreeTrunk') {
1396
+ return [update]
1397
+ }
1398
+
1399
+ return [{ ...update, hint: msg`Tree trunk edges are cut by hand, so delivery takes three weeks longer.` }]
1400
+ })
1401
+ .build('tree-trunk-delivery')
1402
+ ```
1403
+
1404
+ </details>