@salsita-ai/sdk 0.50.0-develop.dede205ab0 → 0.50.0-develop.df1d25280c
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.
- package/README.md +19 -14
- package/dist/admin/create-admin-pages-from-spec.d.ts +1 -1
- package/dist/admin/default-admin-elements.d.ts +9 -0
- package/dist/admin/default-admin-elements.js +1 -0
- package/dist/admin/default-elements/built-in-entity-element.d.ts +10 -0
- package/dist/admin/default-elements/built-in-entity-element.js +1 -0
- package/dist/admin/default-elements/built-in-layout-element.d.ts +10 -0
- package/dist/admin/default-elements/built-in-layout-element.js +1 -0
- package/dist/admin/default-elements/index.d.ts +2 -0
- package/dist/admin/default-elements/index.js +1 -0
- package/dist/admin/index.d.ts +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/application/index.d.ts +1 -0
- package/dist/application/index.js +1 -1
- package/dist/application/mount-application.d.ts +1 -1
- package/dist/application/mount-application.js +1 -1
- package/dist/application/mount-configurator.d.ts +19 -0
- package/dist/application/mount-configurator.js +1 -0
- package/dist/application/mounted-application-runtime.d.ts +4 -0
- package/dist/application/mounted-application-runtime.js +1 -0
- package/dist/application/register-web-component.d.ts +2 -0
- package/dist/application/register-web-component.js +1 -0
- package/dist/application-spec/caching/content-diff.js +1 -1
- package/dist/application-spec/core/application-file.d.ts +0 -2
- package/dist/application-spec/core/application-file.js +1 -1
- package/dist/application-spec/core/components/component-filter.d.ts +53 -0
- package/dist/application-spec/core/components/component-filter.js +1 -0
- package/dist/application-spec/core/components/index.d.ts +2 -0
- package/dist/application-spec/core/components/index.js +1 -0
- package/dist/application-spec/core/components/sdk-code-ref.d.ts +9 -0
- package/dist/application-spec/core/components/sdk-code-ref.js +1 -0
- package/dist/application-spec/core/enhanced-json-value.d.ts +0 -68
- package/dist/application-spec/core/enhanced-json-value.js +1 -1
- package/dist/application-spec/core/expressions/index.d.ts +2 -0
- package/dist/application-spec/core/expressions/index.js +1 -0
- package/dist/application-spec/core/expressions/relation-expression-params.d.ts +11 -0
- package/dist/application-spec/core/expressions/sdk-expression-implementation.d.ts +24 -0
- package/dist/application-spec/core/expressions/sdk-expression-implementation.js +1 -0
- package/dist/application-spec/core/index.d.ts +2 -0
- package/dist/application-spec/core/index.js +1 -1
- package/dist/application-spec/core/json-value.d.ts +1 -1
- package/dist/application-spec/{core → enhanced-json}/eval-to-constant.d.ts +1 -1
- package/dist/application-spec/enhanced-json/index.d.ts +4 -0
- package/dist/application-spec/enhanced-json/index.js +1 -0
- package/dist/application-spec/enhanced-json/is-enhanced-json-array.d.ts +2 -0
- package/dist/application-spec/enhanced-json/is-enhanced-json-array.js +1 -0
- package/dist/application-spec/enhanced-json/resolve-enhanced-json-value.d.ts +18 -0
- package/dist/application-spec/enhanced-json/resolve-enhanced-json-value.js +1 -0
- package/dist/application-spec/enhanced-json/schema-from-value.d.ts +24 -0
- package/dist/application-spec/enhanced-json/schema-from-value.js +1 -0
- package/dist/application-spec/enhanced-json/stringify-enhanced-json-value.d.ts +14 -0
- package/dist/application-spec/enhanced-json/stringify-enhanced-json-value.js +1 -0
- package/dist/application-spec/enhanced-json/validate-enhanced-json-value-caps.d.ts +12 -0
- package/dist/application-spec/enhanced-json/validate-enhanced-json-value-caps.js +1 -0
- package/dist/application-spec/enhanced-json/validate-no-legacy-code-ref.d.ts +13 -0
- package/dist/application-spec/enhanced-json/validate-no-legacy-code-ref.js +1 -0
- package/dist/application-spec/errors/diagnostic-codes.d.ts +23 -0
- package/dist/application-spec/errors/diagnostic-codes.js +1 -1
- package/dist/application-spec/errors/diagnostic-messages.d.ts +27 -1
- package/dist/application-spec/errors/diagnostic-messages.js +1 -1
- package/dist/application-spec/generate-application/code/common/code-imports.js +1 -1
- package/dist/application-spec/generate-application/code/common/env-reader.js +2 -2
- package/dist/application-spec/generate-application/code/common/index.d.ts +1 -0
- package/dist/application-spec/generate-application/code/common/index.js +1 -1
- package/dist/application-spec/generate-application/code/common/single-quoted-string.d.ts +6 -0
- package/dist/application-spec/generate-application/code/common/single-quoted-string.js +1 -0
- package/dist/application-spec/generate-application/code/domain-runtime-files.js +1 -1
- package/dist/application-spec/generate-application/code/generate-application-code.d.ts +3 -2
- package/dist/application-spec/generate-application/code/generate-application-code.js +1 -1
- package/dist/application-spec/generate-application/code/project-scaffolding.d.ts +22 -14
- package/dist/application-spec/generate-application/code/project-scaffolding.js +2 -2
- package/dist/application-spec/generate-application/code/standalone-app-files.d.ts +2 -2
- package/dist/application-spec/generate-application/code/standalone-app-files.js +1 -1
- package/dist/application-spec/generate-application/code/story-files.js +1 -1
- package/dist/application-spec/generate-application/code/templates/admin-config.js +3 -0
- package/dist/application-spec/generate-application/code/templates/application-types.js +6 -6
- package/dist/application-spec/generate-application/code/templates/common/doc-comment.d.ts +2 -0
- package/dist/application-spec/generate-application/code/templates/common/doc-comment.js +1 -0
- package/dist/application-spec/generate-application/code/templates/common/format-property-key.d.ts +7 -0
- package/dist/application-spec/generate-application/code/templates/common/format-property-key.js +1 -0
- package/dist/application-spec/generate-application/code/templates/common/schema-to-type-string.js +3 -3
- package/dist/application-spec/generate-application/code/templates/configurator-config.js +6 -4
- package/dist/application-spec/generate-application/code/templates/configurator-globals.d.ts +2 -1
- package/dist/application-spec/generate-application/code/templates/configurator-globals.js +19 -6
- package/dist/application-spec/generate-application/code/templates/domain-spec/factory-types/domain-factory-types.d.ts +35 -0
- package/dist/application-spec/generate-application/code/templates/domain-spec/factory-types/domain-factory-types.js +5 -0
- package/dist/application-spec/generate-application/code/templates/domain-spec/factory-types/index.d.ts +1 -0
- package/dist/application-spec/generate-application/code/templates/domain-spec/factory-types/index.js +1 -0
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-component-optics.d.ts +1 -1
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-component-optics.js +7 -7
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-defaults.d.ts +4 -2
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-defaults.js +1 -1
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-domain-block.js +72 -76
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-invariants.d.ts +9 -1
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-invariants.js +1 -1
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-phx-globals.js +3 -0
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-presets.js +1 -1
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-relation-expressions.js +1 -1
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-resources.d.ts +6 -8
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-resources.js +21 -21
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-states.d.ts +1 -1
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-states.js +2 -2
- package/dist/application-spec/generate-application/code/templates/domain-spec/index.d.ts +3 -2
- package/dist/application-spec/generate-application/code/templates/domain-spec/index.js +1 -1
- package/dist/application-spec/generate-application/code/templates/domain-spec.js +12 -12
- package/dist/application-spec/generate-application/code/templates/domain.js +3 -3
- package/dist/application-spec/generate-application/code/templates/eslint-config.d.ts +5 -0
- package/dist/application-spec/generate-application/code/templates/eslint-config.js +4 -5
- package/dist/application-spec/generate-application/code/templates/frontend-config.js +3 -5
- package/dist/application-spec/generate-application/code/templates/gitignore.js +0 -3
- package/dist/application-spec/generate-application/code/templates/global-definition/generate-action-types.js +7 -7
- package/dist/application-spec/generate-application/code/templates/global-definition/generate-assistant-form-element-types.d.ts +12 -0
- package/dist/application-spec/generate-application/code/templates/global-definition/generate-assistant-form-element-types.js +7 -0
- package/dist/application-spec/generate-application/code/templates/global-definition/generate-phx-types.d.ts +43 -0
- package/dist/application-spec/generate-application/code/templates/global-definition/generate-phx-types.js +33 -0
- package/dist/application-spec/generate-application/code/templates/global-definition/index.d.ts +2 -0
- package/dist/application-spec/generate-application/code/templates/global-definition/index.js +1 -1
- package/dist/application-spec/generate-application/code/templates/globals.js +24 -43
- package/dist/application-spec/generate-application/code/templates/index.d.ts +3 -10
- package/dist/application-spec/generate-application/code/templates/index.js +1 -1
- package/dist/application-spec/generate-application/code/templates/lingui-rc.d.ts +5 -0
- package/dist/application-spec/generate-application/code/templates/lingui-rc.js +4 -4
- package/dist/application-spec/generate-application/code/templates/prettier-config.d.ts +5 -0
- package/dist/application-spec/generate-application/code/templates/prettier-config.js +4 -5
- package/dist/application-spec/generate-application/code/templates/root-tsconfig.d.ts +6 -0
- package/dist/application-spec/generate-application/code/templates/root-tsconfig.js +2 -0
- package/dist/application-spec/generate-application/code/templates/skills/phoenix-cli-skill.js +1 -1
- package/dist/application-spec/generate-application/code/templates/skills/phoenix-create-configurator-skill.js +66 -42
- package/dist/application-spec/generate-application/code/templates/skills/phoenix-feedback-skill.js +5 -5
- package/dist/application-spec/generate-application/code/templates/skills/phoenix-review-skill.js +9 -3
- package/dist/application-spec/generate-application/code/templates/skills/phoenix-skill.js +1 -1
- package/dist/application-spec/generate-application/code/templates/skills/phoenix-variants-skill.js +2 -2
- package/dist/application-spec/generate-application/code/templates/skills/sdk-content.d.ts +42 -18
- package/dist/application-spec/generate-application/code/templates/skills/sdk-content.js +6 -8
- package/dist/application-spec/generate-application/code/templates/spec-code/collect-spec-code.d.ts +58 -0
- package/dist/application-spec/generate-application/code/templates/spec-code/collect-spec-code.js +1 -0
- package/dist/application-spec/generate-application/code/templates/spec-code/index.d.ts +2 -0
- package/dist/application-spec/generate-application/code/templates/spec-code/index.js +1 -0
- package/dist/application-spec/generate-application/code/templates/spec-code/spec-code.d.ts +18 -0
- package/dist/application-spec/generate-application/code/templates/spec-code/spec-code.js +41 -0
- package/dist/application-spec/generate-application/code/templates/spec-messages/index.d.ts +1 -0
- package/dist/application-spec/generate-application/code/templates/spec-messages/index.js +1 -0
- package/dist/application-spec/generate-application/code/templates/spec-messages/spec-messages.d.ts +20 -0
- package/dist/application-spec/generate-application/code/templates/spec-messages/spec-messages.js +6 -0
- package/dist/application-spec/generate-application/code/templates/story/phx-module.d.ts +8 -2
- package/dist/application-spec/generate-application/code/templates/story/phx-module.js +15 -3
- package/dist/application-spec/generate-application/code/templates/story/wrapper.d.ts +3 -0
- package/dist/application-spec/generate-application/code/templates/story/wrapper.js +2 -1
- package/dist/application-spec/generate-application/code/templates/tsconfig.d.ts +5 -0
- package/dist/application-spec/generate-application/code/templates/tsconfig.js +1 -1
- package/dist/application-spec/generate-application/code/templates/webhook-builders.js +4 -3
- package/dist/application-spec/generate-application/code/templates/webhook-index.d.ts +6 -1
- package/dist/application-spec/generate-application/code/templates/webhook-index.js +10 -1
- package/dist/application-spec/generate-application/code/templates/webhooks-config.js +2 -3
- package/dist/application-spec/generate-application/implementations/phx-application-types.d.ts +25 -0
- package/dist/application-spec/generate-application/implementations/phx-application-types.js +1 -0
- package/dist/application-spec/generate-application/implementations/phx-domain.d.ts +36 -0
- package/dist/application-spec/generate-application/implementations/phx-domain.js +1 -0
- package/dist/application-spec/generate-application/implementations/phx-model.d.ts +24 -0
- package/dist/application-spec/generate-application/implementations/phx-model.js +1 -0
- package/dist/application-spec/generate-application/implementations/phx.d.ts +22 -0
- package/dist/application-spec/generate-application/implementations/phx.js +1 -0
- package/dist/application-spec/generate-application/index.d.ts +4 -0
- package/dist/application-spec/generate-application/index.js +1 -1
- package/dist/application-spec/generate-application/runtime/admin-runtime/admin-model-runtime.d.ts +6 -4
- package/dist/application-spec/generate-application/runtime/admin-runtime/admin-model-runtime.js +1 -1
- package/dist/application-spec/generate-application/runtime/admin-runtime/admin-runtime.d.ts +12 -4
- package/dist/application-spec/generate-application/runtime/admin-runtime/admin-runtime.js +1 -1
- package/dist/application-spec/generate-application/runtime/admin-runtime/admin-spec-runtime.d.ts +16 -0
- package/dist/application-spec/generate-application/runtime/admin-runtime/admin-spec-runtime.js +1 -0
- package/dist/application-spec/generate-application/runtime/admin-runtime/states-runtime.d.ts +2 -2
- package/dist/application-spec/generate-application/runtime/application-runtime.d.ts +35 -10
- package/dist/application-spec/generate-application/runtime/application-runtime.js +1 -1
- package/dist/application-spec/generate-application/runtime/application-spec-slice.d.ts +71 -0
- package/dist/application-spec/generate-application/runtime/application-spec-slice.js +1 -0
- package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-model-runtime.d.ts +7 -5
- package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-model-runtime.js +1 -1
- package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-runtime.d.ts +12 -7
- package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-runtime.js +1 -1
- package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-spec-runtime.d.ts +16 -0
- package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-spec-runtime.js +1 -0
- package/dist/application-spec/generate-application/runtime/configurator-runtime/states-runtime.d.ts +2 -2
- package/dist/application-spec/generate-application/runtime/create-application.d.ts +57 -0
- package/dist/application-spec/generate-application/runtime/create-application.js +1 -0
- package/dist/application-spec/generate-application/runtime/factory-data/factory-data-runtime.d.ts +43 -0
- package/dist/application-spec/generate-application/runtime/factory-data/factory-data-runtime.js +1 -0
- package/dist/application-spec/generate-application/runtime/factory-data/index.d.ts +3 -0
- package/dist/application-spec/generate-application/runtime/factory-data/index.js +1 -0
- package/dist/application-spec/generate-application/runtime/factory-data/recipe-defaults.d.ts +13 -0
- package/dist/application-spec/generate-application/runtime/factory-data/recipe-defaults.js +1 -0
- package/dist/application-spec/generate-application/runtime/factory-data/static-violations.d.ts +16 -0
- package/dist/application-spec/generate-application/runtime/factory-data/static-violations.js +1 -0
- package/dist/application-spec/generate-application/runtime/index.d.ts +8 -0
- package/dist/application-spec/generate-application/runtime/index.js +1 -0
- package/dist/application-spec/generate-application/runtime/migrations/index.d.ts +1 -0
- package/dist/application-spec/generate-application/runtime/migrations/index.js +1 -0
- package/dist/application-spec/generate-application/runtime/migrations/migration-runtime.d.ts +53 -0
- package/dist/application-spec/generate-application/runtime/migrations/migration-runtime.js +1 -0
- package/dist/application-spec/generate-application/runtime/sections/assistant-runtime.d.ts +2 -2
- package/dist/application-spec/generate-application/runtime/sections/build-sdk-optic.d.ts +3 -2
- package/dist/application-spec/generate-application/runtime/sections/build-sdk-optic.js +1 -1
- package/dist/application-spec/generate-application/runtime/sections/build-user-bound-optic.d.ts +2 -1
- package/dist/application-spec/generate-application/runtime/sections/build-user-bound-optic.js +1 -1
- package/dist/application-spec/generate-application/runtime/sections/component-optic.d.ts +5 -1
- package/dist/application-spec/generate-application/runtime/sections/component-optic.js +1 -1
- package/dist/application-spec/generate-application/runtime/sections/data-runtime.d.ts +4 -4
- package/dist/application-spec/generate-application/runtime/sections/expression-runtime.d.ts +15 -6
- package/dist/application-spec/generate-application/runtime/sections/expression-runtime.js +1 -1
- package/dist/application-spec/generate-application/runtime/sections/generate-memo-eval-plan-runtime.d.ts +9 -5
- package/dist/application-spec/generate-application/runtime/sections/generate-memo-eval-plan-runtime.js +1 -1
- package/dist/application-spec/generate-application/runtime/sections/reflection-constants-runtime.d.ts +3 -1
- package/dist/application-spec/generate-application/runtime/sections/reflection-constants-runtime.js +1 -1
- package/dist/application-spec/generate-application/runtime/sections/theme-runtime.d.ts +2 -2
- package/dist/application-spec/generate-application/runtime/sections/transformers-runtime.d.ts +4 -6
- package/dist/application-spec/generate-application/runtime/spec-code/index.d.ts +2 -0
- package/dist/application-spec/generate-application/runtime/spec-code/index.js +1 -0
- package/dist/application-spec/generate-application/runtime/spec-code/resolve-spec-code.d.ts +18 -0
- package/dist/application-spec/generate-application/runtime/spec-code/resolve-spec-code.js +1 -0
- package/dist/application-spec/generate-application/runtime/spec-code/spec-code-module.d.ts +17 -0
- package/dist/application-spec/generate-application/runtime/spec-code/spec-code-module.js +1 -0
- package/dist/application-spec/generate-application/runtime/spec-runtime.d.ts +21 -0
- package/dist/application-spec/generate-application/runtime/spec-runtime.js +1 -0
- package/dist/application-spec/generate-application/runtime-spec/decode-runtime-spec.d.ts +9 -0
- package/dist/application-spec/generate-application/runtime-spec/decode-runtime-spec.js +1 -0
- package/dist/application-spec/generate-application/runtime-spec/encode-runtime-spec.d.ts +8 -0
- package/dist/application-spec/generate-application/runtime-spec/encode-runtime-spec.js +1 -0
- package/dist/application-spec/generate-application/runtime-spec/encoded-runtime-spec.d.ts +28 -0
- package/dist/application-spec/generate-application/runtime-spec/encoded-runtime-spec.js +1 -0
- package/dist/application-spec/generate-application/runtime-spec/index.d.ts +5 -0
- package/dist/application-spec/generate-application/runtime-spec/index.js +1 -0
- package/dist/application-spec/generate-application/runtime-spec/runtime-spec.d.ts +103 -0
- package/dist/application-spec/generate-application/runtime-spec/runtime-spec.js +1 -0
- package/dist/application-spec/generate-application/runtime-spec/spec-code-id.d.ts +40 -0
- package/dist/application-spec/generate-application/runtime-spec/spec-code-id.js +1 -0
- package/dist/application-spec/index.d.ts +1 -0
- package/dist/application-spec/index.js +1 -1
- package/dist/application-spec/parse-application-files/categorize/categorize-files.d.ts +34 -0
- package/dist/application-spec/parse-application-files/categorize/categorize-files.js +1 -1
- package/dist/application-spec/parse-application-files/categorize/earlier-generated-editor-configs.d.ts +16 -0
- package/dist/application-spec/parse-application-files/categorize/earlier-generated-editor-configs.js +9 -0
- package/dist/application-spec/parse-application-files/categorize/earlier-generated-tsconfig.d.ts +9 -0
- package/dist/application-spec/parse-application-files/categorize/earlier-generated-tsconfig.js +1 -0
- package/dist/application-spec/parse-application-files/categorize/module-analysis.d.ts +1 -1
- package/dist/application-spec/parse-application-files/categorize/module-analysis.js +1 -1
- package/dist/application-spec/parse-application-files/raw-spec/parse-yaml-spec-file.js +1 -1
- package/dist/application-spec/parse-application-files/raw-spec/raw-assistant.d.ts +47 -4
- package/dist/application-spec/parse-application-files/raw-spec/raw-assistant.js +1 -1
- package/dist/application-spec/parse-application-files/raw-spec/raw-spec-file.js +1 -1
- package/dist/application-spec/parse-application-files/spec/application/admin-spec/admin-spec.js +1 -1
- package/dist/application-spec/parse-application-files/spec/application/configurator-spec/configurator-spec.js +1 -1
- package/dist/application-spec/parse-application-files/spec/common/index.d.ts +1 -0
- package/dist/application-spec/parse-application-files/spec/common/index.js +1 -1
- package/dist/application-spec/parse-application-files/spec/common/value-type/format-value-type.d.ts +3 -0
- package/dist/application-spec/parse-application-files/spec/common/value-type/format-value-type.js +1 -0
- package/dist/application-spec/parse-application-files/spec/common/value-type/index.d.ts +5 -0
- package/dist/application-spec/parse-application-files/spec/common/value-type/index.js +1 -0
- package/dist/application-spec/parse-application-files/spec/common/value-type/intersect-value-types.d.ts +6 -0
- package/dist/application-spec/parse-application-files/spec/common/value-type/intersect-value-types.js +1 -0
- package/dist/application-spec/parse-application-files/spec/common/value-type/is-assignable-value-type.d.ts +8 -0
- package/dist/application-spec/parse-application-files/spec/common/value-type/is-assignable-value-type.js +1 -0
- package/dist/application-spec/parse-application-files/spec/common/value-type/value-type-at.d.ts +10 -0
- package/dist/application-spec/parse-application-files/spec/common/value-type/value-type-at.js +1 -0
- package/dist/application-spec/parse-application-files/spec/common/value-type/value-type.d.ts +98 -0
- package/dist/application-spec/parse-application-files/spec/common/value-type/value-type.js +1 -0
- package/dist/application-spec/parse-application-files/spec/components/bindings/component-path.d.ts +13 -0
- package/dist/application-spec/parse-application-files/spec/components/bindings/component-path.js +1 -0
- package/dist/application-spec/parse-application-files/spec/components/bindings/index.d.ts +2 -0
- package/dist/application-spec/parse-application-files/spec/components/bindings/index.js +1 -1
- package/dist/application-spec/parse-application-files/spec/components/bindings/read-binding-type.d.ts +24 -0
- package/dist/application-spec/parse-application-files/spec/components/bindings/read-binding-type.js +1 -0
- package/dist/application-spec/parse-application-files/spec/components/component-entry.d.ts +1 -9
- package/dist/application-spec/parse-application-files/spec/components/component-entry.js +1 -1
- package/dist/application-spec/parse-application-files/spec/components/component-filter.d.ts +1 -54
- package/dist/application-spec/parse-application-files/spec/components/component-filter.js +1 -1
- package/dist/application-spec/parse-application-files/spec/components/component-state-type.d.ts +8 -0
- package/dist/application-spec/parse-application-files/spec/components/component-state-type.js +1 -0
- package/dist/application-spec/parse-application-files/spec/components/filter-criterion-types.d.ts +13 -0
- package/dist/application-spec/parse-application-files/spec/components/filter-criterion-types.js +1 -0
- package/dist/application-spec/parse-application-files/spec/components/index.d.ts +1 -1
- package/dist/application-spec/parse-application-files/spec/components/index.js +1 -1
- package/dist/application-spec/parse-application-files/spec/components/static-entity-id.d.ts +14 -0
- package/dist/application-spec/parse-application-files/spec/components/static-entity-id.js +1 -0
- package/dist/application-spec/parse-application-files/spec/components/user-component-entry.d.ts +6 -0
- package/dist/application-spec/parse-application-files/spec/components/user-component-entry.js +1 -1
- package/dist/application-spec/parse-application-files/spec/components/user-components.d.ts +7 -4
- package/dist/application-spec/parse-application-files/spec/components/user-components.js +1 -1
- package/dist/application-spec/parse-application-files/spec/expressions/expression-read-types.d.ts +24 -0
- package/dist/application-spec/parse-application-files/spec/expressions/expression-read-types.js +1 -0
- package/dist/application-spec/parse-application-files/spec/expressions/expression-read.d.ts +13 -0
- package/dist/application-spec/parse-application-files/spec/expressions/expression-read.js +1 -0
- package/dist/application-spec/parse-application-files/spec/expressions/expression-value-type.d.ts +9 -0
- package/dist/application-spec/parse-application-files/spec/expressions/expression-value-type.js +1 -0
- package/dist/application-spec/parse-application-files/spec/expressions/expression.d.ts +1 -28
- package/dist/application-spec/parse-application-files/spec/expressions/expression.js +1 -1
- package/dist/application-spec/parse-application-files/spec/expressions/expressions.d.ts +7 -3
- package/dist/application-spec/parse-application-files/spec/expressions/expressions.js +1 -1
- package/dist/application-spec/parse-application-files/spec/expressions/index.d.ts +0 -1
- package/dist/application-spec/parse-application-files/spec/expressions/index.js +1 -1
- package/dist/application-spec/parse-application-files/spec/expressions/memo-eval-plan.js +1 -1
- package/dist/application-spec/parse-application-files/spec/expressions/user-expressions.d.ts +3 -1
- package/dist/application-spec/parse-application-files/spec/expressions/user-expressions.js +1 -1
- package/dist/application-spec/parse-application-files/spec/invariants/invariants.d.ts +2 -2
- package/dist/application-spec/parse-application-files/spec/invariants/invariants.js +1 -1
- package/dist/application-spec/parse-application-files/spec/model/defaults.d.ts +7 -2
- package/dist/application-spec/parse-application-files/spec/model/defaults.js +1 -1
- package/dist/application-spec/parse-application-files/spec/model/index.d.ts +1 -0
- package/dist/application-spec/parse-application-files/spec/model/index.js +1 -1
- package/dist/application-spec/parse-application-files/spec/model/model-type-resolution.d.ts +10 -0
- package/dist/application-spec/parse-application-files/spec/model/model-type-resolution.js +1 -0
- package/dist/application-spec/parse-application-files/spec/relations/reference-field-type.d.ts +25 -0
- package/dist/application-spec/parse-application-files/spec/relations/reference-field-type.js +1 -0
- package/dist/application-spec/parse-application-files/spec/relations/relation-field-mismatch.d.ts +46 -0
- package/dist/application-spec/parse-application-files/spec/relations/relation-field-mismatch.js +1 -0
- package/dist/application-spec/parse-application-files/spec/relations/relations.d.ts +4 -3
- package/dist/application-spec/parse-application-files/spec/relations/relations.js +1 -1
- package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-form-elements.d.ts +9 -0
- package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-form-elements.js +1 -0
- package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-schema.d.ts +4 -1
- package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-schema.js +1 -1
- package/dist/application-spec/parse-application-files/spec/sections/infra.d.ts +2 -0
- package/dist/application-spec/parse-application-files/spec/sections/infra.js +1 -1
- package/dist/client/authorized-client.d.ts +3 -1
- package/dist/client/authorized-client.js +1 -1
- package/dist/client/contract.d.ts +17 -0
- package/dist/client/index.d.ts +1 -1
- package/dist/client/local-authorized-client.d.ts +3 -1
- package/dist/client/local-authorized-client.js +1 -1
- package/dist/client/memory-authorized-client.d.ts +4 -1
- package/dist/client/memory-authorized-client.js +1 -1
- package/dist/client/phoenix-api.d.ts +814 -121
- package/dist/configurator/ConfiguratorApp.js +1 -1
- package/dist/configurator/app-loader-content/DefaultAppLoaderContent.d.ts +2 -0
- package/dist/configurator/app-loader-content/DefaultAppLoaderContent.js +5 -0
- package/dist/configurator/app-loader-content/index.d.ts +1 -0
- package/dist/configurator/app-loader-content/index.js +1 -0
- package/dist/configurator/application-runtime/extensions/create-configurator-extensions.js +1 -1
- package/dist/configurator/application-runtime/extensions/selectors.d.ts +3 -1
- package/dist/configurator/application-runtime/extensions/selectors.js +1 -1
- package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.d.ts +88 -4
- package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.js +1 -1
- package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.d.ts +40 -7
- package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.js +1 -1
- package/dist/configurator/application-runtime/extensions/systems/camera-control-system/camera-control-system.d.ts +1 -1
- package/dist/configurator/application-runtime/extensions/systems/canvas-system.d.ts +8 -0
- package/dist/configurator/application-runtime/extensions/systems/canvas-system.js +1 -1
- package/dist/configurator/application-runtime/extensions/systems/drag-and-drop-system/drag-and-drop-system.d.ts +3 -3
- package/dist/configurator/application-runtime/extensions/systems/export-system/export-busy-error.d.ts +8 -0
- package/dist/configurator/application-runtime/extensions/systems/export-system/export-busy-error.js +1 -0
- package/dist/configurator/application-runtime/extensions/systems/export-system/export-system.d.ts +23 -1
- package/dist/configurator/application-runtime/extensions/systems/export-system/export-system.js +1 -1
- package/dist/configurator/application-runtime/extensions/systems/graphql-system/close-unclosed-braces.d.ts +12 -0
- package/dist/configurator/application-runtime/extensions/systems/graphql-system/close-unclosed-braces.js +1 -0
- package/dist/configurator/application-runtime/extensions/systems/graphql-system/entity-meta.d.ts +14 -1
- package/dist/configurator/application-runtime/extensions/systems/graphql-system/entity-meta.js +1 -1
- package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.d.ts +70 -7
- package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.js +1 -1
- package/dist/configurator/application-runtime/extensions/systems/graphql-system/inject-assistant-lenses.d.ts +11 -0
- package/dist/configurator/application-runtime/extensions/systems/graphql-system/inject-assistant-lenses.js +1 -0
- package/dist/configurator/application-runtime/extensions/systems/image-rendering-system/image-rendering-system.d.ts +14 -5
- package/dist/configurator/application-runtime/extensions/systems/image-rendering-system/image-rendering-system.js +1 -1
- package/dist/configurator/application-runtime/extensions/systems/index.d.ts +1 -1
- package/dist/configurator/application-runtime/extensions/systems/layout-system/layout-system.d.ts +2 -2
- package/dist/configurator/application-runtime/extensions/systems/layout-system/layout-system.js +1 -1
- package/dist/configurator/common/configurator-interface.d.ts +145 -5
- package/dist/configurator/common/configurator-interface.js +1 -1
- package/dist/configurator/common/index.d.ts +3 -1
- package/dist/configurator/common/index.js +1 -1
- package/dist/configurator/common/use-reset-camera.d.ts +6 -0
- package/dist/configurator/common/use-reset-camera.js +1 -0
- package/dist/configurator/configuration-not-found-page/BuiltInConfigurationNotFoundPage.d.ts +5 -0
- package/dist/configurator/configuration-not-found-page/BuiltInConfigurationNotFoundPage.js +1 -0
- package/dist/configurator/configuration-not-found-page/ConfigurationNotFoundPageElement.d.ts +6 -0
- package/dist/configurator/configuration-not-found-page/ConfigurationNotFoundPageElement.js +1 -0
- package/dist/configurator/configuration-not-found-page/index.d.ts +2 -0
- package/dist/configurator/configuration-not-found-page/index.js +1 -0
- package/dist/configurator/configurator-context/ConfiguratorResponsiveProvider.d.ts +12 -0
- package/dist/configurator/configurator-context/ConfiguratorResponsiveProvider.js +1 -0
- package/dist/configurator/configurator-context/PresetSelectionProvider.js +1 -1
- package/dist/configurator/configurator-context/PreviewContextProvider.js +1 -1
- package/dist/configurator/configurator-context/ViewportStateSync.d.ts +2 -2
- package/dist/configurator/configurator-context/ViewportStateSync.js +1 -1
- package/dist/configurator/configurator-context/configurator-hooks/layout-hooks.d.ts +11 -1
- package/dist/configurator/configurator-context/configurator-routing/ConfiguratorRoutingProvider.js +1 -1
- package/dist/configurator/configurator-error-page/BuiltInConfiguratorErrorPage.d.ts +6 -0
- package/dist/configurator/configurator-error-page/BuiltInConfiguratorErrorPage.js +1 -0
- package/dist/configurator/configurator-error-page/ConfiguratorErrorPageElement.d.ts +7 -0
- package/dist/configurator/configurator-error-page/ConfiguratorErrorPageElement.js +1 -0
- package/dist/configurator/configurator-error-page/index.d.ts +2 -0
- package/dist/configurator/configurator-error-page/index.js +1 -0
- package/dist/configurator/index.d.ts +10 -0
- package/dist/configurator/index.js +1 -1
- package/dist/configurator/pages/ConfiguratorErrorPage.d.ts +0 -1
- package/dist/configurator/pages/ConfiguratorErrorPage.js +1 -1
- package/dist/configurator/pages/ConfiguratorNotFoundPage.js +1 -1
- package/dist/configurator/pages/DefaultConfiguratorLayout.d.ts +7 -0
- package/dist/configurator/pages/DefaultConfiguratorLayout.js +1 -0
- package/dist/configurator/pages/DefaultNotAuthenticatedPage.d.ts +8 -0
- package/dist/configurator/pages/DefaultNotAuthenticatedPage.js +1 -0
- package/dist/configurator/pages/DefaultPresetUi.d.ts +7 -0
- package/dist/configurator/pages/DefaultPresetUi.js +1 -0
- package/dist/configurator/pages/LoadedConfiguratorDetailPage.js +1 -1
- package/dist/configurator/pages/NewConfiguratorPage.js +1 -1
- package/dist/configurator/pages/PresetCreationErrorPage.d.ts +1 -1
- package/dist/configurator/pages/PresetCreationErrorPage.js +1 -1
- package/dist/configurator/pages/RootPage.js +1 -1
- package/dist/configurator/pages/configurator-layout-name.d.ts +2 -0
- package/dist/configurator/pages/configurator-layout-name.js +1 -0
- package/dist/configurator/pages/default-configurator-elements.d.ts +13 -0
- package/dist/configurator/pages/default-configurator-elements.js +1 -0
- package/dist/configurator/pages/default-elements/built-in-entity-element.d.ts +10 -0
- package/dist/configurator/pages/default-elements/built-in-entity-element.js +1 -0
- package/dist/configurator/pages/default-elements/built-in-layout-element.d.ts +10 -0
- package/dist/configurator/pages/default-elements/built-in-layout-element.js +1 -0
- package/dist/configurator/pages/default-elements/domain-control-elements.d.ts +6 -0
- package/dist/configurator/pages/default-elements/domain-control-elements.js +1 -0
- package/dist/configurator/pages/default-elements/index.d.ts +5 -0
- package/dist/configurator/pages/default-elements/index.js +1 -0
- package/dist/configurator/pages/default-elements/recipe-panel-elements.d.ts +3 -0
- package/dist/configurator/pages/default-elements/recipe-panel-elements.js +1 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInAddEntityFab.d.ts +3 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInAddEntityFab.js +1 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInDeleteEntityFab.d.ts +3 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInDeleteEntityFab.js +1 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInNavigationHotspot.d.ts +3 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInNavigationHotspot.js +1 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInSelectionHotspot.d.ts +3 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInSelectionHotspot.js +1 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInToolMenuFab.d.ts +3 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInToolMenuFab.js +1 -0
- package/dist/configurator/pages/default-elements/scene-controls/index.d.ts +6 -0
- package/dist/configurator/pages/default-elements/scene-controls/index.js +1 -0
- package/dist/configurator/pages/default-elements/scene-controls/scene-control-elements.d.ts +6 -0
- package/dist/configurator/pages/default-elements/scene-controls/scene-control-elements.js +1 -0
- package/dist/configurator/pages/default-elements/sidebar-footer-elements.d.ts +7 -0
- package/dist/configurator/pages/default-elements/sidebar-footer-elements.js +1 -0
- package/dist/configurator/pages/default-elements/toolbar-elements.d.ts +7 -0
- package/dist/configurator/pages/default-elements/toolbar-elements.js +1 -0
- package/dist/configurator/pages/error-boundaries/GeneralErrorBoundary.js +1 -1
- package/dist/configurator/pages/error-boundaries/LoadingErrorBoundary.js +1 -1
- package/dist/configurator/pages/index.d.ts +1 -0
- package/dist/configurator/pages/index.js +1 -1
- package/dist/configurator/preset-screen-elements/PresetDeviceNotSupportedElement.d.ts +4 -0
- package/dist/configurator/preset-screen-elements/PresetDeviceNotSupportedElement.js +1 -0
- package/dist/configurator/preset-screen-elements/PresetPageActionElement.d.ts +4 -0
- package/dist/configurator/preset-screen-elements/PresetPageActionElement.js +1 -0
- package/dist/configurator/preset-screen-elements/index.d.ts +2 -0
- package/dist/configurator/preset-screen-elements/index.js +1 -0
- package/dist/configurator/scene/index.d.ts +1 -0
- package/dist/configurator/scene/index.js +1 -1
- package/dist/configurator/scene/scene-controls/DeleteEntityFab.js +1 -1
- package/dist/configurator/scene/scene-controls/SelectionHotspot.js +1 -1
- package/dist/configurator/scene/scene-controls/ToolFab.d.ts +4 -0
- package/dist/configurator/scene/scene-controls/ToolFab.js +1 -1
- package/dist/configurator/scene/scene-controls/hotspot-drag-handle/HotspotDragHandle.d.ts +1 -1
- package/dist/configurator/scene/scene-controls/hotspot-drag-handle/HotspotDragSceneHandle.d.ts +1 -1
- package/dist/configurator/scene/scene-controls/use-scene-control-tooltip.d.ts +2 -1
- package/dist/configurator/scene/scene-entity/dimension-indicators/DimensionIndicator.d.ts +1 -1
- package/dist/configurator/scene/scene-entity/dimension-indicators/DimensionIndicatorInternal.d.ts +1 -1
- package/dist/configurator/scene/scene-entity/drag-and-drop/shared.d.ts +2 -2
- package/dist/configurator/scene/scene-entity/drag-and-drop/use-drag-object.d.ts +1 -1
- package/dist/configurator/scene/scene-entity/materials/RemoteReplacedMaterial.js +1 -1
- package/dist/configurator/scene/scene-entity/objects/SceneEntityObjectTextDecal.d.ts +1 -1
- package/dist/configurator/scene/scene-entity/scene-controls/SceneEntityHtmlHotspots.js +1 -1
- package/dist/configurator/toolbar-actions/index.d.ts +3 -0
- package/dist/configurator/toolbar-actions/index.js +1 -0
- package/dist/configurator/toolbar-actions/use-assistant-panel.d.ts +18 -0
- package/dist/configurator/toolbar-actions/use-assistant-panel.js +1 -0
- package/dist/configurator/toolbar-actions/use-measurements.d.ts +35 -0
- package/dist/configurator/toolbar-actions/use-measurements.js +1 -0
- package/dist/configurator/toolbar-actions/use-toolbar-actions.d.ts +100 -0
- package/dist/configurator/toolbar-actions/use-toolbar-actions.js +1 -0
- package/dist/configurator/toolbar-actions/use-toolbar-help.d.ts +7 -0
- package/dist/configurator/toolbar-actions/use-toolbar-help.js +1 -0
- package/dist/configurator/ui/assistant/AssistantChips.d.ts +10 -3
- package/dist/configurator/ui/assistant/AssistantChips.js +1 -1
- package/dist/configurator/ui/assistant/AssistantMarkdown.d.ts +7 -2
- package/dist/configurator/ui/assistant/AssistantMarkdown.js +1 -1
- package/dist/configurator/ui/assistant/AssistantPanel.js +1 -1
- package/dist/configurator/ui/assistant/AssistantThread.js +1 -1
- package/dist/configurator/ui/assistant/alert/AssistantAlert.d.ts +8 -0
- package/dist/configurator/ui/assistant/alert/AssistantAlert.js +1 -0
- package/dist/configurator/ui/assistant/alert/index.d.ts +2 -0
- package/dist/configurator/ui/assistant/alert/index.js +1 -0
- package/dist/configurator/ui/assistant/alert/remark-alerts.d.ts +10 -0
- package/dist/configurator/ui/assistant/alert/remark-alerts.js +1 -0
- package/dist/configurator/ui/assistant/entity-link/AssistantEntityLink.d.ts +13 -0
- package/dist/configurator/ui/assistant/entity-link/AssistantEntityLink.js +1 -0
- package/dist/configurator/ui/assistant/entity-link/entity-link-selection.d.ts +22 -0
- package/dist/configurator/ui/assistant/entity-link/entity-link-selection.js +1 -0
- package/dist/configurator/ui/assistant/entity-link/entity-link-state.d.ts +27 -0
- package/dist/configurator/ui/assistant/entity-link/entity-link-state.js +1 -0
- package/dist/configurator/ui/assistant/entity-link/index.d.ts +2 -0
- package/dist/configurator/ui/assistant/entity-link/index.js +1 -0
- package/dist/configurator/ui/assistant/form/AssistantForm.d.ts +19 -0
- package/dist/configurator/ui/assistant/form/AssistantForm.js +1 -0
- package/dist/configurator/ui/assistant/form/compose-answer.d.ts +11 -0
- package/dist/configurator/ui/assistant/form/compose-answer.js +1 -0
- package/dist/configurator/ui/assistant/form/describe-build-errors.d.ts +6 -0
- package/dist/configurator/ui/assistant/form/describe-build-errors.js +1 -0
- package/dist/configurator/ui/assistant/form/form-model.d.ts +37 -0
- package/dist/configurator/ui/assistant/form/form-model.js +1 -0
- package/dist/configurator/ui/assistant/form/form-state.d.ts +4 -0
- package/dist/configurator/ui/assistant/form/form-state.js +1 -0
- package/dist/configurator/ui/assistant/form/index.d.ts +4 -0
- package/dist/configurator/ui/assistant/form/index.js +1 -0
- package/dist/configurator/ui/assistant/form/parse-form-block.d.ts +10 -0
- package/dist/configurator/ui/assistant/form/parse-form-block.js +1 -0
- package/dist/configurator/ui/assistant/form/read-form-attributes.d.ts +13 -0
- package/dist/configurator/ui/assistant/form/read-form-attributes.js +1 -0
- package/dist/configurator/ui/assistant/form/registry/built-in-form-elements.d.ts +3 -0
- package/dist/configurator/ui/assistant/form/registry/built-in-form-elements.js +1 -0
- package/dist/configurator/ui/assistant/form/registry/create-assistant-form-element.d.ts +31 -0
- package/dist/configurator/ui/assistant/form/registry/create-assistant-form-element.js +1 -0
- package/dist/configurator/ui/assistant/form/registry/form-element-definition.d.ts +16 -0
- package/dist/configurator/ui/assistant/form/registry/form-element-definition.js +1 -0
- package/dist/configurator/ui/assistant/form/registry/form-registry.d.ts +31 -0
- package/dist/configurator/ui/assistant/form/registry/form-registry.js +1 -0
- package/dist/configurator/ui/assistant/form/registry/index.d.ts +6 -0
- package/dist/configurator/ui/assistant/form/registry/index.js +1 -0
- package/dist/configurator/ui/assistant/form/registry/use-form-registry.d.ts +8 -0
- package/dist/configurator/ui/assistant/form/registry/use-form-registry.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/FormCard.d.ts +9 -0
- package/dist/configurator/ui/assistant/form-elements/FormCard.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/FormConfirm.d.ts +9 -0
- package/dist/configurator/ui/assistant/form-elements/FormConfirm.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/FormGroup.d.ts +6 -0
- package/dist/configurator/ui/assistant/form-elements/FormGroup.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/FormNumber.d.ts +9 -0
- package/dist/configurator/ui/assistant/form-elements/FormNumber.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/FormOptions.d.ts +6 -0
- package/dist/configurator/ui/assistant/form-elements/FormOptions.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/FormReply.d.ts +6 -0
- package/dist/configurator/ui/assistant/form-elements/FormReply.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/FormSwatch.d.ts +10 -0
- package/dist/configurator/ui/assistant/form-elements/FormSwatch.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/FormText.d.ts +6 -0
- package/dist/configurator/ui/assistant/form-elements/FormText.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/clamp-form-number.d.ts +10 -0
- package/dist/configurator/ui/assistant/form-elements/clamp-form-number.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/form-element-props.d.ts +38 -0
- package/dist/configurator/ui/assistant/form-elements/form-element-props.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/index.d.ts +9 -0
- package/dist/configurator/ui/assistant/form-elements/index.js +1 -0
- package/dist/configurator/ui/assistant/index.d.ts +3 -0
- package/dist/configurator/ui/assistant/index.js +1 -1
- package/dist/configurator/ui/assistant/reference-link/AssistantReferenceLink.d.ts +16 -0
- package/dist/configurator/ui/assistant/reference-link/AssistantReferenceLink.js +1 -0
- package/dist/configurator/ui/assistant/reference-link/assistant-link-target.d.ts +34 -0
- package/dist/configurator/ui/assistant/reference-link/assistant-link-target.js +1 -0
- package/dist/configurator/ui/assistant/reference-link/assistant-reference-details.d.ts +25 -0
- package/dist/configurator/ui/assistant/reference-link/assistant-reference-details.js +1 -0
- package/dist/configurator/ui/assistant/reference-link/index.d.ts +3 -0
- package/dist/configurator/ui/assistant/reference-link/index.js +1 -0
- package/dist/configurator/ui/assistant/reference-link/reference-styles.d.ts +12 -0
- package/dist/configurator/ui/assistant/reference-link/reference-styles.js +1 -0
- package/dist/configurator/ui/assistant/reference-link/use-assistant-reference-details.d.ts +8 -0
- package/dist/configurator/ui/assistant/reference-link/use-assistant-reference-details.js +1 -0
- package/dist/configurator/ui/assistant/resource-image/AssistantImage.d.ts +9 -0
- package/dist/configurator/ui/assistant/resource-image/AssistantImage.js +1 -0
- package/dist/configurator/ui/assistant/resource-image/index.d.ts +3 -0
- package/dist/configurator/ui/assistant/resource-image/index.js +1 -0
- package/dist/configurator/ui/assistant/resource-image/resource-path.d.ts +2 -0
- package/dist/configurator/ui/assistant/resource-image/resource-path.js +1 -0
- package/dist/configurator/ui/assistant/resource-image/use-resource-image-url.d.ts +5 -0
- package/dist/configurator/ui/assistant/resource-image/use-resource-image-url.js +1 -0
- package/dist/configurator/ui/assistant/screenshots/ScreenshotThumbnails.d.ts +9 -0
- package/dist/configurator/ui/assistant/screenshots/ScreenshotThumbnails.js +1 -0
- package/dist/configurator/ui/assistant/screenshots/index.d.ts +2 -0
- package/dist/configurator/ui/assistant/screenshots/index.js +1 -0
- package/dist/configurator/ui/assistant/screenshots/tool-screenshots.d.ts +22 -0
- package/dist/configurator/ui/assistant/screenshots/tool-screenshots.js +1 -0
- package/dist/configurator/ui/assistant/screenshots/use-screenshot-src.d.ts +8 -0
- package/dist/configurator/ui/assistant/screenshots/use-screenshot-src.js +1 -0
- package/dist/configurator/ui/assistant/streamed-markdown.d.ts +4 -2
- package/dist/configurator/ui/assistant/streamed-markdown.js +2 -2
- package/dist/configurator/ui/assistant/thread-items.d.ts +8 -1
- package/dist/configurator/ui/assistant/thread-items.js +1 -1
- package/dist/configurator/ui/assistant/tool-chip.js +1 -1
- package/dist/configurator/ui/assistant/use-follow-stream.js +1 -1
- package/dist/configurator/ui/configurator-layout/sidebar-keys/index.d.ts +1 -0
- package/dist/configurator/ui/configurator-layout/sidebar-keys/index.js +1 -0
- package/dist/configurator/ui/configurator-layout/sidebar-keys/sidebar-keys.d.ts +11 -0
- package/dist/configurator/ui/configurator-layout/sidebar-keys/sidebar-keys.js +1 -0
- package/dist/configurator/ui/configurator-layout/slots/canvas/LayoutCanvas.js +1 -1
- package/dist/configurator/ui/configurator-layout/slots/canvas/SharedCanvas.js +1 -1
- package/dist/configurator/ui/configurator-layout/slots/desktop-sidebar/DesktopSidebar.d.ts +101 -0
- package/dist/configurator/ui/configurator-layout/slots/desktop-sidebar/DesktopSidebar.js +16 -0
- package/dist/configurator/ui/configurator-layout/slots/desktop-sidebar/index.d.ts +1 -0
- package/dist/configurator/ui/configurator-layout/slots/desktop-sidebar/index.js +1 -0
- package/dist/configurator/ui/configurator-layout/slots/mobile-tabs/use-mobile-tabs.d.ts +1 -1
- package/dist/configurator/ui/configurator-layout/slots/mobile-tabs/use-mobile-tabs.js +1 -1
- package/dist/configurator/ui/configurator-layout/slots/services/InvariantViolations.d.ts +4 -4
- package/dist/configurator/ui/configurator-layout/slots/services/InvariantViolations.js +1 -1
- package/dist/configurator/ui/configurator-layout/slots/services/Services.js +1 -1
- package/dist/configurator/ui/configurator-layout/slots/services/SideEffects.d.ts +3 -6
- package/dist/configurator/ui/configurator-layout/slots/services/SideEffects.js +1 -1
- package/dist/configurator/ui/configurator-layout/slots/sidebar-tabs/use-sidebar-tabs.d.ts +1 -1
- package/dist/configurator/ui/configurator-layout/slots/sidebar-tabs/use-sidebar-tabs.js +1 -1
- package/dist/configurator/ui/configurator-layout/slots/slots.d.ts +1 -0
- package/dist/configurator/ui/configurator-layout/slots/slots.js +1 -1
- package/dist/configurator/ui/configurator-layout/universal/DesktopLayout.d.ts +0 -74
- package/dist/configurator/ui/configurator-layout/universal/DesktopLayout.js +5 -20
- package/dist/configurator/ui/configurator-layout/universal/DesktopPreview.js +1 -1
- package/dist/configurator/ui/configurator-layout/universal/ExportingOverlay.d.ts +5 -0
- package/dist/configurator/ui/configurator-layout/universal/ExportingOverlay.js +1 -0
- package/dist/configurator/ui/configurator-layout/universal/Layout.js +1 -1
- package/dist/configurator/ui/configurator-layout/universal/MobileLayout.js +4 -4
- package/dist/configurator/ui/configurator-layout/universal/MobilePreview.js +1 -1
- package/dist/configurator/ui/configurator-layout/universal/use-layout-scene-safe-area.d.ts +47 -0
- package/dist/configurator/ui/configurator-layout/universal/use-layout-scene-safe-area.js +1 -0
- package/dist/configurator/ui/configurator-layout/universal/use-scene-safe-area.d.ts +11 -26
- package/dist/configurator/ui/configurator-layout/universal/use-scene-safe-area.js +1 -1
- package/dist/configurator/ui/index.d.ts +1 -0
- package/dist/configurator/ui/index.js +1 -1
- package/dist/configurator/ui/legacy/layout/common/CommonFinalizeButton.js +1 -1
- package/dist/configurator/ui/legacy/layout/common/CommonSummaryButton.js +1 -1
- package/dist/configurator/ui/legacy/layout/common/CommonTopNavigation.js +1 -1
- package/dist/configurator/ui/legacy/layout/common/ReactiveInterfaceLayout.js +1 -1
- package/dist/configurator/ui/legacy/layout/common/ResponsiveFinalizeButton.js +1 -1
- package/dist/configurator/ui/legacy/layout/common/SummaryReadLayout.js +1 -1
- package/dist/configurator/ui/legacy/layout/simple/SimpleOwnerLayout.js +1 -1
- package/dist/configurator/ui/legacy/layout/simple/SimpleTopNavigation.js +1 -1
- package/dist/configurator/ui/legacy/layout/steps/StepsNavigation.d.ts +2 -2
- package/dist/configurator/ui/legacy/layout/steps/StepsNavigation.js +1 -1
- package/dist/configurator/ui/legacy/layout/steps/StepsOwnerLayout.js +1 -1
- package/dist/configurator/ui/legacy/layout/steps/StepsSidebarFooter.js +1 -1
- package/dist/configurator/ui/legacy/layout/tabs/TabsOwnerLayout.js +1 -1
- package/dist/configurator/ui/legacy/toolbar/common/DimensionUnitSelector.js +1 -1
- package/dist/configurator/ui/legacy/toolbar/common/MeasurementsIndicatorsSwitch.js +1 -1
- package/dist/configurator/ui/legacy/toolbar/desktop-toolbar/FullscreenToolbarAction.js +1 -1
- package/dist/configurator/ui/legacy/toolbar/desktop-toolbar/HelpToolbarAction.js +1 -1
- package/dist/configurator/ui/legacy/toolbar/desktop-toolbar/MeasurementsToolbarAction.js +1 -1
- package/dist/configurator/ui/legacy/toolbar/desktop-toolbar/UndoRedoToolbarGroup.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/AppLoader.d.ts +0 -7
- package/dist/configurator/ui/phoenix-layout-elements/AppLoader.js +2 -6
- package/dist/configurator/ui/phoenix-layout-elements/AssistantToolbarButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/EnterFullscreenToolbarButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/ExitFullscreenToolbarButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/HelpToolbarButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/LanguageMenuAction.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/LanguageToolbarButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/LayoutCustomOwnerUi.d.ts +1 -0
- package/dist/configurator/ui/phoenix-layout-elements/LayoutCustomOwnerUi.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/LayoutCustomReadUi.d.ts +1 -0
- package/dist/configurator/ui/phoenix-layout-elements/LayoutCustomReadUi.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/MeasurementsMenuAction.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/MeasurementsToolbarButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/RedoToolbarButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/ShareToolbarButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/UndoToolbarButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/header/common/back-button/use-go-back-action.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/header/common/horizontal-tabs/DesktopHorizontalTabs.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/header/common/step-navigation/DesktopNavigationSteps.d.ts +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/header/common/step-navigation/DesktopNavigationSteps.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/header/common/step-navigation/StepsNavigation.d.ts +2 -8
- package/dist/configurator/ui/phoenix-layout-elements/header/common/step-navigation/StepsNavigation.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/index.d.ts +8 -1
- package/dist/configurator/ui/phoenix-layout-elements/index.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/measurements/DimensionUnitSelector.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/measurements/MeasurementsIndicatorsSwitch.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/share/ShareModal.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/share/use-share.d.ts +7 -8
- package/dist/configurator/ui/phoenix-layout-elements/share/use-share.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/sidebar-footer/basic/BasicFinalizeButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/sidebar-footer/common/CustomFinalizeButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/sidebar-footer/common/EnterSummaryButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/sidebar-footer/common/FinalizeActions.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/sidebar-footer/common/NextStepButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/sidebar-footer/common/PreviousStepButton.js +1 -1
- package/dist/configurator/ui/preset-layout/CategoryPresetUi.js +1 -1
- package/dist/configurator/ui/preset-layout/PresetUi.d.ts +4 -2
- package/dist/configurator/ui/preset-layout/PresetUi.js +1 -1
- package/dist/configurator/ui/preset-layout/index.d.ts +6 -1
- package/dist/configurator/ui/preset-layout/index.js +1 -1
- package/dist/configurator/ui/save-message-snackbars/SaveMessageSnackbars.d.ts +10 -0
- package/dist/configurator/ui/save-message-snackbars/SaveMessageSnackbars.js +1 -0
- package/dist/configurator/ui/save-message-snackbars/index.d.ts +1 -0
- package/dist/configurator/ui/save-message-snackbars/index.js +1 -0
- package/dist/docs/complex-use-cases/filtered-controls-with-fix-dialog.mdx +16 -19
- package/dist/docs/complex-use-cases/focus-mode.mdx +2 -0
- package/dist/docs/complex-use-cases/sketching.mdx +0 -38
- package/dist/docs/controls/select-attribute/cardselect.mdx +9 -13
- package/dist/docs/controls/select-child-entity/cardselect.mdx +1 -0
- package/dist/docs/dimensions/3d-scene-integration/dimension-indicators.mdx +2 -2
- package/dist/docs/dimensions/3d-scene-integration/editable-angle-indicator.mdx +1 -1
- package/dist/docs/dimensions/3d-scene-integration/editable-distance-dimension-indicator.mdx +1 -1
- package/dist/docs/dimensions/3d-scene-integration/list-selector-dimension-indicator.mdx +1 -1
- package/dist/docs/drag-and-drop/drag-handle.mdx +1 -1
- package/dist/docs/drag-and-drop/hotspot-handle.mdx +1 -1
- package/dist/docs/drag-and-drop/planes.mdx +1 -1
- package/dist/docs/drag-and-drop/rotatable.mdx +2 -2
- package/dist/docs/fabs/basic.mdx +6 -2
- package/dist/docs/index.json +136 -1
- package/dist/docs/integrations/webcomponent-api/basics.mdx +2 -0
- package/dist/docs/integrations/woocommerce/local-development.mdx +1 -1
- package/dist/docs/layouts/custom-layout.mdx +2597 -0
- package/dist/docs/layouts/gallery/ardent-compressor.mdx +3516 -0
- package/dist/docs/layouts/gallery/corvid-drone.mdx +3428 -0
- package/dist/docs/layouts/gallery/fenwick-window.mdx +2803 -0
- package/dist/docs/layouts/gallery/ferrule-bar-station.mdx +6567 -0
- package/dist/docs/layouts/gallery/kestrel-kettle.mdx +1858 -0
- package/dist/docs/layouts/gallery/nightjar-guitar.mdx +3698 -0
- package/dist/docs/layouts/gallery/sunfold-solar.mdx +2683 -0
- package/dist/docs/layouts/gallery/tidepool-aquascape.mdx +5203 -0
- package/dist/docs/layouts/header/fixed.mdx +2 -2
- package/dist/docs/layouts/header/floating.mdx +2 -2
- package/dist/docs/layouts/sidebar/in-a-custom-layout.mdx +380 -0
- package/dist/docs/layouts/sidebar-footer/basic.mdx +32 -77
- package/dist/docs/other-features/client-side-rendering/declarative.mdx +2 -2
- package/dist/docs/other-features/error-5xx.mdx +1 -1
- package/dist/docs/other-features/navigation-hotspot.mdx +2 -0
- package/dist/docs/other-features/not-found-404.mdx +1 -1
- package/dist/docs/other-features/side-effects.mdx +8 -11
- package/dist/docs/other-features/transformers.mdx +4 -0
- package/dist/docs/other-features/violation-messages.mdx +52 -56
- package/dist/docs/phoenix/application-states.mdx +9 -7
- package/dist/docs/phoenix/clerk-sign-in.mdx +1 -1
- package/dist/docs/phoenix/components.mdx +6 -0
- package/dist/docs/phoenix/configurator-interface.mdx +402 -81
- package/dist/docs/phoenix/deployments.mdx +2 -6
- package/dist/docs/phoenix/domain-model.mdx +6 -0
- package/dist/docs/phoenix/expression-context.mdx +11 -3
- package/dist/docs/phoenix/finalization.mdx +1 -1
- package/dist/docs/phoenix/getting-started.mdx +7 -4
- package/dist/docs/phoenix/layout-slots.mdx +116 -0
- package/dist/docs/phoenix/localization.mdx +10 -6
- package/dist/docs/phoenix/migration-guide.mdx +24 -11
- package/dist/docs/phoenix/phoenix-cli.mdx +91 -44
- package/dist/docs/phoenix/project-structure.mdx +80 -36
- package/dist/docs/phoenix/quickstart.mdx +9 -9
- package/dist/docs/phoenix/sdk-builder-workflow.mdx +13 -11
- package/dist/docs/phoenix/sessions-and-access.mdx +2 -0
- package/dist/docs/phoenix/testing.mdx +148 -0
- package/dist/docs/phoenix/webhook-membership.mdx +10 -9
- package/dist/docs/phoenix/webhooks.mdx +23 -6
- package/dist/docs/selection-and-highlight/hotspots.mdx +2 -0
- package/dist/docs/ux-guidelines/choosing-a-control.mdx +11 -0
- package/dist/domain/admin-domain/implementation/common-admin-expressions.d.ts +26 -11
- package/dist/domain/admin-domain/implementation/common-admin-publish.d.ts +1 -2
- package/dist/domain/admin-domain/index.d.ts +7 -2
- package/dist/domain/admin-domain/index.js +1 -1
- package/dist/domain/application/GetApplicationWrapperHandler.d.ts +2 -2
- package/dist/domain/application/GetThemeHandler.d.ts +1 -1
- package/dist/domain/application/GetWebComponentOptions.d.ts +1 -1
- package/dist/domain/application/admin-page-factories.d.ts +1 -2
- package/dist/domain/application/application-config.d.ts +9 -26
- package/dist/domain/application/assistant/assistant-fields.d.ts +12 -0
- package/dist/domain/application/assistant/assistant-fields.js +1 -0
- package/dist/domain/application/assistant/assistant-manifest.d.ts +25 -2
- package/dist/domain/application/assistant/assistant-resolved-manifest.d.ts +46 -3
- package/dist/domain/application/assistant/assistant-resolved-manifest.js +1 -1
- package/dist/domain/application/assistant/build-assistant-lenses.d.ts +14 -0
- package/dist/domain/application/assistant/build-assistant-lenses.js +5 -0
- package/dist/domain/application/assistant/build-assistant-manifest.js +1 -1
- package/dist/domain/application/assistant/create-assistant-execution-schema.d.ts +32 -0
- package/dist/domain/application/assistant/create-assistant-execution-schema.js +1 -0
- package/dist/domain/application/assistant/form/assistant-form-element-name.d.ts +11 -0
- package/dist/domain/application/assistant/form/assistant-form-element-name.js +8 -0
- package/dist/domain/application/assistant/form/assistant-form-elements.d.ts +174 -0
- package/dist/domain/application/assistant/form/assistant-form-elements.js +1 -0
- package/dist/domain/application/assistant/form/assistant-resource-path.d.ts +10 -0
- package/dist/domain/application/assistant/form/assistant-resource-path.js +1 -0
- package/dist/domain/application/assistant/form/index.d.ts +4 -0
- package/dist/domain/application/assistant/form/index.js +1 -0
- package/dist/domain/application/assistant/generate-assistant-prompt.d.ts +3 -0
- package/dist/domain/application/assistant/generate-assistant-prompt.js +1 -1
- package/dist/domain/application/assistant/index.d.ts +8 -2
- package/dist/domain/application/assistant/index.js +1 -1
- package/dist/domain/application/assistant/session-setup/AssistantSetupHandler.d.ts +20 -0
- package/dist/domain/application/assistant/session-setup/AssistantSetupHandler.js +1 -0
- package/dist/domain/application/assistant/session-setup/apply-assistant-setup.d.ts +10 -0
- package/dist/domain/application/assistant/session-setup/apply-assistant-setup.js +1 -0
- package/dist/domain/application/assistant/session-setup/assistant-setup-manifest.d.ts +50 -0
- package/dist/domain/application/assistant/session-setup/assistant-setup-manifest.js +1 -0
- package/dist/domain/application/assistant/session-setup/create-session-assistant.d.ts +15 -0
- package/dist/domain/application/assistant/session-setup/create-session-assistant.js +1 -0
- package/dist/domain/application/assistant/session-setup/index.d.ts +4 -0
- package/dist/domain/application/assistant/session-setup/index.js +1 -0
- package/dist/domain/application/assistant-mutations.d.ts +2 -1
- package/dist/domain/application/assistant-recipe-groups.d.ts +4 -2
- package/dist/domain/application/configurator-builder.d.ts +11 -2
- package/dist/domain/application/configurator-builder.js +1 -1
- package/dist/domain/application/create-initial-published-data.d.ts +6 -7
- package/dist/domain/application/index.d.ts +2 -6
- package/dist/domain/application/index.js +1 -1
- package/dist/domain/application/published-data/DataRowValidatorHandler.d.ts +1 -1
- package/dist/domain/application/published-data/FilterPublishedChunksHandler.d.ts +1 -1
- package/dist/domain/application/published-data/MapPublishedChunkedDataHandler.d.ts +1 -1
- package/dist/domain/application/published-data/MapPublishedRevisionDataHandler.d.ts +1 -1
- package/dist/domain/application/published-data/SheetValidatorHandler.d.ts +1 -1
- package/dist/domain/application/published-data/build-legend-data.d.ts +1 -1
- package/dist/domain/application/published-data/format-field-type.d.ts +1 -1
- package/dist/domain/application/published-data/map-data-to-sheet.d.ts +1 -1
- package/dist/domain/application/published-data/map-published-chunked-data.d.ts +3 -3
- package/dist/domain/application/published-data/map-published-data.d.ts +7 -3
- package/dist/domain/application/published-data/validate-sheet-data.d.ts +1 -1
- package/dist/domain/application/standard-properties.js +1 -1
- package/dist/domain/application/web-component-property.d.ts +3 -1
- package/dist/domain/application/web-component-property.js +1 -1
- package/dist/domain/available-system-components.d.ts +1 -1
- package/dist/domain/available-system-components.js +1 -1
- package/dist/domain/core/action/action-factory.d.ts +2 -2
- package/dist/domain/core/action/action.d.ts +19 -14
- package/dist/domain/core/component/domain-component-optic.d.ts +29 -40
- package/dist/domain/core/component/domain-component-optic.js +2 -2
- package/dist/domain/core/component/legacy-filter.d.ts +2 -17
- package/dist/domain/core/component/system-component-filter.d.ts +36 -18
- package/dist/domain/core/data-schema/data-cell-value.d.ts +4 -0
- package/dist/domain/core/data-schema/data-cell-value.js +1 -0
- package/dist/domain/core/data-schema/data-schema-array-field.d.ts +5 -0
- package/dist/domain/core/data-schema/data-schema-array-field.js +1 -0
- package/dist/domain/core/data-schema/data-schema-field-object.d.ts +4 -0
- package/dist/domain/core/data-schema/data-schema-field-object.js +1 -0
- package/dist/domain/core/data-schema/data-schema-field.d.ts +2 -0
- package/dist/domain/core/data-schema/data-schema-field.js +1 -0
- package/dist/domain/core/data-schema/data-schema-localized-field.d.ts +4 -0
- package/dist/domain/core/data-schema/data-schema-localized-field.js +1 -0
- package/dist/domain/core/data-schema/data-schema-primitive-field.d.ts +5 -0
- package/dist/domain/core/data-schema/data-schema-primitive-field.js +1 -0
- package/dist/domain/core/data-schema/data-schema.d.ts +2 -0
- package/dist/domain/core/data-schema/data-schema.js +1 -0
- package/dist/domain/core/data-schema/index.d.ts +7 -0
- package/dist/domain/core/data-schema/index.js +1 -0
- package/dist/domain/core/domain.d.ts +2 -2
- package/dist/domain/core/emission/index.d.ts +8 -0
- package/dist/domain/core/emission/index.js +1 -0
- package/dist/domain/core/emission/reset-state-emission.d.ts +12 -0
- package/dist/domain/core/emission/reset-state-emission.js +1 -0
- package/dist/domain/core/emission/state-emission.d.ts +4 -0
- package/dist/domain/core/emission/state-emission.js +1 -0
- package/dist/domain/core/emission/state-update-emission.d.ts +14 -0
- package/dist/domain/core/emission/state-update-emission.js +1 -0
- package/dist/domain/core/emission/state-validation-result.d.ts +18 -0
- package/dist/domain/core/emission/state-validation-result.js +1 -0
- package/dist/domain/core/emission/transformation-log.d.ts +2 -0
- package/dist/domain/core/emission/transformation-log.js +1 -0
- package/dist/domain/core/emission/transformer-log-entry.d.ts +6 -0
- package/dist/domain/core/emission/transformer-log-entry.js +1 -0
- package/dist/domain/core/emission/transformer-log.d.ts +11 -0
- package/dist/domain/core/emission/transformer-log.js +1 -0
- package/dist/domain/core/emission/transformer-phase.d.ts +1 -0
- package/dist/domain/core/emission/transformer-phase.js +1 -0
- package/dist/domain/core/expression/aliased-expressions.d.ts +2 -2
- package/dist/domain/core/expression/constant-expressions.d.ts +16 -8
- package/dist/domain/core/expression/constant-expressions.js +1 -1
- package/dist/domain/core/expression/custom-expression.d.ts +20 -7
- package/dist/domain/core/expression/custom-expression.js +1 -1
- package/dist/domain/core/expression/expression.d.ts +15 -17
- package/dist/domain/core/index.d.ts +2 -0
- package/dist/domain/core/invariant/custom-invariants.d.ts +8 -16
- package/dist/domain/core/invariant/index.d.ts +1 -1
- package/dist/domain/core/invariant/index.js +1 -1
- package/dist/domain/core/invariant/invariants.d.ts +4 -70
- package/dist/domain/core/invariant/invariants.js +1 -1
- package/dist/domain/core/invariant/violation.d.ts +51 -3
- package/dist/domain/core/invariant/violation.js +1 -1
- package/dist/domain/core/model/model.d.ts +1 -1
- package/dist/domain/core/recipe/recipes.d.ts +18 -50
- package/dist/domain/core/recipe/recipes.js +1 -1
- package/dist/domain/core/relation/all-of-type-relation.d.ts +8 -21
- package/dist/domain/core/relation/all-of-type-relation.js +1 -1
- package/dist/domain/core/relation/direct-relation.d.ts +13 -24
- package/dist/domain/core/relation/index.d.ts +0 -1
- package/dist/domain/core/relation/indirect-relation.d.ts +12 -67
- package/dist/domain/core/relation/indirect-relation.js +1 -1
- package/dist/domain/core/relation/reference-component.d.ts +2 -2
- package/dist/domain/core/relation/relation-factory.d.ts +19 -15
- package/dist/domain/core/relation/relation-factory.js +1 -1
- package/dist/domain/core/schema/extended-schema-validator.js +1 -1
- package/dist/domain/core/state/migrations.d.ts +14 -45
- package/dist/domain/core/state/migrations.js +1 -1
- package/dist/domain/core/state/state.d.ts +1 -1
- package/dist/domain/domain-builder.d.ts +10 -4
- package/dist/domain/domain-builder.js +1 -1
- package/dist/domain/domain-context/action-system/action-system.d.ts +2 -2
- package/dist/domain/domain-context/action-system/action-system.js +1 -1
- package/dist/domain/domain-context/action-system/index.d.ts +1 -0
- package/dist/domain/domain-context/action-system/index.js +1 -0
- package/dist/domain/domain-context/analytics-system/index.d.ts +2 -0
- package/dist/domain/domain-context/analytics-system/index.js +1 -0
- package/dist/domain/domain-context/create-transformer.d.ts +1 -1
- package/dist/domain/domain-context/dimension-system/dimension-system.d.ts +2 -2
- package/dist/domain/domain-context/dimension-system/dimension-system.js +1 -1
- package/dist/domain/domain-context/dimension-system/index.d.ts +1 -0
- package/dist/domain/domain-context/dimension-system/index.js +1 -0
- package/dist/domain/domain-context/domain-context-systems.d.ts +7 -7
- package/dist/domain/domain-context/index.d.ts +8 -17
- package/dist/domain/domain-context/index.js +1 -1
- package/dist/domain/domain-context/navigation-system/index.d.ts +3 -0
- package/dist/domain/domain-context/navigation-system/index.js +1 -0
- package/dist/domain/domain-context/navigation-system/navigation-system.d.ts +2 -3
- package/dist/domain/domain-context/navigation-system/navigation-system.js +1 -1
- package/dist/domain/domain-context/navigation-system/selection-transformers.d.ts +1 -1
- package/dist/domain/domain-context/recipe-system/index.d.ts +1 -0
- package/dist/domain/domain-context/recipe-system/index.js +1 -0
- package/dist/domain/domain-context/recipe-system/recipe-cooker-system.d.ts +1 -1
- package/dist/domain/domain-context/recipe-system/recipe-cooker-system.js +1 -1
- package/dist/domain/domain-context/relation-transformers/cascade-deletes.d.ts +2 -2
- package/dist/domain/domain-context/relation-transformers/cascade-ref-pruning.d.ts +2 -2
- package/dist/domain/domain-context/relation-transformers/create-entity-refs.d.ts +2 -2
- package/dist/domain/domain-context/relation-transformers/index.d.ts +4 -0
- package/dist/domain/domain-context/relation-transformers/index.js +1 -0
- package/dist/domain/domain-context/relation-transformers/replace-refs.d.ts +2 -2
- package/dist/domain/domain-context/store-system/index.d.ts +4 -0
- package/dist/domain/domain-context/store-system/index.js +1 -0
- package/dist/domain/domain-context/store-system/reconcile-projected-entities.js +1 -1
- package/dist/domain/domain-context/store-system/store-system.d.ts +7 -35
- package/dist/domain/domain-context/store-system/store-system.js +2 -2
- package/dist/domain/domain-context/store-system/system-state.d.ts +1 -1
- package/dist/domain/domain-context/transformers/actions-builder.js +1 -1
- package/dist/domain/domain-context/transformers/auto-snap-transformer.d.ts +5 -7
- package/dist/domain/domain-context/transformers/auto-snap-transformer.js +1 -1
- package/dist/domain/domain-context/transformers/chain-builder.d.ts +1 -1
- package/dist/domain/domain-context/transformers/context.d.ts +2 -3
- package/dist/domain/domain-context/transformers/context.js +1 -1
- package/dist/domain/domain-context/transformers/entity-builder.js +1 -1
- package/dist/domain/domain-context/transformers/index.d.ts +1 -1
- package/dist/domain/domain-context/transformers/index.js +1 -1
- package/dist/domain/domain-context/transformers/when-builder.d.ts +2 -3
- package/dist/domain/domain-context/transformers/when-builder.js +1 -1
- package/dist/domain/domain-context/undo-system.d.ts +29 -3
- package/dist/domain/domain-context/undo-system.js +1 -1
- package/dist/domain/domain-runtime/access/selectors.d.ts +9 -0
- package/dist/domain/domain-runtime/access/selectors.js +1 -1
- package/dist/domain/domain-runtime/access/types.d.ts +2 -0
- package/dist/domain/domain-runtime/access/types.js +1 -1
- package/dist/domain/domain-runtime/application.d.ts +39 -0
- package/dist/domain/domain-runtime/application.js +1 -0
- package/dist/domain/domain-runtime/domain-context/action-context.d.ts +11 -0
- package/dist/domain/domain-runtime/domain-context/action-context.js +1 -0
- package/dist/domain/domain-runtime/domain-context/domain-context.js +1 -1
- package/dist/domain/domain-runtime/domain-context/expression-context.d.ts +8 -0
- package/dist/domain/domain-runtime/domain-context/expression-context.js +1 -0
- package/dist/domain/domain-runtime/domain-context/index.d.ts +3 -0
- package/dist/domain/domain-runtime/domain-context/runtime-expression-context.d.ts +18 -0
- package/dist/domain/domain-runtime/domain-context/runtime-expression-context.js +1 -0
- package/dist/domain/domain-runtime/domain-context/selectors.d.ts +19 -22
- package/dist/domain/domain-runtime/domain-context/selectors.js +1 -1
- package/dist/domain/domain-runtime/domain-context/types.d.ts +4 -1
- package/dist/domain/domain-runtime/domain-runtime.d.ts +128 -72
- package/dist/domain/domain-runtime/domain-runtime.js +1 -1
- package/dist/domain/domain-runtime/environment/initialize.d.ts +1 -1
- package/dist/domain/domain-runtime/environment/types.d.ts +1 -1
- package/dist/domain/domain-runtime/errors/implementation-error-collector.d.ts +21 -0
- package/dist/domain/domain-runtime/errors/implementation-error-collector.js +1 -0
- package/dist/domain/domain-runtime/errors/implementation-error.d.ts +46 -0
- package/dist/domain/domain-runtime/errors/implementation-error.js +1 -0
- package/dist/domain/domain-runtime/errors/implementation-errors.d.ts +13 -0
- package/dist/domain/domain-runtime/errors/implementation-errors.js +1 -0
- package/dist/domain/domain-runtime/errors/index.d.ts +4 -0
- package/dist/domain/domain-runtime/errors/index.js +1 -0
- package/dist/domain/domain-runtime/errors/to-implementation-errors.d.ts +10 -0
- package/dist/domain/domain-runtime/errors/to-implementation-errors.js +1 -0
- package/dist/domain/domain-runtime/index.d.ts +2 -0
- package/dist/domain/domain-runtime/index.js +1 -1
- package/dist/domain/domain-runtime/spec/create-violation-expressions.d.ts +24 -0
- package/dist/domain/domain-runtime/spec/create-violation-expressions.js +1 -0
- package/dist/domain/domain-runtime/spec/index.d.ts +2 -0
- package/dist/domain/domain-runtime/spec/index.js +1 -1
- package/dist/domain/domain-runtime/spec/initialize.d.ts +11 -0
- package/dist/domain/domain-runtime/spec/initialize.js +1 -1
- package/dist/domain/{application → domain-runtime/spec/module-checks}/element-registration.d.ts +29 -14
- package/dist/domain/domain-runtime/spec/module-checks/element-registration.js +1 -0
- package/dist/domain/domain-runtime/spec/module-checks/find-assistant-form-element-errors.d.ts +12 -0
- package/dist/domain/domain-runtime/spec/module-checks/find-assistant-form-element-errors.js +1 -0
- package/dist/domain/{application → domain-runtime/spec/module-checks}/handler-registration.d.ts +1 -1
- package/dist/domain/domain-runtime/spec/module-checks/handler-registration.js +1 -0
- package/dist/domain/domain-runtime/spec/module-checks/index.d.ts +10 -0
- package/dist/domain/domain-runtime/spec/module-checks/index.js +1 -0
- package/dist/domain/domain-runtime/spec/module-checks/merge-expression-modules.d.ts +23 -0
- package/dist/domain/domain-runtime/spec/module-checks/merge-expression-modules.js +1 -0
- package/dist/domain/{project-modules → domain-runtime/spec/module-checks}/project-modules.d.ts +8 -17
- package/dist/domain/domain-runtime/spec/module-checks/project-modules.js +1 -0
- package/dist/domain/domain-runtime/spec/module-checks/resolve-action-modules.d.ts +4 -0
- package/dist/domain/domain-runtime/spec/module-checks/resolve-action-modules.js +1 -0
- package/dist/domain/domain-runtime/spec/module-checks/resolve-component-optic-modules.d.ts +4 -0
- package/dist/domain/domain-runtime/spec/module-checks/resolve-component-optic-modules.js +1 -0
- package/dist/domain/domain-runtime/spec/module-checks/resolve-expression-modules.d.ts +14 -0
- package/dist/domain/domain-runtime/spec/module-checks/resolve-expression-modules.js +1 -0
- package/dist/domain/domain-runtime/spec/module-checks/resolve-imported-transformers.d.ts +22 -0
- package/dist/domain/domain-runtime/spec/module-checks/resolve-imported-transformers.js +1 -0
- package/dist/domain/domain-runtime/spec/module-checks/resolve-invariant-modules.d.ts +6 -0
- package/dist/domain/domain-runtime/spec/module-checks/resolve-invariant-modules.js +1 -0
- package/dist/domain/domain-runtime/spec/selectors.d.ts +8 -7
- package/dist/domain/domain-runtime/spec/selectors.js +1 -1
- package/dist/domain/domain-runtime/spec/types.d.ts +5 -2
- package/dist/domain/domain-runtime/web-component/actions.d.ts +3 -0
- package/dist/domain/domain-runtime/web-component/actions.js +1 -1
- package/dist/domain/domain-runtime/web-component/initialize.d.ts +1 -0
- package/dist/domain/domain-runtime/web-component/initialize.js +1 -1
- package/dist/domain/domain-runtime/web-component/selectors.d.ts +2 -0
- package/dist/domain/domain-runtime/web-component/selectors.js +1 -1
- package/dist/domain/domain-runtime/web-component/types.d.ts +6 -3
- package/dist/domain/extensions/attribute-switch.d.ts +1 -1
- package/dist/domain/extensions/attribute-switch.js +1 -1
- package/dist/domain/extensions/canvas-config.d.ts +1 -1
- package/dist/domain/extensions/common/angle-indicator-schema.d.ts +2 -2
- package/dist/domain/extensions/common/dimension-indicator-schema.d.ts +2 -2
- package/dist/domain/extensions/editable-angle-indicator.d.ts +1 -1
- package/dist/domain/extensions/editable-distance-dimension-indicator.d.ts +1 -1
- package/dist/domain/extensions/editable-offset-indicator.d.ts +1 -1
- package/dist/domain/extensions/editable-offset-indicator.js +1 -1
- package/dist/domain/extensions/export-images/agent-screenshot.d.ts +24 -0
- package/dist/domain/extensions/export-images/agent-screenshot.js +1 -0
- package/dist/domain/extensions/export-images/client-side-image.d.ts +14 -0
- package/dist/domain/extensions/export-images/client-side-image.js +1 -0
- package/dist/domain/extensions/export-images/index.d.ts +3 -0
- package/dist/domain/extensions/export-images/index.js +1 -0
- package/dist/domain/extensions/{save-template-thumbnail.d.ts → export-images/save-template-thumbnail.d.ts} +4 -4
- package/dist/domain/extensions/export-images/save-template-thumbnail.js +1 -0
- package/dist/domain/extensions/fit-selection-orthographic-camera-component.js +1 -1
- package/dist/domain/extensions/fit-selection-perspective-camera-component.js +1 -1
- package/dist/domain/extensions/horizontal-tabs.d.ts +2 -2
- package/dist/domain/extensions/index.d.ts +1 -2
- package/dist/domain/extensions/index.js +1 -1
- package/dist/domain/extensions/list-selector-dimension-indicator.d.ts +1 -1
- package/dist/domain/extensions/navigation-steps.d.ts +2 -2
- package/dist/domain/extensions/offset-indicator.js +1 -1
- package/dist/domain/extensions/rotation-handle.d.ts +2 -2
- package/dist/domain/extensions/scene-entity-animation.js +1 -1
- package/dist/domain/index.d.ts +0 -1
- package/dist/domain/index.js +1 -1
- package/dist/domain/mocks/create-mock-domain-context.d.ts +1 -1
- package/dist/domain/mocks/create-mock-domain-runtime-services.d.ts +1 -1
- package/dist/domain/mocks/create-mock-domain-runtime.d.ts +37 -19
- package/dist/domain/mocks/create-mock-domain-runtime.js +1 -1
- package/dist/domain/mocks/create-mock-domain.d.ts +1 -1
- package/dist/domain/mocks/create-mock-domain.js +1 -1
- package/dist/domain/mocks/create-mock-state.d.ts +2 -2
- package/dist/domain/mocks/create-test-application-config.d.ts +59 -0
- package/dist/domain/mocks/create-test-application-config.js +1 -0
- package/dist/domain/mocks/index.d.ts +1 -0
- package/dist/domain/mocks/index.js +1 -1
- package/dist/domain/projections/blender-projections/blender-projections.d.ts +1 -2
- package/dist/domain/projections/blender-projections/camera.d.ts +2 -2
- package/dist/domain/projections/collision-projections.d.ts +1 -1
- package/dist/domain/projections/composition-projections.d.ts +1 -1
- package/dist/domain/projections/constraint-projections.d.ts +1 -1
- package/dist/domain/projections/index.d.ts +1 -1
- package/dist/domain/projections/position-projections.d.ts +1 -1
- package/dist/domain/projections/projected-entities-projections.d.ts +1 -1
- package/dist/domain/projections/snapping-projections.d.ts +1 -1
- package/dist/domain/projections/validation-projections.d.ts +3 -19
- package/dist/domain/sketching/sketching-projections.d.ts +1 -1
- package/dist/domain/system-components/application-config.d.ts +2 -2
- package/dist/domain/system-components/child-entity-selection.js +1 -1
- package/dist/domain/system-components/collision-box-geometry.d.ts +4 -2
- package/dist/domain/system-components/collision-geometry.d.ts +4 -2
- package/dist/domain/system-components/collision-point-geometry.d.ts +4 -2
- package/dist/domain/system-components/common/material-override-schema.d.ts +2 -2
- package/dist/domain/system-components/common/recipes.d.ts +21 -3
- package/dist/domain/system-components/common/recipes.js +1 -1
- package/dist/domain/system-components/common/scene-entity-control-schema.d.ts +3 -0
- package/dist/domain/system-components/common/scene-entity-control-schema.js +1 -1
- package/dist/domain/system-components/constraint.d.ts +10 -23
- package/dist/domain/system-components/drag-handle.d.ts +1 -1
- package/dist/domain/system-components/drag-handle.js +1 -1
- package/dist/domain/system-components/fit-entity-orthographic-camera-component.js +1 -1
- package/dist/domain/system-components/fit-entity-perspective-camera-component.js +1 -1
- package/dist/domain/system-components/fit-root-orthographic-camera-component.js +1 -1
- package/dist/domain/system-components/fit-root-perspective-camera-component.js +1 -1
- package/dist/domain/system-components/hotspot-drag-handle.d.ts +1 -1
- package/dist/domain/system-components/hotspot-drag-handle.js +1 -1
- package/dist/domain/system-components/material-swatch.js +1 -1
- package/dist/domain/system-components/phoenix-entity-elements/admin-data-table-sidebar.d.ts +1 -1
- package/dist/domain/system-components/phoenix-layout-elements/admin-connected-resource-page.d.ts +1 -1
- package/dist/domain/system-components/phoenix-layout-elements/admin-data-table-actions.d.ts +1 -1
- package/dist/domain/system-components/phoenix-layout-elements/admin-data-table-page.d.ts +1 -1
- package/dist/domain/system-components/scene-entity-material-override.d.ts +1 -1
- package/dist/domain/system-components/scene-entity-object-material-override.d.ts +1 -1
- package/dist/domain/system-components/scene-entity-object-text-decal.d.ts +1 -1
- package/dist/domain/system-components/scene-entity-object-transimissive-material-override.d.ts +1 -1
- package/dist/domain/system-components/scene-entity-transimissive-material-override.d.ts +1 -1
- package/dist/domain/system-components/static-orthographic-camera-component.js +1 -1
- package/dist/domain/system-components/static-perspective-camera-component.js +1 -1
- package/dist/domain/utils/eval-cache.d.ts +1 -1
- package/dist/domain/utils/map-nested-object.d.ts +1 -1
- package/dist/domain/utils/memo-eval.d.ts +2 -2
- package/dist/editor/Editor.d.ts +7 -0
- package/dist/editor/Editor.js +1 -1
- package/dist/editor/domain-editors/DomainSpecContext.js +1 -1
- package/dist/editor/domain-editors/apply-spec-update.d.ts +10 -2
- package/dist/editor/domain-editors/apply-spec-update.js +1 -1
- package/dist/editor/domain-editors/use-implementation-files.d.ts +7 -16
- package/dist/editor/domain-editors/use-implementation-files.js +1 -1
- package/dist/editor/mocks/CreateMockYaml.js +2 -2
- package/dist/editor/mocks/EditorMockContext.d.ts +2 -0
- package/dist/editor/mocks/EditorMockContext.js +1 -1
- package/dist/editor/screenshot/ScreenshotHandler.js +1 -1
- package/dist/globals/index.d.ts +2 -0
- package/dist/i18n/locales/cs/messages.js +1 -1
- package/dist/i18n/locales/da/messages.js +1 -1
- package/dist/i18n/locales/de/messages.js +1 -1
- package/dist/i18n/locales/de-AT/messages.js +1 -1
- package/dist/i18n/locales/en/messages.js +1 -1
- package/dist/i18n/locales/en-AU/messages.js +1 -1
- package/dist/i18n/locales/en-GB/messages.js +1 -1
- package/dist/i18n/locales/es/messages.js +1 -1
- package/dist/i18n/locales/fr/messages.js +1 -1
- package/dist/i18n/locales/hu/messages.js +1 -1
- package/dist/i18n/locales/it/messages.js +1 -1
- package/dist/i18n/locales/nl/messages.js +1 -1
- package/dist/i18n/locales/pl/messages.js +1 -1
- package/dist/i18n/locales/pt/messages.js +1 -1
- package/dist/i18n/locales/ro/messages.js +1 -1
- package/dist/i18n/locales/sk/messages.js +1 -1
- package/dist/i18n/locales/tr/messages.js +1 -1
- package/dist/legacy/domain-cli/gen/configurator-builder.js +13 -12
- package/dist/legacy/domain-cli/gen/constant-expressions.js +1 -3
- package/dist/legacy/domain-cli/gen/defaults.js +1 -7
- package/dist/legacy/domain-cli/gen/implementation.js +7 -11
- package/dist/legacy/domain-cli/gen/invariants.js +7 -6
- package/dist/legacy/domain-cli/gen/relations.js +1 -1
- package/dist/legacy/domain-cli/utils/cache.d.ts +1 -1
- package/dist/legacy/domain-cli/utils/cache.js +1 -1
- package/dist/legacy/domain-spec/__generated/domain-schema.d.ts +176 -148
- package/dist/legacy/domain-spec/spec/domain-spec.js +1 -1
- package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/agents/claude-md.d.ts +1 -1
- package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/agents/cursor-rules.d.ts +1 -1
- package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/agents/shared-sdk-content.d.ts +1 -1
- package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/agents/shared-sdk-content.js +13 -0
- package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/domain-index.js +17 -15
- package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/env-example.d.ts +1 -1
- package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/env-example.js +4 -0
- package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/frontend-admin.js +15 -14
- package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/frontend-configurator.js +14 -12
- package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/frontend-embedded-admin.js +14 -13
- package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/frontend-embedded-configurator.js +13 -11
- package/dist/phoenix/application-spec/application-spec-builder.d.ts +0 -2
- package/dist/phoenix/application-spec/application-spec-builder.js +1 -1
- package/dist/phoenix/application-spec/generate-application-spec-project.d.ts +0 -2
- package/dist/phoenix/application-spec/generate-application-spec-project.js +2 -2
- package/dist/phoenix/application-spec/generate-application-spec-story.js +2 -2
- package/dist/phoenix/application-spec/generate-project-files.d.ts +0 -2
- package/dist/phoenix/application-spec/project-files.js +1 -1
- package/dist/phoenix/bin.d.ts +2 -0
- package/dist/phoenix/bin.js +2 -0
- package/dist/phoenix/check-configs/built-in-eslint-config.d.ts +9 -0
- package/dist/phoenix/check-configs/built-in-eslint-config.js +1 -0
- package/dist/phoenix/check-configs/eslint-config.d.ts +10 -0
- package/dist/phoenix/check-configs/eslint-config.js +1 -0
- package/dist/phoenix/check-configs/index.d.ts +8 -0
- package/dist/phoenix/check-configs/index.js +1 -0
- package/dist/phoenix/check-configs/typescript-project.d.ts +5 -0
- package/dist/phoenix/check-configs/typescript-project.js +1 -0
- package/dist/phoenix/cli.d.ts +0 -1
- package/dist/phoenix/cli.js +1 -2
- package/dist/phoenix/commands/build.js +1 -1
- package/dist/phoenix/commands/check.js +1 -1
- package/dist/phoenix/commands/clean.js +1 -1
- package/dist/phoenix/commands/deploy.js +2 -2
- package/dist/phoenix/commands/deps/deps.d.ts +73 -0
- package/dist/phoenix/commands/deps/deps.js +3 -0
- package/dist/phoenix/commands/deps/index.d.ts +1 -0
- package/dist/phoenix/commands/deps/index.js +1 -0
- package/dist/phoenix/commands/deps/sdk-manifest.d.ts +12 -0
- package/dist/phoenix/commands/deps/sdk-manifest.js +1 -0
- package/dist/phoenix/commands/dev.js +5 -5
- package/dist/phoenix/commands/fix.js +1 -1
- package/dist/phoenix/commands/index.d.ts +1 -0
- package/dist/phoenix/commands/index.js +1 -1
- package/dist/phoenix/commands/init.d.ts +17 -5
- package/dist/phoenix/commands/init.js +1 -1
- package/dist/phoenix/commands/link.js +1 -1
- package/dist/phoenix/commands/prettier.js +1 -1
- package/dist/phoenix/commands/sync.js +1 -1
- package/dist/phoenix/commands/unlink.js +1 -1
- package/dist/phoenix/services/application-spec-project-watcher.d.ts +2 -2
- package/dist/phoenix/services/application-spec-project-watcher.js +3 -3
- package/dist/phoenix/services/lingui.d.ts +8 -0
- package/dist/phoenix/services/lingui.js +1 -1
- package/dist/phoenix/services/source-archive.d.ts +1 -0
- package/dist/phoenix/services/source-archive.js +1 -1
- package/dist/phoenix/services/swc.js +1 -1
- package/dist/phoenix/services/vite-config.js +1 -1
- package/dist/phoenix/utils/git/index.d.ts +1 -0
- package/dist/phoenix/utils/git/index.js +1 -0
- package/dist/phoenix/utils/git/is-inside-git-repository.d.ts +6 -0
- package/dist/phoenix/utils/git/is-inside-git-repository.js +1 -0
- package/dist/phoenix/utils/index.d.ts +5 -2
- package/dist/phoenix/utils/index.js +1 -1
- package/dist/phoenix/utils/node-version/index.d.ts +1 -0
- package/dist/phoenix/utils/node-version/index.js +1 -0
- package/dist/phoenix/utils/node-version/supported-node-version.d.ts +12 -0
- package/dist/phoenix/utils/node-version/supported-node-version.js +4 -0
- package/dist/phoenix/utils/package-info.d.ts +0 -9
- package/dist/phoenix/utils/package-info.js +1 -1
- package/dist/phoenix/utils/package-manager/index.d.ts +2 -0
- package/dist/phoenix/utils/package-manager/index.js +1 -0
- package/dist/phoenix/utils/package-manager/package-manager-commands.d.ts +19 -0
- package/dist/phoenix/utils/package-manager/package-manager-commands.js +1 -0
- package/dist/phoenix/utils/package-manager/pnpm-project.d.ts +9 -0
- package/dist/phoenix/utils/package-manager/pnpm-project.js +1 -0
- package/dist/phoenix/utils/run-command.d.ts +11 -0
- package/dist/phoenix/utils/run-command.js +1 -1
- package/dist/phoenix/utils/sdk-tool/index.d.ts +1 -0
- package/dist/phoenix/utils/sdk-tool/index.js +1 -0
- package/dist/phoenix/utils/sdk-tool/resolve-sdk-tool-bin.d.ts +15 -0
- package/dist/phoenix/utils/sdk-tool/resolve-sdk-tool-bin.js +1 -0
- package/dist/react-sdk/application-runtime/common-services/analytics/analytics-service.d.ts +1 -1
- package/dist/{configurator/common → react-sdk/application-runtime/common-services/analytics}/frontend-analytics.d.ts +6 -0
- package/dist/react-sdk/application-runtime/common-services/analytics/frontend-analytics.js +1 -0
- package/dist/react-sdk/application-runtime/common-services/analytics/index.d.ts +1 -0
- package/dist/react-sdk/application-runtime/common-services/analytics/index.js +1 -1
- package/dist/react-sdk/application-runtime/common-services/initialize.d.ts +2 -2
- package/dist/react-sdk/application-runtime/hooks/index.d.ts +2 -0
- package/dist/react-sdk/application-runtime/hooks/index.js +1 -1
- package/dist/react-sdk/application-runtime/hooks/loading/index.d.ts +5 -0
- package/dist/react-sdk/application-runtime/hooks/loading/index.js +1 -0
- package/dist/react-sdk/application-runtime/hooks/loading/loader-host-context.d.ts +11 -0
- package/dist/react-sdk/application-runtime/hooks/loading/loader-host-context.js +1 -0
- package/dist/react-sdk/application-runtime/hooks/loading/use-is-awaiting-loading-phase.d.ts +8 -0
- package/dist/react-sdk/application-runtime/hooks/loading/use-is-awaiting-loading-phase.js +1 -0
- package/dist/react-sdk/application-runtime/hooks/loading/use-is-loader-hosted.d.ts +7 -0
- package/dist/react-sdk/application-runtime/hooks/loading/use-is-loader-hosted.js +1 -0
- package/dist/react-sdk/application-runtime/hooks/loading/use-loading-actions.d.ts +9 -0
- package/dist/react-sdk/application-runtime/hooks/loading/use-loading-actions.js +1 -0
- package/dist/react-sdk/application-runtime/hooks/loading/use-loading-application.d.ts +24 -0
- package/dist/react-sdk/application-runtime/hooks/loading/use-loading-application.js +1 -0
- package/dist/react-sdk/application-runtime/hooks/responsive/index.d.ts +3 -0
- package/dist/react-sdk/application-runtime/hooks/responsive/index.js +1 -0
- package/dist/react-sdk/application-runtime/hooks/responsive/use-responsive-actions.d.ts +9 -0
- package/dist/react-sdk/application-runtime/hooks/responsive/use-responsive-actions.js +1 -0
- package/dist/react-sdk/application-runtime/hooks/responsive/use-responsive-application.d.ts +26 -0
- package/dist/react-sdk/application-runtime/hooks/responsive/use-responsive-application.js +1 -0
- package/dist/react-sdk/application-runtime/hooks/responsive/use-responsive-state.d.ts +10 -0
- package/dist/react-sdk/application-runtime/hooks/responsive/use-responsive-state.js +1 -0
- package/dist/react-sdk/application-runtime/hooks/responsive/use-responsive-store.d.ts +24 -0
- package/dist/react-sdk/application-runtime/hooks/responsive/use-responsive-store.js +1 -0
- package/dist/react-sdk/application-runtime/hooks/use-access-service.d.ts +7 -0
- package/dist/react-sdk/application-runtime/hooks/use-access-service.js +1 -1
- package/dist/react-sdk/application-runtime/hooks/use-phoenix-element-slots.d.ts +2 -1
- package/dist/react-sdk/application-runtime/hooks/use-web-component-readonly-sync.d.ts +4 -11
- package/dist/react-sdk/application-runtime/hooks/use-web-component-readonly-sync.js +1 -1
- package/dist/react-sdk/application-runtime/hooks/use-web-component.d.ts +5 -0
- package/dist/react-sdk/application-runtime/hooks/use-web-component.js +1 -1
- package/dist/react-sdk/application-runtime/host-properties/actions.d.ts +15 -0
- package/dist/react-sdk/application-runtime/host-properties/actions.js +1 -0
- package/dist/react-sdk/application-runtime/host-properties/connect-host-properties.d.ts +30 -0
- package/dist/react-sdk/application-runtime/host-properties/connect-host-properties.js +1 -0
- package/dist/react-sdk/application-runtime/host-properties/domain-host-properties.d.ts +7 -0
- package/dist/react-sdk/application-runtime/host-properties/domain-host-properties.js +1 -0
- package/dist/react-sdk/application-runtime/host-properties/host-property-descriptors.d.ts +21 -0
- package/dist/react-sdk/application-runtime/host-properties/host-property-descriptors.js +1 -0
- package/dist/react-sdk/application-runtime/host-properties/host-property-scopes.d.ts +42 -0
- package/dist/react-sdk/application-runtime/host-properties/host-property-scopes.js +1 -0
- package/dist/react-sdk/application-runtime/host-properties/index.d.ts +8 -0
- package/dist/react-sdk/application-runtime/host-properties/index.js +1 -0
- package/dist/react-sdk/application-runtime/host-properties/initialize.d.ts +7 -0
- package/dist/react-sdk/application-runtime/host-properties/initialize.js +1 -0
- package/dist/react-sdk/application-runtime/host-properties/selectors.d.ts +54 -0
- package/dist/react-sdk/application-runtime/host-properties/selectors.js +1 -0
- package/dist/react-sdk/application-runtime/host-properties/types.d.ts +18 -0
- package/dist/react-sdk/application-runtime/host-properties/types.js +1 -0
- package/dist/react-sdk/application-runtime/index.d.ts +3 -0
- package/dist/react-sdk/application-runtime/integration/initialize.d.ts +7 -6
- package/dist/react-sdk/application-runtime/integration/initialize.js +1 -1
- package/dist/react-sdk/application-runtime/integration/selectors.d.ts +11 -2
- package/dist/react-sdk/application-runtime/integration/selectors.js +1 -1
- package/dist/react-sdk/application-runtime/integration/types.d.ts +5 -2
- package/dist/react-sdk/application-runtime/loading/actions.d.ts +45 -0
- package/dist/react-sdk/application-runtime/loading/actions.js +1 -0
- package/dist/react-sdk/application-runtime/loading/index.d.ts +4 -0
- package/dist/react-sdk/application-runtime/loading/index.js +1 -0
- package/dist/react-sdk/application-runtime/loading/initialize.d.ts +3 -0
- package/dist/react-sdk/application-runtime/loading/initialize.js +1 -0
- package/dist/react-sdk/application-runtime/loading/selectors.d.ts +18 -0
- package/dist/react-sdk/application-runtime/loading/selectors.js +1 -0
- package/dist/react-sdk/application-runtime/loading/types.d.ts +59 -0
- package/dist/react-sdk/application-runtime/loading/types.js +1 -0
- package/dist/react-sdk/application-runtime/mocks/create-mock-application-runtime.js +1 -1
- package/dist/react-sdk/application-runtime/provider/ApplicationRuntime.d.ts +6 -0
- package/dist/react-sdk/application-runtime/provider/ApplicationRuntime.js +1 -1
- package/dist/react-sdk/application-runtime/provider/ApplicationType.d.ts +7 -0
- package/dist/react-sdk/application-runtime/provider/ApplicationType.js +1 -1
- package/dist/react-sdk/application-runtime/responsive/actions.d.ts +47 -0
- package/dist/react-sdk/application-runtime/responsive/actions.js +1 -0
- package/dist/react-sdk/application-runtime/responsive/index.d.ts +4 -0
- package/dist/react-sdk/application-runtime/responsive/index.js +1 -0
- package/dist/react-sdk/application-runtime/responsive/initialize.d.ts +3 -0
- package/dist/react-sdk/application-runtime/responsive/initialize.js +1 -0
- package/dist/react-sdk/application-runtime/responsive/selectors.d.ts +20 -0
- package/dist/react-sdk/application-runtime/responsive/selectors.js +1 -0
- package/dist/react-sdk/application-runtime/responsive/types.d.ts +104 -0
- package/dist/react-sdk/application-runtime/responsive/types.js +1 -0
- package/dist/react-sdk/application-runtime/routing/access-service.d.ts +1 -0
- package/dist/react-sdk/application-runtime/routing/routing-service.d.ts +34 -2
- package/dist/react-sdk/application-runtime/routing/routing-service.js +1 -1
- package/dist/react-sdk/application-runtime/runtime/create-application-runtime.d.ts +366 -46
- package/dist/react-sdk/application-runtime/runtime/create-application-runtime.js +1 -1
- package/dist/react-sdk/domain-application-context/BackendDataProvider.js +1 -1
- package/dist/react-sdk/domain-application-context/DomainLifecycleBoundary.js +1 -1
- package/dist/react-sdk/domain-application-context/FrontendDataProvider.js +1 -1
- package/dist/react-sdk/domain-application-context/PublishedDataProvider.js +1 -1
- package/dist/react-sdk/domain-context/common-hooks/index.d.ts +9 -0
- package/dist/react-sdk/domain-context/common-hooks/index.js +1 -0
- package/dist/react-sdk/domain-context/common-hooks/use-configuration-save-state.d.ts +23 -0
- package/dist/react-sdk/domain-context/common-hooks/use-configuration-save-state.js +1 -0
- package/dist/react-sdk/domain-context/common-hooks/use-configurator-messages.d.ts +41 -0
- package/dist/react-sdk/domain-context/common-hooks/use-configurator-messages.js +1 -0
- package/dist/react-sdk/domain-context/common-hooks/use-domain-context.d.ts +10 -9
- package/dist/react-sdk/domain-context/component-hooks/index.d.ts +1 -0
- package/dist/react-sdk/domain-context/component-hooks/index.js +1 -0
- package/dist/react-sdk/domain-context/component-hooks/use-component.js +1 -1
- package/dist/react-sdk/domain-context/entity-hooks/use-domain-entity-state.js +1 -1
- package/dist/react-sdk/domain-context/entity-hooks/use-entity-price.js +1 -1
- package/dist/react-sdk/domain-context/entity-hooks/use-root-entity-id.js +1 -1
- package/dist/react-sdk/domain-context/entity-hooks/use-root-entity-state.js +1 -1
- package/dist/react-sdk/domain-context/index.d.ts +9 -1
- package/dist/react-sdk/domain-context/index.js +1 -1
- package/dist/react-sdk/domain-context/system-hooks/composition-hooks.js +1 -1
- package/dist/react-sdk/domain-context/system-hooks/dimension-hooks.js +1 -1
- package/dist/react-sdk/domain-context/system-hooks/generate-share-link-hooks.d.ts +8 -0
- package/dist/react-sdk/domain-context/system-hooks/generate-share-link-hooks.js +1 -0
- package/dist/react-sdk/domain-context/system-hooks/hover-hooks.js +1 -1
- package/dist/react-sdk/domain-context/system-hooks/locale-switch-hooks.d.ts +24 -0
- package/dist/react-sdk/domain-context/system-hooks/locale-switch-hooks.js +1 -0
- package/dist/react-sdk/domain-context/system-hooks/navigation-hooks.d.ts +11 -0
- package/dist/react-sdk/domain-context/system-hooks/navigation-hooks.js +1 -1
- package/dist/react-sdk/domain-context/system-hooks/selection-hooks.js +1 -1
- package/dist/react-sdk/domain-context/system-hooks/share-links-hooks.d.ts +32 -0
- package/dist/react-sdk/domain-context/system-hooks/share-links-hooks.js +1 -0
- package/dist/react-sdk/domain-context/system-hooks/step-navigation-hooks.d.ts +57 -0
- package/dist/react-sdk/domain-context/system-hooks/step-navigation-hooks.js +1 -0
- package/dist/react-sdk/domain-context/system-hooks/tab-navigation-hooks.d.ts +61 -0
- package/dist/react-sdk/domain-context/system-hooks/tab-navigation-hooks.js +1 -0
- package/dist/react-sdk/domain-context/system-hooks/undo-redo-hooks.d.ts +20 -0
- package/dist/react-sdk/domain-context/system-hooks/undo-redo-hooks.js +1 -0
- package/dist/react-sdk/domain-controls/hooks/use-angle-dimension.d.ts +1 -1
- package/dist/react-sdk/handlers/FinalizeActionRunner.d.ts +13 -0
- package/dist/react-sdk/handlers/FinalizeActionRunner.js +1 -0
- package/dist/react-sdk/handlers/FinalizeActionsHost.d.ts +10 -0
- package/dist/react-sdk/handlers/FinalizeActionsHost.js +1 -0
- package/dist/react-sdk/handlers/FinalizeActionsProvider.d.ts +11 -0
- package/dist/react-sdk/handlers/FinalizeActionsProvider.js +1 -0
- package/dist/react-sdk/handlers/finalize-actions-context.d.ts +6 -0
- package/dist/react-sdk/handlers/finalize-actions-context.js +1 -0
- package/dist/react-sdk/handlers/finalize-actions-store.d.ts +23 -0
- package/dist/react-sdk/handlers/finalize-actions-store.js +1 -0
- package/dist/react-sdk/handlers/index.d.ts +6 -0
- package/dist/react-sdk/handlers/index.js +1 -1
- package/dist/react-sdk/handlers/use-finalize-action.d.ts +32 -0
- package/dist/react-sdk/handlers/use-finalize-action.js +1 -0
- package/dist/react-sdk/handlers/use-finalize-actions.d.ts +53 -0
- package/dist/react-sdk/handlers/use-finalize-actions.js +1 -0
- package/dist/react-sdk/index.d.ts +2 -0
- package/dist/react-sdk/index.js +1 -1
- package/dist/react-sdk/loading-state/LoaderHost.d.ts +20 -0
- package/dist/react-sdk/loading-state/LoaderHost.js +1 -0
- package/dist/react-sdk/loading-state/built-in-loading-phase.d.ts +9 -0
- package/dist/react-sdk/loading-state/built-in-loading-phase.js +1 -0
- package/dist/react-sdk/loading-state/create-app-loader.d.ts +18 -0
- package/dist/react-sdk/loading-state/create-app-loader.js +1 -0
- package/dist/react-sdk/loading-state/index.d.ts +4 -2
- package/dist/react-sdk/loading-state/index.js +1 -1
- package/dist/react-sdk/loading-state/{LoadingStateProvider.d.ts → loading-state-hooks.d.ts} +3 -12
- package/dist/react-sdk/loading-state/loading-state-hooks.js +1 -0
- package/dist/react-sdk/page-elements/ConfigurationNotFoundPagePropsProvider.d.ts +17 -0
- package/dist/react-sdk/page-elements/ConfigurationNotFoundPagePropsProvider.js +1 -0
- package/dist/react-sdk/page-elements/ConfiguratorErrorPagePropsProvider.d.ts +17 -0
- package/dist/react-sdk/page-elements/ConfiguratorErrorPagePropsProvider.js +1 -0
- package/dist/react-sdk/page-elements/configurator-error-page-props.d.ts +20 -0
- package/dist/react-sdk/page-elements/configurator-error-page-props.js +1 -0
- package/dist/react-sdk/page-elements/create-configuration-not-found-page.d.ts +15 -0
- package/dist/react-sdk/page-elements/create-configuration-not-found-page.js +1 -0
- package/dist/react-sdk/page-elements/create-configurator-error-page.d.ts +14 -0
- package/dist/react-sdk/page-elements/create-configurator-error-page.js +1 -0
- package/dist/react-sdk/page-elements/create-preset-ui.d.ts +9 -0
- package/dist/react-sdk/page-elements/create-preset-ui.js +1 -0
- package/dist/react-sdk/page-elements/index.d.ts +6 -0
- package/dist/react-sdk/page-elements/index.js +1 -0
- package/dist/react-sdk/scene-control-elements/AddEntityFabElement.d.ts +36 -0
- package/dist/react-sdk/scene-control-elements/AddEntityFabElement.js +1 -0
- package/dist/react-sdk/scene-control-elements/DeleteEntityFabElement.d.ts +44 -0
- package/dist/react-sdk/scene-control-elements/DeleteEntityFabElement.js +1 -0
- package/dist/react-sdk/scene-control-elements/NavigationHotspotElement.d.ts +38 -0
- package/dist/react-sdk/scene-control-elements/NavigationHotspotElement.js +1 -0
- package/dist/react-sdk/scene-control-elements/SelectionHotspotElement.d.ts +30 -0
- package/dist/react-sdk/scene-control-elements/SelectionHotspotElement.js +1 -0
- package/dist/react-sdk/scene-control-elements/ToolMenuFabElement.d.ts +30 -0
- package/dist/react-sdk/scene-control-elements/ToolMenuFabElement.js +1 -0
- package/dist/react-sdk/scene-control-elements/create-add-entity-fab.d.ts +9 -0
- package/dist/react-sdk/scene-control-elements/create-add-entity-fab.js +1 -0
- package/dist/react-sdk/scene-control-elements/create-delete-entity-fab.d.ts +9 -0
- package/dist/react-sdk/scene-control-elements/create-delete-entity-fab.js +1 -0
- package/dist/react-sdk/scene-control-elements/create-navigation-hotspot.d.ts +10 -0
- package/dist/react-sdk/scene-control-elements/create-navigation-hotspot.js +1 -0
- package/dist/react-sdk/scene-control-elements/create-selection-hotspot.d.ts +9 -0
- package/dist/react-sdk/scene-control-elements/create-selection-hotspot.js +1 -0
- package/dist/react-sdk/scene-control-elements/create-tool-menu-fab.d.ts +9 -0
- package/dist/react-sdk/scene-control-elements/create-tool-menu-fab.js +1 -0
- package/dist/react-sdk/scene-control-elements/index.d.ts +11 -0
- package/dist/react-sdk/scene-control-elements/index.js +1 -0
- package/dist/react-sdk/scene-control-elements/scene-control-tooltip-visibility.d.ts +5 -0
- package/dist/react-sdk/scene-control-elements/scene-control-tooltip-visibility.js +1 -0
- package/dist/react-sdk/session/NotAuthenticatedPage.d.ts +4 -0
- package/dist/react-sdk/session/NotAuthenticatedPage.js +1 -1
- package/dist/react-sdk/session/SessionServiceProvider.js +1 -1
- package/dist/react-sdk/web-component/create-web-component.js +1 -1
- package/dist/react-sdk/web-component/god-mode/god-mode-registry.d.ts +30 -0
- package/dist/react-sdk/web-component/god-mode/god-mode-registry.js +1 -0
- package/dist/react-sdk/web-component/god-mode/index.d.ts +1 -0
- package/dist/react-sdk/web-component/god-mode/index.js +1 -0
- package/dist/ui-sdk/icons/__generated/Lightbulb.d.ts +3 -0
- package/dist/ui-sdk/icons/__generated/Lightbulb.js +1 -0
- package/dist/ui-sdk/icons/__generated/XCircle.d.ts +3 -0
- package/dist/ui-sdk/icons/__generated/XCircle.js +1 -0
- package/dist/ui-sdk/icons/__generated/index.d.ts +4 -0
- package/dist/ui-sdk/icons/__generated/index.js +1 -1
- package/dist/ui-sdk/icons/icons-registry.js +1 -1
- package/dist/ui-sdk/responsive-application/ResponsiveApplicationProvider.d.ts +9 -0
- package/dist/ui-sdk/responsive-application/ResponsiveApplicationProvider.js +1 -1
- package/dist/ui-sdk/responsive-application/index.d.ts +1 -0
- package/dist/ui-sdk/responsive-application/responsive-state-store.d.ts +59 -0
- package/dist/ui-sdk/responsive-application/responsive-state-store.js +1 -0
- package/dist/ui-sdk/responsive-application/use-store-responsive-info.d.ts +7 -0
- package/dist/ui-sdk/responsive-application/use-store-responsive-info.js +1 -0
- package/dist/ui-sdk/theme/types.d.ts +5 -1
- package/dist/webhook/builders/common.d.ts +5 -0
- package/dist/webhook/builders/webhook-builder.js +1 -1
- package/package.json +58 -36
- package/schema/domain-spec.json +1341 -217
- package/dist/application-spec/generate-application/code/templates/env-ci.d.ts +0 -1
- package/dist/application-spec/generate-application/code/templates/env-ci.js +0 -25
- package/dist/application-spec/generate-application/code/templates/env-example.d.ts +0 -1
- package/dist/application-spec/generate-application/code/templates/env-example.js +0 -90
- package/dist/application-spec/generate-application/code/templates/nvmrc.d.ts +0 -1
- package/dist/application-spec/generate-application/code/templates/nvmrc.js +0 -2
- package/dist/application-spec/generate-application/code/templates/package-json.d.ts +0 -10
- package/dist/application-spec/generate-application/code/templates/package-json.js +0 -1
- package/dist/application-spec/generate-application/code/templates/prettier-ignore.d.ts +0 -1
- package/dist/application-spec/generate-application/code/templates/prettier-ignore.js +0 -6
- package/dist/application-spec/generate-application/code/templates/private-assets-readme.d.ts +0 -1
- package/dist/application-spec/generate-application/code/templates/private-assets-readme.js +0 -24
- package/dist/application-spec/generate-application/code/templates/public-assets-readme.d.ts +0 -1
- package/dist/application-spec/generate-application/code/templates/public-assets-readme.js +0 -24
- package/dist/application-spec/generate-application/code/templates/readme.d.ts +0 -1
- package/dist/application-spec/generate-application/code/templates/readme.js +0 -23
- package/dist/application-spec/generate-application/code/templates/skills/agents-md.d.ts +0 -1
- package/dist/application-spec/generate-application/code/templates/skills/agents-md.js +0 -2
- package/dist/application-spec/generate-application/code/templates/webhook-implementation.d.ts +0 -1
- package/dist/application-spec/generate-application/code/templates/webhook-implementation.js +0 -7
- package/dist/configurator/common/frontend-analytics.js +0 -1
- package/dist/configurator/ui/phoenix-layout-elements/language/use-locale-options.d.ts +0 -4
- package/dist/configurator/ui/phoenix-layout-elements/language/use-locale-options.js +0 -1
- package/dist/configurator/ui/phoenix-layout-elements/measurements/use-measurements-visibility.d.ts +0 -4
- package/dist/configurator/ui/phoenix-layout-elements/measurements/use-measurements-visibility.js +0 -1
- package/dist/domain/application/element-registration.js +0 -1
- package/dist/domain/application/handler-registration.js +0 -1
- package/dist/domain/application/resolve-imported-transformers.d.ts +0 -23
- package/dist/domain/application/resolve-imported-transformers.js +0 -1
- package/dist/domain/application/resource-builder.d.ts +0 -13
- package/dist/domain/application/resource-builder.js +0 -1
- package/dist/domain/core/relation/relation-implementation.d.ts +0 -7
- package/dist/domain/extensions/client-side-image.d.ts +0 -14
- package/dist/domain/extensions/client-side-image.js +0 -1
- package/dist/domain/extensions/save-template-thumbnail.js +0 -1
- package/dist/domain/project-modules/index.d.ts +0 -1
- package/dist/domain/project-modules/index.js +0 -1
- package/dist/domain/project-modules/project-modules.js +0 -1
- package/dist/phoenix/commands/generate-project-files.d.ts +0 -6
- package/dist/phoenix/commands/generate-project-files.js +0 -1
- package/dist/react-sdk/application-runtime/runtime/god-mode.d.ts +0 -19
- package/dist/react-sdk/application-runtime/runtime/god-mode.js +0 -1
- package/dist/react-sdk/loading-state/LoadingStateProvider.js +0 -1
- package/dist/react-sdk/loading-state/loading-state-manager.d.ts +0 -32
- package/dist/react-sdk/loading-state/loading-state-manager.js +0 -1
- /package/dist/{domain/core/relation/relation-implementation.js → application-spec/core/expressions/relation-expression-params.js} +0 -0
- /package/dist/application-spec/{core → enhanced-json}/eval-code-uses-self.d.ts +0 -0
- /package/dist/application-spec/{core → enhanced-json}/eval-code-uses-self.js +0 -0
- /package/dist/application-spec/{core → enhanced-json}/eval-to-constant.js +0 -0
|
@@ -0,0 +1,1858 @@
|
|
|
1
|
+
# Kestrel Kettle
|
|
2
|
+
|
|
3
|
+
Sell a small product from one calm page that looks like the shop's own. A specialty-coffee shop, Aldermoor Coffee, sells its Kestrel pour-over kettle in three finishes, two handle woods and with or without a thermometer lid. The page reads like an editorial product page: the kettle on the left, a quiet column on the right with the name, the story, three rows of choices, the price and **Add to cart**, and the shop's promises in a thin strip at the bottom. On a phone the page opens on the shop's own start screen, "Make it yours", and then shows the kettle above one scrolling column. The project writes the page as one layout element; the spec holds the product, its prices, the rule between finish and wood, and the cart action.
|
|
4
|
+
|
|
5
|
+
- [Try it](#try-it)
|
|
6
|
+
- [What the example demonstrates](#what-the-example-demonstrates)
|
|
7
|
+
- [One page over the scene](#one-page-over-the-scene)
|
|
8
|
+
- [Choices from the spec](#choices-from-the-spec)
|
|
9
|
+
- [A rule between two choices](#a-rule-between-two-choices)
|
|
10
|
+
- [Add to cart](#add-to-cart)
|
|
11
|
+
- [The phone's start screen](#the-phones-start-screen)
|
|
12
|
+
- [The shop's footer and the Powered by mark](#the-shops-footer-and-the-powered-by-mark)
|
|
13
|
+
- [Texts from the spec](#texts-from-the-spec)
|
|
14
|
+
- [The stage and the model](#the-stage-and-the-model)
|
|
15
|
+
- [Test cases](#test-cases)
|
|
16
|
+
- [What this layout leaves out](#what-this-layout-leaves-out)
|
|
17
|
+
- [Related pages](#related-pages)
|
|
18
|
+
- [Complete Implementation](#complete-implementation)
|
|
19
|
+
|
|
20
|
+
## Try it
|
|
21
|
+
|
|
22
|
+
The phone version is under [The phone's start screen](#the-phones-start-screen).
|
|
23
|
+
|
|
24
|
+
## What the example demonstrates
|
|
25
|
+
|
|
26
|
+
[Custom Layout](?path=/docs/layouts-custom-layout--docs) explains how a project layout works: the element name, the scene, the safe area and the hooks. This page is a finished design built the same way, for a single-page product with no steps or tabs, and it shows the pieces Custom Layout does not use:
|
|
27
|
+
|
|
28
|
+
| Piece | Where |
|
|
29
|
+
| ------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- |
|
|
30
|
+
| `phx.frontend.useAttributeSwitch()` for an on/off choice | `ThermometerRow`, [Choices from the spec](#choices-from-the-spec) |
|
|
31
|
+
| `LayoutSlots.Services` with the built-in snackbars in `DesktopSnackbarsRoot` and `MobileSnackbarsRoot` | [A rule between two choices](#a-rule-between-two-choices) |
|
|
32
|
+
| `phx.frontend.useFinalizeActions()` for the spec's `addToCart` action | `CartBlock`, [Add to cart](#add-to-cart) |
|
|
33
|
+
| `phx.frontend.usePreview()` with the layout's own start screen, and `phx.frontend.useCloseAction()` | `PhonePoster`, `PhonePage`, [The phone's start screen](#the-phones-start-screen) |
|
|
34
|
+
| `phx.frontend.createLayoutFooter` with `LayoutSlots.DesktopFooter` and `MobileFooter` | [The shop's footer](#the-shops-footer-and-the-powered-by-mark) |
|
|
35
|
+
| `LayoutSlots.DesktopPoweredBy` and `MobilePoweredBy` | the footer strip and the end of the phone's column |
|
|
36
|
+
| `phx.frontend.useLocalizable()` and `LocalizableMessage` | `ProductHeading`, [Texts from the spec](#texts-from-the-spec) |
|
|
37
|
+
| A `canvasCustomEnvironment` stage with procedural light and a contact shadow | `KettleStudio`, [The stage and the model](#the-stage-and-the-model) |
|
|
38
|
+
|
|
39
|
+
## One page over the scene
|
|
40
|
+
|
|
41
|
+
`src/elements/ConfiguratorLayout.tsx` keeps the scene and the services mounted for as long as the configuration is open and chooses what lies over the scene: the start screen on a phone while `phx.frontend.usePreview().isPreview` is set, the phone page, or the desktop page. `phx.frontend.useActiveViewports()` tells desktop from phone by the width of the configurator's container, not the window.
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
import { Box } from '@mui/material'
|
|
45
|
+
|
|
46
|
+
import { LayoutSlots } from '@salsita-ai/sdk/configurator'
|
|
47
|
+
|
|
48
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
49
|
+
import { DesktopPage } from '../_shared/DesktopPage.js'
|
|
50
|
+
import { PhonePage } from '../_shared/PhonePage.js'
|
|
51
|
+
import { PhonePoster } from '../_shared/PhonePoster.js'
|
|
52
|
+
import { KESTREL } from '../_shared/tokens.js'
|
|
53
|
+
|
|
54
|
+
// One page, no steps or tabs. The canvas and the services stay mounted the whole time; what lies over the canvas is
|
|
55
|
+
// the phone's start screen, the phone page or the desktop page. Each calls `useSceneSafeArea` itself, so only the one
|
|
56
|
+
// on screen tells the camera where the kettle goes.
|
|
57
|
+
const ConfiguratorLayout = () => {
|
|
58
|
+
// `null` until the container has been measured; only the scene shows until then
|
|
59
|
+
const viewports = phx.frontend.useActiveViewports()
|
|
60
|
+
const { isPreview } = phx.frontend.usePreview()
|
|
61
|
+
const isDesktop = viewports?.includes('desktop') ?? false
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<Box component="div" sx={{ position: 'absolute', inset: 0, overflow: 'clip', bgcolor: KESTREL.oat }}>
|
|
65
|
+
<LayoutSlots.Services />
|
|
66
|
+
<LayoutSlots.SharedCanvas />
|
|
67
|
+
{viewports !== null && (isPreview ? <PhonePoster /> : isDesktop ? <DesktopPage /> : <PhonePage />)}
|
|
68
|
+
</Box>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export default phx.frontend.createCustomPhoenixLayoutElement('ConfiguratorLayout', ConfiguratorLayout)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- **Each arrangement measures its own safe area.** `DesktopPage`, `PhonePage` and `PhonePoster` each call `phx.frontend.useSceneSafeArea()` and attach `safeAreaRef` to a box inside the free area, inset from its edges. The camera fits the kettle into that box, so the inset is the breathing room around the product. Only the arrangement on screen is mounted, so only one of them steers the camera.
|
|
76
|
+
- **The camera fits the product, it does not use a fixed distance.** Both `fitRootPerspectiveCamera` instances leave `distance` out and set `fitToBox: true`. A `distance` overrides the fit, and the kettle is then as large on a 390-pixel phone as on a desktop.
|
|
77
|
+
- **Fullscreen** removes the column and the footer, so the free area, and the kettle with it, takes the whole canvas. The button sets the flag with `phx.frontend.useSetFullscreen()`; the layout reads it with `phx.frontend.useIsFullscreenActive()`. Like the built-in fullscreen button, it records `FrontendAnalyticsFactory.FullScreenModeToggled()` from `@salsita-ai/sdk/configurator` through `phx.frontend.useAnalytics().push()`, on entering and on leaving.
|
|
78
|
+
|
|
79
|
+
## Choices from the spec
|
|
80
|
+
|
|
81
|
+
The three choices are plain spec components on the root entity. The layout decides how they look: round swatches for the finish and the wood, a switch for the thermometer lid.
|
|
82
|
+
|
|
83
|
+
```yaml
|
|
84
|
+
components:
|
|
85
|
+
Kettle:
|
|
86
|
+
attributeSelection:
|
|
87
|
+
bodyFinish:
|
|
88
|
+
value:
|
|
89
|
+
$bind: bodyFinish
|
|
90
|
+
options:
|
|
91
|
+
- label: Brushed steel
|
|
92
|
+
description: Satin stainless that hides fingerprints
|
|
93
|
+
value: BrushedSteel
|
|
94
|
+
- label: Matte black
|
|
95
|
+
description: A soft powder coat
|
|
96
|
+
value: MatteBlack
|
|
97
|
+
- label: Copper
|
|
98
|
+
description: Lacquered copper, warm in the light
|
|
99
|
+
value: Copper
|
|
100
|
+
handleWood:
|
|
101
|
+
value:
|
|
102
|
+
$bind: handleWood
|
|
103
|
+
options:
|
|
104
|
+
- label: Walnut
|
|
105
|
+
description: Dark and oiled
|
|
106
|
+
value: Walnut
|
|
107
|
+
- label: Oak
|
|
108
|
+
description: Pale and matte
|
|
109
|
+
value: Oak
|
|
110
|
+
attributeSwitch:
|
|
111
|
+
thermometer:
|
|
112
|
+
value:
|
|
113
|
+
$bind: thermometer
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`SwatchRow` draws one `attributeSelection` with `phx.frontend.useAttributeSelection(kettleId, instanceName)`: a `radiogroup` of round buttons, the chosen option's `title` beside the label and its `description` below. The colours of the swatches are the layout's, keyed by the option `value`; the spec's `attributeSelection` carries no label either, so "Body finish" and "Handle" are the layout's text too. The arrow keys move the selection within a row.
|
|
117
|
+
|
|
118
|
+
An `attributeSwitch` is a boolean. `phx.frontend.useAttributeSwitch(kettleId, 'thermometer')` returns `state.value` and `onChange()`, which writes the opposite value, so it fits a switch directly:
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
import { Box, Switch, Typography } from '@mui/material'
|
|
122
|
+
|
|
123
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
124
|
+
import { KESTREL, LABEL_SX } from './tokens.js'
|
|
125
|
+
|
|
126
|
+
interface ThermometerRowProps {
|
|
127
|
+
readonly readOnly: boolean
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// The spec's `attributeSwitch` as a labelled switch: on, the lid carries a dial thermometer; off, a plain wooden knob
|
|
131
|
+
export const ThermometerRow = ({ readOnly }: ThermometerRowProps) => {
|
|
132
|
+
const kettleId = phx.frontend.useRootEntityId()
|
|
133
|
+
const thermometer = phx.frontend.useAttributeSwitch(kettleId, 'thermometer')
|
|
134
|
+
const isOn = thermometer.state.value
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<Box component="section" sx={{ display: 'grid', gap: 0.5, paddingBlock: 2 }}>
|
|
138
|
+
<Box component="div" sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 2 }}>
|
|
139
|
+
<Typography component="h3" id="kestrel-thermometer-label" sx={LABEL_SX}>
|
|
140
|
+
Thermometer lid
|
|
141
|
+
</Typography>
|
|
142
|
+
<Switch
|
|
143
|
+
checked={isOn}
|
|
144
|
+
disabled={readOnly || thermometer.disabled}
|
|
145
|
+
onChange={thermometer.onChange}
|
|
146
|
+
inputProps={{ 'aria-labelledby': 'kestrel-thermometer-label' }}
|
|
147
|
+
sx={{
|
|
148
|
+
'& .MuiSwitch-switchBase.Mui-checked': { color: KESTREL.oat },
|
|
149
|
+
'& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track': { bgcolor: KESTREL.copper, opacity: 1 },
|
|
150
|
+
'& .MuiSwitch-track': { bgcolor: KESTREL.hairline, opacity: 1 },
|
|
151
|
+
}}
|
|
152
|
+
/>
|
|
153
|
+
</Box>
|
|
154
|
+
<Typography sx={{ fontSize: 13, color: KESTREL.muted }}>
|
|
155
|
+
{isOn ? 'A dial in the lid shows when the water is ready to pour.' : 'A plain lid with a wooden knob.'}
|
|
156
|
+
</Typography>
|
|
157
|
+
</Box>
|
|
158
|
+
)
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The choices change the scene through the spec, not through the layout. A material override recolours the `Body` material from expressions in `src/expressions/kettle.ts`, which also add each choice's surcharge to `$price`, and the switch shows the dial or the knob:
|
|
163
|
+
|
|
164
|
+
```yaml
|
|
165
|
+
components:
|
|
166
|
+
Kettle:
|
|
167
|
+
sceneEntityObjectProperties:
|
|
168
|
+
knob:
|
|
169
|
+
visible:
|
|
170
|
+
$read: $plainKnob
|
|
171
|
+
thermometerDial:
|
|
172
|
+
visible:
|
|
173
|
+
$read: thermometer
|
|
174
|
+
sceneEntityLocalMaterialOverride:
|
|
175
|
+
body:
|
|
176
|
+
materialsToOverride: [Body]
|
|
177
|
+
materialType: physical
|
|
178
|
+
color:
|
|
179
|
+
$read: $bodyColor
|
|
180
|
+
metalness:
|
|
181
|
+
$read: $bodyMetalness
|
|
182
|
+
roughness:
|
|
183
|
+
$read: $bodyRoughness
|
|
184
|
+
clearcoat:
|
|
185
|
+
$read: $bodyClearcoat
|
|
186
|
+
clearcoatRoughness: 0.15
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## A rule between two choices
|
|
190
|
+
|
|
191
|
+
The copper body is sold only with the walnut handle. The rule is an invariant: its message and severity are in the spec, its condition in `src/invariants/kettle.ts`.
|
|
192
|
+
|
|
193
|
+
```yaml
|
|
194
|
+
invariants:
|
|
195
|
+
Kettle:
|
|
196
|
+
copperNeedsWalnut:
|
|
197
|
+
type: copperNeedsWalnut
|
|
198
|
+
severity: fixable
|
|
199
|
+
message: The copper body comes only with the walnut handle.
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
204
|
+
|
|
205
|
+
// The copper body is sold only with the walnut handle. The spec marks the violation `fixable`, so a change that breaks
|
|
206
|
+
// it is rejected and the built-in snackbar shows the spec's message.
|
|
207
|
+
export default phx.domain.implementCustomInvariants({
|
|
208
|
+
Kettle: {
|
|
209
|
+
copperNeedsWalnut: s => {
|
|
210
|
+
return s.bodyFinish !== 'Copper' || s.handleWood === 'Walnut'
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
})
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
The customer sees the rule twice:
|
|
217
|
+
|
|
218
|
+
- **Before choosing.** While the handle is oak, the control hook marks the copper option `disabled` with `hint` set to the invariant's message. `SwatchRow` fades the swatch, sets `aria-disabled` and shows the hint below the row; while the body is copper, the oak swatch is faded the same way.
|
|
219
|
+
- **After choosing anyway.** The faded swatch stays clickable and calls the option's `onSelect()`. A `fixable` violation rejects the change, the kettle keeps its finish, and `LayoutSlots.Services` raises the built-in snackbar "Kettle-1: The copper body comes only with the walnut handle." The built-in snackbar puts the entity id before the message.
|
|
220
|
+
|
|
221
|
+
The snackbars render where the layout mounts a root. On a desktop `LayoutSlots.DesktopSnackbarsRoot` is a zero-height element at the bottom left of the free area, and the snackbars stack upwards from it. On a phone `LayoutSlots.MobileSnackbarsRoot` leaves them fixed to the viewport; `PhonePage` places them below its top bar by styling `notistackSnackbarClasses.container` from `@salsita-ai/sdk/ui`. Mount the snackbars or `phx.frontend.useConfiguratorMessages()`, not both, see [Custom Layout → Show messages](?path=/docs/layouts-custom-layout--docs#show-messages) for the other way.
|
|
222
|
+
|
|
223
|
+
Passing the violation type to the hook's third argument, `fixableViolations`, does not enable the option: it only drops the violation from `hint`. A layout that wants the option clickable calls `onSelect()` on the disabled option, as `SwatchRow` does.
|
|
224
|
+
|
|
225
|
+
## Add to cart
|
|
226
|
+
|
|
227
|
+
The spec declares one finalize action. Its handler, `src/handlers/add-to-cart.ts`, stands in for the shop's cart: it waits, then enters the `added` navigation state.
|
|
228
|
+
|
|
229
|
+
```yaml
|
|
230
|
+
navigationStates:
|
|
231
|
+
- configure
|
|
232
|
+
- added
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
```yaml
|
|
236
|
+
components:
|
|
237
|
+
Kettle:
|
|
238
|
+
finalizeAction:
|
|
239
|
+
addToCart:
|
|
240
|
+
variant: primary
|
|
241
|
+
label: Add to cart
|
|
242
|
+
title: Add the kettle as configured to the cart
|
|
243
|
+
icon: ShoppingBag
|
|
244
|
+
handler: addToCart
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
import { useCallback } from 'react'
|
|
249
|
+
|
|
250
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
251
|
+
|
|
252
|
+
// Stands in for the shop's cart: adding takes a moment, then the page shows the confirmation
|
|
253
|
+
export default phx.frontend.createPhoenixHandler('addToCart', () => {
|
|
254
|
+
const navigate = phx.frontend.useNavigate()
|
|
255
|
+
|
|
256
|
+
return {
|
|
257
|
+
handler: useCallback(async () => {
|
|
258
|
+
await new Promise(resolve => setTimeout(resolve, 1200))
|
|
259
|
+
navigate('added')
|
|
260
|
+
}, [navigate]),
|
|
261
|
+
}
|
|
262
|
+
})
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
`CartBlock` shows the price from `phx.frontend.useRootEntityPrice()` and runs the action from `phx.frontend.useFinalizeActions().primary`. The hook runs the handler beside the layout, so the pending state survives the block unmounting, for example in fullscreen. In the `added` state the block confirms the purchase and **Make another** returns to `configure`; `KettleOptions` keeps the choices as they were added until then. A viewer of a shared configuration sees the price and no button, because neither hook checks read mode. `DesktopPage` keeps the block at the bottom of the column with `position: sticky`, so the button stays in view when a short window makes the column scroll.
|
|
266
|
+
|
|
267
|
+
```tsx
|
|
268
|
+
import { Alert, Box, Button, CircularProgress, Typography } from '@mui/material'
|
|
269
|
+
|
|
270
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
271
|
+
import { KESTREL } from './tokens.js'
|
|
272
|
+
|
|
273
|
+
const CHECK_ICON = 'M5 12.5 10 17.5 19 7'
|
|
274
|
+
|
|
275
|
+
// The price and the spec's `addToCart` finalize action. `useFinalizeActions` runs the action's handler beside the
|
|
276
|
+
// layout, so its pending state survives this block unmounting, as it does in fullscreen. The handler moves to the
|
|
277
|
+
// `added` navigation state, where the block confirms the purchase instead. A viewer sees the price only.
|
|
278
|
+
export const CartBlock = () => {
|
|
279
|
+
const price = phx.frontend.useRootEntityPrice()
|
|
280
|
+
const { primary, hints } = phx.frontend.useFinalizeActions()
|
|
281
|
+
const navigationState = phx.frontend.useActiveNavigationState()
|
|
282
|
+
const navigate = phx.frontend.useNavigate()
|
|
283
|
+
const { accessInfo } = phx.frontend.useAccessService()
|
|
284
|
+
const isPending = primary?.isPending ?? false
|
|
285
|
+
|
|
286
|
+
if (navigationState === 'added') {
|
|
287
|
+
return (
|
|
288
|
+
<Box component="div" role="status" sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
|
|
289
|
+
<Box
|
|
290
|
+
component="svg"
|
|
291
|
+
viewBox="0 0 24 24"
|
|
292
|
+
aria-hidden
|
|
293
|
+
sx={{ inlineSize: 40, blockSize: 40, flex: 'none', padding: 1, borderRadius: '50%', bgcolor: KESTREL.sage }}
|
|
294
|
+
>
|
|
295
|
+
<path d={CHECK_ICON} fill="none" stroke={KESTREL.oat} strokeWidth={2.4} strokeLinecap="round" />
|
|
296
|
+
</Box>
|
|
297
|
+
<Box component="div" sx={{ display: 'grid', flex: 1 }}>
|
|
298
|
+
<Typography sx={{ fontFamily: KESTREL.display, fontSize: 20, color: KESTREL.charcoal }}>
|
|
299
|
+
In your cart
|
|
300
|
+
</Typography>
|
|
301
|
+
<Typography sx={{ fontSize: 13, color: KESTREL.muted }}>Kestrel, {price}</Typography>
|
|
302
|
+
</Box>
|
|
303
|
+
<Button
|
|
304
|
+
onClick={() => navigate('configure')}
|
|
305
|
+
sx={{ textTransform: 'none', color: KESTREL.charcoal, textDecoration: 'underline', fontSize: 14 }}
|
|
306
|
+
>
|
|
307
|
+
Make another
|
|
308
|
+
</Button>
|
|
309
|
+
</Box>
|
|
310
|
+
)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const showButton = primary !== null && !accessInfo.viewMode
|
|
314
|
+
|
|
315
|
+
return (
|
|
316
|
+
<Box component="div" sx={{ display: 'grid', gap: 1.5 }}>
|
|
317
|
+
<Box component="div" sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 2 }}>
|
|
318
|
+
<Box component="div" sx={{ display: 'grid' }}>
|
|
319
|
+
<Typography sx={{ fontFamily: KESTREL.display, fontSize: 30, lineHeight: 1.1, color: KESTREL.charcoal }}>
|
|
320
|
+
{price}
|
|
321
|
+
</Typography>
|
|
322
|
+
<Typography sx={{ fontSize: 12, color: KESTREL.muted, whiteSpace: 'nowrap' }}>Ships in two days</Typography>
|
|
323
|
+
</Box>
|
|
324
|
+
{showButton && (
|
|
325
|
+
<Button
|
|
326
|
+
variant="contained"
|
|
327
|
+
disableElevation
|
|
328
|
+
disabled={primary.disabled || isPending}
|
|
329
|
+
onClick={() => void primary.run()}
|
|
330
|
+
title={primary.title}
|
|
331
|
+
startIcon={isPending ? <CircularProgress size={16} color="inherit" /> : undefined}
|
|
332
|
+
sx={{
|
|
333
|
+
minBlockSize: 52,
|
|
334
|
+
paddingInline: 4.5,
|
|
335
|
+
borderRadius: 999,
|
|
336
|
+
bgcolor: KESTREL.charcoal,
|
|
337
|
+
color: KESTREL.oat,
|
|
338
|
+
fontFamily: KESTREL.body,
|
|
339
|
+
fontSize: 15,
|
|
340
|
+
letterSpacing: '0.02em',
|
|
341
|
+
textTransform: 'none',
|
|
342
|
+
'&:hover': { bgcolor: '#000000' },
|
|
343
|
+
'&.Mui-disabled': { bgcolor: KESTREL.charcoal, color: KESTREL.oat, opacity: 0.55 },
|
|
344
|
+
}}
|
|
345
|
+
>
|
|
346
|
+
{isPending ? 'Adding…' : primary.label}
|
|
347
|
+
</Button>
|
|
348
|
+
)}
|
|
349
|
+
</Box>
|
|
350
|
+
{showButton && primary.disabled && hints && (
|
|
351
|
+
<Typography sx={{ fontSize: 13, color: KESTREL.muted }}>{hints}</Typography>
|
|
352
|
+
)}
|
|
353
|
+
{primary?.error && <Alert severity="error">The kettle could not be added: {primary.error.message}</Alert>}
|
|
354
|
+
</Box>
|
|
355
|
+
)
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
## The phone's start screen
|
|
360
|
+
|
|
361
|
+
`preview: auto` at the top of the spec asks for a start screen when the configurator's container is phone-sized. The built-in layout shows `MobilePreview`; a project layout shows its own while `phx.frontend.usePreview().isPreview` is set, and calls `enter()` to open the page. The poster frames the kettle in the area above its text with its own `useSceneSafeArea()`.
|
|
362
|
+
|
|
363
|
+
```yaml
|
|
364
|
+
preview: auto
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
The same layout in a frame 390 pixels wide, as on a phone. It opens on the start screen; **Start designing** opens the page, and the close button at the top left returns to the start screen. Opened on its own from the sidebar, the **Phone** story sets Storybook's viewport to 390 × 844.
|
|
368
|
+
|
|
369
|
+
```tsx
|
|
370
|
+
import { Box, Button, Typography } from '@mui/material'
|
|
371
|
+
|
|
372
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
373
|
+
import { KESTREL, LABEL_SX } from './tokens.js'
|
|
374
|
+
|
|
375
|
+
// The layout's own start screen, shown on a phone while `usePreview().isPreview` is set (the spec's `preview: auto`).
|
|
376
|
+
// It frames the kettle in the area above the text with its own safe area; `enter()` opens the page.
|
|
377
|
+
export const PhonePoster = () => {
|
|
378
|
+
const { containerRef, safeAreaRef } = phx.frontend.useSceneSafeArea()
|
|
379
|
+
const { enter } = phx.frontend.usePreview()
|
|
380
|
+
const price = phx.frontend.useRootEntityPrice()
|
|
381
|
+
|
|
382
|
+
return (
|
|
383
|
+
<Box
|
|
384
|
+
component="div"
|
|
385
|
+
ref={containerRef}
|
|
386
|
+
sx={{
|
|
387
|
+
position: 'absolute',
|
|
388
|
+
inset: 0,
|
|
389
|
+
display: 'flex',
|
|
390
|
+
flexDirection: 'column',
|
|
391
|
+
fontFamily: KESTREL.body,
|
|
392
|
+
pointerEvents: 'none',
|
|
393
|
+
}}
|
|
394
|
+
>
|
|
395
|
+
<Typography
|
|
396
|
+
sx={{
|
|
397
|
+
paddingBlockStart: 3,
|
|
398
|
+
textAlign: 'center',
|
|
399
|
+
fontFamily: KESTREL.display,
|
|
400
|
+
fontSize: 20,
|
|
401
|
+
color: KESTREL.charcoal,
|
|
402
|
+
}}
|
|
403
|
+
>
|
|
404
|
+
Aldermoor
|
|
405
|
+
</Typography>
|
|
406
|
+
<Box component="div" ref={safeAreaRef} sx={{ flex: '1 1 0', minBlockSize: 0, marginInline: 3 }} />
|
|
407
|
+
<Box component="div" sx={{ display: 'grid', gap: 2, padding: 3, paddingBlockEnd: 4, pointerEvents: 'auto' }}>
|
|
408
|
+
<Typography sx={{ ...LABEL_SX, color: KESTREL.copper }}>The Kestrel pour-over kettle</Typography>
|
|
409
|
+
<Typography
|
|
410
|
+
component="h1"
|
|
411
|
+
sx={{
|
|
412
|
+
fontFamily: KESTREL.display,
|
|
413
|
+
fontSize: 48,
|
|
414
|
+
lineHeight: 1,
|
|
415
|
+
letterSpacing: '-0.01em',
|
|
416
|
+
color: KESTREL.charcoal,
|
|
417
|
+
}}
|
|
418
|
+
>
|
|
419
|
+
Make it yours
|
|
420
|
+
</Typography>
|
|
421
|
+
<Typography sx={{ fontSize: 15, lineHeight: 1.6, color: KESTREL.muted }}>
|
|
422
|
+
Three finishes, two woods and a thermometer lid if you want one. As shown, {price}.
|
|
423
|
+
</Typography>
|
|
424
|
+
<Button
|
|
425
|
+
variant="contained"
|
|
426
|
+
disableElevation
|
|
427
|
+
onClick={enter}
|
|
428
|
+
sx={{
|
|
429
|
+
marginBlockStart: 1,
|
|
430
|
+
minBlockSize: 52,
|
|
431
|
+
borderRadius: 999,
|
|
432
|
+
bgcolor: KESTREL.charcoal,
|
|
433
|
+
color: KESTREL.oat,
|
|
434
|
+
fontFamily: KESTREL.body,
|
|
435
|
+
fontSize: 15,
|
|
436
|
+
textTransform: 'none',
|
|
437
|
+
'&:hover': { bgcolor: '#000000' },
|
|
438
|
+
}}
|
|
439
|
+
>
|
|
440
|
+
Start designing
|
|
441
|
+
</Button>
|
|
442
|
+
</Box>
|
|
443
|
+
</Box>
|
|
444
|
+
)
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
On a phone, `enter()` also expands the configurator, which `usePreview().isExpanded` reports. `PhonePage` offers one close button at the top left: the host's close action from `phx.frontend.useCloseAction()` when the integration provides one, otherwise `usePreview().leave()`, which returns to the start screen. Storybook provides no close action, so here the button returns to the start screen; with neither, the button is not shown.
|
|
449
|
+
|
|
450
|
+
## The shop's footer and the Powered by mark
|
|
451
|
+
|
|
452
|
+
`LayoutSlots.DesktopFooter` and `LayoutSlots.MobileFooter` render the project's `LayoutFooter` element, registered with `phx.frontend.createLayoutFooter`, and nothing when there is none. The desktop page mounts it in the footer strip, with `LayoutSlots.DesktopPoweredBy` at the strip's right end; the phone page mounts `MobileFooter` and `MobilePoweredBy` at the end of its column.
|
|
453
|
+
|
|
454
|
+
```tsx
|
|
455
|
+
import { Box } from '@mui/material'
|
|
456
|
+
|
|
457
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
458
|
+
import { KESTREL } from '../_shared/tokens.js'
|
|
459
|
+
|
|
460
|
+
const PROMISES = ['Free delivery over $75', 'Two-year warranty', '30-day returns']
|
|
461
|
+
|
|
462
|
+
// The shop's promises. `createLayoutFooter` registers it as the `LayoutFooter` element, which the layout shows where it
|
|
463
|
+
// mounts `LayoutSlots.DesktopFooter` or `LayoutSlots.MobileFooter`.
|
|
464
|
+
const LayoutFooter = () => {
|
|
465
|
+
return (
|
|
466
|
+
<Box
|
|
467
|
+
component="ul"
|
|
468
|
+
sx={{
|
|
469
|
+
display: 'flex',
|
|
470
|
+
flexWrap: 'wrap',
|
|
471
|
+
columnGap: 3,
|
|
472
|
+
rowGap: 0.5,
|
|
473
|
+
margin: 0,
|
|
474
|
+
padding: 0,
|
|
475
|
+
listStyle: 'none',
|
|
476
|
+
fontSize: 12,
|
|
477
|
+
letterSpacing: '0.04em',
|
|
478
|
+
color: KESTREL.muted,
|
|
479
|
+
}}
|
|
480
|
+
>
|
|
481
|
+
{PROMISES.map(promise => (
|
|
482
|
+
<Box
|
|
483
|
+
component="li"
|
|
484
|
+
key={promise}
|
|
485
|
+
sx={{ display: 'flex', alignItems: 'center', gap: 1, '&::before': { content: '"·"', color: KESTREL.sage } }}
|
|
486
|
+
>
|
|
487
|
+
{promise}
|
|
488
|
+
</Box>
|
|
489
|
+
))}
|
|
490
|
+
</Box>
|
|
491
|
+
)
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
export default phx.frontend.createLayoutFooter(LayoutFooter)
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
## Texts from the spec
|
|
498
|
+
|
|
499
|
+
The `detail` component holds the name, the subtitle and the story. Its fields are `Localizable`, not `string`. `ProductHeading` resolves the title and subtitle with `phx.frontend.useLocalizable()` and renders the description in place with `LocalizableMessage` from `@salsita-ai/sdk/react`; `SwatchRow` resolves a list of option titles with `phx.frontend.useResolveLocalizable()`. See [Localization](?path=/docs/phoenix-localization--docs).
|
|
500
|
+
|
|
501
|
+
```yaml
|
|
502
|
+
components:
|
|
503
|
+
Kettle:
|
|
504
|
+
detail:
|
|
505
|
+
main:
|
|
506
|
+
title: Kestrel
|
|
507
|
+
subtitle: Pour-over kettle, 0.9 litres
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
```tsx
|
|
511
|
+
import { Box, Typography } from '@mui/material'
|
|
512
|
+
|
|
513
|
+
import { detailComponent } from '@salsita-ai/sdk/domain'
|
|
514
|
+
import { LocalizableMessage } from '@salsita-ai/sdk/react'
|
|
515
|
+
|
|
516
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
517
|
+
import { KESTREL, LABEL_SX } from './tokens.js'
|
|
518
|
+
|
|
519
|
+
interface ProductHeadingProps {
|
|
520
|
+
readonly size: 'large' | 'small'
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// The overline, the name and the story from the spec's `detail` component. Its texts are `Localizable`:
|
|
524
|
+
// `useLocalizable` resolves one into a string and `LocalizableMessage` renders one in place.
|
|
525
|
+
export const ProductHeading = ({ size }: ProductHeadingProps) => {
|
|
526
|
+
const detail = phx.frontend.useFirstRootComponent(detailComponent)
|
|
527
|
+
const title = phx.frontend.useLocalizable(detail?.state.title)
|
|
528
|
+
const subtitle = phx.frontend.useLocalizable(detail?.state.subtitle)
|
|
529
|
+
|
|
530
|
+
return (
|
|
531
|
+
<Box component="header" sx={{ display: 'grid', gap: size === 'large' ? 2 : 1.5 }}>
|
|
532
|
+
<Typography sx={{ ...LABEL_SX, color: KESTREL.copper }}>Aldermoor Coffee</Typography>
|
|
533
|
+
<Box component="div" sx={{ display: 'grid', gap: 0.75 }}>
|
|
534
|
+
<Typography
|
|
535
|
+
component="h1"
|
|
536
|
+
sx={{
|
|
537
|
+
fontFamily: KESTREL.display,
|
|
538
|
+
fontSize: size === 'large' ? 60 : 40,
|
|
539
|
+
lineHeight: 1,
|
|
540
|
+
letterSpacing: '-0.01em',
|
|
541
|
+
color: KESTREL.charcoal,
|
|
542
|
+
}}
|
|
543
|
+
>
|
|
544
|
+
{title}
|
|
545
|
+
</Typography>
|
|
546
|
+
<Typography sx={{ fontFamily: KESTREL.body, fontSize: 15, color: KESTREL.muted }}>{subtitle}</Typography>
|
|
547
|
+
</Box>
|
|
548
|
+
<Typography sx={{ fontFamily: KESTREL.body, fontSize: 15, lineHeight: 1.65, color: KESTREL.charcoal }}>
|
|
549
|
+
<LocalizableMessage>{detail?.state.description}</LocalizableMessage>
|
|
550
|
+
</Typography>
|
|
551
|
+
</Box>
|
|
552
|
+
)
|
|
553
|
+
}
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
## The stage and the model
|
|
557
|
+
|
|
558
|
+
The spec's `canvasCustomEnvironment` names `KettleStudio`, a layout element rendered inside the scene. It paints the page's oat colour as the scene's background, so the scene and the column read as one surface, lights the kettle with drei's `Lightformer` panels, which show only in the reflections and need no image download, and grounds it with a `ContactShadows` plane just below its base. The scene is in millimetres.
|
|
559
|
+
|
|
560
|
+
```tsx
|
|
561
|
+
import { ContactShadows, Environment, Lightformer } from '@react-three/drei'
|
|
562
|
+
|
|
563
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
564
|
+
import { KESTREL } from '../_shared/tokens.js'
|
|
565
|
+
|
|
566
|
+
// The stage named by the spec's `canvasCustomEnvironment`: a backdrop, a soft shadow under the kettle and a studio of
|
|
567
|
+
// light panels. The panels exist only in the reflections, so the metal finishes have something to mirror and no image
|
|
568
|
+
// has to be downloaded. The scene is in millimetres.
|
|
569
|
+
export default phx.frontend.createCustomPhoenixLayoutElement('KettleStudio', () => {
|
|
570
|
+
return (
|
|
571
|
+
<>
|
|
572
|
+
{/* The page's oat background, so the scene and the layout read as one surface */}
|
|
573
|
+
<color attach="background" args={[KESTREL.oat]} />
|
|
574
|
+
<ambientLight intensity={0.35} />
|
|
575
|
+
<directionalLight position={[400, 900, 600]} intensity={1.1} />
|
|
576
|
+
|
|
577
|
+
<Environment resolution={256} frames={1}>
|
|
578
|
+
<color attach="background" args={['#77706a']} />
|
|
579
|
+
{/* A softbox above, tall strips at the sides for the long highlights, a warm fill behind, a dim one in front */}
|
|
580
|
+
<Lightformer form="rect" intensity={2.4} position={[0, 6, 0]} rotation-x={Math.PI / 2} scale={[10, 6, 1]} />
|
|
581
|
+
<Lightformer form="rect" intensity={3} position={[-6, 1, 2]} rotation-y={Math.PI / 2} scale={[1.2, 8, 1]} />
|
|
582
|
+
<Lightformer form="rect" intensity={1.6} position={[6, 1, 3]} rotation-y={-Math.PI / 2} scale={[1.2, 8, 1]} />
|
|
583
|
+
<Lightformer form="rect" color="#f3d9c2" intensity={1} position={[0, 1, -8]} scale={[12, 4, 1]} />
|
|
584
|
+
<Lightformer form="rect" intensity={0.8} position={[0, 0, 8]} rotation-y={Math.PI} scale={[10, 3, 1]} />
|
|
585
|
+
</Environment>
|
|
586
|
+
|
|
587
|
+
<ContactShadows position={[0, -1, 0]} scale={520} far={60} blur={2.2} opacity={0.7} resolution={512} />
|
|
588
|
+
</>
|
|
589
|
+
)
|
|
590
|
+
})
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
The kettle is `public/models/gallery/kettle.glb`, generated by `scripts/models/kettle.ts` in the Storybook package from three.js geometry: lathed body, lid, base ring and knob, a gooseneck spout and a flat handle swept along curves, and a dial with ticks and a needle. Each part is a named node the spec loads with `sceneEntityRemoteObject.<name>.objectName`; the parts that change with a choice carry the `Body` and `Handle` materials the overrides target. The script and its helper live in `scripts/models/`, outside the example's `src/`, because every file under `src/` is part of this page.
|
|
594
|
+
|
|
595
|
+
## Test cases
|
|
596
|
+
|
|
597
|
+
- The kettle stands on the left of the page, centred in the free area beside the column, with a soft shadow below it. The column shows "Aldermoor Coffee", **Kestrel**, the subtitle, the story, the three choices, **$175.00** and **Add to cart**; the footer strip shows the three promises and the Powered by mark.
|
|
598
|
+
- **Matte black** turns the body, lid and spout black and the price to $185.00; **Copper** turns them copper at $220.00. The chosen swatch has a ring and its name and description change.
|
|
599
|
+
- **Oak** turns the handle and, without the thermometer, the knob pale. The price drops by $10.
|
|
600
|
+
- With **Oak** chosen, the **Copper** swatch is faded and "The copper body comes only with the walnut handle." is shown below the finishes. Clicking it keeps the finish and shows the snackbar "Kettle-1: The copper body comes only with the walnut handle." at the bottom left of the free area.
|
|
601
|
+
- With **Copper** chosen, the **Oak** swatch is faded and the same sentence is shown below the handles.
|
|
602
|
+
- Turning **Thermometer lid** off replaces the dial with a wooden knob and lowers the price by $20; turning it on brings the dial back.
|
|
603
|
+
- Tab reaches the chosen swatch of each row, and the arrow keys move the selection, skipping a faded swatch.
|
|
604
|
+
- **Add to cart** shows a spinner and "Adding…" for about a second, then "In your cart" with the price; the choices cannot be changed until **Make another**, which brings the button back.
|
|
605
|
+
- **Fullscreen** removes the column and the footer, and the kettle moves to the centre of the canvas; **Exit fullscreen** brings both back.
|
|
606
|
+
- Clicking **Fullscreen** and **Exit fullscreen** each pushes the `fullscreenButton` user-action event, as an `AnalyticsService.push` line in the browser console shows with its Verbose level enabled: without a Google Tag Manager id, Storybook's analytics log their events with `console.debug`.
|
|
607
|
+
- In a window too short for the column, the column scrolls and the price with **Add to cart** stays at its bottom edge.
|
|
608
|
+
- Dragging in the free area turns the kettle.
|
|
609
|
+
- In the **Phone** story the start screen shows the kettle above "Make it yours" and **Start designing**. **Start designing** opens the page: the kettle at the top, the column below it and the price with **Add to cart** in a bar at the bottom of the screen.
|
|
610
|
+
- On the phone, the column scrolls under the kettle and ends with the promises and the Powered by mark; the bar with the price stays.
|
|
611
|
+
- On the phone, the snackbar of the copper rule appears below the top bar.
|
|
612
|
+
- On the phone, the close button at the top left returns to the start screen.
|
|
613
|
+
- The browser console shows no errors.
|
|
614
|
+
|
|
615
|
+
## What this layout leaves out
|
|
616
|
+
|
|
617
|
+
- **Undo and redo, sharing, measurements and the language switch.** The page has none of the toolbar's actions. A layout adds undo and redo with `phx.frontend.useUndoRedo()`, see [Configurator Interface → Hooks for a Project Layout](?path=/docs/phoenix-configurator-interface--docs#hooks-for-a-project-layout).
|
|
618
|
+
- **Read mode.** The layout hides **Add to cart** and makes the choices inert while `phx.frontend.useAccessService().accessInfo.viewMode` is set, but the example ships no read template; [Custom Layout → Serve read mode](?path=/docs/layouts-custom-layout--docs#serve-read-mode) shows one.
|
|
619
|
+
- **Messages in the layout's own UI.** The rejected change is a built-in snackbar; a layout that wants its own toast uses `phx.frontend.useConfiguratorMessages()` instead.
|
|
620
|
+
- **The built-in arrangement.** Header, sidebar, sidebar footer, tabs, tool controls, view controls and the built-in `DesktopPreview` and `MobilePreview` are not mounted; this page draws its own. [Layout Slots](?path=/docs/phoenix-layout-slots--docs) lists every slot a project layout can mount.
|
|
621
|
+
|
|
622
|
+
## Related pages
|
|
623
|
+
|
|
624
|
+
- [Custom Layout](?path=/docs/layouts-custom-layout--docs) explains a project layout step by step.
|
|
625
|
+
- [Configurator Interface → Hooks for a Project Layout](?path=/docs/phoenix-configurator-interface--docs#hooks-for-a-project-layout) lists every hook used here.
|
|
626
|
+
- [Layout Slots](?path=/docs/phoenix-layout-slots--docs) describes `Services`, the snackbar roots, the footers and the Powered by mark.
|
|
627
|
+
- [Preview / Auto](?path=/docs/layouts-preview-auto--docs) shows the built-in start screen that `preview: auto` opens.
|
|
628
|
+
|
|
629
|
+
## Complete Implementation
|
|
630
|
+
|
|
631
|
+
{/* AUTO-GENERATED SECTION: This section is automatically updated by 'phoenix story build' */}
|
|
632
|
+
|
|
633
|
+
<details>
|
|
634
|
+
<summary>Click to view the complete implementation files</summary>
|
|
635
|
+
|
|
636
|
+
### ./spec/domain.yaml
|
|
637
|
+
|
|
638
|
+
```yaml
|
|
639
|
+
preview: auto
|
|
640
|
+
|
|
641
|
+
model:
|
|
642
|
+
latest:
|
|
643
|
+
entityTypes:
|
|
644
|
+
- Kettle
|
|
645
|
+
aliases:
|
|
646
|
+
RootEntity:
|
|
647
|
+
- Kettle
|
|
648
|
+
commonTypes:
|
|
649
|
+
BodyFinish:
|
|
650
|
+
enum:
|
|
651
|
+
- BrushedSteel
|
|
652
|
+
- MatteBlack
|
|
653
|
+
- Copper
|
|
654
|
+
HandleWood:
|
|
655
|
+
enum:
|
|
656
|
+
- Walnut
|
|
657
|
+
- Oak
|
|
658
|
+
shapes:
|
|
659
|
+
Kettle:
|
|
660
|
+
bodyFinish:
|
|
661
|
+
$ref: '#/model/latest/commonTypes/BodyFinish'
|
|
662
|
+
handleWood:
|
|
663
|
+
$ref: '#/model/latest/commonTypes/HandleWood'
|
|
664
|
+
thermometer:
|
|
665
|
+
type: boolean
|
|
666
|
+
|
|
667
|
+
presets:
|
|
668
|
+
- rootEntityType: Kettle
|
|
669
|
+
initialDomainEntities:
|
|
670
|
+
- id: Kettle-1
|
|
671
|
+
type: Kettle
|
|
672
|
+
bodyFinish: BrushedSteel
|
|
673
|
+
handleWood: Walnut
|
|
674
|
+
thermometer: true
|
|
675
|
+
|
|
676
|
+
navigationStates:
|
|
677
|
+
- configure
|
|
678
|
+
- added
|
|
679
|
+
|
|
680
|
+
invariants:
|
|
681
|
+
Kettle:
|
|
682
|
+
copperNeedsWalnut:
|
|
683
|
+
type: copperNeedsWalnut
|
|
684
|
+
severity: fixable
|
|
685
|
+
message: The copper body comes only with the walnut handle.
|
|
686
|
+
|
|
687
|
+
components:
|
|
688
|
+
Kettle:
|
|
689
|
+
detail:
|
|
690
|
+
main:
|
|
691
|
+
title: Kestrel
|
|
692
|
+
subtitle: Pour-over kettle, 0.9 litres
|
|
693
|
+
description: A gooseneck kettle for slow, even pours. The spout narrows to a steady thread of water, and the dial in the lid tells you when it has cooled to brewing temperature.
|
|
694
|
+
price:
|
|
695
|
+
main:
|
|
696
|
+
price:
|
|
697
|
+
$read: $price
|
|
698
|
+
attributeSelection:
|
|
699
|
+
bodyFinish:
|
|
700
|
+
value:
|
|
701
|
+
$bind: bodyFinish
|
|
702
|
+
options:
|
|
703
|
+
- label: Brushed steel
|
|
704
|
+
description: Satin stainless that hides fingerprints
|
|
705
|
+
value: BrushedSteel
|
|
706
|
+
- label: Matte black
|
|
707
|
+
description: A soft powder coat
|
|
708
|
+
value: MatteBlack
|
|
709
|
+
- label: Copper
|
|
710
|
+
description: Lacquered copper, warm in the light
|
|
711
|
+
value: Copper
|
|
712
|
+
handleWood:
|
|
713
|
+
value:
|
|
714
|
+
$bind: handleWood
|
|
715
|
+
options:
|
|
716
|
+
- label: Walnut
|
|
717
|
+
description: Dark and oiled
|
|
718
|
+
value: Walnut
|
|
719
|
+
- label: Oak
|
|
720
|
+
description: Pale and matte
|
|
721
|
+
value: Oak
|
|
722
|
+
attributeSwitch:
|
|
723
|
+
thermometer:
|
|
724
|
+
value:
|
|
725
|
+
$bind: thermometer
|
|
726
|
+
finalizeAction:
|
|
727
|
+
addToCart:
|
|
728
|
+
variant: primary
|
|
729
|
+
label: Add to cart
|
|
730
|
+
title: Add the kettle as configured to the cart
|
|
731
|
+
icon: ShoppingBag
|
|
732
|
+
handler: addToCart
|
|
733
|
+
|
|
734
|
+
canvasConfig:
|
|
735
|
+
main:
|
|
736
|
+
highlightingDisabled: true
|
|
737
|
+
canvasCustomEnvironment:
|
|
738
|
+
main:
|
|
739
|
+
name: KettleStudio
|
|
740
|
+
fitRootPerspectiveCamera:
|
|
741
|
+
desktop:
|
|
742
|
+
priority: 2
|
|
743
|
+
fov: 30
|
|
744
|
+
near: 10
|
|
745
|
+
far: 5000
|
|
746
|
+
minDistance: 350
|
|
747
|
+
maxDistance: 1400
|
|
748
|
+
azimuthAngle: 0.35
|
|
749
|
+
polarAngle: 1.2
|
|
750
|
+
minPolarAngle: 0.5
|
|
751
|
+
maxPolarAngle: 1.5
|
|
752
|
+
fitToBox: true
|
|
753
|
+
fitMeshChanges: false
|
|
754
|
+
$filter:
|
|
755
|
+
viewports: [desktop]
|
|
756
|
+
phone:
|
|
757
|
+
priority: 1
|
|
758
|
+
fov: 30
|
|
759
|
+
near: 10
|
|
760
|
+
far: 5000
|
|
761
|
+
minDistance: 350
|
|
762
|
+
maxDistance: 1600
|
|
763
|
+
azimuthAngle: 0.35
|
|
764
|
+
polarAngle: 1.2
|
|
765
|
+
minPolarAngle: 0.5
|
|
766
|
+
maxPolarAngle: 1.5
|
|
767
|
+
fitToBox: true
|
|
768
|
+
fitMeshChanges: false
|
|
769
|
+
$filter:
|
|
770
|
+
viewports: [mobile]
|
|
771
|
+
|
|
772
|
+
sceneEntityRemoteObject:
|
|
773
|
+
body:
|
|
774
|
+
fileUrl: /models/gallery/kettle.glb
|
|
775
|
+
objectName: Body
|
|
776
|
+
dimensionUnit: m
|
|
777
|
+
lid:
|
|
778
|
+
fileUrl: /models/gallery/kettle.glb
|
|
779
|
+
objectName: Lid
|
|
780
|
+
dimensionUnit: m
|
|
781
|
+
spout:
|
|
782
|
+
fileUrl: /models/gallery/kettle.glb
|
|
783
|
+
objectName: Spout
|
|
784
|
+
dimensionUnit: m
|
|
785
|
+
baseRing:
|
|
786
|
+
fileUrl: /models/gallery/kettle.glb
|
|
787
|
+
objectName: BaseRing
|
|
788
|
+
dimensionUnit: m
|
|
789
|
+
handle:
|
|
790
|
+
fileUrl: /models/gallery/kettle.glb
|
|
791
|
+
objectName: Handle
|
|
792
|
+
dimensionUnit: m
|
|
793
|
+
handleCollars:
|
|
794
|
+
fileUrl: /models/gallery/kettle.glb
|
|
795
|
+
objectName: HandleCollars
|
|
796
|
+
dimensionUnit: m
|
|
797
|
+
knob:
|
|
798
|
+
fileUrl: /models/gallery/kettle.glb
|
|
799
|
+
objectName: Knob
|
|
800
|
+
dimensionUnit: m
|
|
801
|
+
thermometerDial:
|
|
802
|
+
fileUrl: /models/gallery/kettle.glb
|
|
803
|
+
objectName: ThermometerDial
|
|
804
|
+
dimensionUnit: m
|
|
805
|
+
dialFace:
|
|
806
|
+
fileUrl: /models/gallery/kettle.glb
|
|
807
|
+
objectName: DialFace
|
|
808
|
+
dimensionUnit: m
|
|
809
|
+
dialGlass:
|
|
810
|
+
fileUrl: /models/gallery/kettle.glb
|
|
811
|
+
objectName: DialGlass
|
|
812
|
+
dimensionUnit: m
|
|
813
|
+
sceneEntityObjectProperties:
|
|
814
|
+
knob:
|
|
815
|
+
visible:
|
|
816
|
+
$read: $plainKnob
|
|
817
|
+
thermometerDial:
|
|
818
|
+
visible:
|
|
819
|
+
$read: thermometer
|
|
820
|
+
dialFace:
|
|
821
|
+
visible:
|
|
822
|
+
$read: thermometer
|
|
823
|
+
dialGlass:
|
|
824
|
+
visible:
|
|
825
|
+
$read: thermometer
|
|
826
|
+
sceneEntityLocalMaterialOverride:
|
|
827
|
+
body:
|
|
828
|
+
materialsToOverride: [Body]
|
|
829
|
+
materialType: physical
|
|
830
|
+
color:
|
|
831
|
+
$read: $bodyColor
|
|
832
|
+
metalness:
|
|
833
|
+
$read: $bodyMetalness
|
|
834
|
+
roughness:
|
|
835
|
+
$read: $bodyRoughness
|
|
836
|
+
clearcoat:
|
|
837
|
+
$read: $bodyClearcoat
|
|
838
|
+
clearcoatRoughness: 0.15
|
|
839
|
+
handle:
|
|
840
|
+
materialsToOverride: [Handle]
|
|
841
|
+
color:
|
|
842
|
+
$read: $handleColor
|
|
843
|
+
metalness: 0
|
|
844
|
+
roughness: 0.58
|
|
845
|
+
glass:
|
|
846
|
+
materialsToOverride: [DialGlass]
|
|
847
|
+
materialType: physical
|
|
848
|
+
color: '#ffffff'
|
|
849
|
+
metalness: 0
|
|
850
|
+
roughness: 0.05
|
|
851
|
+
transparent: true
|
|
852
|
+
opacity: 0.18
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
### ./src/\_shared/CartBlock.tsx
|
|
856
|
+
|
|
857
|
+
```tsx
|
|
858
|
+
import { Alert, Box, Button, CircularProgress, Typography } from '@mui/material'
|
|
859
|
+
|
|
860
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
861
|
+
import { KESTREL } from './tokens.js'
|
|
862
|
+
|
|
863
|
+
const CHECK_ICON = 'M5 12.5 10 17.5 19 7'
|
|
864
|
+
|
|
865
|
+
// The price and the spec's `addToCart` finalize action. `useFinalizeActions` runs the action's handler beside the
|
|
866
|
+
// layout, so its pending state survives this block unmounting, as it does in fullscreen. The handler moves to the
|
|
867
|
+
// `added` navigation state, where the block confirms the purchase instead. A viewer sees the price only.
|
|
868
|
+
export const CartBlock = () => {
|
|
869
|
+
const price = phx.frontend.useRootEntityPrice()
|
|
870
|
+
const { primary, hints } = phx.frontend.useFinalizeActions()
|
|
871
|
+
const navigationState = phx.frontend.useActiveNavigationState()
|
|
872
|
+
const navigate = phx.frontend.useNavigate()
|
|
873
|
+
const { accessInfo } = phx.frontend.useAccessService()
|
|
874
|
+
const isPending = primary?.isPending ?? false
|
|
875
|
+
|
|
876
|
+
if (navigationState === 'added') {
|
|
877
|
+
return (
|
|
878
|
+
<Box component="div" role="status" sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
|
|
879
|
+
<Box
|
|
880
|
+
component="svg"
|
|
881
|
+
viewBox="0 0 24 24"
|
|
882
|
+
aria-hidden
|
|
883
|
+
sx={{ inlineSize: 40, blockSize: 40, flex: 'none', padding: 1, borderRadius: '50%', bgcolor: KESTREL.sage }}
|
|
884
|
+
>
|
|
885
|
+
<path d={CHECK_ICON} fill="none" stroke={KESTREL.oat} strokeWidth={2.4} strokeLinecap="round" />
|
|
886
|
+
</Box>
|
|
887
|
+
<Box component="div" sx={{ display: 'grid', flex: 1 }}>
|
|
888
|
+
<Typography sx={{ fontFamily: KESTREL.display, fontSize: 20, color: KESTREL.charcoal }}>
|
|
889
|
+
In your cart
|
|
890
|
+
</Typography>
|
|
891
|
+
<Typography sx={{ fontSize: 13, color: KESTREL.muted }}>Kestrel, {price}</Typography>
|
|
892
|
+
</Box>
|
|
893
|
+
<Button
|
|
894
|
+
onClick={() => navigate('configure')}
|
|
895
|
+
sx={{ textTransform: 'none', color: KESTREL.charcoal, textDecoration: 'underline', fontSize: 14 }}
|
|
896
|
+
>
|
|
897
|
+
Make another
|
|
898
|
+
</Button>
|
|
899
|
+
</Box>
|
|
900
|
+
)
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
const showButton = primary !== null && !accessInfo.viewMode
|
|
904
|
+
|
|
905
|
+
return (
|
|
906
|
+
<Box component="div" sx={{ display: 'grid', gap: 1.5 }}>
|
|
907
|
+
<Box component="div" sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 2 }}>
|
|
908
|
+
<Box component="div" sx={{ display: 'grid' }}>
|
|
909
|
+
<Typography sx={{ fontFamily: KESTREL.display, fontSize: 30, lineHeight: 1.1, color: KESTREL.charcoal }}>
|
|
910
|
+
{price}
|
|
911
|
+
</Typography>
|
|
912
|
+
<Typography sx={{ fontSize: 12, color: KESTREL.muted, whiteSpace: 'nowrap' }}>Ships in two days</Typography>
|
|
913
|
+
</Box>
|
|
914
|
+
{showButton && (
|
|
915
|
+
<Button
|
|
916
|
+
variant="contained"
|
|
917
|
+
disableElevation
|
|
918
|
+
disabled={primary.disabled || isPending}
|
|
919
|
+
onClick={() => void primary.run()}
|
|
920
|
+
title={primary.title}
|
|
921
|
+
startIcon={isPending ? <CircularProgress size={16} color="inherit" /> : undefined}
|
|
922
|
+
sx={{
|
|
923
|
+
minBlockSize: 52,
|
|
924
|
+
paddingInline: 4.5,
|
|
925
|
+
borderRadius: 999,
|
|
926
|
+
bgcolor: KESTREL.charcoal,
|
|
927
|
+
color: KESTREL.oat,
|
|
928
|
+
fontFamily: KESTREL.body,
|
|
929
|
+
fontSize: 15,
|
|
930
|
+
letterSpacing: '0.02em',
|
|
931
|
+
textTransform: 'none',
|
|
932
|
+
'&:hover': { bgcolor: '#000000' },
|
|
933
|
+
'&.Mui-disabled': { bgcolor: KESTREL.charcoal, color: KESTREL.oat, opacity: 0.55 },
|
|
934
|
+
}}
|
|
935
|
+
>
|
|
936
|
+
{isPending ? 'Adding…' : primary.label}
|
|
937
|
+
</Button>
|
|
938
|
+
)}
|
|
939
|
+
</Box>
|
|
940
|
+
{showButton && primary.disabled && hints && (
|
|
941
|
+
<Typography sx={{ fontSize: 13, color: KESTREL.muted }}>{hints}</Typography>
|
|
942
|
+
)}
|
|
943
|
+
{primary?.error && <Alert severity="error">The kettle could not be added: {primary.error.message}</Alert>}
|
|
944
|
+
</Box>
|
|
945
|
+
)
|
|
946
|
+
}
|
|
947
|
+
```
|
|
948
|
+
|
|
949
|
+
### ./src/\_shared/DesktopPage.tsx
|
|
950
|
+
|
|
951
|
+
```tsx
|
|
952
|
+
import { Box, Typography } from '@mui/material'
|
|
953
|
+
|
|
954
|
+
import { LayoutSlots } from '@salsita-ai/sdk/configurator'
|
|
955
|
+
|
|
956
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
957
|
+
import { CartBlock } from './CartBlock.js'
|
|
958
|
+
import { FullscreenButton } from './FullscreenButton.js'
|
|
959
|
+
import { KettleOptions } from './KettleOptions.js'
|
|
960
|
+
import { ProductHeading } from './ProductHeading.js'
|
|
961
|
+
import { KESTREL } from './tokens.js'
|
|
962
|
+
|
|
963
|
+
const COLUMN_WIDTH = 'clamp(380px, 38%, 520px)'
|
|
964
|
+
const FOOTER_HEIGHT = 52
|
|
965
|
+
const GUTTER = 32
|
|
966
|
+
|
|
967
|
+
// The desktop page: the kettle in the free area on the left, the product column on the right and the shop's footer
|
|
968
|
+
// strip below both. In fullscreen only the free area stays, so the camera frames the kettle in the whole canvas.
|
|
969
|
+
export const DesktopPage = () => {
|
|
970
|
+
const { containerRef, safeAreaRef } = phx.frontend.useSceneSafeArea()
|
|
971
|
+
const isFullscreen = phx.frontend.useIsFullscreenActive()
|
|
972
|
+
const { accessInfo } = phx.frontend.useAccessService()
|
|
973
|
+
|
|
974
|
+
return (
|
|
975
|
+
<Box
|
|
976
|
+
component="div"
|
|
977
|
+
ref={containerRef}
|
|
978
|
+
sx={{
|
|
979
|
+
position: 'absolute',
|
|
980
|
+
inset: 0,
|
|
981
|
+
display: 'grid',
|
|
982
|
+
gridTemplateColumns: isFullscreen ? 'minmax(0, 1fr)' : `minmax(0, 1fr) ${COLUMN_WIDTH}`,
|
|
983
|
+
gridTemplateRows: isFullscreen ? 'minmax(0, 1fr)' : `minmax(0, 1fr) ${FOOTER_HEIGHT}px`,
|
|
984
|
+
fontFamily: KESTREL.body,
|
|
985
|
+
// The free area lies over the canvas; only the controls in it take the pointer
|
|
986
|
+
pointerEvents: 'none',
|
|
987
|
+
}}
|
|
988
|
+
>
|
|
989
|
+
<Box component="div" sx={{ position: 'relative', minInlineSize: 0 }}>
|
|
990
|
+
{/* The camera fits the kettle into this box, so its inset is the breathing room around the kettle */}
|
|
991
|
+
<Box component="div" ref={safeAreaRef} sx={{ position: 'absolute', inset: '112px 72px 96px' }} />
|
|
992
|
+
<Box
|
|
993
|
+
component="div"
|
|
994
|
+
sx={{ position: 'absolute', insetBlockStart: GUTTER, insetInlineStart: GUTTER, display: 'grid' }}
|
|
995
|
+
>
|
|
996
|
+
<Typography sx={{ fontFamily: KESTREL.display, fontSize: 22, lineHeight: 1, color: KESTREL.charcoal }}>
|
|
997
|
+
Aldermoor
|
|
998
|
+
</Typography>
|
|
999
|
+
</Box>
|
|
1000
|
+
<Box
|
|
1001
|
+
component="div"
|
|
1002
|
+
sx={{ position: 'absolute', insetBlockStart: GUTTER - 8, insetInlineEnd: GUTTER, pointerEvents: 'auto' }}
|
|
1003
|
+
>
|
|
1004
|
+
<FullscreenButton />
|
|
1005
|
+
</Box>
|
|
1006
|
+
<Typography
|
|
1007
|
+
sx={{
|
|
1008
|
+
position: 'absolute',
|
|
1009
|
+
insetBlockEnd: GUTTER,
|
|
1010
|
+
insetInline: 0,
|
|
1011
|
+
textAlign: 'center',
|
|
1012
|
+
fontSize: 12,
|
|
1013
|
+
letterSpacing: '0.08em',
|
|
1014
|
+
color: KESTREL.muted,
|
|
1015
|
+
}}
|
|
1016
|
+
>
|
|
1017
|
+
Drag to turn the kettle
|
|
1018
|
+
</Typography>
|
|
1019
|
+
{/* The built-in snackbars stack upwards from this zero-height root, so it sits where their bottom edge goes */}
|
|
1020
|
+
<Box
|
|
1021
|
+
component="div"
|
|
1022
|
+
sx={{
|
|
1023
|
+
position: 'absolute',
|
|
1024
|
+
insetBlockEnd: GUTTER,
|
|
1025
|
+
insetInlineStart: GUTTER,
|
|
1026
|
+
inlineSize: 340,
|
|
1027
|
+
pointerEvents: 'auto',
|
|
1028
|
+
}}
|
|
1029
|
+
>
|
|
1030
|
+
<LayoutSlots.DesktopSnackbarsRoot />
|
|
1031
|
+
</Box>
|
|
1032
|
+
</Box>
|
|
1033
|
+
|
|
1034
|
+
{!isFullscreen && (
|
|
1035
|
+
<>
|
|
1036
|
+
<Box
|
|
1037
|
+
component="aside"
|
|
1038
|
+
aria-label="Kestrel kettle"
|
|
1039
|
+
sx={{
|
|
1040
|
+
display: 'flex',
|
|
1041
|
+
flexDirection: 'column',
|
|
1042
|
+
overflowY: 'auto',
|
|
1043
|
+
bgcolor: KESTREL.oat,
|
|
1044
|
+
borderInlineStart: `1px solid ${KESTREL.hairline}`,
|
|
1045
|
+
pointerEvents: 'auto',
|
|
1046
|
+
}}
|
|
1047
|
+
>
|
|
1048
|
+
{/* Centred while it fits, scrolling from the top once it does not */}
|
|
1049
|
+
<Box
|
|
1050
|
+
component="div"
|
|
1051
|
+
sx={{ display: 'grid', gap: 3.5, marginBlock: 'auto', paddingInline: 7, paddingBlockStart: 5 }}
|
|
1052
|
+
>
|
|
1053
|
+
<ProductHeading size="large" />
|
|
1054
|
+
<KettleOptions readOnly={accessInfo.viewMode} />
|
|
1055
|
+
{/* Below the choices while the column fits; at the column's bottom edge while it scrolls */}
|
|
1056
|
+
<Box
|
|
1057
|
+
component="div"
|
|
1058
|
+
sx={{
|
|
1059
|
+
position: 'sticky',
|
|
1060
|
+
insetBlockEnd: 0,
|
|
1061
|
+
marginBlockStart: -3.5,
|
|
1062
|
+
paddingBlock: 3,
|
|
1063
|
+
bgcolor: KESTREL.oat,
|
|
1064
|
+
borderBlockStart: `1px solid ${KESTREL.hairline}`,
|
|
1065
|
+
}}
|
|
1066
|
+
>
|
|
1067
|
+
<CartBlock />
|
|
1068
|
+
</Box>
|
|
1069
|
+
</Box>
|
|
1070
|
+
</Box>
|
|
1071
|
+
|
|
1072
|
+
<Box
|
|
1073
|
+
component="footer"
|
|
1074
|
+
sx={{
|
|
1075
|
+
gridColumn: '1 / -1',
|
|
1076
|
+
display: 'flex',
|
|
1077
|
+
alignItems: 'center',
|
|
1078
|
+
justifyContent: 'space-between',
|
|
1079
|
+
gap: 3,
|
|
1080
|
+
paddingInline: `${GUTTER}px`,
|
|
1081
|
+
bgcolor: KESTREL.oat,
|
|
1082
|
+
borderBlockStart: `1px solid ${KESTREL.hairline}`,
|
|
1083
|
+
pointerEvents: 'auto',
|
|
1084
|
+
}}
|
|
1085
|
+
>
|
|
1086
|
+
<LayoutSlots.DesktopFooter />
|
|
1087
|
+
<LayoutSlots.DesktopPoweredBy />
|
|
1088
|
+
</Box>
|
|
1089
|
+
</>
|
|
1090
|
+
)}
|
|
1091
|
+
</Box>
|
|
1092
|
+
)
|
|
1093
|
+
}
|
|
1094
|
+
```
|
|
1095
|
+
|
|
1096
|
+
### ./src/\_shared/FullscreenButton.tsx
|
|
1097
|
+
|
|
1098
|
+
```tsx
|
|
1099
|
+
import { IconButton, Tooltip } from '@mui/material'
|
|
1100
|
+
|
|
1101
|
+
import { FrontendAnalyticsFactory } from '@salsita-ai/sdk/configurator'
|
|
1102
|
+
|
|
1103
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
1104
|
+
import { KESTREL } from './tokens.js'
|
|
1105
|
+
|
|
1106
|
+
const ENTER_ICON = 'M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5'
|
|
1107
|
+
const EXIT_ICON = 'M9 4v5H4M15 4v5h5M15 20v-5h5M9 20v-5H4'
|
|
1108
|
+
|
|
1109
|
+
// Shows the kettle alone: the layout reads the flag and leaves out everything but the scene while it is set
|
|
1110
|
+
export const FullscreenButton = () => {
|
|
1111
|
+
const isFullscreen = phx.frontend.useIsFullscreenActive()
|
|
1112
|
+
const setFullscreen = phx.frontend.useSetFullscreen()
|
|
1113
|
+
const analytics = phx.frontend.useAnalytics()
|
|
1114
|
+
const label = isFullscreen ? 'Exit fullscreen' : 'Fullscreen'
|
|
1115
|
+
|
|
1116
|
+
// The same event the built-in fullscreen button records, for entering and for leaving
|
|
1117
|
+
const toggle = () => {
|
|
1118
|
+
analytics.push(FrontendAnalyticsFactory.FullScreenModeToggled())
|
|
1119
|
+
setFullscreen(!isFullscreen)
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
return (
|
|
1123
|
+
<Tooltip title={label}>
|
|
1124
|
+
<IconButton
|
|
1125
|
+
aria-label={label}
|
|
1126
|
+
onClick={toggle}
|
|
1127
|
+
sx={{
|
|
1128
|
+
inlineSize: 44,
|
|
1129
|
+
blockSize: 44,
|
|
1130
|
+
color: KESTREL.charcoal,
|
|
1131
|
+
border: `1px solid ${KESTREL.hairline}`,
|
|
1132
|
+
bgcolor: 'rgba(244, 239, 232, 0.8)',
|
|
1133
|
+
'&:hover': { bgcolor: KESTREL.oat },
|
|
1134
|
+
}}
|
|
1135
|
+
>
|
|
1136
|
+
<svg viewBox="0 0 24 24" width={18} height={18} fill="none" stroke="currentColor" strokeWidth={1.6}>
|
|
1137
|
+
<path d={isFullscreen ? EXIT_ICON : ENTER_ICON} />
|
|
1138
|
+
</svg>
|
|
1139
|
+
</IconButton>
|
|
1140
|
+
</Tooltip>
|
|
1141
|
+
)
|
|
1142
|
+
}
|
|
1143
|
+
```
|
|
1144
|
+
|
|
1145
|
+
### ./src/\_shared/KettleOptions.tsx
|
|
1146
|
+
|
|
1147
|
+
```tsx
|
|
1148
|
+
import { Box, Divider } from '@mui/material'
|
|
1149
|
+
|
|
1150
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
1151
|
+
import { SwatchRow } from './SwatchRow.js'
|
|
1152
|
+
import { ThermometerRow } from './ThermometerRow.js'
|
|
1153
|
+
import { KESTREL } from './tokens.js'
|
|
1154
|
+
|
|
1155
|
+
// The swatches' look, keyed by the option values of the spec
|
|
1156
|
+
const FINISH_FILLS = {
|
|
1157
|
+
BrushedSteel: 'linear-gradient(135deg, #f1f2f4 0%, #a9aeb4 55%, #dcdfe2 100%)',
|
|
1158
|
+
MatteBlack: 'linear-gradient(135deg, #4a4744 0%, #1f1d1b 100%)',
|
|
1159
|
+
Copper: 'linear-gradient(135deg, #f0b48a 0%, #b8693d 55%, #8a4a28 100%)',
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
const WOOD_FILLS = {
|
|
1163
|
+
Walnut: 'linear-gradient(135deg, #7a5238 0%, #4a2f1f 100%)',
|
|
1164
|
+
Oak: 'linear-gradient(135deg, #ead2ad 0%, #c49a6c 100%)',
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
interface KettleOptionsProps {
|
|
1168
|
+
readonly readOnly: boolean
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
// The three choices, in the order a buyer makes them. The spec's `attributeSelection` has no label, so the labels
|
|
1172
|
+
// are the layout's own. Once the kettle is in the cart the choices stay as they were added, until "Make another".
|
|
1173
|
+
export const KettleOptions = ({ readOnly }: KettleOptionsProps) => {
|
|
1174
|
+
const isAdded = phx.frontend.useActiveNavigationState() === 'added'
|
|
1175
|
+
const locked = readOnly || isAdded
|
|
1176
|
+
|
|
1177
|
+
return (
|
|
1178
|
+
<Box component="div" sx={{ display: 'grid' }}>
|
|
1179
|
+
<Divider sx={{ borderColor: KESTREL.hairline }} />
|
|
1180
|
+
<SwatchRow label="Body finish" instanceName="bodyFinish" fills={FINISH_FILLS} readOnly={locked} />
|
|
1181
|
+
<Divider sx={{ borderColor: KESTREL.hairline }} />
|
|
1182
|
+
<SwatchRow label="Handle" instanceName="handleWood" fills={WOOD_FILLS} readOnly={locked} />
|
|
1183
|
+
<Divider sx={{ borderColor: KESTREL.hairline }} />
|
|
1184
|
+
<ThermometerRow readOnly={locked} />
|
|
1185
|
+
</Box>
|
|
1186
|
+
)
|
|
1187
|
+
}
|
|
1188
|
+
```
|
|
1189
|
+
|
|
1190
|
+
### ./src/\_shared/PhonePage.tsx
|
|
1191
|
+
|
|
1192
|
+
```tsx
|
|
1193
|
+
import { Box, IconButton, Tooltip, Typography } from '@mui/material'
|
|
1194
|
+
|
|
1195
|
+
import { LayoutSlots } from '@salsita-ai/sdk/configurator'
|
|
1196
|
+
import { notistackSnackbarClasses } from '@salsita-ai/sdk/ui'
|
|
1197
|
+
|
|
1198
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
1199
|
+
import { CartBlock } from './CartBlock.js'
|
|
1200
|
+
import { FullscreenButton } from './FullscreenButton.js'
|
|
1201
|
+
import { KettleOptions } from './KettleOptions.js'
|
|
1202
|
+
import { ProductHeading } from './ProductHeading.js'
|
|
1203
|
+
import { KESTREL } from './tokens.js'
|
|
1204
|
+
|
|
1205
|
+
const CLOSE_ICON = 'M6 6l12 12M18 6 6 18'
|
|
1206
|
+
const GUTTER = 16
|
|
1207
|
+
const SCENE_HEIGHT = '44%'
|
|
1208
|
+
|
|
1209
|
+
// The phone page: the kettle at the top, then one column that scrolls below it, with the price and the button in a
|
|
1210
|
+
// bar that stays at the bottom. In fullscreen only the kettle stays.
|
|
1211
|
+
export const PhonePage = () => {
|
|
1212
|
+
const { containerRef, safeAreaRef } = phx.frontend.useSceneSafeArea()
|
|
1213
|
+
const isFullscreen = phx.frontend.useIsFullscreenActive()
|
|
1214
|
+
const { accessInfo } = phx.frontend.useAccessService()
|
|
1215
|
+
const closeAction = phx.frontend.useCloseAction()
|
|
1216
|
+
const { isExpanded, leave } = phx.frontend.usePreview()
|
|
1217
|
+
// The host's close action when it offers one; otherwise, once the start screen expanded the page, the way back to it
|
|
1218
|
+
const close = closeAction ? () => void closeAction() : isExpanded ? leave : null
|
|
1219
|
+
|
|
1220
|
+
return (
|
|
1221
|
+
<Box
|
|
1222
|
+
component="div"
|
|
1223
|
+
ref={containerRef}
|
|
1224
|
+
sx={{
|
|
1225
|
+
position: 'absolute',
|
|
1226
|
+
inset: 0,
|
|
1227
|
+
display: 'flex',
|
|
1228
|
+
flexDirection: 'column',
|
|
1229
|
+
fontFamily: KESTREL.body,
|
|
1230
|
+
pointerEvents: 'none',
|
|
1231
|
+
}}
|
|
1232
|
+
>
|
|
1233
|
+
<Box
|
|
1234
|
+
component="div"
|
|
1235
|
+
sx={{ position: 'relative', flex: isFullscreen ? '1 1 0' : `0 0 ${SCENE_HEIGHT}`, minBlockSize: 0 }}
|
|
1236
|
+
>
|
|
1237
|
+
{/* The camera fits the kettle into this box: below the top bar, clear of the screen's edges */}
|
|
1238
|
+
<Box
|
|
1239
|
+
component="div"
|
|
1240
|
+
ref={safeAreaRef}
|
|
1241
|
+
sx={{ position: 'absolute', inset: `${GUTTER + 52}px ${GUTTER}px ${GUTTER}px` }}
|
|
1242
|
+
/>
|
|
1243
|
+
<Box
|
|
1244
|
+
component="div"
|
|
1245
|
+
sx={{
|
|
1246
|
+
position: 'absolute',
|
|
1247
|
+
insetBlockStart: GUTTER,
|
|
1248
|
+
insetInline: GUTTER,
|
|
1249
|
+
display: 'grid',
|
|
1250
|
+
gridTemplateColumns: '44px 1fr 44px',
|
|
1251
|
+
alignItems: 'center',
|
|
1252
|
+
}}
|
|
1253
|
+
>
|
|
1254
|
+
{close ? (
|
|
1255
|
+
<Tooltip title="Close">
|
|
1256
|
+
<IconButton aria-label="Close" onClick={close} sx={{ color: KESTREL.charcoal, pointerEvents: 'auto' }}>
|
|
1257
|
+
<svg viewBox="0 0 24 24" width={20} height={20} fill="none" stroke="currentColor" strokeWidth={1.6}>
|
|
1258
|
+
<path d={CLOSE_ICON} />
|
|
1259
|
+
</svg>
|
|
1260
|
+
</IconButton>
|
|
1261
|
+
</Tooltip>
|
|
1262
|
+
) : (
|
|
1263
|
+
<span />
|
|
1264
|
+
)}
|
|
1265
|
+
<Typography sx={{ fontFamily: KESTREL.display, fontSize: 20, textAlign: 'center', color: KESTREL.charcoal }}>
|
|
1266
|
+
Aldermoor
|
|
1267
|
+
</Typography>
|
|
1268
|
+
<Box component="div" sx={{ pointerEvents: 'auto' }}>
|
|
1269
|
+
<FullscreenButton />
|
|
1270
|
+
</Box>
|
|
1271
|
+
</Box>
|
|
1272
|
+
{/* The phone root leaves the snackbars fixed to the viewport; here they drop in below the top bar instead */}
|
|
1273
|
+
<Box
|
|
1274
|
+
component="div"
|
|
1275
|
+
sx={{
|
|
1276
|
+
position: 'absolute',
|
|
1277
|
+
insetBlockStart: GUTTER + 56,
|
|
1278
|
+
insetInline: GUTTER,
|
|
1279
|
+
pointerEvents: 'auto',
|
|
1280
|
+
[`& .${notistackSnackbarClasses.container}`]: {
|
|
1281
|
+
position: 'absolute',
|
|
1282
|
+
inset: '0 0 auto 0',
|
|
1283
|
+
inlineSize: 'auto',
|
|
1284
|
+
transform: 'none',
|
|
1285
|
+
},
|
|
1286
|
+
}}
|
|
1287
|
+
>
|
|
1288
|
+
<LayoutSlots.MobileSnackbarsRoot />
|
|
1289
|
+
</Box>
|
|
1290
|
+
</Box>
|
|
1291
|
+
|
|
1292
|
+
{!isFullscreen && (
|
|
1293
|
+
<Box
|
|
1294
|
+
component="main"
|
|
1295
|
+
sx={{
|
|
1296
|
+
flex: '1 1 0',
|
|
1297
|
+
minBlockSize: 0,
|
|
1298
|
+
overflowY: 'auto',
|
|
1299
|
+
overscrollBehavior: 'contain',
|
|
1300
|
+
bgcolor: KESTREL.oat,
|
|
1301
|
+
borderBlockStart: `1px solid ${KESTREL.hairline}`,
|
|
1302
|
+
pointerEvents: 'auto',
|
|
1303
|
+
}}
|
|
1304
|
+
>
|
|
1305
|
+
<Box component="div" sx={{ display: 'grid', gap: 3, padding: 3, paddingBlockEnd: 4 }}>
|
|
1306
|
+
<ProductHeading size="small" />
|
|
1307
|
+
<KettleOptions readOnly={accessInfo.viewMode} />
|
|
1308
|
+
<Box
|
|
1309
|
+
component="div"
|
|
1310
|
+
sx={{
|
|
1311
|
+
display: 'grid',
|
|
1312
|
+
justifyItems: 'start',
|
|
1313
|
+
gap: 2,
|
|
1314
|
+
paddingBlockStart: 3,
|
|
1315
|
+
borderBlockStart: `1px solid ${KESTREL.hairline}`,
|
|
1316
|
+
}}
|
|
1317
|
+
>
|
|
1318
|
+
<LayoutSlots.MobileFooter />
|
|
1319
|
+
<LayoutSlots.MobilePoweredBy />
|
|
1320
|
+
</Box>
|
|
1321
|
+
</Box>
|
|
1322
|
+
<Box
|
|
1323
|
+
component="div"
|
|
1324
|
+
sx={{
|
|
1325
|
+
position: 'sticky',
|
|
1326
|
+
insetBlockEnd: 0,
|
|
1327
|
+
paddingInline: 3,
|
|
1328
|
+
paddingBlock: 2,
|
|
1329
|
+
bgcolor: KESTREL.oat,
|
|
1330
|
+
borderBlockStart: `1px solid ${KESTREL.hairline}`,
|
|
1331
|
+
}}
|
|
1332
|
+
>
|
|
1333
|
+
<CartBlock />
|
|
1334
|
+
</Box>
|
|
1335
|
+
</Box>
|
|
1336
|
+
)}
|
|
1337
|
+
</Box>
|
|
1338
|
+
)
|
|
1339
|
+
}
|
|
1340
|
+
```
|
|
1341
|
+
|
|
1342
|
+
### ./src/\_shared/PhonePoster.tsx
|
|
1343
|
+
|
|
1344
|
+
```tsx
|
|
1345
|
+
import { Box, Button, Typography } from '@mui/material'
|
|
1346
|
+
|
|
1347
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
1348
|
+
import { KESTREL, LABEL_SX } from './tokens.js'
|
|
1349
|
+
|
|
1350
|
+
// The layout's own start screen, shown on a phone while `usePreview().isPreview` is set (the spec's `preview: auto`).
|
|
1351
|
+
// It frames the kettle in the area above the text with its own safe area; `enter()` opens the page.
|
|
1352
|
+
export const PhonePoster = () => {
|
|
1353
|
+
const { containerRef, safeAreaRef } = phx.frontend.useSceneSafeArea()
|
|
1354
|
+
const { enter } = phx.frontend.usePreview()
|
|
1355
|
+
const price = phx.frontend.useRootEntityPrice()
|
|
1356
|
+
|
|
1357
|
+
return (
|
|
1358
|
+
<Box
|
|
1359
|
+
component="div"
|
|
1360
|
+
ref={containerRef}
|
|
1361
|
+
sx={{
|
|
1362
|
+
position: 'absolute',
|
|
1363
|
+
inset: 0,
|
|
1364
|
+
display: 'flex',
|
|
1365
|
+
flexDirection: 'column',
|
|
1366
|
+
fontFamily: KESTREL.body,
|
|
1367
|
+
pointerEvents: 'none',
|
|
1368
|
+
}}
|
|
1369
|
+
>
|
|
1370
|
+
<Typography
|
|
1371
|
+
sx={{
|
|
1372
|
+
paddingBlockStart: 3,
|
|
1373
|
+
textAlign: 'center',
|
|
1374
|
+
fontFamily: KESTREL.display,
|
|
1375
|
+
fontSize: 20,
|
|
1376
|
+
color: KESTREL.charcoal,
|
|
1377
|
+
}}
|
|
1378
|
+
>
|
|
1379
|
+
Aldermoor
|
|
1380
|
+
</Typography>
|
|
1381
|
+
<Box component="div" ref={safeAreaRef} sx={{ flex: '1 1 0', minBlockSize: 0, marginInline: 3 }} />
|
|
1382
|
+
<Box component="div" sx={{ display: 'grid', gap: 2, padding: 3, paddingBlockEnd: 4, pointerEvents: 'auto' }}>
|
|
1383
|
+
<Typography sx={{ ...LABEL_SX, color: KESTREL.copper }}>The Kestrel pour-over kettle</Typography>
|
|
1384
|
+
<Typography
|
|
1385
|
+
component="h1"
|
|
1386
|
+
sx={{
|
|
1387
|
+
fontFamily: KESTREL.display,
|
|
1388
|
+
fontSize: 48,
|
|
1389
|
+
lineHeight: 1,
|
|
1390
|
+
letterSpacing: '-0.01em',
|
|
1391
|
+
color: KESTREL.charcoal,
|
|
1392
|
+
}}
|
|
1393
|
+
>
|
|
1394
|
+
Make it yours
|
|
1395
|
+
</Typography>
|
|
1396
|
+
<Typography sx={{ fontSize: 15, lineHeight: 1.6, color: KESTREL.muted }}>
|
|
1397
|
+
Three finishes, two woods and a thermometer lid if you want one. As shown, {price}.
|
|
1398
|
+
</Typography>
|
|
1399
|
+
<Button
|
|
1400
|
+
variant="contained"
|
|
1401
|
+
disableElevation
|
|
1402
|
+
onClick={enter}
|
|
1403
|
+
sx={{
|
|
1404
|
+
marginBlockStart: 1,
|
|
1405
|
+
minBlockSize: 52,
|
|
1406
|
+
borderRadius: 999,
|
|
1407
|
+
bgcolor: KESTREL.charcoal,
|
|
1408
|
+
color: KESTREL.oat,
|
|
1409
|
+
fontFamily: KESTREL.body,
|
|
1410
|
+
fontSize: 15,
|
|
1411
|
+
textTransform: 'none',
|
|
1412
|
+
'&:hover': { bgcolor: '#000000' },
|
|
1413
|
+
}}
|
|
1414
|
+
>
|
|
1415
|
+
Start designing
|
|
1416
|
+
</Button>
|
|
1417
|
+
</Box>
|
|
1418
|
+
</Box>
|
|
1419
|
+
)
|
|
1420
|
+
}
|
|
1421
|
+
```
|
|
1422
|
+
|
|
1423
|
+
### ./src/\_shared/ProductHeading.tsx
|
|
1424
|
+
|
|
1425
|
+
```tsx
|
|
1426
|
+
import { Box, Typography } from '@mui/material'
|
|
1427
|
+
|
|
1428
|
+
import { detailComponent } from '@salsita-ai/sdk/domain'
|
|
1429
|
+
import { LocalizableMessage } from '@salsita-ai/sdk/react'
|
|
1430
|
+
|
|
1431
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
1432
|
+
import { KESTREL, LABEL_SX } from './tokens.js'
|
|
1433
|
+
|
|
1434
|
+
interface ProductHeadingProps {
|
|
1435
|
+
readonly size: 'large' | 'small'
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
// The overline, the name and the story from the spec's `detail` component. Its texts are `Localizable`:
|
|
1439
|
+
// `useLocalizable` resolves one into a string and `LocalizableMessage` renders one in place.
|
|
1440
|
+
export const ProductHeading = ({ size }: ProductHeadingProps) => {
|
|
1441
|
+
const detail = phx.frontend.useFirstRootComponent(detailComponent)
|
|
1442
|
+
const title = phx.frontend.useLocalizable(detail?.state.title)
|
|
1443
|
+
const subtitle = phx.frontend.useLocalizable(detail?.state.subtitle)
|
|
1444
|
+
|
|
1445
|
+
return (
|
|
1446
|
+
<Box component="header" sx={{ display: 'grid', gap: size === 'large' ? 2 : 1.5 }}>
|
|
1447
|
+
<Typography sx={{ ...LABEL_SX, color: KESTREL.copper }}>Aldermoor Coffee</Typography>
|
|
1448
|
+
<Box component="div" sx={{ display: 'grid', gap: 0.75 }}>
|
|
1449
|
+
<Typography
|
|
1450
|
+
component="h1"
|
|
1451
|
+
sx={{
|
|
1452
|
+
fontFamily: KESTREL.display,
|
|
1453
|
+
fontSize: size === 'large' ? 60 : 40,
|
|
1454
|
+
lineHeight: 1,
|
|
1455
|
+
letterSpacing: '-0.01em',
|
|
1456
|
+
color: KESTREL.charcoal,
|
|
1457
|
+
}}
|
|
1458
|
+
>
|
|
1459
|
+
{title}
|
|
1460
|
+
</Typography>
|
|
1461
|
+
<Typography sx={{ fontFamily: KESTREL.body, fontSize: 15, color: KESTREL.muted }}>{subtitle}</Typography>
|
|
1462
|
+
</Box>
|
|
1463
|
+
<Typography sx={{ fontFamily: KESTREL.body, fontSize: 15, lineHeight: 1.65, color: KESTREL.charcoal }}>
|
|
1464
|
+
<LocalizableMessage>{detail?.state.description}</LocalizableMessage>
|
|
1465
|
+
</Typography>
|
|
1466
|
+
</Box>
|
|
1467
|
+
)
|
|
1468
|
+
}
|
|
1469
|
+
```
|
|
1470
|
+
|
|
1471
|
+
### ./src/\_shared/SwatchRow.tsx
|
|
1472
|
+
|
|
1473
|
+
```tsx
|
|
1474
|
+
import { Box, ButtonBase, Typography } from '@mui/material'
|
|
1475
|
+
import type { KeyboardEvent } from 'react'
|
|
1476
|
+
|
|
1477
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
1478
|
+
import { KESTREL, LABEL_SX } from './tokens.js'
|
|
1479
|
+
|
|
1480
|
+
// Arrow keys move the selection between the swatches, as in a native radio group
|
|
1481
|
+
const ARROW_STEPS: Readonly<Record<string, number | undefined>> = {
|
|
1482
|
+
ArrowRight: 1,
|
|
1483
|
+
ArrowDown: 1,
|
|
1484
|
+
ArrowLeft: -1,
|
|
1485
|
+
ArrowUp: -1,
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
interface SwatchRowProps {
|
|
1489
|
+
readonly label: string
|
|
1490
|
+
readonly instanceName: string
|
|
1491
|
+
// How each option looks, keyed by the spec's option values: a CSS background
|
|
1492
|
+
readonly fills: Readonly<Record<string, string>>
|
|
1493
|
+
readonly readOnly: boolean
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
// One `attributeSelection` of the spec as a row of round swatches, with the chosen option's name and description.
|
|
1497
|
+
// An option the spec's invariants rule out is `disabled`: it is drawn faded and its hint says why, but it can still be
|
|
1498
|
+
// clicked. Its `onSelect` then makes the change, which the invariant rejects, and the built-in snackbar repeats the
|
|
1499
|
+
// reason. The arrow keys skip it.
|
|
1500
|
+
export const SwatchRow = ({ label, instanceName, fills, readOnly }: SwatchRowProps) => {
|
|
1501
|
+
const resolve = phx.frontend.useResolveLocalizable()
|
|
1502
|
+
const kettleId = phx.frontend.useRootEntityId()
|
|
1503
|
+
const { value, options } = phx.frontend.useAttributeSelection(kettleId, instanceName)
|
|
1504
|
+
const selected = options.find(option => option.value === value)
|
|
1505
|
+
const hint = options.find(option => option.disabled && option.hint)?.hint
|
|
1506
|
+
|
|
1507
|
+
const handleKeyDown = (event: KeyboardEvent<HTMLElement>, index: number) => {
|
|
1508
|
+
const step = ARROW_STEPS[event.key]
|
|
1509
|
+
|
|
1510
|
+
if (step === undefined) {
|
|
1511
|
+
return
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
event.preventDefault()
|
|
1515
|
+
// The next enabled option in the arrow's direction, wrapping around
|
|
1516
|
+
const count = options.length
|
|
1517
|
+
const next = Array.from(
|
|
1518
|
+
{ length: count - 1 },
|
|
1519
|
+
(_, offset) => (((index + step * (offset + 1)) % count) + count) % count
|
|
1520
|
+
).find(candidate => !options[candidate]?.disabled)
|
|
1521
|
+
|
|
1522
|
+
if (next === undefined) {
|
|
1523
|
+
return
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
options[next]?.onSelect()
|
|
1527
|
+
event.currentTarget.parentElement?.querySelectorAll<HTMLElement>('[role="radio"]')[next]?.focus()
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
return (
|
|
1531
|
+
<Box component="section" sx={{ display: 'grid', gap: 1.5, paddingBlock: 2 }}>
|
|
1532
|
+
<Box component="div" sx={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 2 }}>
|
|
1533
|
+
<Typography component="h3" sx={LABEL_SX}>
|
|
1534
|
+
{label}
|
|
1535
|
+
</Typography>
|
|
1536
|
+
<Typography sx={{ fontFamily: KESTREL.display, fontSize: 18, color: KESTREL.charcoal }}>
|
|
1537
|
+
{resolve(selected?.title)}
|
|
1538
|
+
</Typography>
|
|
1539
|
+
</Box>
|
|
1540
|
+
|
|
1541
|
+
<Box component="div" role="radiogroup" aria-label={label} sx={{ display: 'flex', gap: 1.5 }}>
|
|
1542
|
+
{options.map((option, index) => {
|
|
1543
|
+
const isSelected = option.value === value
|
|
1544
|
+
const title = resolve(option.title)
|
|
1545
|
+
|
|
1546
|
+
return (
|
|
1547
|
+
<ButtonBase
|
|
1548
|
+
key={String(option.value)}
|
|
1549
|
+
role="radio"
|
|
1550
|
+
aria-checked={isSelected}
|
|
1551
|
+
aria-label={title}
|
|
1552
|
+
title={option.hint ?? title}
|
|
1553
|
+
aria-disabled={option.disabled}
|
|
1554
|
+
tabIndex={isSelected ? 0 : -1}
|
|
1555
|
+
disabled={readOnly}
|
|
1556
|
+
onClick={option.onSelect}
|
|
1557
|
+
onKeyDown={event => handleKeyDown(event, index)}
|
|
1558
|
+
sx={{
|
|
1559
|
+
inlineSize: 40,
|
|
1560
|
+
blockSize: 40,
|
|
1561
|
+
borderRadius: '50%',
|
|
1562
|
+
background: fills[String(option.value)],
|
|
1563
|
+
// A ring of the page's colour between the swatch and the outline of the chosen one
|
|
1564
|
+
boxShadow: isSelected
|
|
1565
|
+
? `0 0 0 3px ${KESTREL.oat}, 0 0 0 4px ${KESTREL.charcoal}`
|
|
1566
|
+
: `inset 0 0 0 1px ${KESTREL.hairline}`,
|
|
1567
|
+
transition: 'box-shadow 160ms, transform 160ms',
|
|
1568
|
+
opacity: option.disabled ? 0.3 : 1,
|
|
1569
|
+
'&:hover': { transform: isSelected || option.disabled ? 'none' : 'scale(1.06)' },
|
|
1570
|
+
'&.Mui-focusVisible': { outline: `2px solid ${KESTREL.copper}`, outlineOffset: 6 },
|
|
1571
|
+
// A viewer sees the chosen swatch only as chosen; the others fade
|
|
1572
|
+
'&.Mui-disabled': { opacity: isSelected ? 1 : 0.3 },
|
|
1573
|
+
}}
|
|
1574
|
+
/>
|
|
1575
|
+
)
|
|
1576
|
+
})}
|
|
1577
|
+
</Box>
|
|
1578
|
+
|
|
1579
|
+
<Typography sx={{ fontSize: 13, color: KESTREL.muted }}>
|
|
1580
|
+
{hint && !readOnly ? hint : resolve(selected?.description)}
|
|
1581
|
+
</Typography>
|
|
1582
|
+
</Box>
|
|
1583
|
+
)
|
|
1584
|
+
}
|
|
1585
|
+
```
|
|
1586
|
+
|
|
1587
|
+
### ./src/\_shared/ThermometerRow.tsx
|
|
1588
|
+
|
|
1589
|
+
```tsx
|
|
1590
|
+
import { Box, Switch, Typography } from '@mui/material'
|
|
1591
|
+
|
|
1592
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
1593
|
+
import { KESTREL, LABEL_SX } from './tokens.js'
|
|
1594
|
+
|
|
1595
|
+
interface ThermometerRowProps {
|
|
1596
|
+
readonly readOnly: boolean
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
// The spec's `attributeSwitch` as a labelled switch: on, the lid carries a dial thermometer; off, a plain wooden knob
|
|
1600
|
+
export const ThermometerRow = ({ readOnly }: ThermometerRowProps) => {
|
|
1601
|
+
const kettleId = phx.frontend.useRootEntityId()
|
|
1602
|
+
const thermometer = phx.frontend.useAttributeSwitch(kettleId, 'thermometer')
|
|
1603
|
+
const isOn = thermometer.state.value
|
|
1604
|
+
|
|
1605
|
+
return (
|
|
1606
|
+
<Box component="section" sx={{ display: 'grid', gap: 0.5, paddingBlock: 2 }}>
|
|
1607
|
+
<Box component="div" sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 2 }}>
|
|
1608
|
+
<Typography component="h3" id="kestrel-thermometer-label" sx={LABEL_SX}>
|
|
1609
|
+
Thermometer lid
|
|
1610
|
+
</Typography>
|
|
1611
|
+
<Switch
|
|
1612
|
+
checked={isOn}
|
|
1613
|
+
disabled={readOnly || thermometer.disabled}
|
|
1614
|
+
onChange={thermometer.onChange}
|
|
1615
|
+
inputProps={{ 'aria-labelledby': 'kestrel-thermometer-label' }}
|
|
1616
|
+
sx={{
|
|
1617
|
+
'& .MuiSwitch-switchBase.Mui-checked': { color: KESTREL.oat },
|
|
1618
|
+
'& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track': { bgcolor: KESTREL.copper, opacity: 1 },
|
|
1619
|
+
'& .MuiSwitch-track': { bgcolor: KESTREL.hairline, opacity: 1 },
|
|
1620
|
+
}}
|
|
1621
|
+
/>
|
|
1622
|
+
</Box>
|
|
1623
|
+
<Typography sx={{ fontSize: 13, color: KESTREL.muted }}>
|
|
1624
|
+
{isOn ? 'A dial in the lid shows when the water is ready to pour.' : 'A plain lid with a wooden knob.'}
|
|
1625
|
+
</Typography>
|
|
1626
|
+
</Box>
|
|
1627
|
+
)
|
|
1628
|
+
}
|
|
1629
|
+
```
|
|
1630
|
+
|
|
1631
|
+
### ./src/\_shared/tokens.ts
|
|
1632
|
+
|
|
1633
|
+
```ts
|
|
1634
|
+
// The brand's palette and type. Playfair Display and Circular Std are the fonts the brand ships; the stacks fall back
|
|
1635
|
+
// to system fonts where they are not loaded.
|
|
1636
|
+
export const KESTREL = {
|
|
1637
|
+
oat: '#f4efe8',
|
|
1638
|
+
charcoal: '#1f1d1b',
|
|
1639
|
+
copper: '#b8693d',
|
|
1640
|
+
sage: '#9daa94',
|
|
1641
|
+
muted: 'rgba(31, 29, 27, 0.62)',
|
|
1642
|
+
hairline: 'rgba(31, 29, 27, 0.12)',
|
|
1643
|
+
display: "'PlayfairDisplay-Regular', 'Playfair Display', Georgia, serif",
|
|
1644
|
+
body: "'Circular-Std-Book', 'Helvetica Neue', Arial, sans-serif",
|
|
1645
|
+
} as const
|
|
1646
|
+
|
|
1647
|
+
// Small capitals with wide tracking, for the overline and the option labels
|
|
1648
|
+
export const LABEL_SX = {
|
|
1649
|
+
fontFamily: KESTREL.body,
|
|
1650
|
+
fontSize: 11,
|
|
1651
|
+
letterSpacing: '0.18em',
|
|
1652
|
+
textTransform: 'uppercase',
|
|
1653
|
+
color: KESTREL.muted,
|
|
1654
|
+
} as const
|
|
1655
|
+
```
|
|
1656
|
+
|
|
1657
|
+
### ./src/elements/ConfiguratorLayout.tsx
|
|
1658
|
+
|
|
1659
|
+
```tsx
|
|
1660
|
+
import { Box } from '@mui/material'
|
|
1661
|
+
|
|
1662
|
+
import { LayoutSlots } from '@salsita-ai/sdk/configurator'
|
|
1663
|
+
|
|
1664
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
1665
|
+
import { DesktopPage } from '../_shared/DesktopPage.js'
|
|
1666
|
+
import { PhonePage } from '../_shared/PhonePage.js'
|
|
1667
|
+
import { PhonePoster } from '../_shared/PhonePoster.js'
|
|
1668
|
+
import { KESTREL } from '../_shared/tokens.js'
|
|
1669
|
+
|
|
1670
|
+
// One page, no steps or tabs. The canvas and the services stay mounted the whole time; what lies over the canvas is
|
|
1671
|
+
// the phone's start screen, the phone page or the desktop page. Each calls `useSceneSafeArea` itself, so only the one
|
|
1672
|
+
// on screen tells the camera where the kettle goes.
|
|
1673
|
+
const ConfiguratorLayout = () => {
|
|
1674
|
+
// `null` until the container has been measured; only the scene shows until then
|
|
1675
|
+
const viewports = phx.frontend.useActiveViewports()
|
|
1676
|
+
const { isPreview } = phx.frontend.usePreview()
|
|
1677
|
+
const isDesktop = viewports?.includes('desktop') ?? false
|
|
1678
|
+
|
|
1679
|
+
return (
|
|
1680
|
+
<Box component="div" sx={{ position: 'absolute', inset: 0, overflow: 'clip', bgcolor: KESTREL.oat }}>
|
|
1681
|
+
<LayoutSlots.Services />
|
|
1682
|
+
<LayoutSlots.SharedCanvas />
|
|
1683
|
+
{viewports !== null && (isPreview ? <PhonePoster /> : isDesktop ? <DesktopPage /> : <PhonePage />)}
|
|
1684
|
+
</Box>
|
|
1685
|
+
)
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
export default phx.frontend.createCustomPhoenixLayoutElement('ConfiguratorLayout', ConfiguratorLayout)
|
|
1689
|
+
```
|
|
1690
|
+
|
|
1691
|
+
### ./src/elements/KettleStudio.tsx
|
|
1692
|
+
|
|
1693
|
+
```tsx
|
|
1694
|
+
import { ContactShadows, Environment, Lightformer } from '@react-three/drei'
|
|
1695
|
+
|
|
1696
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
1697
|
+
import { KESTREL } from '../_shared/tokens.js'
|
|
1698
|
+
|
|
1699
|
+
// The stage named by the spec's `canvasCustomEnvironment`: a backdrop, a soft shadow under the kettle and a studio of
|
|
1700
|
+
// light panels. The panels exist only in the reflections, so the metal finishes have something to mirror and no image
|
|
1701
|
+
// has to be downloaded. The scene is in millimetres.
|
|
1702
|
+
export default phx.frontend.createCustomPhoenixLayoutElement('KettleStudio', () => {
|
|
1703
|
+
return (
|
|
1704
|
+
<>
|
|
1705
|
+
{/* The page's oat background, so the scene and the layout read as one surface */}
|
|
1706
|
+
<color attach="background" args={[KESTREL.oat]} />
|
|
1707
|
+
<ambientLight intensity={0.35} />
|
|
1708
|
+
<directionalLight position={[400, 900, 600]} intensity={1.1} />
|
|
1709
|
+
|
|
1710
|
+
<Environment resolution={256} frames={1}>
|
|
1711
|
+
<color attach="background" args={['#77706a']} />
|
|
1712
|
+
{/* A softbox above, tall strips at the sides for the long highlights, a warm fill behind, a dim one in front */}
|
|
1713
|
+
<Lightformer form="rect" intensity={2.4} position={[0, 6, 0]} rotation-x={Math.PI / 2} scale={[10, 6, 1]} />
|
|
1714
|
+
<Lightformer form="rect" intensity={3} position={[-6, 1, 2]} rotation-y={Math.PI / 2} scale={[1.2, 8, 1]} />
|
|
1715
|
+
<Lightformer form="rect" intensity={1.6} position={[6, 1, 3]} rotation-y={-Math.PI / 2} scale={[1.2, 8, 1]} />
|
|
1716
|
+
<Lightformer form="rect" color="#f3d9c2" intensity={1} position={[0, 1, -8]} scale={[12, 4, 1]} />
|
|
1717
|
+
<Lightformer form="rect" intensity={0.8} position={[0, 0, 8]} rotation-y={Math.PI} scale={[10, 3, 1]} />
|
|
1718
|
+
</Environment>
|
|
1719
|
+
|
|
1720
|
+
<ContactShadows position={[0, -1, 0]} scale={520} far={60} blur={2.2} opacity={0.7} resolution={512} />
|
|
1721
|
+
</>
|
|
1722
|
+
)
|
|
1723
|
+
})
|
|
1724
|
+
```
|
|
1725
|
+
|
|
1726
|
+
### ./src/elements/LayoutFooter.tsx
|
|
1727
|
+
|
|
1728
|
+
```tsx
|
|
1729
|
+
import { Box } from '@mui/material'
|
|
1730
|
+
|
|
1731
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
1732
|
+
import { KESTREL } from '../_shared/tokens.js'
|
|
1733
|
+
|
|
1734
|
+
const PROMISES = ['Free delivery over $75', 'Two-year warranty', '30-day returns']
|
|
1735
|
+
|
|
1736
|
+
// The shop's promises. `createLayoutFooter` registers it as the `LayoutFooter` element, which the layout shows where it
|
|
1737
|
+
// mounts `LayoutSlots.DesktopFooter` or `LayoutSlots.MobileFooter`.
|
|
1738
|
+
const LayoutFooter = () => {
|
|
1739
|
+
return (
|
|
1740
|
+
<Box
|
|
1741
|
+
component="ul"
|
|
1742
|
+
sx={{
|
|
1743
|
+
display: 'flex',
|
|
1744
|
+
flexWrap: 'wrap',
|
|
1745
|
+
columnGap: 3,
|
|
1746
|
+
rowGap: 0.5,
|
|
1747
|
+
margin: 0,
|
|
1748
|
+
padding: 0,
|
|
1749
|
+
listStyle: 'none',
|
|
1750
|
+
fontSize: 12,
|
|
1751
|
+
letterSpacing: '0.04em',
|
|
1752
|
+
color: KESTREL.muted,
|
|
1753
|
+
}}
|
|
1754
|
+
>
|
|
1755
|
+
{PROMISES.map(promise => (
|
|
1756
|
+
<Box
|
|
1757
|
+
component="li"
|
|
1758
|
+
key={promise}
|
|
1759
|
+
sx={{ display: 'flex', alignItems: 'center', gap: 1, '&::before': { content: '"·"', color: KESTREL.sage } }}
|
|
1760
|
+
>
|
|
1761
|
+
{promise}
|
|
1762
|
+
</Box>
|
|
1763
|
+
))}
|
|
1764
|
+
</Box>
|
|
1765
|
+
)
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
export default phx.frontend.createLayoutFooter(LayoutFooter)
|
|
1769
|
+
```
|
|
1770
|
+
|
|
1771
|
+
### ./src/expressions/kettle.ts
|
|
1772
|
+
|
|
1773
|
+
```ts
|
|
1774
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
1775
|
+
|
|
1776
|
+
const BASE_PRICE = 145
|
|
1777
|
+
const FINISH_SURCHARGE = { BrushedSteel: 0, MatteBlack: 10, Copper: 45 }
|
|
1778
|
+
const WOOD_SURCHARGE = { Walnut: 10, Oak: 0 }
|
|
1779
|
+
const THERMOMETER_SURCHARGE = 20
|
|
1780
|
+
|
|
1781
|
+
// How each finish renders: the spec's material override of the `Body` material reads these
|
|
1782
|
+
const FINISHES = {
|
|
1783
|
+
BrushedSteel: { color: '#c9ccd0', metalness: 1, roughness: 0.3, clearcoat: 0 },
|
|
1784
|
+
MatteBlack: { color: '#2b2927', metalness: 0.1, roughness: 0.55, clearcoat: 0 },
|
|
1785
|
+
Copper: { color: '#d08a5c', metalness: 1, roughness: 0.2, clearcoat: 0.6 },
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
const WOODS = { Walnut: '#4a2f1f', Oak: '#c49a6c' }
|
|
1789
|
+
|
|
1790
|
+
export default phx.domain.implementCustomExpressions({
|
|
1791
|
+
Kettle: {
|
|
1792
|
+
$price: s => {
|
|
1793
|
+
return (
|
|
1794
|
+
BASE_PRICE +
|
|
1795
|
+
FINISH_SURCHARGE[s.bodyFinish] +
|
|
1796
|
+
WOOD_SURCHARGE[s.handleWood] +
|
|
1797
|
+
(s.thermometer ? THERMOMETER_SURCHARGE : 0)
|
|
1798
|
+
)
|
|
1799
|
+
},
|
|
1800
|
+
$plainKnob: s => {
|
|
1801
|
+
return !s.thermometer
|
|
1802
|
+
},
|
|
1803
|
+
$bodyColor: s => {
|
|
1804
|
+
return FINISHES[s.bodyFinish].color
|
|
1805
|
+
},
|
|
1806
|
+
$bodyMetalness: s => {
|
|
1807
|
+
return FINISHES[s.bodyFinish].metalness
|
|
1808
|
+
},
|
|
1809
|
+
$bodyRoughness: s => {
|
|
1810
|
+
return FINISHES[s.bodyFinish].roughness
|
|
1811
|
+
},
|
|
1812
|
+
$bodyClearcoat: s => {
|
|
1813
|
+
return FINISHES[s.bodyFinish].clearcoat
|
|
1814
|
+
},
|
|
1815
|
+
$handleColor: s => {
|
|
1816
|
+
return WOODS[s.handleWood]
|
|
1817
|
+
},
|
|
1818
|
+
},
|
|
1819
|
+
})
|
|
1820
|
+
```
|
|
1821
|
+
|
|
1822
|
+
### ./src/handlers/add-to-cart.ts
|
|
1823
|
+
|
|
1824
|
+
```ts
|
|
1825
|
+
import { useCallback } from 'react'
|
|
1826
|
+
|
|
1827
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
1828
|
+
|
|
1829
|
+
// Stands in for the shop's cart: adding takes a moment, then the page shows the confirmation
|
|
1830
|
+
export default phx.frontend.createPhoenixHandler('addToCart', () => {
|
|
1831
|
+
const navigate = phx.frontend.useNavigate()
|
|
1832
|
+
|
|
1833
|
+
return {
|
|
1834
|
+
handler: useCallback(async () => {
|
|
1835
|
+
await new Promise(resolve => setTimeout(resolve, 1200))
|
|
1836
|
+
navigate('added')
|
|
1837
|
+
}, [navigate]),
|
|
1838
|
+
}
|
|
1839
|
+
})
|
|
1840
|
+
```
|
|
1841
|
+
|
|
1842
|
+
### ./src/invariants/kettle.ts
|
|
1843
|
+
|
|
1844
|
+
```ts
|
|
1845
|
+
import { phx } from '../../.phoenix/phx.js'
|
|
1846
|
+
|
|
1847
|
+
// The copper body is sold only with the walnut handle. The spec marks the violation `fixable`, so a change that breaks
|
|
1848
|
+
// it is rejected and the built-in snackbar shows the spec's message.
|
|
1849
|
+
export default phx.domain.implementCustomInvariants({
|
|
1850
|
+
Kettle: {
|
|
1851
|
+
copperNeedsWalnut: s => {
|
|
1852
|
+
return s.bodyFinish !== 'Copper' || s.handleWood === 'Walnut'
|
|
1853
|
+
},
|
|
1854
|
+
},
|
|
1855
|
+
})
|
|
1856
|
+
```
|
|
1857
|
+
|
|
1858
|
+
</details>
|