@salsita-ai/sdk 0.50.0-develop.9267bdc12e → 0.50.0-develop.98166fe7c3
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 +14 -13
- 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-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/relation-expression-params.js +1 -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 +9 -0
- package/dist/application-spec/errors/diagnostic-codes.js +1 -1
- package/dist/application-spec/errors/diagnostic-messages.d.ts +12 -0
- package/dist/application-spec/errors/diagnostic-messages.js +1 -1
- 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 +11 -8
- 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/templates/admin-config.js +3 -0
- package/dist/application-spec/generate-application/code/templates/configurator-config.js +6 -4
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-component-optics.js +4 -4
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-defaults.js +1 -1
- 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/globals.js +7 -5
- package/dist/application-spec/generate-application/code/templates/index.d.ts +3 -1
- 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/package-json.js +1 -1
- 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-review-skill.js +1 -1
- package/dist/application-spec/generate-application/code/templates/skills/phoenix-skill.js +1 -1
- package/dist/application-spec/generate-application/code/templates/skills/sdk-content.d.ts +13 -6
- package/dist/application-spec/generate-application/code/templates/skills/sdk-content.js +2 -2
- 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/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-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/index.d.ts +2 -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 +4 -3
- package/dist/application-spec/generate-application/runtime/admin-runtime/admin-runtime.d.ts +7 -3
- package/dist/application-spec/generate-application/runtime/admin-runtime/admin-runtime.js +1 -1
- 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 +13 -5
- package/dist/application-spec/generate-application/runtime/application-runtime.js +1 -1
- package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-model-runtime.d.ts +4 -3
- package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-runtime.d.ts +6 -2
- package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-runtime.js +1 -1
- package/dist/application-spec/generate-application/runtime/configurator-runtime/states-runtime.d.ts +2 -2
- 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/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 +1 -1
- package/dist/application-spec/generate-application/runtime/sections/build-sdk-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 +3 -2
- package/dist/application-spec/generate-application/runtime/sections/expression-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 +3 -3
- 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 +27 -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 +68 -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/raw-spec/parse-yaml-spec-file.js +1 -1
- package/dist/application-spec/parse-application-files/raw-spec/raw-assistant.d.ts +15 -2
- 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.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/sections/assistant/assistant-schema.js +1 -1
- package/dist/client/phoenix-api.d.ts +463 -0
- package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.d.ts +36 -1
- 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 +7 -1
- package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.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/graphql-system/graphql-system.d.ts +17 -3
- 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/layout-system/layout-system.d.ts +2 -2
- package/dist/configurator/common/configurator-interface.d.ts +22 -1
- package/dist/configurator/common/configurator-interface.js +1 -1
- package/dist/configurator/common/frontend-analytics.d.ts +2 -0
- package/dist/configurator/common/frontend-analytics.js +1 -1
- package/dist/configurator/common/index.d.ts +2 -0
- package/dist/configurator/common/index.js +1 -1
- package/dist/configurator/common/use-finalize-action.d.ts +31 -0
- package/dist/configurator/common/use-finalize-action.js +1 -0
- package/dist/configurator/common/use-reset-camera.d.ts +6 -0
- package/dist/configurator/common/use-reset-camera.js +1 -0
- package/dist/configurator/configurator-context/configurator-hooks/layout-hooks.d.ts +1 -1
- package/dist/configurator/pages/DefaultConfiguratorLayout.d.ts +3 -2
- package/dist/configurator/pages/LoadedConfiguratorDetailPage.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 +8 -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 +4 -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/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/index.d.ts +1 -0
- package/dist/configurator/pages/index.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-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/ui/assistant/AssistantChips.d.ts +8 -2
- 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/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/built-in-form-registry.d.ts +10 -0
- package/dist/configurator/ui/assistant/form/built-in-form-registry.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-element-definition.d.ts +14 -0
- package/dist/configurator/ui/assistant/form/form-element-definition.js +1 -0
- package/dist/configurator/ui/assistant/form/form-model.d.ts +38 -0
- package/dist/configurator/ui/assistant/form/form-model.js +1 -0
- package/dist/configurator/ui/assistant/form/form-registry.d.ts +31 -0
- package/dist/configurator/ui/assistant/form/form-registry.js +8 -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 +2 -0
- package/dist/configurator/ui/assistant/form/index.js +1 -0
- package/dist/configurator/ui/assistant/form/parse-form-block.d.ts +9 -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-elements/FormGroup.d.ts +3 -0
- package/dist/configurator/ui/assistant/form-elements/FormGroup.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/FormOptions.d.ts +3 -0
- package/dist/configurator/ui/assistant/form-elements/FormOptions.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/FormReply.d.ts +3 -0
- package/dist/configurator/ui/assistant/form-elements/FormReply.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/FormText.d.ts +3 -0
- package/dist/configurator/ui/assistant/form-elements/FormText.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/form-element-props.d.ts +34 -0
- package/dist/configurator/ui/assistant/form-elements/form-element-props.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/index.d.ts +5 -0
- package/dist/configurator/ui/assistant/form-elements/index.js +1 -0
- 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/streamed-markdown.d.ts +2 -0
- 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/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/{universal → slots/desktop-sidebar}/DesktopSidebar.d.ts +23 -14
- 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/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/SideEffects.d.ts +3 -6
- package/dist/configurator/ui/configurator-layout/slots/services/SideEffects.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 +1 -1
- package/dist/configurator/ui/configurator-layout/universal/DesktopLayout.js +2 -2
- package/dist/configurator/ui/legacy/layout/steps/StepsNavigation.d.ts +2 -2
- package/dist/configurator/ui/phoenix-layout-elements/header/common/step-navigation/StepsNavigation.d.ts +2 -2
- 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 +2 -2
- package/dist/docs/index.json +32 -1
- package/dist/docs/layouts/custom-layout.mdx +1636 -183
- 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 +1 -1
- package/dist/docs/other-features/transformers.mdx +4 -0
- package/dist/docs/phoenix/application-states.mdx +9 -7
- package/dist/docs/phoenix/components.mdx +6 -0
- package/dist/docs/phoenix/configurator-interface.mdx +135 -18
- package/dist/docs/phoenix/deployments.mdx +2 -6
- package/dist/docs/phoenix/domain-model.mdx +2 -0
- package/dist/docs/phoenix/finalization.mdx +1 -1
- package/dist/docs/phoenix/getting-started.mdx +2 -1
- package/dist/docs/phoenix/layout-slots.mdx +116 -0
- package/dist/docs/phoenix/localization.mdx +10 -6
- package/dist/docs/phoenix/migration-guide.mdx +21 -8
- package/dist/docs/phoenix/phoenix-cli.mdx +51 -11
- package/dist/docs/phoenix/project-structure.mdx +33 -13
- package/dist/docs/phoenix/sdk-builder-workflow.mdx +2 -2
- package/dist/docs/phoenix/testing.mdx +140 -0
- package/dist/docs/phoenix/webhooks.mdx +21 -4
- package/dist/domain/application/application-config.d.ts +3 -1
- package/dist/domain/application/assistant/assistant-fields.d.ts +8 -1
- package/dist/domain/application/assistant/assistant-fields.js +1 -1
- package/dist/domain/application/assistant/assistant-form-elements.d.ts +28 -0
- package/dist/domain/application/assistant/assistant-form-elements.js +1 -0
- package/dist/domain/application/assistant/assistant-manifest.d.ts +9 -1
- package/dist/domain/application/assistant/assistant-resolved-manifest.d.ts +11 -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/generate-assistant-prompt.js +1 -1
- package/dist/domain/application/assistant/index.d.ts +5 -1
- package/dist/domain/application/assistant/index.js +1 -1
- package/dist/domain/application/assistant/session-setup/apply-assistant-setup.js +1 -1
- package/dist/domain/application/assistant-recipe-groups.d.ts +3 -1
- package/dist/domain/application/configurator-builder.d.ts +4 -1
- package/dist/domain/application/configurator-builder.js +1 -1
- package/dist/domain/core/invariant/violation.d.ts +50 -2
- package/dist/domain/core/invariant/violation.js +1 -1
- package/dist/domain/core/model/model.d.ts +1 -1
- package/dist/domain/core/schema/extended-schema-validator.js +1 -1
- package/dist/domain/domain-context/index.d.ts +1 -1
- package/dist/domain/domain-context/undo-system.d.ts +28 -1
- package/dist/domain/domain-context/undo-system.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/domain-runtime/spec/selectors.js +1 -1
- package/dist/domain/domain-runtime/spec/types.d.ts +2 -0
- 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/client-side-image.d.ts +2 -2
- package/dist/domain/extensions/client-side-image.js +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/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/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/save-template-thumbnail.d.ts +2 -2
- package/dist/domain/extensions/save-template-thumbnail.js +1 -1
- package/dist/domain/extensions/scene-entity-animation.js +1 -1
- 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/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/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/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/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 +160 -148
- 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 +7 -1
- 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.js +1 -1
- package/dist/phoenix/application-spec/generate-application-spec-story.js +2 -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/check.js +1 -1
- package/dist/phoenix/commands/deploy.js +1 -1
- package/dist/phoenix/commands/deps/deps.d.ts +52 -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/prettier.js +1 -1
- package/dist/phoenix/services/application-spec-project-watcher.d.ts +2 -0
- 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/index.d.ts +2 -1
- 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/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/domain-context/common-hooks/use-configurator-messages.d.ts +30 -0
- package/dist/react-sdk/domain-context/common-hooks/use-configurator-messages.js +1 -0
- package/dist/react-sdk/domain-context/index.d.ts +2 -1
- package/dist/react-sdk/domain-context/index.js +1 -1
- package/dist/react-sdk/domain-context/system-hooks/navigation-hooks.d.ts +5 -0
- package/dist/react-sdk/domain-context/system-hooks/navigation-hooks.js +1 -1
- package/dist/react-sdk/domain-controls/hooks/use-angle-dimension.d.ts +1 -1
- package/dist/ui-sdk/theme/types.d.ts +1 -1
- package/package.json +46 -35
- package/schema/domain-spec.json +1201 -217
- 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/ui/configurator-layout/universal/DesktopSidebar.js +0 -16
- /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
|
@@ -158,30 +158,35 @@ const viewState = phx.frontend.useActiveViewState()
|
|
|
158
158
|
const toolState = phx.frontend.useActiveToolState()
|
|
159
159
|
|
|
160
160
|
// Navigation actions
|
|
161
|
-
const navigate = phx.frontend.useNavigate()
|
|
162
|
-
const pushNavigate = phx.frontend.usePushNavigate()
|
|
163
|
-
const popNavigate = phx.frontend.usePopNavigate()
|
|
161
|
+
const navigate = phx.frontend.useNavigate() // navigate(state) replaces the active state and clears the history
|
|
162
|
+
const pushNavigate = phx.frontend.usePushNavigate() // pushNavigate(state) remembers the active state for popNavigate
|
|
163
|
+
const popNavigate = phx.frontend.usePopNavigate() // popNavigate() returns to the remembered state, if there is one
|
|
164
164
|
|
|
165
165
|
// Fullscreen: a flag in the configurator's state that the layout honours; it does not put the browser into fullscreen
|
|
166
166
|
const isFullscreen = phx.frontend.useIsFullscreenActive()
|
|
167
167
|
const setFullscreen = phx.frontend.useSetFullscreen() // setFullscreen(true) or setFullscreen(false)
|
|
168
|
+
|
|
169
|
+
// View state and camera
|
|
170
|
+
const setViewState = phx.frontend.useSetViewState() // setViewState(state) makes one of the spec's viewStates active
|
|
171
|
+
const resetCamera = phx.frontend.useResetCamera() // resetCamera() undoes the user's orbit, pan and zoom
|
|
168
172
|
```
|
|
169
173
|
|
|
170
174
|
### Controls
|
|
171
175
|
|
|
172
176
|
```typescript
|
|
173
|
-
// Control hooks for UI inputs
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
const
|
|
177
|
-
const
|
|
178
|
-
const
|
|
179
|
-
const
|
|
180
|
-
const
|
|
177
|
+
// Control hooks for UI inputs: the entity id and the instance name of the control component on it
|
|
178
|
+
// useSwatchSelection requires its third argument, the fixable violation types
|
|
179
|
+
const swatchSelection = phx.frontend.useSwatchSelection(entityId, instanceName, [])
|
|
180
|
+
const textValue = phx.frontend.useTextValue(entityId, instanceName)
|
|
181
|
+
const attributeSelection = phx.frontend.useAttributeSelection(entityId, instanceName)
|
|
182
|
+
const attributeSwitch = phx.frontend.useAttributeSwitch(entityId, instanceName)
|
|
183
|
+
const distanceDimension = phx.frontend.useDistanceDimension(entityId, instanceName)
|
|
184
|
+
const angleDimension = phx.frontend.useAngleDimension(entityId, instanceName)
|
|
185
|
+
const genericDimension = phx.frontend.useGenericDimension(entityId, instanceName)
|
|
181
186
|
|
|
182
187
|
// Update control
|
|
183
188
|
const updateControl = phx.frontend.useUpdateControl()
|
|
184
|
-
const updatedControl = phx.frontend.useUpdatedControl(
|
|
189
|
+
const updatedControl = phx.frontend.useUpdatedControl(updates)
|
|
185
190
|
```
|
|
186
191
|
|
|
187
192
|
### Recipes & Entity Creation
|
|
@@ -207,15 +212,19 @@ const deletedEntity = phx.frontend.useDeletedEntity()
|
|
|
207
212
|
### Validation & Violations
|
|
208
213
|
|
|
209
214
|
```typescript
|
|
210
|
-
//
|
|
215
|
+
// Validity of the last committed state; a rejected change never becomes committed, so it is not seen here
|
|
211
216
|
const validity = phx.frontend.useStateValidity()
|
|
212
217
|
|
|
213
|
-
// Control violations
|
|
214
|
-
|
|
218
|
+
// Control violations: takes the violation types to ignore and returns a function that maps a prepared
|
|
219
|
+
// state emission to { disabled, hints, violations }
|
|
220
|
+
const controlViolations = phx.frontend.useControlViolations([])
|
|
215
221
|
|
|
216
222
|
// Finalize violations
|
|
217
223
|
const { disabled, hints } = phx.frontend.useFinalizeViolations()
|
|
218
224
|
|
|
225
|
+
// Messages for the user: violations of a rejected change, side-effect hints and errors, one call each
|
|
226
|
+
phx.frontend.useConfiguratorMessages(message => showToast(message.text))
|
|
227
|
+
|
|
219
228
|
// Map violations to hints
|
|
220
229
|
const mapViolationHints = phx.frontend.useMapViolationHints()
|
|
221
230
|
```
|
|
@@ -420,11 +429,119 @@ export default phx.frontend.createCustomPhoenixLayoutElement('ConfiguratorLayout
|
|
|
420
429
|
- `LayoutSlots.SharedCanvas` renders the scene. It is absolutely positioned and fills its nearest positioned ancestor, so the layout's root is positioned and covers the page. The layout positions its own UI above the canvas and after it in the markup, as the `aside` does; unpositioned content is painted under the canvas.
|
|
421
430
|
- `useSceneSafeArea()`, called without arguments, tells the camera which part of the canvas the UI leaves free. Attach `containerRef` to the element that covers the whole canvas and `safeAreaRef` to the region the scene should stay visible in: the hook measures the gap between the two and the camera frames the scene inside the safe area. Without it the scene is framed in the whole canvas. The safe-area element lies over the canvas, so it sets `pointerEvents: 'none'` to leave orbiting and clicking to the scene. A `canvasPadding` component in the spec scales the measured gaps, see [Canvas Padding](?path=/docs/layouts-canvas-padding--docs).
|
|
422
431
|
- The layout has to mount `LayoutSlots.SharedCanvas`, or the project sets `appLoader: legacy`. Otherwise the app loader stays on screen.
|
|
423
|
-
- The layout composes the rest from what `@salsita-ai/sdk/configurator` exports: `LayoutSlots.Services` and the other members of `LayoutSlots
|
|
424
|
-
-
|
|
425
|
-
-
|
|
432
|
+
- The layout composes the rest from what `@salsita-ai/sdk/configurator` exports: `LayoutSlots.Services` and the other members of `LayoutSlots`, which [Layout Slots](?path=/docs/phoenix-layout-slots--docs) lists with what each shows, what feeds it, what it renders when the spec configures nothing for it and what it does in read mode.
|
|
433
|
+
- `LayoutSlots.DesktopSidebar` is the built-in desktop sidebar as one piece: the spec's tabs, back button, property pages and sidebar footer with their spacing, scrolling and empty states, and the assistant panel. Use it when the spec's property pages are what the customer should see and only their place changes, for example a sidebar on the left; build the controls yourself when they have to look like the brand's own. Without `width` it fills its container, so the layout positions and sizes that container; `miniSidebar` does not shrink it, so a layout that honours it reads `LayoutSlots.useSidebarContent().hasMiniSidebar` and lets the container take the sidebar's height. Its tabs sit outside it on the left; `side="start"` puts them on its right, for a sidebar on the left. In fullscreen it stays in place, transparent and inert, so a layout that wants the space back removes it while `phx.frontend.useIsFullscreenActive()` is set. See [Sidebar in a Custom Layout](?path=/docs/layouts-sidebar-in-a-custom-layout--docs).
|
|
434
|
+
- Nothing of the built-in layouts is rendered for it. A project layout finalizes over the spec's `finalizeAction` components, see the finalize paragraph of [Hooks for a Project Layout](#hooks-for-a-project-layout). The `finalizePage` and `finalizeButton` components are legacy: they cannot be declared in YAML, only in TypeScript, and `Legacy.CommonFinalizePage`, which is deprecated, shows a `finalizePage` for projects that still have one. `LayoutDialog` renders only what the project registers with `createLayoutDialog` and is not part of the finalize flow. The preview start screen is `DesktopPreview` or `MobilePreview`, which the layout shows while `usePreview().isPreview` is set. Both previews frame the scene themselves, so the layout renders the component that calls `useSceneSafeArea()` only while `isPreview` is not set; it then measures when it mounts after the preview. The assistant panel is available to a project layout only inside `LayoutSlots.DesktopSidebar`.
|
|
435
|
+
- The layout reads the state it has to react to from hooks, listed with what each returns in [Hooks for a Project Layout](#hooks-for-a-project-layout).
|
|
436
|
+
- Messages for the user come one of two ways. `LayoutSlots.Services` shows violations of a rejected change, side-effect hints and errors as the built-in snackbars, which render into `LayoutSlots.DesktopSnackbarsRoot` or `LayoutSlots.MobileSnackbarsRoot` wherever the layout mounts it. `phx.frontend.useConfiguratorMessages(onMessage)` hands the same messages to the layout's own UI instead, with their text resolved, as the toast in [Custom Layout](?path=/docs/layouts-custom-layout--docs#show-messages) does; mount one of the two, not both, or every message is shown twice. Some messages stay snackbars either way: a failure to save the configuration and an error of the built-in finalize and other actions. They render into the snackbar root, so a layout that mounts none shows them outside the configurator, in the page's `body`. An error while a preset is applied appears on the preset screen, outside the layout. A finalize action the layout runs with `phx.frontend.useFinalizeAction` reports its error as that hook's `error` instead, neither as a message nor as a snackbar.
|
|
426
437
|
- Any project layout element named `ConfiguratorLayout` takes over the page.
|
|
427
438
|
|
|
439
|
+
`defaultConfiguratorElements`, exported from `@salsita-ai/sdk/configurator`, holds the built-in UI as a `ConfiguratorLayout` registration that renders the layout the spec selects. Generated code registers these defaults with `withDefaultElements`, apart from the project's elements, so the built-in UI is a registration like any other; a project element registered under the same name wins over a default. The list also holds the configurator's built-in controls and layout elements under the kinds the spec names them by, such as `attributeSelect` or `undoToolbarButton`, so a project element registered under one of those names replaces the built-in one wherever the spec names that kind. A config assembled by hand, without generated code, calls `withDefaultElements(defaultConfiguratorElements)` too; without it no `ConfiguratorLayout` is registered and the page shows a "not found" box instead of the configurator. The admin mounts a full configurator, so its list, `defaultAdminElements` from `@salsita-ai/sdk/admin`, holds the configurator's defaults followed by the admin's built-in pages, sidebars and actions; generated admin code passes it to `withDefaultElements` in place of `defaultConfiguratorElements`, because each call replaces the defaults passed before.
|
|
440
|
+
|
|
441
|
+
#### Hooks for a Project Layout
|
|
442
|
+
|
|
443
|
+
A project layout reads the product and the configurator's state through hooks, and changes them through the functions the hooks return. Each row names where its hook comes from; the `phx.frontend` hooks in these tables are also exported from `@salsita-ai/sdk/react` under the same name. No hook looks at read mode: the control hooks and the navigation and fullscreen setters keep working while `accessInfo.viewMode` is `true`, so the layout decides what a viewer can change.
|
|
444
|
+
|
|
445
|
+
**The product**
|
|
446
|
+
|
|
447
|
+
| Hook | Returns |
|
|
448
|
+
| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
449
|
+
| `phx.frontend.useRootEntityId()` | The id of the root entity, which the control hooks take. |
|
|
450
|
+
| `phx.frontend.useSelectedDomainEntityId()` | The id of the selected entity, or the root entity's id while nothing is selected. |
|
|
451
|
+
| `phx.frontend.useFirstRootComponent(componentType)` | The first component of that type on the root entity as `{ componentInstance, state }`, or `null` without one. It takes a component type such as `detailComponent` from `@salsita-ai/sdk/domain`, or an array of them. The `detail` component's `state` is `{ title, subtitle, description, thumbnailUrl? }`, all `Localizable`. |
|
|
452
|
+
| `phx.frontend.useComponents({ componentTypes, entityIds?, instanceNames? })` | Every matching component on any entity, as `{ componentInstance, state }[]`. Its type on `phx.frontend` includes `null`, but it returns an empty array when nothing matches. |
|
|
453
|
+
| `phx.frontend.useRootEntityPrice()` and `phx.frontend.useEntityPrice(entityId)` | The value of the entity's `price` component formatted as currency for the current locale, in the component's `currency` or `USD`, or `null` without a `price` component. |
|
|
454
|
+
|
|
455
|
+
**Controls**
|
|
456
|
+
|
|
457
|
+
| Hook | Returns |
|
|
458
|
+
| ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
459
|
+
| `phx.frontend.useAttributeSelection(entityId, instanceName)` | `{ value, options }`. Each option has `title` and `description` (`Localizable`, the spec's `label` and `description`), `value`, `imageSrc` (the spec's `img`), `disabled`, `error`, `hint` (a `string` saying why it is disabled, or `undefined`) and `onSelect()`, which writes the option; the selected option's `onSelect` does nothing. It throws when the entity has no `attributeSelection` component named `instanceName`. |
|
|
460
|
+
| `phx.frontend.useAttributeSwitch(entityId, instanceName)` | `{ state, onChange, disabled, error, hint }`: `state.value` is the boolean and `onChange()` writes its opposite. It throws without the component. |
|
|
461
|
+
|
|
462
|
+
The other control hooks in [Controls](#controls) take the same two arguments, `useSwatchSelection` a required third. `useSwatchSelection` returns `{ value, options }`, where `value` is the selected swatch key and each option is `{ swatchName, onClick, swatchKey, selected, thumbnailUrl, disabled, color, hint?, trace? }`; `useTextValue` and the dimension hooks return `{ value, hints, hasErrors, update, resolve, trace }` instead, where `update(value)` stages a value the scene shows at once (`useTextValue`'s is an `onChange` handler, `update(event, value)`) and `resolve()` commits it, or rolls it back when it breaks an invariant. Their TypeScript types give the exact shapes, and [Custom Controls](?path=/docs/controls-custom--docs) lists them.
|
|
463
|
+
|
|
464
|
+
**Texts**
|
|
465
|
+
|
|
466
|
+
Texts from the spec, such as option titles and the `detail` fields, are `Localizable`, not `string`. `useResolveLocalizable()` from `@salsita-ai/sdk/react` returns a function that turns one into a string in the current language, which suits a list; `useLocalizable(text)` and `<LocalizableMessage>` resolve a single text, see [Localization](?path=/docs/phoenix-localization--docs).
|
|
467
|
+
|
|
468
|
+
**Mode, fullscreen, preview and navigation**
|
|
469
|
+
|
|
470
|
+
| Hook | Returns |
|
|
471
|
+
| ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
472
|
+
| `phx.frontend.useAccessService()` | `{ configurationId, accessInfo }`. `accessInfo.viewMode` is `true` while a configuration shared for viewing is open, and also while the host sets the `readonly` property. |
|
|
473
|
+
| `phx.frontend.useIsFullscreenActive()` and `phx.frontend.useSetFullscreen()` | The fullscreen flag, a `boolean`, and a function `(enabled: boolean) => void` that sets it. |
|
|
474
|
+
| `usePreview()` from `@salsita-ai/sdk/configurator` | `{ isPreview, isExpanded, isPreviewEnabled, isHidden, enter, leave }`. The layout shows a preview start screen while `isPreview` is `true`. |
|
|
475
|
+
| `phx.frontend.useActiveNavigationState()` | The active navigation state, one of the spec's `navigationStates`. |
|
|
476
|
+
| `phx.frontend.usePushNavigate()` and `phx.frontend.usePopNavigate()` | `(state) => void`, which enters a state and remembers the active one, and `() => void`, which returns to the remembered state and does nothing when there is none. `phx.frontend.useNavigate()` returns `(state) => void`, which enters a state and forgets the history. |
|
|
477
|
+
| `phx.frontend.useActiveViewState()` and `phx.frontend.useActiveToolState()` | The active view state and tool state. |
|
|
478
|
+
| `phx.frontend.useSetViewState()` | `(state) => void`, which makes the given view state, one of the spec's `viewStates`, the active one; setting the active state again keeps it. Cameras and components filtered by `viewStates` follow the change. |
|
|
479
|
+
| `phx.frontend.useResetCamera()` | `() => void`, which moves the camera back to the framing of the active camera configuration, undoing the user's orbit, pan and zoom, as the toolbar's reset button does. Besides `phx.frontend`, `@salsita-ai/sdk/configurator` exports it, not `@salsita-ai/sdk/react`. |
|
|
480
|
+
| `useActiveViewports()` from `@salsita-ai/sdk/react` | The responsive breakpoints the configurator's container satisfies, as `Viewport[]`, or `null` before it is measured. It follows the container, not the window, so it is the switch between a desktop and a phone layout. `desktop` is a container wider than 768 pixels and `mobile` one at most 768 pixels wide; `phone` is narrower than 480 and `tablet` between 480 and 1024 pixels; `landscape` and `portrait` follow the browser window's orientation. The built-in layout uses its phone arrangement unless `desktop` is active. |
|
|
481
|
+
|
|
482
|
+
**Violations**
|
|
483
|
+
|
|
484
|
+
| Hook | Returns |
|
|
485
|
+
| ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
486
|
+
| `phx.frontend.useStateValidity()` | The validity of the last committed state: `{ valid: true, severity: null }`, or `{ valid: true, severity: 'notice' \| 'warning', entityViolations }`. A change that leaves a `fixable` or `fatal` violation is rejected and never committed, and neither is a change during which an error was thrown, so neither is seen here. |
|
|
487
|
+
| `phx.frontend.useFinalizeViolations()` | `{ disabled, hints, violations }`. `disabled` is `true` while a `warning`, `fixable` or `fatal` violation holds or the configuration failed to save; `hints` is the violations' text, or `undefined`. |
|
|
488
|
+
| `phx.frontend.useConfiguratorMessages(onMessage)` | Nothing. It calls `onMessage(message)` once per message: `{ kind: 'violation', entityId, violation, text }` for each violation of the rejected state, including notices and warnings already present, so `violation.severity` tells the reason for the rejection (`fixable` or `fatal`) from them, `{ kind: 'sideEffect', text }` for each hint of a committed update, and `{ kind: 'error', error, text }` when an error is thrown while a change is validated, with `text` the generic "Oops, something went wrong". `text` is resolved to the current language; a violation's is its `message`, or its `type` without one, and the built-in snackbar prefixes it with `entityId`. Hints committed before the layout mounted are not delivered; when the most recent change was rejected or threw, its messages are delivered again when the hook mounts. `onMessage` may be a new function on every render. On `phx.frontend` the message is typed by the project, so `violation.type` narrows to its violation types; from `@salsita-ai/sdk/react` the type is `ConfiguratorMessage`. |
|
|
489
|
+
| `phx.frontend.useFinalizeAction(handler)` | `{ run, isPending, error, disabled, hints }` for the `finalizeAction` whose `handler` it is given; see the Finalize paragraph below for how to call it. `run()` records the finalize-button click for analytics and runs the project's handler, and does nothing while `disabled` or `isPending`; `error` is what the handler's last run rejected with, or `null`; `disabled` and `hints` are those of `useFinalizeViolations()`. The type of the result is `UseFinalizeActionResult` from `@salsita-ai/sdk/configurator`, which also exports the hook. |
|
|
490
|
+
|
|
491
|
+
`LayoutSlots.Services` shows the messages of `useConfiguratorMessages` as snackbars; see the messages paragraph of [Loaded Configuration UI](#loaded-configuration-ui) for choosing between the two and for the messages that stay snackbars.
|
|
492
|
+
|
|
493
|
+
**Finalize**
|
|
494
|
+
|
|
495
|
+
A project layout finalizes over the spec's `finalizeAction` components. `phx.frontend.useComponents({ componentTypes: [finalizeActionComponent] })`, with `finalizeActionComponent` from `@salsita-ai/sdk/domain`, lists them; each `state` is `{ variant, label, title, icon, handler }`, where `variant` is `'primary'` or `'secondary'` and `handler` names the project's handler registered with `phx.frontend.createPhoenixHandler`. The built-in footer offers the first `'primary'` action, or else the first action, as its button and the others in a menu; a project layout follows the same rule when it offers one action.
|
|
496
|
+
|
|
497
|
+
Each action gets a component of its own that calls `phx.frontend.useFinalizeAction(action.state.handler)` once, never in a loop or conditionally, because the hook runs the project's handler factory, which calls hooks. The layout wraps that component in `<PhoenixHandlerBoundary name={action.state.handler}>` from `@salsita-ai/sdk/react`, so an edited handler takes effect without a reload. The hook returns:
|
|
498
|
+
|
|
499
|
+
- `run()`, which records the finalize-button click for analytics and then runs the handler. It does nothing while `disabled` or `isPending`.
|
|
500
|
+
- `isPending`, `true` while the handler runs.
|
|
501
|
+
- `error`, what the handler's last run rejected with, or `null`; a rejection that is not an `Error` is wrapped in one, with the value as its `cause`. It is cleared when the action runs again. No snackbar is raised; the layout shows the error its own way.
|
|
502
|
+
- `disabled` and `hints`, those of `useFinalizeViolations()`: finalizing is not possible while a `warning`, `fixable` or `fatal` violation holds or the configuration failed to save, and `hints` says why.
|
|
503
|
+
|
|
504
|
+
`isPending` and `error` belong to the mounted component: when it unmounts during a run, the handler keeps running, and a component mounted afterwards starts with `isPending` false and no `error`.
|
|
505
|
+
|
|
506
|
+
```tsx
|
|
507
|
+
import { finalizeActionComponent } from '@salsita-ai/sdk/domain'
|
|
508
|
+
import { PhoenixHandlerBoundary, useResolveLocalizable } from '@salsita-ai/sdk/react'
|
|
509
|
+
|
|
510
|
+
const FinalizeButton = ({ handler, label }: { handler: string; label: string }) => {
|
|
511
|
+
const { run, isPending, error, disabled, hints } = phx.frontend.useFinalizeAction(handler)
|
|
512
|
+
|
|
513
|
+
return (
|
|
514
|
+
<div>
|
|
515
|
+
<button type="button" disabled={disabled || isPending} onClick={run} title={hints}>
|
|
516
|
+
{isPending ? 'Sending…' : label}
|
|
517
|
+
</button>
|
|
518
|
+
{error && <p role="alert">{error.message}</p>}
|
|
519
|
+
</div>
|
|
520
|
+
)
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
export const Finalize = () => {
|
|
524
|
+
const { accessInfo } = phx.frontend.useAccessService()
|
|
525
|
+
const resolve = useResolveLocalizable()
|
|
526
|
+
const actions = phx.frontend.useComponents({ componentTypes: [finalizeActionComponent] }) ?? []
|
|
527
|
+
const primary = actions.find(action => action.state.variant === 'primary') ?? actions[0]
|
|
528
|
+
|
|
529
|
+
if (accessInfo.viewMode || !primary) {
|
|
530
|
+
return null
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
return (
|
|
534
|
+
<PhoenixHandlerBoundary name={primary.state.handler}>
|
|
535
|
+
<FinalizeButton handler={primary.state.handler} label={resolve(primary.state.label)} />
|
|
536
|
+
</PhoenixHandlerBoundary>
|
|
537
|
+
)
|
|
538
|
+
}
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
The hook does not check read mode, so the layout hides finalizing while `accessInfo.viewMode` is `true`, as above. [Custom Layout](?path=/docs/layouts-custom-layout--docs#request-a-quote) runs a finalize action this way from its review step.
|
|
542
|
+
|
|
543
|
+
Instead of its own buttons, a project layout can mount `<FinalizeActions />` from `@salsita-ai/sdk/configurator`: the built-in footer's finalize buttons, the primary action plus a menu of the others, disabled with the hints of `useFinalizeViolations()`, with a spinner while the handler runs and a snackbar when it fails. It renders nothing without a `finalizeAction`, and it does not check read mode either.
|
|
544
|
+
|
|
428
545
|
## TransformerBuilder
|
|
429
546
|
|
|
430
547
|
Use `transformerBuilder` to create entity transformers:
|
|
@@ -281,9 +281,7 @@ Phoenix provides two helper functions for reading environment variables with val
|
|
|
281
281
|
**`createEnvReader`** - General purpose environment reader used in frontend and deployment contexts:
|
|
282
282
|
|
|
283
283
|
```typescript
|
|
284
|
-
import { bool, str } from '
|
|
285
|
-
|
|
286
|
-
import { createEnvReader } from '@salsita-ai/sdk/common/env'
|
|
284
|
+
import { bool, createEnvReader, str } from '@salsita-ai/sdk/common/env'
|
|
287
285
|
|
|
288
286
|
// Create a reader function
|
|
289
287
|
const readEnv = createEnvReader({
|
|
@@ -301,9 +299,7 @@ console.log(env.SERVER_URL) // Typed and validated
|
|
|
301
299
|
|
|
302
300
|
```typescript
|
|
303
301
|
// webhooks/webhooks.config.ts
|
|
304
|
-
import { str } from '
|
|
305
|
-
|
|
306
|
-
import { createEnvReader } from '@salsita-ai/sdk/common/env'
|
|
302
|
+
import { createEnvReader, str } from '@salsita-ai/sdk/common/env'
|
|
307
303
|
|
|
308
304
|
export const readRuntimeConfig = createEnvReader({
|
|
309
305
|
AWS_S3_PUBLIC_RESOURCES_BUCKET: str(),
|
|
@@ -329,6 +329,8 @@ components:
|
|
|
329
329
|
|
|
330
330
|
The code generator will automatically create an expression with the same name and infer the return type based on usage context.
|
|
331
331
|
|
|
332
|
+
The type of an expression must share values with the type every component expects where it is read, and with its declared type. An expression declared as a number and read into a `title`, or one read both into a `title` and into `offsetX`, has no value its implementation could return, so the build reports `EXPRESSION_READ_TYPE_CONFLICT` at the expression and names each place it is read. A type given only as `tsType` is not checked here.
|
|
333
|
+
|
|
332
334
|
## Constants
|
|
333
335
|
|
|
334
336
|
Constants are pre-generated expressions that return fixed values. Under the hood, they are implemented as expressions but are automatically generated by the Phoenix system, so you don't need to write TypeScript implementation code for them.
|
|
@@ -15,7 +15,7 @@ Finalization is Phoenix's system for completing configurator sessions and proces
|
|
|
15
15
|
|
|
16
16
|
> For integration-specific finalization flows — how host-specific data is passed in and how the host is notified on completion (event dispatch in `headless`, redirect in `handoff`) — see [Finalization (Internal)](?path=/docs/phoenix-integration-finalization-internal--docs) and [Finalization (External)](?path=/docs/phoenix-integration-finalization-external--docs).
|
|
17
17
|
|
|
18
|
-
Phoenix selects one primary footer action and places additional finalization actions in its menu.
|
|
18
|
+
The universal sidebar footer offers the spec's `finalizeAction` components: Phoenix selects one primary footer action and places additional finalization actions in its menu. It never opens a `finalizePage`; the `finalizePage` and `finalizeButton` components are legacy, declared only in TypeScript, and used by the basic sidebar footer and the legacy layouts. Built-in finalization actions use configuration validity to disable the footer action and provide pending and generic error states, including for add-to-cart handlers. See [Universal Sidebar Footer](?path=/docs/layouts-sidebar-footer-universal--docs) for the layout behavior. A project layout (`ConfiguratorLayout`) offers the same actions with its own buttons through `phx.frontend.useFinalizeAction`, which runs an action's handler and returns its pending state, its error and the disabled state with hints; see the Finalize paragraph of [Configurator Interface → Hooks for a Project Layout](?path=/docs/phoenix-configurator-interface--docs#hooks-for-a-project-layout).
|
|
19
19
|
|
|
20
20
|
## How Finalization Works
|
|
21
21
|
|
|
@@ -26,6 +26,7 @@ The Phoenix CLI (`phoenix` command) is the unified tool for all configurator dev
|
|
|
26
26
|
- `phoenix dev` - Start the development server with hot reload
|
|
27
27
|
- `phoenix build` - Build the configurator for production
|
|
28
28
|
- `phoenix sync` - Synchronize dependencies and generated code
|
|
29
|
+
- `phoenix deps` - Add the SDK's missing peer dependencies to `package.json` and move out-of-range ones into range
|
|
29
30
|
- `phoenix check` - Validate domain configuration and code
|
|
30
31
|
- `phoenix fix` - Auto-fix common issues in domain files
|
|
31
32
|
|
|
@@ -57,7 +58,7 @@ This section provides practical guidance for developers who are new to Phoenix P
|
|
|
57
58
|
|
|
58
59
|
Before diving into Phoenix Platform development, ensure you have:
|
|
59
60
|
|
|
60
|
-
- **Node.js** and **pnpm** -
|
|
61
|
+
- **Node.js 22.13 or newer** and **pnpm** - The SDK and the Phoenix CLI run on Node.js 22.13 or newer (see [Starting a New Project](?path=/docs/phoenix-phoenix-cli--docs#starting-a-new-project)); a project generated by Phoenix pins the exact Node.js and pnpm versions it is developed with
|
|
61
62
|
- **JavaScript/TypeScript** - Phoenix generates TypeScript code and uses modern JavaScript patterns
|
|
62
63
|
- **React** - The platform builds on React components, hooks, and modern React patterns
|
|
63
64
|
- **Three.js** - Basic knowledge of 3D graphics, scenes, cameras, and rendering concepts
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Layout Slots
|
|
2
|
+
|
|
3
|
+
A project layout registered as `ConfiguratorLayout` builds its UI from its own components and from the pieces of the built-in layout it wants to keep. Those pieces are the members of `LayoutSlots`, from `@salsita-ai/sdk/configurator`. This page lists every member: what it shows, what in the spec or the configurator's state feeds it, what it renders when the spec configures nothing for it, and what it does in read mode. [Configurator Interface → Loaded Configuration UI](?path=/docs/phoenix-configurator-interface--docs#loaded-configuration-ui) says what a project layout has to mount, and its [Hooks for a Project Layout](?path=/docs/phoenix-configurator-interface--docs#hooks-for-a-project-layout) list the hooks for a layout that draws its own UI.
|
|
4
|
+
|
|
5
|
+
- [How the slots behave](#how-the-slots-behave)
|
|
6
|
+
- [Canvas and services](#canvas-and-services)
|
|
7
|
+
- [Desktop sidebar](#desktop-sidebar)
|
|
8
|
+
- [Header, toolbar and controls](#header-toolbar-and-controls)
|
|
9
|
+
- [Banners and branding](#banners-and-branding)
|
|
10
|
+
- [Page footer](#page-footer)
|
|
11
|
+
- [Phone layout](#phone-layout)
|
|
12
|
+
- [Others](#others)
|
|
13
|
+
|
|
14
|
+
## How the slots behave
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import { LayoutSlots } from '@salsita-ai/sdk/configurator'
|
|
18
|
+
|
|
19
|
+
// Part of a ConfiguratorLayout: the built-in toolbar, placed by the layout in the bottom right corner
|
|
20
|
+
export const Toolbar = () => (
|
|
21
|
+
<div style={{ position: 'absolute', insetBlockEnd: 24, insetInlineEnd: 24 }}>
|
|
22
|
+
<LayoutSlots.DesktopToolbar />
|
|
23
|
+
</div>
|
|
24
|
+
)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- A slot takes no props unless its row names them, and reads what it shows from the spec and the configurator's state. It renders inside the configurator only, under a `ConfiguratorLayout`.
|
|
28
|
+
- A slot brings its own look but not its place: it adds no padding or scrolling around itself, so the layout puts it in a container. Two members differ: `SharedCanvas` fills its nearest positioned ancestor, and `DesktopSidebar` brings the sidebar's spacing and scrolling with it.
|
|
29
|
+
- Read mode means `useAccessService().accessInfo.viewMode` is `true`: a configuration shared for viewing is open, or the host sets the `readonly` property. "No change" in the read-mode column means the slot renders the same for a viewer, so the layout decides whether a viewer sees it.
|
|
30
|
+
- `Desktop*` and `Mobile*` members are twins that differ in size and arrangement; [Phone layout](#phone-layout) lists the phone ones. The container's width, not the window's, decides which one fits: `useActiveViewports()` from `@salsita-ai/sdk/react` returns the breakpoints the container satisfies. The built-in layout uses the `Desktop*` members while `desktop` is active, for a container wider than 768 pixels, and the `Mobile*` members otherwise, while `mobile` is active; `phone` means narrower than 480 pixels and `tablet` between 480 and 1024.
|
|
31
|
+
|
|
32
|
+
## Canvas and services
|
|
33
|
+
|
|
34
|
+
| Member | Shows | Fed by | With nothing configured | Read mode |
|
|
35
|
+
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | ----------------------- | --------- |
|
|
36
|
+
| `SharedCanvas` | The 3D scene, in a container that is `position: absolute; inset: 0` with the scene's background colour. The scene is hidden for a moment while the preview expands or collapses. | The scene of the spec, through `Canvas` | Always renders | No change |
|
|
37
|
+
| `Canvas` | The WebGL canvas alone, or `GPUIssuePage` when the browser has no WebGL or no GPU acceleration. It reports the scene-assets loading phase the app loader waits for. | The scene, the canvas settings and the `CanvasLoader` element | Always renders | No change |
|
|
38
|
+
| `Services` | Nothing visible: it mounts `InvariantViolations` and `SideEffects`, which show the messages of `useConfiguratorMessages()` as snackbars | The configurator's state | Always mounted | No change |
|
|
39
|
+
| `InvariantViolations` | When a change is rejected, a snackbar for each violation of the rejected state, including notices and warnings already present, as `<entity id>: <message>` (a `notice` as info, a `warning` as warning, `fixable` and `fatal` as error), and "Oops, something went wrong" for an error thrown while the state was validated | The spec's invariants | Nothing | No change |
|
|
40
|
+
| `SideEffects` | An info snackbar for each committed update that carries a hint | The hints of committed updates | Nothing | No change |
|
|
41
|
+
| `DesktopSnackbarsRoot` | The element the snackbars are rendered into: a stack anchored to its bottom edge, at most 320 pixels wide | Every snackbar the configurator raises | An empty element | No change |
|
|
42
|
+
|
|
43
|
+
- Mount `SharedCanvas`, not `Canvas`: `Canvas` suspends while it probes the GPU on its first mount, and `SharedCanvas` holds the boundary that catches it. Without either, the app loader stays on screen unless the project sets `appLoader: legacy`.
|
|
44
|
+
- `SharedCanvas` fills its nearest positioned ancestor and paints an opaque background, so the layout positions its own UI after it in the markup.
|
|
45
|
+
- Snackbars are raised by `Services`, and also by the built-in finalize and footer actions when their handler fails and when saving the configuration fails. A layout that shows violations, side-effect hints and validation errors its own way calls `phx.frontend.useConfiguratorMessages(onMessage)` instead of mounting `Services`, see [Configurator Interface → Hooks for a Project Layout](?path=/docs/phoenix-configurator-interface--docs#hooks-for-a-project-layout); the other snackbars still need a root. They render into the snackbar root the layout mounts; with no root mounted they render into the page's `document.body`, outside the configurator. The desktop root is a zero-height element the snackbars stack upwards from, so the layout places it where their bottom edge belongs. The phone root leaves them fixed to the viewport, see `MobileSnackbarsRoot`. A finalize action the layout runs with `phx.frontend.useFinalizeAction` raises no snackbar; its error is the hook's `error`.
|
|
46
|
+
|
|
47
|
+
## Desktop sidebar
|
|
48
|
+
|
|
49
|
+
| Member | Shows | Fed by | With nothing configured | Read mode |
|
|
50
|
+
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
51
|
+
| `DesktopSidebar` | The whole built-in desktop sidebar: tabs, back button, property pages and sidebar footer with their spacing, scrolling and empty states, and the assistant panel. Props: `width`, and `side` (`'start'` or `'end'`, typed `DesktopSidebarSide`; `DesktopSidebarProps` types both) | The members below | As its parts | As its parts. In fullscreen it stays in place, transparent and inert |
|
|
52
|
+
| `DesktopSidebarTabs` | Tabs that switch the navigation state | The `sidebarTabs` components of the selected entity; the `horizontalTabs` component is not shown here | Nothing; also nothing while the summary is shown | No change |
|
|
53
|
+
| `useSidebarTabs()` | A hook, `{ tabs, activeTab, onChange }`: each tab is `{ label, icon, value, isActive }`, `activeTab` is the active tab's value or `'none'`, and `onChange(value)` switches to that tab's first navigation state | As `DesktopSidebarTabs` | `tabs` is empty | No change |
|
|
54
|
+
| `DesktopSidebarBackButton` | A "Back" button. Props: the MUI `Button` props and `icon`, also settable in the theme as `PhxDesktopSidebarBackButton`; the application config's `sidebarBackIcon` takes precedence over both | The sidebar's way back: a navigation state to pop, a stacked property page, or a selected entity other than the root, unless the application config sets `showSelectionBackButton` to `false` or sets `ignoreSelectionInSidebar` | Nothing while there is no way back | No change |
|
|
55
|
+
| `DesktopSidebarContent` | The property pages of the selected entity with its entity header, a stacked page opened from them, or the summary page while the summary is shown. With the application config's `ignoreSelectionInSidebar` set, every `propertyPage` of every entity shows under the root, whatever is selected | `propertyPage`, `entityHeader`, `simpleSummary` and `customSummaryPage` components, and `ignoreSelectionInSidebar` | Nothing | **No change: the controls stay editable.** Limit them with `$filter.modes`, or render something else in read mode |
|
|
56
|
+
| `useSidebarContent(options?)` | A hook, `{ content, goBack, hasMiniSidebar, hasSplitSidebar }`: `content` is what `DesktopSidebarContent` shows, `goBack` is the back action or `null`. `options` sets the `HeaderContainer` and `BodyContainer` components the content is wrapped in | As `DesktopSidebarContent` | `content` is empty | No change |
|
|
57
|
+
| `EntityHeader` | An entity's title, subtitle, description and thumbnail, with its primary and secondary buttons, such as delete or replace. Props, typed `EntityHeaderProps`: `entityId` and `headerComponent` | The texts and thumbnail from the entity's `detail` component (the title falls back to the entity type); the buttons from the `entityHeader` component passed in | — | No change |
|
|
58
|
+
| `DesktopSidebarFooter` | The price and the actions | `basicSidebarFooter`, `universalSidebarFooter`, `readSidebarFooter`, `hiddenSidebarFooter` or `customSidebarFooter`. The basic footer offers a `finalizeButton`, else a button for a `finalizePage`, else a disabled button; the universal footer offers the `finalizeAction` and `otherAction` components | The basic footer: the price and a finalize button. With a `navigationSteps` component of two or more steps, previous and next step buttons and the finalize button only on the last step; with a summary and no steps, a **Summary** button until the summary is shown; in a preset embed, **Save Template** instead of finalize | With nothing configured, the read footer: price only. The basic footer hides its buttons. **The universal footer still shows its finalize and other actions to a viewer**; limit them with `$filter.modes` |
|
|
59
|
+
|
|
60
|
+
A sidebar footer with `universalSidebarFooter` does not check read mode, although the component's own description says its buttons are hidden then. A viewer of a shared configuration sees its actions. The `custom` footer renders its children unchanged as well.
|
|
61
|
+
|
|
62
|
+
## Header, toolbar and controls
|
|
63
|
+
|
|
64
|
+
| Member | Shows | Fed by | With nothing configured | Read mode |
|
|
65
|
+
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
66
|
+
| `DesktopHeader` | The floating, fixed or custom header | The first `floatingHeader`, `fixedHeader`, `hiddenHeader` or `customHeader` component | The floating header. Nothing with `hiddenHeader` or in fullscreen | The floating header shows the back button instead of the step navigation; the fixed header hides its horizontal tabs |
|
|
67
|
+
| `DesktopToolbar` | The toolbar's button groups | The `toolbar` component's `desktop` list, or else a default set | Default buttons: fullscreen and camera reset; language with more than one locale; share unless sharing is disabled; measurements with more than one dimension or with `indicatorSwitch` on (the default), and help in that group when the project registers a `ToolbarHelp` element; undo and redo; the assistant when the spec has an `assistant` section. In fullscreen, only the exit button | The default set drops share and undo/redo; a configured `toolbar` is shown unchanged |
|
|
68
|
+
| `DesktopViewControls` | A toggle between view states | The root entity's `viewControls` component and the active view state | Nothing without the component or without an active view state | No change |
|
|
69
|
+
| `DesktopToolControls` | A vertical group of tool buttons that switch the tool state | The root entity's `toolControls` component | Nothing without the component | No change |
|
|
70
|
+
| `ToolControls` | The same component as `DesktopToolControls` and `MobileToolControls` | As `DesktopToolControls` | Nothing without the component | No change |
|
|
71
|
+
| `DesktopCallToAction` | **The button that leaves a tool mode, not the finalize button.** Clicking it switches to the component's `exitTo` tool state | An `exitToolModeFab` component, usually filtered to the tool states it belongs to | Nothing. It throws when more than one is active | Nothing |
|
|
72
|
+
|
|
73
|
+
Instead of `DesktopViewControls` or `MobileViewControls`, a layout can build its own view buttons with `phx.frontend.useActiveViewState()` and `phx.frontend.useSetViewState()`, which need no `viewControls` component, see [Hooks for a Project Layout](?path=/docs/phoenix-configurator-interface--docs#hooks-for-a-project-layout).
|
|
74
|
+
|
|
75
|
+
## Banners and branding
|
|
76
|
+
|
|
77
|
+
| Member | Shows | Fed by | With nothing configured | Read mode |
|
|
78
|
+
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
|
79
|
+
| `DesktopReadonlyBanner` | "You're viewing a read-only configuration" with an **Edit configuration** button that opens `CloneToEditDialog`. Props: the MUI `Alert` props and `icon`, also settable in the theme as `PhxDesktopReadonlyBanner` | `useIsCloningAllowed()`; its icon from the application config's `readonlyBannerIcon` | Nothing unless cloning is allowed | **It does not check read mode.** The layout renders it only in read mode, as the built-in layout does while not in fullscreen |
|
|
80
|
+
| `MobileReadonlyBanner` | An **Edit** button that opens `CloneToEditDialog`. Props: the MUI `Button` props and `icon`, also settable in the theme as `PhxMobileReadonlyBanner` | As `DesktopReadonlyBanner` | Nothing unless cloning is allowed | As `DesktopReadonlyBanner` |
|
|
81
|
+
| `CloneToEditDialog` | The "Edit configuration" dialog that creates an editable copy of the configuration and opens it. Props, typed `CloneToEditDialogProps`: `open` and `onClose` | The open configuration | — | — |
|
|
82
|
+
| `useIsCloningAllowed()` | A hook, `boolean`: `true` when the application config sets `shareCloneToEdit` and the session's role may create configurations | The application config and the session | `false` | Does not check read mode |
|
|
83
|
+
| `DesktopPoweredBy` / `MobilePoweredBy` | The "Powered by Salsita" mark, a link | Its props `visible`, `variant` (`'black'` or `'white'`), `href`, `title`, `slots` and `slotProps`. All but `href` and `title` are also settable in the theme as `PhxDesktopBrandingPoweredBy` / `PhxMobileBrandingPoweredBy` | The mark | No change |
|
|
84
|
+
|
|
85
|
+
## Page footer
|
|
86
|
+
|
|
87
|
+
| Member | Shows | Fed by | With nothing configured | Read mode |
|
|
88
|
+
| -------------------------------- | ------------------------------------------------------- | --------------------------------------------------------------------------------------- | ----------------------- | --------- |
|
|
89
|
+
| `DesktopFooter` / `MobileFooter` | A footer below the whole layout, not the sidebar footer | The project's `LayoutFooter` element, registered with `phx.frontend.createLayoutFooter` | Nothing | No change |
|
|
90
|
+
|
|
91
|
+
## Phone layout
|
|
92
|
+
|
|
93
|
+
The phone twins read the same spec as their desktop members.
|
|
94
|
+
|
|
95
|
+
| Member | Shows | Differences from the desktop member |
|
|
96
|
+
| ------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
97
|
+
| `MobileHeader` | The header | The floating and fixed headers show a back button and the branding; the back button is hidden with steps and in read mode |
|
|
98
|
+
| `MobileToolbar` | The toolbar | Reads the `toolbar` component's `mobile` list, rendered in reverse order. The default set has undo and redo, camera reset, fullscreen and the assistant, and drops undo and redo in read mode |
|
|
99
|
+
| `MobileHamburgerMenu` | A menu button that opens the remaining actions in a dialog | Reads the `toolbar` component's `mobileMenu` list, or else share, measurements, language and help under the same conditions as the desktop toolbar; share is dropped in read mode. Nothing when the list is empty. Props: `icon` and `closeIcon`, also settable in the theme as `PhxMobileHamburgerMenu`; the application config's `hamburgerIcon` and `toolbarCloseIcon` take precedence |
|
|
100
|
+
| `MobileTabs` | Scrollable tabs that switch the navigation state | Reads the selected entity's `sidebarTabs` or the `horizontalTabs` component, and throws when both are active or when more than one of either is active. Nothing without tabs or while the summary is shown. Unlike the desktop fixed header, it keeps horizontal tabs in read mode |
|
|
101
|
+
| `MobileViewControls` | A toolbar button with the active view's icon that opens the list of views | Nothing without the component, an active view state or that view's icon |
|
|
102
|
+
| `MobileToolControls` | The tool buttons | Same component as `DesktopToolControls` |
|
|
103
|
+
| `MobileCallToAction` | The button that leaves a tool mode | Same as `DesktopCallToAction` |
|
|
104
|
+
| `MobileSidebarBackButton` | A "Back" button | Same as `DesktopSidebarBackButton`, smaller, with `sidebarBackIcon` taking precedence the same way; its theme name is `PhxMobileSidebarBackButton` |
|
|
105
|
+
| `MobileSidebarContent` | The property pages | Same content as `DesktopSidebarContent` |
|
|
106
|
+
| `MobileSidebarFooter` | The price and the actions | Same as `DesktopSidebarFooter`; the universal footer adds the step label and progress |
|
|
107
|
+
| `MobileSnackbarsRoot` | The element the snackbars are rendered into | It does not position the snackbars: they keep notistack's `position: fixed` and sit at the viewport's edge wherever the root is. The built-in phone layout positions them with its own styles; a project layout styles `notistackSnackbarClasses.container` from `@salsita-ai/sdk/ui` |
|
|
108
|
+
|
|
109
|
+
## Others
|
|
110
|
+
|
|
111
|
+
| Member | Shows |
|
|
112
|
+
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
113
|
+
| `GPUIssuePage` | `WebGLNotSupported` or `GPUAccelerationDisabled`, chosen by its `issue` prop. `Canvas` renders it; a layout does not need it |
|
|
114
|
+
| `GPUIssue` | The two values of that prop, `'no-gpu'` and `'no-acceleration'`, as a constant and a type |
|
|
115
|
+
| `WebGLNotSupported` | A full-page message that WebGL is not supported, with a **Go To Homepage** button that returns to the configurator's start page |
|
|
116
|
+
| `GPUAccelerationDisabled` | A full-page message that GPU acceleration is disabled, with the same button |
|
|
@@ -152,6 +152,8 @@ entities:
|
|
|
152
152
|
|
|
153
153
|
This is the way to go when you're dealing with content that might evolve over time. The message ID stays the same, so your existing translations remain valid even when you tweak the wording. Plus, you can use dot notation to create nice, organized namespaces for your translations.
|
|
154
154
|
|
|
155
|
+
A `$msg` compiles to a message descriptor. When an expression that holds one also declares a schema, the schema has to accept a message descriptor, such as `$ref: 'phx:Localizable'` or `$ref: 'phx:MessageDescriptor'`; a `$msg` declared as `type: string` or `type: number` is reported as `EXPRESSION_VALUE_TYPE_MISMATCH`.
|
|
156
|
+
|
|
155
157
|
You can use both approaches throughout your domain specifications. Here are some common patterns that work well:
|
|
156
158
|
|
|
157
159
|
```yaml
|
|
@@ -408,7 +410,7 @@ function EntityList({ entities }) {
|
|
|
408
410
|
When you need to do more complex text formatting with placeholders or embedded elements, you can reach for Lingui's `Trans` macro directly:
|
|
409
411
|
|
|
410
412
|
```tsx
|
|
411
|
-
import { Trans
|
|
413
|
+
import { Trans } from '@lingui/react/macro'
|
|
412
414
|
|
|
413
415
|
function WelcomeMessage({ userName, itemCount }) {
|
|
414
416
|
return (
|
|
@@ -423,14 +425,14 @@ function WelcomeMessage({ userName, itemCount }) {
|
|
|
423
425
|
|
|
424
426
|
## Server-Side Translations for Webhooks
|
|
425
427
|
|
|
426
|
-
The localization system isn't just for the frontend — it works in server-side webhook handlers too. PDF and email tasks render React templates with the same
|
|
428
|
+
The localization system isn't just for the frontend — it works in server-side webhook handlers too. PDF and email tasks render React templates with the same Lingui macros (`<Trans>` from `@lingui/react/macro`, `msg` from `@lingui/core/macro`) you already use in UI components. The task context exposes `ctx.resolveLocalizable` already bound to the request locale and domain fallback chain, and the React builders use it for localizable subjects, attachment filenames, bodies, headers, footers, and watermark text.
|
|
427
429
|
|
|
428
430
|
### In the handler
|
|
429
431
|
|
|
430
432
|
Use the `msg` template tag for one-off strings you pass into builder methods:
|
|
431
433
|
|
|
432
434
|
```tsx
|
|
433
|
-
import { msg } from '@lingui/macro'
|
|
435
|
+
import { msg } from '@lingui/core/macro'
|
|
434
436
|
|
|
435
437
|
export const emailTask = phx.webhooks.taskFactory.createSendEmailTask((resources, data, ctx) => {
|
|
436
438
|
return ctx.emailTaskBuilder
|
|
@@ -450,7 +452,7 @@ export const emailTask = phx.webhooks.taskFactory.createSendEmailTask((resources
|
|
|
450
452
|
Use `<Trans>` for inline strings — exactly as in the frontend — and `<HtmlHelpers.Localized>` to render localizable values pulled from the domain (e.g. `$root.$summary[].title`, which are typed as `MessageDescriptor` or `MultilingualString`):
|
|
451
453
|
|
|
452
454
|
```tsx
|
|
453
|
-
import { Trans } from '@lingui/macro'
|
|
455
|
+
import { Trans } from '@lingui/react/macro'
|
|
454
456
|
|
|
455
457
|
import { HtmlHelpers } from '@salsita-ai/sdk/webhook'
|
|
456
458
|
|
|
@@ -547,6 +549,8 @@ When you're ready to ship:
|
|
|
547
549
|
phx build
|
|
548
550
|
```
|
|
549
551
|
|
|
552
|
+
With the application-spec pipeline, `phx dev` and `phx build` compile the Lingui macros in your frontend code with the SDK's own Lingui macro plugin and the configuration in `.phoenix/.linguirc`, so the project installs no Babel macro packages for them (see [Current and legacy project tooling](?path=/docs/phoenix-phoenix-cli--docs#current-and-legacy-project-tooling)).
|
|
553
|
+
|
|
550
554
|
### Translation Files
|
|
551
555
|
|
|
552
556
|
The `.po` files in `src/locales/` are standard GNU gettext format that most translation tools support:
|
|
@@ -565,7 +569,7 @@ During development, missing translations fall back to the message ID. In product
|
|
|
565
569
|
|
|
566
570
|
### Locale Fallback Configuration
|
|
567
571
|
|
|
568
|
-
Phoenix automatically configures comprehensive locale fallbacks in the
|
|
572
|
+
Phoenix automatically configures comprehensive locale fallbacks in the Lingui configuration it generates. When a translation is missing for a specific regional locale, it gracefully falls back to the base language before falling back to the default language (English).
|
|
569
573
|
|
|
570
574
|
**Fallback Rules:**
|
|
571
575
|
|
|
@@ -595,7 +599,7 @@ User locale: de-AT (Austrian German)
|
|
|
595
599
|
└─ Translation in en? → Use it (default fallback)
|
|
596
600
|
```
|
|
597
601
|
|
|
598
|
-
The fallback configuration is generated by `phx sync` and stored in `.linguirc
|
|
602
|
+
The fallback configuration is generated by `phx sync` and stored in `.phoenix/.linguirc` (in the project root on the legacy pipeline; see [Current and legacy project tooling](?path=/docs/phoenix-phoenix-cli--docs#current-and-legacy-project-tooling)). You don't need to configure this manually - it's handled automatically based on your `availableLocales` in `spec/application.yaml`.
|
|
599
603
|
|
|
600
604
|
## What We Learned
|
|
601
605
|
|