@praxisui/settings-panel 9.0.5-rc.37 → 9.0.5-rc.39

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 CHANGED
@@ -49,6 +49,9 @@ export class SettingsContentComponent implements SettingsValueProvider {
49
49
 
50
50
  Open this standalone content with `SettingsPanelService.open(...)`; the host
51
51
  observes `SettingsPanelRef.applied$` and `saved$` to apply or persist changes.
52
+ When that content needs to open a subordinate authoring editor, use
53
+ `SettingsPanelService.openChild(...)`. The child receives its own lifecycle
54
+ while the parent panel and its unsaved draft remain mounted.
52
55
 
53
56
  Peer dependencies (Angular v21):
54
57
 
@@ -80,6 +83,7 @@ Peer dependencies (Angular v21):
80
83
  - `expanded: true` abre o painel ja expandido de forma efetiva, respeitando `maxWidth`.
81
84
  - Expandir temporariamente o painel nao substitui a preferencia persistida do usuario; apenas o resize manual continua sendo persistido.
82
85
  - Quando um editor autoral tentar abrir outro painel sobre o atual, o shell passa pela mesma mediacao de fechamento do proprio painel. Se `onBeforeClose` vetar o fechamento, a substituicao nao acontece.
86
+ - Para composicao intencional de editores, use `openChild(...)`: o painel filho fica acima do pai e, ao fechar, devolve o controle ao draft pai sem emitir fechamento ou descarte nele.
83
87
 
84
88
  ### 2. Drawer runtime
85
89
 
@@ -155,6 +159,12 @@ Regra de integracao:
155
159
  - `config.maxWidth?: string`
156
160
  - `config.diagnostics?: SettingsPanelDiagnosticsConfig`
157
161
  - `config.content: { component: Type<any>; inputs?: Record<string, any> }`
162
+ - `openChild(config: SettingsPanelConfig): SettingsPanelRef`
163
+ - use somente para delegar uma parte do mesmo documento autoral a um editor subordinado
164
+ - preserva o draft do pai, mas torna sua superfície inerte e suspende seus atalhos globais
165
+ - ao fechar o filho, restaura foco/interação do pai sem emitir `closed$` nele
166
+ - `close(reason?: SettingsPanelCloseReason): void`
167
+ - fecha o painel atualmente ativo; em uma composição pai/filho, fecha primeiro o filho
158
168
 
159
169
  ### Ref
160
170
 
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-08-19T01:49:06.767Z",
3
+ "generatedAt": "2026-08-19T11:10:58.413Z",
4
4
  "packageName": "@praxisui/settings-panel",
5
- "packageVersion": "9.0.5-rc.37",
5
+ "packageVersion": "9.0.5-rc.39",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 1,
@@ -191,7 +191,7 @@
191
191
  {
192
192
  "name": "config",
193
193
  "type": "SettingsPanelConfig",
194
- "description": "Canonical settings panel shell config passed to SettingsPanelService.open."
194
+ "description": "Canonical settings panel shell config passed to SettingsPanelService.open or to openChild for a subordinate editor of the same authoring document."
195
195
  },
196
196
  {
197
197
  "name": "config.diagnostics",
@@ -862,7 +862,8 @@
862
862
  "editor-component-registered",
863
863
  "settings-value-provider-contract-present",
864
864
  "consumer-config-delegated",
865
- "editor-inputs-serializable"
865
+ "editor-inputs-serializable",
866
+ "child-panel-isolates-parent-interaction"
866
867
  ],
867
868
  "affectedPaths": [
868
869
  "config.content.component",
@@ -949,6 +950,12 @@
949
950
  "code": "SETTINGS_PANEL_REPLACEMENT_MEDIATES_CLOSE",
950
951
  "description": "Opening a replacement panel must consult the current editor onBeforeClose before closing."
951
952
  },
953
+ {
954
+ "validatorId": "child-panel-isolates-parent-interaction",
955
+ "level": "error",
956
+ "code": "SETTINGS_PANEL_CHILD_ISOLATES_PARENT",
957
+ "description": "A subordinate authoring panel must preserve the parent draft while making the parent inert and preventing parent keyboard shortcuts until the child closes."
958
+ },
952
959
  {
953
960
  "validatorId": "title-i18n-compatible",
954
961
  "level": "warning",
@@ -1081,7 +1088,8 @@
1081
1088
  "SettingsValueProvider owns apply/save/reset payload extraction, while consumer config semantics stay delegated to the owning component manifest.",
1082
1089
  "Apply must emit applied$ without closing; Save must emit saved$ and close with reason save; Reset must be confirmed and emit reset$.",
1083
1090
  "Busy, dirty and valid state must gate Apply and Save consistently and remain visible through diagnostics.",
1084
- "Opening a replacement panel must pass through the current editor onBeforeClose and dirty-discard mediation."
1091
+ "Opening a replacement panel must pass through the current editor onBeforeClose and dirty-discard mediation.",
1092
+ "Opening a subordinate editor with openChild must preserve the parent draft, isolate parent focus and shortcuts, and reactivate the parent only after the child closes."
1085
1093
  ],
1086
1094
  "examples": [
1087
1095
  {
@@ -1287,9 +1295,9 @@
1287
1295
  {
1288
1296
  "chunkIndex": 8,
1289
1297
  "chunkKind": "authoring_manifest",
1290
- "content": "{\"operationId\":\"editor.host.configure\",\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"praxis-settings-panel\",\"ownerPackage\":\"@praxisui/settings-panel\",\"configSchemaId\":\"SettingsPanelConfig\",\"chunkSection\":\"operation_card\",\"semanticSummary\":\"Configure hosted editor Effects: compile-domain-patch. Open the table settings editor in the settings panel. Use settings-panel to rename a table column directly. Host a component that has no dirty, valid, busy or getSettingsValue contract.\",\"scope\":\"templating\",\"target\":{\"kind\":\"editorHost\",\"resolver\":\"settings-panel-editor-host\",\"required\":true},\"inputContract\":{\"required\":[\"componentId\"],\"properties\":[\"componentId\",\"inputs\",\"configManifestComponentId\",\"editorContract\"],\"semanticTerms\":[\"componentId\",\"inputs\",\"configManifestComponentId\",\"editorContract\",\"SettingsValueProvider\"]},\"effects\":[\"compile-domain-patch\"],\"affectedPaths\":[\"config.content.component\",\"config.content.inputs\",\"delegatedConsumerPatch\"],\"validators\":[{\"validatorId\":\"editor-component-registered\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_EDITOR_REGISTERED\",\"description\":\"Hosted editor component must resolve from governed component metadata or host registration.\"},{\"validatorId\":\"settings-value-provider-contract-present\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_PROVIDER_CONTRACT_PRESENT\",\"description\":\"Hosted authoring editors must implement SettingsValueProvider state and value contract.\"},{\"validatorId\":\"consumer-config-delegated\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_CONSUMER_CONFIG_DELEGATED\",\"description\":\"Consumer-specific config operations must delegate to the owning component manifest.\"},{\"validatorId\":\"editor-inputs-serializable\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_EDITOR_INPUTS_SERIALIZABLE\",\"description\":\"Persisted editor host inputs must be serializable safe values.\"}],\"preconditions\":[\"component-metadata-resolved\"],\"submissionImpact\":\"config-only\",\"presentationAffordances\":[],\"positiveExamples\":[{\"id\":\"open-component-editor\",\"request\":\"Open the table settings editor in the settings panel.\",\"operationId\":\"editor.host.configure\",\"params\":{\"componentId\":\"praxis-table\",\"inputs\":{\"tableId\":\"orders\"},\"configManifestComponentId\":\"praxis-table\",\"editorContract\":\"SettingsValueProvider\"},\"isPositive\":true}],\"negativeExamples\":[{\"id\":\"reject-table-column-direct-edit\",\"request\":\"Use settings-panel to rename a table column directly.\",\"operationId\":\"editor.host.configure\",\"params\":{\"componentId\":\"praxis-settings-panel\",\"inputs\":{\"columns\":[{\"field\":\"name\",\"label\":\"Name\"}]}},\"isPositive\":false},{\"id\":\"reject-missing-provider\",\"request\":\"Host a component that has no dirty, valid, busy or getSettingsValue contract.\",\"operationId\":\"editor.host.configure\",\"params\":{\"componentId\":\"plain-info-card\"},\"isPositive\":false}]}",
1298
+ "content": "{\"operationId\":\"editor.host.configure\",\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"praxis-settings-panel\",\"ownerPackage\":\"@praxisui/settings-panel\",\"configSchemaId\":\"SettingsPanelConfig\",\"chunkSection\":\"operation_card\",\"semanticSummary\":\"Configure hosted editor Effects: compile-domain-patch. Open the table settings editor in the settings panel. Use settings-panel to rename a table column directly. Host a component that has no dirty, valid, busy or getSettingsValue contract.\",\"scope\":\"templating\",\"target\":{\"kind\":\"editorHost\",\"resolver\":\"settings-panel-editor-host\",\"required\":true},\"inputContract\":{\"required\":[\"componentId\"],\"properties\":[\"componentId\",\"inputs\",\"configManifestComponentId\",\"editorContract\"],\"semanticTerms\":[\"componentId\",\"inputs\",\"configManifestComponentId\",\"editorContract\",\"SettingsValueProvider\"]},\"effects\":[\"compile-domain-patch\"],\"affectedPaths\":[\"config.content.component\",\"config.content.inputs\",\"delegatedConsumerPatch\"],\"validators\":[{\"validatorId\":\"editor-component-registered\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_EDITOR_REGISTERED\",\"description\":\"Hosted editor component must resolve from governed component metadata or host registration.\"},{\"validatorId\":\"settings-value-provider-contract-present\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_PROVIDER_CONTRACT_PRESENT\",\"description\":\"Hosted authoring editors must implement SettingsValueProvider state and value contract.\"},{\"validatorId\":\"consumer-config-delegated\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_CONSUMER_CONFIG_DELEGATED\",\"description\":\"Consumer-specific config operations must delegate to the owning component manifest.\"},{\"validatorId\":\"editor-inputs-serializable\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_EDITOR_INPUTS_SERIALIZABLE\",\"description\":\"Persisted editor host inputs must be serializable safe values.\"},{\"validatorId\":\"child-panel-isolates-parent-interaction\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_CHILD_ISOLATES_PARENT\",\"description\":\"A subordinate authoring panel must preserve the parent draft while making the parent inert and preventing parent keyboard shortcuts until the child closes.\"}],\"preconditions\":[\"component-metadata-resolved\"],\"submissionImpact\":\"config-only\",\"presentationAffordances\":[],\"positiveExamples\":[{\"id\":\"open-component-editor\",\"request\":\"Open the table settings editor in the settings panel.\",\"operationId\":\"editor.host.configure\",\"params\":{\"componentId\":\"praxis-table\",\"inputs\":{\"tableId\":\"orders\"},\"configManifestComponentId\":\"praxis-table\",\"editorContract\":\"SettingsValueProvider\"},\"isPositive\":true}],\"negativeExamples\":[{\"id\":\"reject-table-column-direct-edit\",\"request\":\"Use settings-panel to rename a table column directly.\",\"operationId\":\"editor.host.configure\",\"params\":{\"componentId\":\"praxis-settings-panel\",\"inputs\":{\"columns\":[{\"field\":\"name\",\"label\":\"Name\"}]}},\"isPositive\":false},{\"id\":\"reject-missing-provider\",\"request\":\"Host a component that has no dirty, valid, busy or getSettingsValue contract.\",\"operationId\":\"editor.host.configure\",\"params\":{\"componentId\":\"plain-info-card\"},\"isPositive\":false}]}",
1291
1299
  "sourcePointer": "projects/praxis-settings-panel/src/lib/ai/praxis-settings-panel-authoring-manifest.ts",
1292
- "contentHash": "c8d462760a6bd9a86f89e0856c2395b58dc314f8a10f8571168ba02cf20add9e",
1300
+ "contentHash": "1c6fc7fe58a3d14fc9e0b9e3040d6935d68bc3b3239338b8c9a8f4bc78659845",
1293
1301
  "sourceKind": "component_definition",
1294
1302
  "sourceId": "praxis-settings-panel",
1295
1303
  "corpusVersion": "1.0.0"
@@ -1317,9 +1325,9 @@
1317
1325
  {
1318
1326
  "chunkIndex": 11,
1319
1327
  "chunkKind": "authoring_manifest",
1320
- "content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"praxis-settings-panel\",\"ownerPackage\":\"@praxisui/settings-panel\",\"configSchemaId\":\"SettingsPanelConfig\",\"chunkSection\":\"runtimeInputs\",\"runtimeInputs\":[{\"name\":\"config\",\"type\":\"SettingsPanelConfig\",\"description\":\"Canonical settings panel shell config passed to SettingsPanelService.open.\"},{\"name\":\"config.diagnostics\",\"type\":\"SettingsPanelDiagnosticsConfig\",\"description\":\"Optional shell diagnostics visibility config for status, disabled reason, busy state and validation state.\"},{\"name\":\"content.component\",\"type\":\"Type<SettingsValueProvider>\",\"description\":\"Standalone editor component hosted inside the authoring shell.\"},{\"name\":\"content.inputs\",\"type\":\"Record<string, unknown>\",\"description\":\"Initial editor inputs owned by the consumer component manifest.\"},{\"name\":\"ref\",\"type\":\"SettingsPanelRef\",\"description\":\"Panel ref that emits applied, saved, reset, closed and sizeChanged events.\"},{\"name\":\"provider\",\"type\":\"SettingsValueProvider\",\"description\":\"Editor protocol for dirty, valid, busy, getSettingsValue, onSave, reset and close hooks.\"}]}",
1328
+ "content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"praxis-settings-panel\",\"ownerPackage\":\"@praxisui/settings-panel\",\"configSchemaId\":\"SettingsPanelConfig\",\"chunkSection\":\"runtimeInputs\",\"runtimeInputs\":[{\"name\":\"config\",\"type\":\"SettingsPanelConfig\",\"description\":\"Canonical settings panel shell config passed to SettingsPanelService.open or to openChild for a subordinate editor of the same authoring document.\"},{\"name\":\"config.diagnostics\",\"type\":\"SettingsPanelDiagnosticsConfig\",\"description\":\"Optional shell diagnostics visibility config for status, disabled reason, busy state and validation state.\"},{\"name\":\"content.component\",\"type\":\"Type<SettingsValueProvider>\",\"description\":\"Standalone editor component hosted inside the authoring shell.\"},{\"name\":\"content.inputs\",\"type\":\"Record<string, unknown>\",\"description\":\"Initial editor inputs owned by the consumer component manifest.\"},{\"name\":\"ref\",\"type\":\"SettingsPanelRef\",\"description\":\"Panel ref that emits applied, saved, reset, closed and sizeChanged events.\"},{\"name\":\"provider\",\"type\":\"SettingsValueProvider\",\"description\":\"Editor protocol for dirty, valid, busy, getSettingsValue, onSave, reset and close hooks.\"}]}",
1321
1329
  "sourcePointer": "projects/praxis-settings-panel/src/lib/ai/praxis-settings-panel-authoring-manifest.ts",
1322
- "contentHash": "a5bb1979f05c7cdb7696331f4f3f6a4cd6d2be4f557caf76effbb9165fd0263e",
1330
+ "contentHash": "6aefd3c8ddd901bf20faa01aab1d3b34a570a06f9485e926f380a5b52230005b",
1323
1331
  "sourceKind": "component_definition",
1324
1332
  "sourceId": "praxis-settings-panel",
1325
1333
  "corpusVersion": "1.0.0"
@@ -1347,9 +1355,9 @@
1347
1355
  {
1348
1356
  "chunkIndex": 14,
1349
1357
  "chunkKind": "authoring_manifest",
1350
- "content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"praxis-settings-panel\",\"ownerPackage\":\"@praxisui/settings-panel\",\"configSchemaId\":\"SettingsPanelConfig\",\"chunkSection\":\"operations\",\"operations\":[{\"operationId\":\"panel.resetBehavior.set\",\"title\":\"Set reset behavior\",\"scope\":\"interaction\",\"targetKind\":\"resetBehavior\",\"target\":{\"kind\":\"resetBehavior\",\"resolver\":\"settings-value-provider-reset-contract\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"minProperties\":1,\"properties\":{\"requireConfirmation\":{\"type\":\"boolean\"},\"callProviderReset\":{\"type\":\"boolean\"},\"emitResetEvent\":{\"type\":\"boolean\"},\"clearSavedStatus\":{\"type\":\"boolean\"}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"settings-panel-reset-behavior-set\",\"handlerContract\":{\"reads\":[\"SettingsValueProvider.reset\",\"SettingsPanelRef.reset$\",\"ConfirmDialogComponent\"],\"writes\":[\"provider.reset()\",\"SettingsPanelRef.reset$\",\"panel.lastSavedAt\"],\"identityKeys\":[\"config.id\",\"provider.reset\"],\"inputSchema\":{\"type\":\"object\",\"properties\":{\"requireConfirmation\":{\"type\":\"boolean\"},\"callProviderReset\":{\"type\":\"boolean\"},\"emitResetEvent\":{\"type\":\"boolean\"}}},\"failureModes\":[\"reset-confirmation-missing\",\"provider-reset-failed\",\"reset-event-not-emitted\"],\"description\":\"Preserves Reset as a confirmed shell action that calls the provider reset hook and emits SettingsPanelRef.reset$.\"}}],\"destructive\":true,\"requiresConfirmation\":true,\"validators\":[\"reset-requires-confirmation\",\"reset-calls-provider-reset\",\"reset-event-emitted\",\"settings-panel-round-trip\"],\"affectedPaths\":[\"provider.reset\",\"ref.reset$\",\"panel.lastSavedAt\"],\"submissionImpact\":\"config-only\",\"preconditions\":[\"settings-value-provider-attached\",\"confirmation-collected\"]},{\"operationId\":\"editor.host.configure\",\"title\":\"Configure hosted editor\",\"scope\":\"templating\",\"targetKind\":\"editorHost\",\"target\":{\"kind\":\"editorHost\",\"resolver\":\"settings-panel-editor-host\",\"ambiguityPolicy\":\"fail\",\"required\":true},\"inputSchema\":{\"type\":\"object\",\"required\":[\"componentId\"],\"properties\":{\"componentId\":{\"type\":\"string\"},\"inputs\":{\"type\":\"object\"},\"configManifestComponentId\":{\"type\":\"string\"},\"editorContract\":{\"enum\":[\"SettingsValueProvider\"]}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"settings-panel-editor-host-configure\",\"handlerContract\":{\"reads\":[\"ComponentMetadataRegistry\",\"SettingsPanelConfig.content\",\"SettingsValueProvider\",\"component.authoringManifest\"],\"writes\":[\"config.content.component\",\"config.content.inputs\",\"delegatedConsumerPatch\"],\"identityKeys\":[\"componentId\",\"configManifestComponentId\"],\"inputSchema\":{\"type\":\"object\",\"required\":[\"componentId\"],\"properties\":{\"componentId\":{\"type\":\"string\"},\"inputs\":{\"type\":\"object\"},\"configManifestComponentId\":{\"type\":\"string\"},\"editorContract\":{\"enum\":[\"SettingsValueProvider\"]}}},\"failureModes\":[\"editor-component-not-registered\",\"settings-value-provider-missing\",\"consumer-manifest-required\",\"consumer-config-boundary-violation\"],\"description\":\"Configures the hosted editor component and input envelope while delegating consumer-specific config edits to the owning component manifest.\"}}],\"validators\":[\"editor-component-registered\",\"settings-value-provider-contract-present\",\"consumer-config-delegated\",\"editor-inputs-serializable\"],\"affectedPaths\":[\"config.content.component\",\"config.content.inputs\",\"delegatedConsumerPatch\"],\"submissionImpact\":\"config-only\",\"destructive\":false,\"requiresConfirmation\":false,\"preconditions\":[\"component-metadata-resolved\"]},{\"operationId\":\"diagnostics.visibility.set\",\"title\":\"Set panel diagnostics visibility\",\"scope\":\"interaction\",\"targetKind\":\"diagnostics\",\"target\":{\"kind\":\"diagnostics\",\"resolver\":\"settings-panel-state-diagnostics\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"minProperties\":1,\"properties\":{\"showStatusMessage\":{\"type\":\"boolean\"},\"showDisabledReason\":{\"type\":\"boolean\"},\"showBusyState\":{\"type\":\"boolean\"},\"exposeValidationState\":{\"type\":\"boolean\"}}},\"effects\":[{\"kind\":\"merge-object\",\"path\":\"config.diagnostics\"}],\"validators\":[\"diagnostics-follow-provider-state\",\"diagnostics-i18n-compatible\",\"busy-valid-dirty-visible-when-needed\",\"settings-panel-round-trip\"],\"affectedPaths\":[\"config.diagnostics.showStatusMessage\",\"config.diagnostics.showDisabledReason\",\"config.diagnostics.showBusyState\",\"config.diagnostics.exposeValidationState\",\"panel.statusMessage\",\"panel.disabledReason\",\"panel.isDirty\",\"panel.isValid\",\"panel.isBusy\"],\"submissionImpact\":\"visual-only\",\"destructive\":false,\"requiresConfirmation\":false,\"preconditions\":[\"settings-value-provider-attached\"]}]}",
1358
+ "content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"praxis-settings-panel\",\"ownerPackage\":\"@praxisui/settings-panel\",\"configSchemaId\":\"SettingsPanelConfig\",\"chunkSection\":\"operations\",\"operations\":[{\"operationId\":\"panel.resetBehavior.set\",\"title\":\"Set reset behavior\",\"scope\":\"interaction\",\"targetKind\":\"resetBehavior\",\"target\":{\"kind\":\"resetBehavior\",\"resolver\":\"settings-value-provider-reset-contract\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"minProperties\":1,\"properties\":{\"requireConfirmation\":{\"type\":\"boolean\"},\"callProviderReset\":{\"type\":\"boolean\"},\"emitResetEvent\":{\"type\":\"boolean\"},\"clearSavedStatus\":{\"type\":\"boolean\"}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"settings-panel-reset-behavior-set\",\"handlerContract\":{\"reads\":[\"SettingsValueProvider.reset\",\"SettingsPanelRef.reset$\",\"ConfirmDialogComponent\"],\"writes\":[\"provider.reset()\",\"SettingsPanelRef.reset$\",\"panel.lastSavedAt\"],\"identityKeys\":[\"config.id\",\"provider.reset\"],\"inputSchema\":{\"type\":\"object\",\"properties\":{\"requireConfirmation\":{\"type\":\"boolean\"},\"callProviderReset\":{\"type\":\"boolean\"},\"emitResetEvent\":{\"type\":\"boolean\"}}},\"failureModes\":[\"reset-confirmation-missing\",\"provider-reset-failed\",\"reset-event-not-emitted\"],\"description\":\"Preserves Reset as a confirmed shell action that calls the provider reset hook and emits SettingsPanelRef.reset$.\"}}],\"destructive\":true,\"requiresConfirmation\":true,\"validators\":[\"reset-requires-confirmation\",\"reset-calls-provider-reset\",\"reset-event-emitted\",\"settings-panel-round-trip\"],\"affectedPaths\":[\"provider.reset\",\"ref.reset$\",\"panel.lastSavedAt\"],\"submissionImpact\":\"config-only\",\"preconditions\":[\"settings-value-provider-attached\",\"confirmation-collected\"]},{\"operationId\":\"editor.host.configure\",\"title\":\"Configure hosted editor\",\"scope\":\"templating\",\"targetKind\":\"editorHost\",\"target\":{\"kind\":\"editorHost\",\"resolver\":\"settings-panel-editor-host\",\"ambiguityPolicy\":\"fail\",\"required\":true},\"inputSchema\":{\"type\":\"object\",\"required\":[\"componentId\"],\"properties\":{\"componentId\":{\"type\":\"string\"},\"inputs\":{\"type\":\"object\"},\"configManifestComponentId\":{\"type\":\"string\"},\"editorContract\":{\"enum\":[\"SettingsValueProvider\"]}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"settings-panel-editor-host-configure\",\"handlerContract\":{\"reads\":[\"ComponentMetadataRegistry\",\"SettingsPanelConfig.content\",\"SettingsValueProvider\",\"component.authoringManifest\"],\"writes\":[\"config.content.component\",\"config.content.inputs\",\"delegatedConsumerPatch\"],\"identityKeys\":[\"componentId\",\"configManifestComponentId\"],\"inputSchema\":{\"type\":\"object\",\"required\":[\"componentId\"],\"properties\":{\"componentId\":{\"type\":\"string\"},\"inputs\":{\"type\":\"object\"},\"configManifestComponentId\":{\"type\":\"string\"},\"editorContract\":{\"enum\":[\"SettingsValueProvider\"]}}},\"failureModes\":[\"editor-component-not-registered\",\"settings-value-provider-missing\",\"consumer-manifest-required\",\"consumer-config-boundary-violation\"],\"description\":\"Configures the hosted editor component and input envelope while delegating consumer-specific config edits to the owning component manifest.\"}}],\"validators\":[\"editor-component-registered\",\"settings-value-provider-contract-present\",\"consumer-config-delegated\",\"editor-inputs-serializable\",\"child-panel-isolates-parent-interaction\"],\"affectedPaths\":[\"config.content.component\",\"config.content.inputs\",\"delegatedConsumerPatch\"],\"submissionImpact\":\"config-only\",\"destructive\":false,\"requiresConfirmation\":false,\"preconditions\":[\"component-metadata-resolved\"]},{\"operationId\":\"diagnostics.visibility.set\",\"title\":\"Set panel diagnostics visibility\",\"scope\":\"interaction\",\"targetKind\":\"diagnostics\",\"target\":{\"kind\":\"diagnostics\",\"resolver\":\"settings-panel-state-diagnostics\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"minProperties\":1,\"properties\":{\"showStatusMessage\":{\"type\":\"boolean\"},\"showDisabledReason\":{\"type\":\"boolean\"},\"showBusyState\":{\"type\":\"boolean\"},\"exposeValidationState\":{\"type\":\"boolean\"}}},\"effects\":[{\"kind\":\"merge-object\",\"path\":\"config.diagnostics\"}],\"validators\":[\"diagnostics-follow-provider-state\",\"diagnostics-i18n-compatible\",\"busy-valid-dirty-visible-when-needed\",\"settings-panel-round-trip\"],\"affectedPaths\":[\"config.diagnostics.showStatusMessage\",\"config.diagnostics.showDisabledReason\",\"config.diagnostics.showBusyState\",\"config.diagnostics.exposeValidationState\",\"panel.statusMessage\",\"panel.disabledReason\",\"panel.isDirty\",\"panel.isValid\",\"panel.isBusy\"],\"submissionImpact\":\"visual-only\",\"destructive\":false,\"requiresConfirmation\":false,\"preconditions\":[\"settings-value-provider-attached\"]}]}",
1351
1359
  "sourcePointer": "projects/praxis-settings-panel/src/lib/ai/praxis-settings-panel-authoring-manifest.ts",
1352
- "contentHash": "f241c2fdcbb24c343dd55e42191c1edfd147dceff22135635d4321a07027e133",
1360
+ "contentHash": "9d55ed7aad2a6a94e5c55c4beb83f7c7459e2c9fcc180fb4043bfb13be2de5c0",
1353
1361
  "sourceKind": "component_definition",
1354
1362
  "sourceId": "praxis-settings-panel",
1355
1363
  "corpusVersion": "1.0.0"
@@ -1357,9 +1365,9 @@
1357
1365
  {
1358
1366
  "chunkIndex": 15,
1359
1367
  "chunkKind": "authoring_manifest",
1360
- "content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"praxis-settings-panel\",\"ownerPackage\":\"@praxisui/settings-panel\",\"configSchemaId\":\"SettingsPanelConfig\",\"chunkSection\":\"validators\",\"validators\":[{\"validatorId\":\"panel-id-stable\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_ID_STABLE\",\"description\":\"Panel id must remain stable for replacement, persistence and diagnostics.\"},{\"validatorId\":\"replacement-mediates-before-close\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_REPLACEMENT_MEDIATES_CLOSE\",\"description\":\"Opening a replacement panel must consult the current editor onBeforeClose before closing.\"},{\"validatorId\":\"title-i18n-compatible\",\"level\":\"warning\",\"code\":\"SETTINGS_PANEL_TITLE_I18N_COMPATIBLE\",\"description\":\"Authoring chrome text must remain compatible with the settings panel i18n namespace.\"},{\"validatorId\":\"panel-size-safe\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_SIZE_SAFE\",\"description\":\"Panel sizes must be finite numbers or safe CSS size strings.\"},{\"validatorId\":\"panel-min-max-consistent\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_MIN_MAX_CONSISTENT\",\"description\":\"Minimum width must not exceed maximum width.\"},{\"validatorId\":\"resize-persistence-explicit\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_RESIZE_PERSISTENCE_EXPLICIT\",\"description\":\"Persisted resize must use a stable persistSizeKey or be explicitly transient.\"},{\"validatorId\":\"apply-requires-provider-value\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_APPLY_REQUIRES_PROVIDER_VALUE\",\"description\":\"Apply must obtain payloads from SettingsValueProvider.getSettingsValue().\"},{\"validatorId\":\"apply-does-not-close-panel\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_APPLY_DOES_NOT_CLOSE\",\"description\":\"Apply emits preview payloads without closing the panel.\"},{\"validatorId\":\"dirty-valid-busy-gates-preserved\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_STATE_GATES_PRESERVED\",\"description\":\"Apply and Save remain gated by dirty, valid and busy state.\"},{\"validatorId\":\"save-prefers-provider-hook\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_SAVE_PREFERS_PROVIDER_HOOK\",\"description\":\"Save must call onSave when provided before falling back to getSettingsValue().\"},{\"validatorId\":\"save-fallback-value-preserved\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_SAVE_FALLBACK_PRESERVED\",\"description\":\"Save fallback must preserve getSettingsValue payload semantics.\"},{\"validatorId\":\"save-closes-with-save-reason\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_SAVE_CLOSE_REASON\",\"description\":\"Successful save must emit saved$ and close with reason save.\"},{\"validatorId\":\"reset-requires-confirmation\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_RESET_REQUIRES_CONFIRMATION\",\"description\":\"Reset is destructive and must remain confirmed before provider reset is called.\"},{\"validatorId\":\"reset-calls-provider-reset\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_RESET_CALLS_PROVIDER\",\"description\":\"Reset must call the hosted provider reset hook when present.\"},{\"validatorId\":\"reset-event-emitted\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_RESET_EVENT_EMITTED\",\"description\":\"Reset must emit SettingsPanelRef.reset$ so hosts can coordinate state.\"},{\"validatorId\":\"editor-component-registered\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_EDITOR_REGISTERED\",\"description\":\"Hosted editor component must resolve from governed component metadata or host registration.\"},{\"validatorId\":\"settings-value-provider-contract-present\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_PROVIDER_CONTRACT_PRESENT\",\"description\":\"Hosted authoring editors must implement SettingsValueProvider state and value contract.\"},{\"validatorId\":\"consumer-config-delegated\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_CONSUMER_CONFIG_DELEGATED\",\"description\":\"Consumer-specific config operations must delegate to the owning component manifest.\"},{\"validatorId\":\"editor-inputs-serializable\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_EDITOR_INPUTS_SERIALIZABLE\",\"description\":\"Persisted editor host inputs must be serializable safe values.\"},{\"validatorId\":\"diagnostics-follow-provider-state\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_DIAGNOSTICS_PROVIDER_STATE\",\"description\":\"Diagnostics must reflect provider dirty, valid and busy state.\"},{\"validatorId\":\"diagnostics-i18n-compatible\",\"level\":\"warning\",\"code\":\"SETTINGS_PANEL_DIAGNOSTICS_I18N_COMPATIBLE\",\"description\":\"Diagnostics copy must use the settings panel i18n namespace.\"},{\"validatorId\":\"busy-valid-dirty-visible-when-needed\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_STATE_VISIBLE\",\"description\":\"Busy, invalid and dirty states must remain visible or explain disabled actions.\"},{\"validatorId\":\"settings-panel-round-trip\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_ROUND_TRIP\",\"description\":\"Open, edit, apply, save, reset and reopen must preserve the shell protocol without mutating consumer config semantics.\"}]}",
1368
+ "content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"praxis-settings-panel\",\"ownerPackage\":\"@praxisui/settings-panel\",\"configSchemaId\":\"SettingsPanelConfig\",\"chunkSection\":\"validators\",\"validators\":[{\"validatorId\":\"panel-id-stable\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_ID_STABLE\",\"description\":\"Panel id must remain stable for replacement, persistence and diagnostics.\"},{\"validatorId\":\"replacement-mediates-before-close\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_REPLACEMENT_MEDIATES_CLOSE\",\"description\":\"Opening a replacement panel must consult the current editor onBeforeClose before closing.\"},{\"validatorId\":\"child-panel-isolates-parent-interaction\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_CHILD_ISOLATES_PARENT\",\"description\":\"A subordinate authoring panel must preserve the parent draft while making the parent inert and preventing parent keyboard shortcuts until the child closes.\"},{\"validatorId\":\"title-i18n-compatible\",\"level\":\"warning\",\"code\":\"SETTINGS_PANEL_TITLE_I18N_COMPATIBLE\",\"description\":\"Authoring chrome text must remain compatible with the settings panel i18n namespace.\"},{\"validatorId\":\"panel-size-safe\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_SIZE_SAFE\",\"description\":\"Panel sizes must be finite numbers or safe CSS size strings.\"},{\"validatorId\":\"panel-min-max-consistent\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_MIN_MAX_CONSISTENT\",\"description\":\"Minimum width must not exceed maximum width.\"},{\"validatorId\":\"resize-persistence-explicit\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_RESIZE_PERSISTENCE_EXPLICIT\",\"description\":\"Persisted resize must use a stable persistSizeKey or be explicitly transient.\"},{\"validatorId\":\"apply-requires-provider-value\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_APPLY_REQUIRES_PROVIDER_VALUE\",\"description\":\"Apply must obtain payloads from SettingsValueProvider.getSettingsValue().\"},{\"validatorId\":\"apply-does-not-close-panel\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_APPLY_DOES_NOT_CLOSE\",\"description\":\"Apply emits preview payloads without closing the panel.\"},{\"validatorId\":\"dirty-valid-busy-gates-preserved\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_STATE_GATES_PRESERVED\",\"description\":\"Apply and Save remain gated by dirty, valid and busy state.\"},{\"validatorId\":\"save-prefers-provider-hook\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_SAVE_PREFERS_PROVIDER_HOOK\",\"description\":\"Save must call onSave when provided before falling back to getSettingsValue().\"},{\"validatorId\":\"save-fallback-value-preserved\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_SAVE_FALLBACK_PRESERVED\",\"description\":\"Save fallback must preserve getSettingsValue payload semantics.\"},{\"validatorId\":\"save-closes-with-save-reason\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_SAVE_CLOSE_REASON\",\"description\":\"Successful save must emit saved$ and close with reason save.\"},{\"validatorId\":\"reset-requires-confirmation\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_RESET_REQUIRES_CONFIRMATION\",\"description\":\"Reset is destructive and must remain confirmed before provider reset is called.\"},{\"validatorId\":\"reset-calls-provider-reset\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_RESET_CALLS_PROVIDER\",\"description\":\"Reset must call the hosted provider reset hook when present.\"},{\"validatorId\":\"reset-event-emitted\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_RESET_EVENT_EMITTED\",\"description\":\"Reset must emit SettingsPanelRef.reset$ so hosts can coordinate state.\"},{\"validatorId\":\"editor-component-registered\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_EDITOR_REGISTERED\",\"description\":\"Hosted editor component must resolve from governed component metadata or host registration.\"},{\"validatorId\":\"settings-value-provider-contract-present\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_PROVIDER_CONTRACT_PRESENT\",\"description\":\"Hosted authoring editors must implement SettingsValueProvider state and value contract.\"},{\"validatorId\":\"consumer-config-delegated\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_CONSUMER_CONFIG_DELEGATED\",\"description\":\"Consumer-specific config operations must delegate to the owning component manifest.\"},{\"validatorId\":\"editor-inputs-serializable\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_EDITOR_INPUTS_SERIALIZABLE\",\"description\":\"Persisted editor host inputs must be serializable safe values.\"},{\"validatorId\":\"diagnostics-follow-provider-state\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_DIAGNOSTICS_PROVIDER_STATE\",\"description\":\"Diagnostics must reflect provider dirty, valid and busy state.\"},{\"validatorId\":\"diagnostics-i18n-compatible\",\"level\":\"warning\",\"code\":\"SETTINGS_PANEL_DIAGNOSTICS_I18N_COMPATIBLE\",\"description\":\"Diagnostics copy must use the settings panel i18n namespace.\"},{\"validatorId\":\"busy-valid-dirty-visible-when-needed\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_STATE_VISIBLE\",\"description\":\"Busy, invalid and dirty states must remain visible or explain disabled actions.\"},{\"validatorId\":\"settings-panel-round-trip\",\"level\":\"error\",\"code\":\"SETTINGS_PANEL_ROUND_TRIP\",\"description\":\"Open, edit, apply, save, reset and reopen must preserve the shell protocol without mutating consumer config semantics.\"}]}",
1361
1369
  "sourcePointer": "projects/praxis-settings-panel/src/lib/ai/praxis-settings-panel-authoring-manifest.ts",
1362
- "contentHash": "a2f66de090eae4c731f69cf673551a0420af3625ab81bcfb4d41c4e6821efe24",
1370
+ "contentHash": "113367420fed3529b93de6f8f978657063d01fb96686feb8ee276c047bd1fe64",
1363
1371
  "sourceKind": "component_definition",
1364
1372
  "sourceId": "praxis-settings-panel",
1365
1373
  "corpusVersion": "1.0.0"
@@ -1367,9 +1375,9 @@
1367
1375
  {
1368
1376
  "chunkIndex": 16,
1369
1377
  "chunkKind": "authoring_manifest",
1370
- "content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"praxis-settings-panel\",\"ownerPackage\":\"@praxisui/settings-panel\",\"configSchemaId\":\"SettingsPanelConfig\",\"chunkSection\":\"roundTripRequirements\",\"roundTripRequirements\":[\"SettingsPanelConfig owns only shell fields: identity, title, size, resize persistence and hosted editor envelope.\",\"SettingsValueProvider owns apply/save/reset payload extraction, while consumer config semantics stay delegated to the owning component manifest.\",\"Apply must emit applied$ without closing; Save must emit saved$ and close with reason save; Reset must be confirmed and emit reset$.\",\"Busy, dirty and valid state must gate Apply and Save consistently and remain visible through diagnostics.\",\"Opening a replacement panel must pass through the current editor onBeforeClose and dirty-discard mediation.\"]}",
1378
+ "content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"praxis-settings-panel\",\"ownerPackage\":\"@praxisui/settings-panel\",\"configSchemaId\":\"SettingsPanelConfig\",\"chunkSection\":\"roundTripRequirements\",\"roundTripRequirements\":[\"SettingsPanelConfig owns only shell fields: identity, title, size, resize persistence and hosted editor envelope.\",\"SettingsValueProvider owns apply/save/reset payload extraction, while consumer config semantics stay delegated to the owning component manifest.\",\"Apply must emit applied$ without closing; Save must emit saved$ and close with reason save; Reset must be confirmed and emit reset$.\",\"Busy, dirty and valid state must gate Apply and Save consistently and remain visible through diagnostics.\",\"Opening a replacement panel must pass through the current editor onBeforeClose and dirty-discard mediation.\",\"Opening a subordinate editor with openChild must preserve the parent draft, isolate parent focus and shortcuts, and reactivate the parent only after the child closes.\"]}",
1371
1379
  "sourcePointer": "projects/praxis-settings-panel/src/lib/ai/praxis-settings-panel-authoring-manifest.ts",
1372
- "contentHash": "75c07611e26a30925189ba8fc8f2a69ef4405adc96da811ead2d218a0e37d8cb",
1380
+ "contentHash": "ab20146fd5fcac4be16991700131c38043e36b38d9518c1db8a7fe9b71e55930",
1373
1381
  "sourceKind": "component_definition",
1374
1382
  "sourceId": "praxis-settings-panel",
1375
1383
  "corpusVersion": "1.0.0"
@@ -547,6 +547,7 @@ class SettingsPanelComponent {
547
547
  resizable = false;
548
548
  persistSizeKey;
549
549
  expanded = false;
550
+ interactionActive = true;
550
551
  ref;
551
552
  contentRef;
552
553
  static nextId = 0;
@@ -574,7 +575,7 @@ class SettingsPanelComponent {
574
575
  this.overlayContainer = overlayContainer;
575
576
  }
576
577
  get canApply() {
577
- return this.isDirty && this.isValid && !this.isBusy;
578
+ return this.interactionActive && this.isDirty && this.isValid && !this.isBusy;
578
579
  }
579
580
  get panelInlineStyles() {
580
581
  return {
@@ -590,7 +591,11 @@ class SettingsPanelComponent {
590
591
  return this.tx('Resize panel');
591
592
  }
592
593
  get canSave() {
593
- return this.isDirty && this.isValid && !this.isBusy;
594
+ return this.interactionActive && this.isDirty && this.isValid && !this.isBusy;
595
+ }
596
+ setInteractionActive(active) {
597
+ this.interactionActive = active;
598
+ this.cdr.detectChanges();
594
599
  }
595
600
  get disabledReason() {
596
601
  if (this.isBusy) {
@@ -903,6 +908,9 @@ class SettingsPanelComponent {
903
908
  }));
904
909
  }
905
910
  handleKeydown(event) {
911
+ if (!this.interactionActive) {
912
+ return;
913
+ }
906
914
  if (event.key === 'Escape') {
907
915
  if (this.shouldDeferEscape(event)) {
908
916
  return;
@@ -1009,7 +1017,7 @@ class SettingsPanelComponent {
1009
1017
  .afterClosed();
1010
1018
  }
1011
1019
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SettingsPanelComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.MatDialog }, { token: i0.ElementRef }, { token: i1$1.OverlayContainer }], target: i0.ɵɵFactoryTarget.Component });
1012
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: SettingsPanelComponent, isStandalone: true, selector: "praxis-settings-panel", host: { listeners: { "document:keydown": "handleKeydown($event)", "document:pointermove": "onDocumentPointerMove($event)", "document:pointerup": "onDocumentPointerEnd($event)", "document:pointercancel": "onDocumentPointerEnd($event)" } }, providers: [providePraxisSettingsPanelI18n()], viewQueries: [{ propertyName: "contentHost", first: true, predicate: ["contentHost"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<div\n class=\"settings-panel\"\n data-testid=\"settings-panel-root\"\n [class.expanded]=\"expanded\"\n [class.is-resizable]=\"showResizeHandle\"\n [ngStyle]=\"panelInlineStyles\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-labelledby]=\"titleId\"\n cdkTrapFocus\n cdkTrapFocusAutoCapture\n >\n @if (showResizeHandle) {\n <div\n class=\"settings-panel__resize-handle\"\n role=\"separator\"\n tabindex=\"0\"\n aria-orientation=\"vertical\"\n [attr.aria-label]=\"resizeHandleLabel\"\n (pointerdown)=\"onResizeHandlePointerDown($event)\"\n (keydown)=\"onResizeHandleKeydown($event)\"\n ></div>\n }\n <header class=\"settings-panel-header\">\n <h2 class=\"settings-panel-title\" [id]=\"titleId\">\n @if (titleIcon) {\n <mat-icon class=\"title-icon\" [praxisIcon]=\"titleIcon\"></mat-icon>\n }\n <span>{{ title }}</span>\n </h2>\n <span class=\"spacer\"></span>\n <button\n [praxisIconButton]=\"expanded ? 'close_fullscreen' : 'open_in_full'\"\n size=\"compact\"\n type=\"button\"\n data-testid=\"settings-panel-toggle-expand\"\n [attr.aria-label]=\"expanded ? tx('Collapse panel') : tx('Expand panel')\"\n [attr.aria-expanded]=\"expanded\"\n [matTooltip]=\"expanded ? tx('Collapse panel') : tx('Expand panel')\"\n (click)=\"toggleExpand()\"\n ></button>\n <button\n praxisIconButton=\"close\"\n size=\"compact\"\n type=\"button\"\n data-testid=\"settings-panel-close-icon\"\n [attr.aria-label]=\"tx('Close')\"\n [matTooltip]=\"tx('Close')\"\n (click)=\"onCancel()\"\n ></button>\n </header>\n @if (showStatusMessage) {\n <div\n class=\"settings-panel-status\"\n [attr.data-status]=\"statusTone\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <mat-icon\n aria-hidden=\"true\"\n [praxisIcon]=\"\n statusTone === 'dirty' || statusTone === 'invalid'\n ? 'warning'\n : statusTone === 'saved'\n ? 'check_circle'\n : statusTone === 'busy'\n ? 'autorenew'\n : 'info'\n \"\n ></mat-icon>\n <span>{{ statusMessage }}</span>\n </div>\n }\n <div class=\"settings-panel-body\">\n <ng-template #contentHost></ng-template>\n </div>\n <footer class=\"settings-panel-footer\">\n <button\n mat-button\n type=\"button\"\n data-testid=\"settings-panel-reset\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); onReset()\"\n [disabled]=\"isBusy\"\n >\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'restart_alt'\"></mat-icon>\n <span>{{ tx('Reset') }}</span>\n </button>\n <span class=\"spacer\"></span>\n <button\n mat-button\n type=\"button\"\n data-testid=\"settings-panel-cancel\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); onCancel()\"\n [disabled]=\"isBusy\"\n >\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'close'\"></mat-icon>\n <span>{{ tx('Cancel') }}</span>\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n data-testid=\"settings-panel-apply\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); onApply()\"\n [disabled]=\"!canApply\"\n [matTooltip]=\"applySaveDisabledReason\"\n [matTooltipDisabled]=\"canApply || !diagnostics.showDisabledReason\"\n [attr.aria-busy]=\"isBusy\"\n [attr.aria-label]=\"applyActionLabel || 'Apply'\"\n >\n @if (showBusyIndicator) {\n <mat-progress-spinner\n mode=\"indeterminate\"\n diameter=\"20\"\n ></mat-progress-spinner>\n }\n @if (!showBusyIndicator) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'done'\"></mat-icon>\n <span class=\"settings-panel-action-label settings-panel-action-label--apply\">{{ applyActionLabel }}</span>\n }\n </button>\n <button\n mat-flat-button\n color=\"primary\"\n type=\"button\"\n data-testid=\"settings-panel-save\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); onSave()\"\n [disabled]=\"!canSave\"\n [matTooltip]=\"applySaveDisabledReason\"\n [matTooltipDisabled]=\"canSave || !diagnostics.showDisabledReason\"\n [attr.aria-busy]=\"isBusy\"\n [attr.aria-label]=\"saveActionLabel || 'Save & Close'\"\n >\n @if (showBusyIndicator) {\n <mat-progress-spinner\n mode=\"indeterminate\"\n diameter=\"20\"\n ></mat-progress-spinner>\n }\n @if (!showBusyIndicator) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'save'\"></mat-icon>\n <span class=\"settings-panel-action-label settings-panel-action-label--save\">{{ saveActionLabel }}</span>\n }\n </button>\n </footer>\n</div>\n", styles: ["@charset \"UTF-8\";praxis-settings-panel{display:block;height:100%;width:100%;min-width:0;flex:1 1 auto}praxis-settings-panel .settings-panel{position:relative;--pfx-settings-panel-surface-container: var( --md-sys-color-surface-container, #ffffff );--pfx-settings-panel-surface-container-high: var( --md-sys-color-surface-container-high, #f7f7f7 );--pfx-settings-panel-surface-container-low: var( --md-sys-color-surface-container-low, #f2f4f7 );--pfx-settings-panel-surface: var(--md-sys-color-surface, #ffffff);--pfx-settings-panel-on-surface: var(--md-sys-color-on-surface, #111827);--pfx-settings-panel-on-surface-variant: var( --md-sys-color-on-surface-variant, rgba(17, 24, 39, .72) );--pfx-settings-panel-outline: var( --md-sys-color-outline, rgba(15, 23, 42, .24) );--pfx-settings-panel-outline-variant: var( --md-sys-color-outline-variant, rgba(15, 23, 42, .12) );--pfx-settings-panel-primary: var(--md-sys-color-primary, #2563eb);--pfx-settings-panel-primary-container: var( --md-sys-color-primary-container, rgba(37, 99, 235, .14) );--pfx-settings-panel-on-primary-container: var( --md-sys-color-on-primary-container, #0f172a );--pfx-settings-panel-secondary: var( --md-sys-color-secondary, var(--pfx-settings-panel-primary) );--pfx-settings-panel-error: var(--md-sys-color-error, #b3261e);--pfx-settings-panel-error-container: var( --md-sys-color-error-container, rgba(179, 38, 30, .14) );display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto auto 1fr auto;grid-template-areas:\"header\" \"status\" \"body\" \"footer\";height:100%;background:var(--pfx-settings-panel-surface-container);color:var(--pfx-settings-panel-on-surface);border-left:1px solid var(--pfx-settings-panel-outline-variant);width:100%;max-width:100%;min-width:0;box-shadow:var(--pfx-settings-panel-elevation, var(--md-sys-elevation-level2, 0 8px 24px rgba(0, 0, 0, .16)));overflow:hidden}praxis-settings-panel .settings-panel__resize-handle{position:absolute;inset:0 auto 0 0;width:12px;cursor:col-resize;touch-action:none;z-index:3;outline:none}praxis-settings-panel .settings-panel__resize-handle:before{content:\"\";position:absolute;inset:0 auto 0 4px;width:2px;background:transparent;transition:background-color var(--pfx-side-panel-motion-duration, .16s) ease,opacity var(--pfx-side-panel-motion-duration, .16s) ease;opacity:0}praxis-settings-panel .settings-panel.is-resizable:hover .settings-panel__resize-handle:before,praxis-settings-panel .settings-panel__resize-handle:focus-visible:before{opacity:1;background:var(--pfx-settings-panel-outline)}praxis-settings-panel .settings-panel-header{grid-area:header;display:flex;align-items:center;gap:var(--pfx-settings-panel-header-gap, 8px);padding:12px var(--pfx-settings-panel-header-padding-x, 20px);min-height:var(--pfx-settings-panel-header-height, 64px);border-bottom:1px solid var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-high);box-shadow:var(--pfx-settings-panel-header-shadow, var(--md-sys-elevation-level1, 0 2px 6px rgba(0, 0, 0, .08)));flex-shrink:0;min-width:0;max-width:100%}praxis-settings-panel .settings-panel-header .spacer{flex:1 1 auto;min-width:0}praxis-settings-panel .settings-panel-status{grid-area:status;display:flex;align-items:center;gap:8px;min-height:36px;padding:6px var(--pfx-settings-panel-status-padding-x, 20px);border-bottom:1px solid var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-high);color:var(--pfx-settings-panel-on-surface);font-size:.85rem;font-weight:500;min-width:0;max-width:100%}praxis-settings-panel .settings-panel-status mat-icon{width:18px;height:18px;font-size:18px}praxis-settings-panel .settings-panel-status[data-status=dirty],praxis-settings-panel .settings-panel-status[data-status=invalid]{color:var(--pfx-settings-panel-error);background:color-mix(in srgb,var(--pfx-settings-panel-error-container) 30%,var(--pfx-settings-panel-surface-container-high))}praxis-settings-panel .settings-panel-status[data-status=saved]{color:var(--pfx-settings-panel-primary);background:color-mix(in srgb,var(--pfx-settings-panel-primary-container) 28%,var(--pfx-settings-panel-surface-container-high))}praxis-settings-panel .settings-panel-body{grid-area:body;overflow-y:auto;overflow-x:hidden;scroll-padding-top:var(--pfx-settings-panel-scroll-padding-start, 16px);scroll-padding-bottom:var(--pfx-settings-panel-scroll-padding-end, 88px);min-height:0;padding:var(--pfx-settings-panel-body-padding, 8px 16px 24px);background:var(--pfx-settings-panel-surface);display:flex;flex-direction:column;min-width:0;max-width:100%}praxis-settings-panel .settings-panel-body>*{min-width:0;max-width:100%}praxis-settings-panel .settings-panel-content{display:block;min-width:0;max-width:100%}praxis-settings-panel .settings-panel-content>*{min-width:0;max-width:100%;box-sizing:border-box}praxis-settings-panel .settings-panel-footer{grid-area:footer;border-top:1px solid var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-high);box-shadow:var(--pfx-settings-panel-footer-shadow, var(--md-sys-elevation-level1, 0 -2px 6px rgba(0, 0, 0, .08)));display:flex;align-items:center;flex-wrap:wrap;padding:var(--pfx-settings-panel-footer-padding, 12px 20px);column-gap:var(--pfx-settings-panel-footer-gap, 12px);row-gap:8px;flex-shrink:0;min-width:0;max-width:100%}praxis-settings-panel .spacer{flex:1}praxis-settings-panel .settings-panel-title{display:inline-flex;align-items:center;flex:1 1 auto;gap:var(--pfx-settings-panel-title-gap, 8px);font-weight:700;line-height:1.2;letter-spacing:.2px;margin:0;min-width:0;overflow:visible;white-space:normal}praxis-settings-panel .settings-panel-title span{min-width:0;overflow:visible;white-space:normal}praxis-settings-panel .settings-panel-title mat-icon{color:var(--pfx-settings-panel-primary)}praxis-settings-panel .settings-panel-title .title-icon{width:20px;height:20px;font-size:20px}praxis-settings-panel .settings-panel-footer button+button{margin-left:var(--pfx-settings-panel-footer-gap, 12px)}praxis-settings-panel .settings-panel-footer button{display:inline-flex;align-items:center}praxis-settings-panel .settings-panel-footer button .mat-icon{flex:0 0 20px;font-size:20px;width:20px;height:20px;line-height:1;display:inline-flex;align-items:center;justify-content:center;overflow:hidden}praxis-settings-panel .settings-panel-footer .mat-button-wrapper{display:inline-flex;align-items:center;gap:var(--pfx-settings-panel-button-gap, 8px)}praxis-settings-panel .settings-panel-footer .mat-progress-spinner{margin-right:8px}praxis-settings-panel .settings-panel-footer .mat-flat-button[color=primary]{font-weight:600}praxis-settings-panel .settings-panel .mdc-button__label{display:inline-flex;align-items:center;gap:var(--pfx-settings-panel-button-gap, 8px);line-height:1}praxis-settings-panel .settings-panel .mdc-button__label>span{display:inline-flex;align-items:center;line-height:1}praxis-settings-panel .settings-panel .mdc-button__label .mat-icon{display:inline-flex;align-items:center;justify-content:center;line-height:1}@media(max-width:520px){praxis-settings-panel .settings-panel-footer{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:stretch}praxis-settings-panel .settings-panel-footer .spacer{display:none}praxis-settings-panel .settings-panel-footer button{justify-content:center;width:100%;min-width:0}praxis-settings-panel .settings-panel-footer button+button{margin-left:0}}praxis-settings-panel .settings-panel .mat-divider{background-color:var(--pfx-settings-panel-outline-variant)!important}praxis-settings-panel .settings-panel .mat-expansion-panel{background:var(--pfx-settings-panel-surface-container)!important;border:1px solid var(--pfx-settings-panel-outline-variant);border-radius:var(--md-sys-shape-corner-medium, 12px);box-shadow:var(--md-sys-elevation-level1, 0 2px 8px rgba(0, 0, 0, .08));color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-expansion-panel-header{background:var(--pfx-settings-panel-surface-container)!important;color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-content{color:var(--pfx-settings-panel-on-surface);flex-wrap:wrap;gap:4px 12px;min-width:0;overflow:visible}praxis-settings-panel .settings-panel .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:hover{background:color-mix(in srgb,var(--pfx-settings-panel-surface-container-high) 84%,var(--pfx-settings-panel-primary) 16%)}praxis-settings-panel .settings-panel .mat-expansion-panel.mat-expanded>.mat-expansion-panel-header{background:var(--pfx-settings-panel-surface-container-high)!important}praxis-settings-panel .settings-panel .mat-expansion-panel-header mat-icon,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-icon{color:var(--pfx-settings-panel-on-surface)!important}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-title,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-description{color:var(--pfx-settings-panel-on-surface);min-width:0;overflow:visible;white-space:normal}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-description{color:var(--pfx-settings-panel-on-surface-variant);flex-wrap:wrap;gap:8px}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-title>*,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-description>*{color:inherit}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-title small,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-description small{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-indicator,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-indicator:after{color:var(--pfx-settings-panel-on-surface-variant);border-color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-expansion-panel .mat-action-row{border-top-color:var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-low)}praxis-settings-panel .settings-panel .mat-accordion,praxis-settings-panel .settings-panel .mat-accordion .mat-expansion-panel-spacing{background:transparent!important}praxis-settings-panel .settings-panel .mat-expansion-panel-content,praxis-settings-panel .settings-panel .mat-expansion-panel-content-wrapper,praxis-settings-panel .settings-panel .mat-expansion-panel-body{background:var(--pfx-settings-panel-surface-container)!important;color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-expansion-panel .mat-expansion-panel-body{padding:8px}praxis-settings-panel .settings-panel .mat-expansion-panel .mat-expansion-panel-body>*{color:inherit}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mat-mdc-tab-header{border-bottom:1px solid var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-low)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab{min-width:0}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab .mdc-tab__text-label{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab:hover .mdc-tab__text-label,praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab:focus .mdc-tab__text-label{color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab.mdc-tab--active .mdc-tab__text-label{color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mat-mdc-tab-header-pagination{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mat-mdc-tab-header-pagination-chevron{border-color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mat-mdc-tab-header-pagination:not(.mat-mdc-tab-header-pagination-disabled):hover{background:color-mix(in srgb,var(--pfx-settings-panel-surface-container-high) 84%,var(--pfx-settings-panel-primary) 16%)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab-indicator__content--underline{border-color:var(--pfx-settings-panel-primary)}praxis-settings-panel .settings-panel .mat-mdc-card{background:var(--pfx-settings-panel-surface-container-low);border:1px solid var(--pfx-settings-panel-outline-variant);color:var(--pfx-settings-panel-on-surface);box-shadow:var(--md-sys-elevation-level1, 0 2px 8px rgba(0, 0, 0, .08))}praxis-settings-panel .settings-panel .mat-mdc-card-subtitle,praxis-settings-panel .settings-panel .mat-mdc-card-content{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-mdc-card-title{color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-mdc-form-field{width:100%;--mdc-filled-text-field-container-color: var( --pfx-settings-panel-surface-container );--mdc-filled-text-field-hover-container-color: var( --pfx-settings-panel-surface-container-high );--mdc-filled-text-field-focus-container-color: var( --pfx-settings-panel-surface-container-high );--mdc-filled-text-field-active-indicator-color: var( --pfx-settings-panel-outline-variant );--mdc-filled-text-field-hover-active-indicator-color: var( --pfx-settings-panel-secondary );--mdc-filled-text-field-focus-active-indicator-color: var( --pfx-settings-panel-primary );--mdc-filled-text-field-label-text-color: var( --pfx-settings-panel-on-surface-variant );--mdc-filled-text-field-focus-label-text-color: var( --pfx-settings-panel-primary );--mdc-filled-text-field-input-text-color: var( --pfx-settings-panel-on-surface );--mdc-filled-text-field-caret-color: var(--pfx-settings-panel-primary);--mdc-outlined-text-field-outline-color: var( --pfx-settings-panel-outline-variant );--mdc-outlined-text-field-hover-outline-color: var( --pfx-settings-panel-secondary );--mdc-outlined-text-field-focus-outline-color: var( --pfx-settings-panel-primary );--mdc-outlined-text-field-label-text-color: var( --pfx-settings-panel-on-surface-variant );--mdc-outlined-text-field-focus-label-text-color: var( --pfx-settings-panel-primary );--mdc-outlined-text-field-input-text-color: var( --pfx-settings-panel-on-surface );--mdc-outlined-text-field-caret-color: var(--pfx-settings-panel-primary);--mat-form-field-focus-select-arrow-color: var( --pfx-settings-panel-primary );--mat-form-field-enabled-select-arrow-color: var( --pfx-settings-panel-on-surface-variant )}praxis-settings-panel .settings-panel .mdc-text-field--filled{background-color:var(--pfx-settings-panel-surface-container)!important;border-radius:var(--md-sys-shape-corner-small, 8px) var(--md-sys-shape-corner-small, 8px) 0 0}praxis-settings-panel .settings-panel .mat-mdc-text-field-wrapper,praxis-settings-panel .settings-panel .mat-mdc-form-field-flex,praxis-settings-panel .settings-panel .mat-mdc-form-field-infix,praxis-settings-panel .settings-panel .mat-mdc-form-field-focus-overlay{background:var(--pfx-settings-panel-surface-container)!important;color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-mdc-form-field-focus-overlay{opacity:0}praxis-settings-panel .settings-panel .mdc-text-field--filled .mdc-text-field__input,praxis-settings-panel .settings-panel .mdc-text-field--filled .mdc-floating-label,praxis-settings-panel .settings-panel .mat-mdc-select-value,praxis-settings-panel .settings-panel .mat-mdc-select-arrow,praxis-settings-panel .settings-panel .mat-mdc-form-field .mat-mdc-floating-label{color:var(--pfx-settings-panel-on-surface-variant)!important}praxis-settings-panel .settings-panel .mdc-text-field--filled.mdc-text-field--focused .mdc-floating-label,praxis-settings-panel .settings-panel .mdc-text-field--filled .mdc-text-field__input{color:var(--pfx-settings-panel-on-surface)!important}praxis-settings-panel .settings-panel .mat-mdc-form-field input,praxis-settings-panel .settings-panel .mat-mdc-form-field textarea,praxis-settings-panel .settings-panel .mat-mdc-form-field .mdc-text-field__input{color:var(--pfx-settings-panel-on-surface)!important}praxis-settings-panel .settings-panel .mat-mdc-form-field-subscript-wrapper,praxis-settings-panel .settings-panel .mat-mdc-form-field-hint-wrapper,praxis-settings-panel .settings-panel .mat-mdc-form-field-error-wrapper,praxis-settings-panel .settings-panel .mat-mdc-hint{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-button-toggle-group{border-color:var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-low)}praxis-settings-panel .settings-panel .mat-button-toggle{background:var(--pfx-settings-panel-surface-container-low);color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-button-toggle+.mat-button-toggle{border-left-color:var(--pfx-settings-panel-outline-variant)}praxis-settings-panel .settings-panel .mat-button-toggle-checked{background:var(--pfx-settings-panel-primary-container)!important;color:var(--pfx-settings-panel-on-primary-container)!important}praxis-settings-panel .settings-panel .mat-button-toggle .mat-icon,praxis-settings-panel .settings-panel .mat-button-toggle-checked .mat-icon{color:inherit}praxis-settings-panel .settings-panel .mat-mdc-slide-toggle .mdc-label{color:var(--pfx-settings-panel-on-surface)}.settings-panel{grid-template-columns:minmax(0,1fr);min-width:0;max-width:100%}.settings-panel-body{overflow-x:hidden;min-width:0}.settings-panel-body>*{min-width:0;max-width:100%}.praxis-settings-panel-backdrop{background:var(--pfx-backdrop, rgba(8, 15, 26, .42));backdrop-filter:blur(var(--pfx-backdrop-blur, 6px)) saturate(110%);-webkit-backdrop-filter:blur(var(--pfx-backdrop-blur, 6px)) saturate(110%)}.praxis-settings-panel-pane{position:fixed!important;top:0!important;right:0!important;display:flex!important;align-items:stretch!important;height:100vh!important;max-width:100vw!important;max-height:100vh!important;z-index:var(--praxis-layer-settings-panel, 1220)!important;transition:width var(--pfx-side-panel-motion-duration-enter, .3s) var(--pfx-side-panel-motion-easing-enter, ease)}.praxis-settings-panel-pane .settings-panel{pointer-events:auto}@media(prefers-reduced-motion:reduce){.praxis-settings-panel-pane{transition:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatDialogModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1020
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: SettingsPanelComponent, isStandalone: true, selector: "praxis-settings-panel", host: { listeners: { "document:keydown": "handleKeydown($event)", "document:pointermove": "onDocumentPointerMove($event)", "document:pointerup": "onDocumentPointerEnd($event)", "document:pointercancel": "onDocumentPointerEnd($event)" } }, providers: [providePraxisSettingsPanelI18n()], viewQueries: [{ propertyName: "contentHost", first: true, predicate: ["contentHost"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<div\n class=\"settings-panel\"\n data-testid=\"settings-panel-root\"\n [class.expanded]=\"expanded\"\n [class.is-resizable]=\"showResizeHandle\"\n [ngStyle]=\"panelInlineStyles\"\n role=\"dialog\"\n [attr.aria-modal]=\"interactionActive ? 'true' : null\"\n [attr.aria-hidden]=\"interactionActive ? null : 'true'\"\n [attr.inert]=\"interactionActive ? null : ''\"\n [attr.aria-labelledby]=\"titleId\"\n [cdkTrapFocus]=\"interactionActive\"\n [cdkTrapFocusAutoCapture]=\"interactionActive\"\n >\n @if (showResizeHandle) {\n <div\n class=\"settings-panel__resize-handle\"\n role=\"separator\"\n tabindex=\"0\"\n aria-orientation=\"vertical\"\n [attr.aria-label]=\"resizeHandleLabel\"\n (pointerdown)=\"onResizeHandlePointerDown($event)\"\n (keydown)=\"onResizeHandleKeydown($event)\"\n ></div>\n }\n <header class=\"settings-panel-header\">\n <h2 class=\"settings-panel-title\" [id]=\"titleId\">\n @if (titleIcon) {\n <mat-icon class=\"title-icon\" [praxisIcon]=\"titleIcon\"></mat-icon>\n }\n <span>{{ title }}</span>\n </h2>\n <span class=\"spacer\"></span>\n <button\n [praxisIconButton]=\"expanded ? 'close_fullscreen' : 'open_in_full'\"\n size=\"compact\"\n type=\"button\"\n data-testid=\"settings-panel-toggle-expand\"\n [attr.aria-label]=\"expanded ? tx('Collapse panel') : tx('Expand panel')\"\n [attr.aria-expanded]=\"expanded\"\n [matTooltip]=\"expanded ? tx('Collapse panel') : tx('Expand panel')\"\n (click)=\"toggleExpand()\"\n ></button>\n <button\n praxisIconButton=\"close\"\n size=\"compact\"\n type=\"button\"\n data-testid=\"settings-panel-close-icon\"\n [attr.aria-label]=\"tx('Close')\"\n [matTooltip]=\"tx('Close')\"\n (click)=\"onCancel()\"\n ></button>\n </header>\n @if (showStatusMessage) {\n <div\n class=\"settings-panel-status\"\n [attr.data-status]=\"statusTone\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <mat-icon\n aria-hidden=\"true\"\n [praxisIcon]=\"\n statusTone === 'dirty' || statusTone === 'invalid'\n ? 'warning'\n : statusTone === 'saved'\n ? 'check_circle'\n : statusTone === 'busy'\n ? 'autorenew'\n : 'info'\n \"\n ></mat-icon>\n <span>{{ statusMessage }}</span>\n </div>\n }\n <div class=\"settings-panel-body\">\n <ng-template #contentHost></ng-template>\n </div>\n <footer class=\"settings-panel-footer\">\n <button\n mat-button\n type=\"button\"\n data-testid=\"settings-panel-reset\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); onReset()\"\n [disabled]=\"isBusy\"\n >\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'restart_alt'\"></mat-icon>\n <span>{{ tx('Reset') }}</span>\n </button>\n <span class=\"spacer\"></span>\n <button\n mat-button\n type=\"button\"\n data-testid=\"settings-panel-cancel\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); onCancel()\"\n [disabled]=\"isBusy\"\n >\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'close'\"></mat-icon>\n <span>{{ tx('Cancel') }}</span>\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n data-testid=\"settings-panel-apply\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); onApply()\"\n [disabled]=\"!canApply\"\n [matTooltip]=\"applySaveDisabledReason\"\n [matTooltipDisabled]=\"canApply || !diagnostics.showDisabledReason\"\n [attr.aria-busy]=\"isBusy\"\n [attr.aria-label]=\"applyActionLabel || 'Apply'\"\n >\n @if (showBusyIndicator) {\n <mat-progress-spinner\n mode=\"indeterminate\"\n diameter=\"20\"\n ></mat-progress-spinner>\n }\n @if (!showBusyIndicator) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'done'\"></mat-icon>\n <span class=\"settings-panel-action-label settings-panel-action-label--apply\">{{ applyActionLabel }}</span>\n }\n </button>\n <button\n mat-flat-button\n color=\"primary\"\n type=\"button\"\n data-testid=\"settings-panel-save\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); onSave()\"\n [disabled]=\"!canSave\"\n [matTooltip]=\"applySaveDisabledReason\"\n [matTooltipDisabled]=\"canSave || !diagnostics.showDisabledReason\"\n [attr.aria-busy]=\"isBusy\"\n [attr.aria-label]=\"saveActionLabel || 'Save & Close'\"\n >\n @if (showBusyIndicator) {\n <mat-progress-spinner\n mode=\"indeterminate\"\n diameter=\"20\"\n ></mat-progress-spinner>\n }\n @if (!showBusyIndicator) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'save'\"></mat-icon>\n <span class=\"settings-panel-action-label settings-panel-action-label--save\">{{ saveActionLabel }}</span>\n }\n </button>\n </footer>\n</div>\n", styles: ["@charset \"UTF-8\";praxis-settings-panel{display:block;height:100%;width:100%;min-width:0;flex:1 1 auto}praxis-settings-panel .settings-panel{position:relative;--pfx-settings-panel-surface-container: var( --md-sys-color-surface-container, #ffffff );--pfx-settings-panel-surface-container-high: var( --md-sys-color-surface-container-high, #f7f7f7 );--pfx-settings-panel-surface-container-low: var( --md-sys-color-surface-container-low, #f2f4f7 );--pfx-settings-panel-surface: var(--md-sys-color-surface, #ffffff);--pfx-settings-panel-on-surface: var(--md-sys-color-on-surface, #111827);--pfx-settings-panel-on-surface-variant: var( --md-sys-color-on-surface-variant, rgba(17, 24, 39, .72) );--pfx-settings-panel-outline: var( --md-sys-color-outline, rgba(15, 23, 42, .24) );--pfx-settings-panel-outline-variant: var( --md-sys-color-outline-variant, rgba(15, 23, 42, .12) );--pfx-settings-panel-primary: var(--md-sys-color-primary, #2563eb);--pfx-settings-panel-primary-container: var( --md-sys-color-primary-container, rgba(37, 99, 235, .14) );--pfx-settings-panel-on-primary-container: var( --md-sys-color-on-primary-container, #0f172a );--pfx-settings-panel-secondary: var( --md-sys-color-secondary, var(--pfx-settings-panel-primary) );--pfx-settings-panel-error: var(--md-sys-color-error, #b3261e);--pfx-settings-panel-error-container: var( --md-sys-color-error-container, rgba(179, 38, 30, .14) );display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto auto 1fr auto;grid-template-areas:\"header\" \"status\" \"body\" \"footer\";height:100%;background:var(--pfx-settings-panel-surface-container);color:var(--pfx-settings-panel-on-surface);border-left:1px solid var(--pfx-settings-panel-outline-variant);width:100%;max-width:100%;min-width:0;box-shadow:var(--pfx-settings-panel-elevation, var(--md-sys-elevation-level2, 0 8px 24px rgba(0, 0, 0, .16)));overflow:hidden}praxis-settings-panel .settings-panel__resize-handle{position:absolute;inset:0 auto 0 0;width:12px;cursor:col-resize;touch-action:none;z-index:3;outline:none}praxis-settings-panel .settings-panel__resize-handle:before{content:\"\";position:absolute;inset:0 auto 0 4px;width:2px;background:transparent;transition:background-color var(--pfx-side-panel-motion-duration, .16s) ease,opacity var(--pfx-side-panel-motion-duration, .16s) ease;opacity:0}praxis-settings-panel .settings-panel.is-resizable:hover .settings-panel__resize-handle:before,praxis-settings-panel .settings-panel__resize-handle:focus-visible:before{opacity:1;background:var(--pfx-settings-panel-outline)}praxis-settings-panel .settings-panel-header{grid-area:header;display:flex;align-items:center;gap:var(--pfx-settings-panel-header-gap, 8px);padding:12px var(--pfx-settings-panel-header-padding-x, 20px);min-height:var(--pfx-settings-panel-header-height, 64px);border-bottom:1px solid var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-high);box-shadow:var(--pfx-settings-panel-header-shadow, var(--md-sys-elevation-level1, 0 2px 6px rgba(0, 0, 0, .08)));flex-shrink:0;min-width:0;max-width:100%}praxis-settings-panel .settings-panel-header .spacer{flex:1 1 auto;min-width:0}praxis-settings-panel .settings-panel-status{grid-area:status;display:flex;align-items:center;gap:8px;min-height:36px;padding:6px var(--pfx-settings-panel-status-padding-x, 20px);border-bottom:1px solid var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-high);color:var(--pfx-settings-panel-on-surface);font-size:.85rem;font-weight:500;min-width:0;max-width:100%}praxis-settings-panel .settings-panel-status mat-icon{width:18px;height:18px;font-size:18px}praxis-settings-panel .settings-panel-status[data-status=dirty],praxis-settings-panel .settings-panel-status[data-status=invalid]{color:var(--pfx-settings-panel-error);background:color-mix(in srgb,var(--pfx-settings-panel-error-container) 30%,var(--pfx-settings-panel-surface-container-high))}praxis-settings-panel .settings-panel-status[data-status=saved]{color:var(--pfx-settings-panel-primary);background:color-mix(in srgb,var(--pfx-settings-panel-primary-container) 28%,var(--pfx-settings-panel-surface-container-high))}praxis-settings-panel .settings-panel-body{grid-area:body;overflow-y:auto;overflow-x:hidden;scroll-padding-top:var(--pfx-settings-panel-scroll-padding-start, 16px);scroll-padding-bottom:var(--pfx-settings-panel-scroll-padding-end, 88px);min-height:0;padding:var(--pfx-settings-panel-body-padding, 8px 16px 24px);background:var(--pfx-settings-panel-surface);display:flex;flex-direction:column;min-width:0;max-width:100%}praxis-settings-panel .settings-panel-body>*{min-width:0;max-width:100%}praxis-settings-panel .settings-panel-content{display:block;min-width:0;max-width:100%}praxis-settings-panel .settings-panel-content>*{min-width:0;max-width:100%;box-sizing:border-box}praxis-settings-panel .settings-panel-footer{grid-area:footer;border-top:1px solid var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-high);box-shadow:var(--pfx-settings-panel-footer-shadow, var(--md-sys-elevation-level1, 0 -2px 6px rgba(0, 0, 0, .08)));display:flex;align-items:center;flex-wrap:wrap;padding:var(--pfx-settings-panel-footer-padding, 12px 20px);column-gap:var(--pfx-settings-panel-footer-gap, 12px);row-gap:8px;flex-shrink:0;min-width:0;max-width:100%}praxis-settings-panel .spacer{flex:1}praxis-settings-panel .settings-panel-title{display:inline-flex;align-items:center;flex:1 1 auto;gap:var(--pfx-settings-panel-title-gap, 8px);font-weight:700;line-height:1.2;letter-spacing:.2px;margin:0;min-width:0;overflow:visible;white-space:normal}praxis-settings-panel .settings-panel-title span{min-width:0;overflow:visible;white-space:normal}praxis-settings-panel .settings-panel-title mat-icon{color:var(--pfx-settings-panel-primary)}praxis-settings-panel .settings-panel-title .title-icon{width:20px;height:20px;font-size:20px}praxis-settings-panel .settings-panel-footer button+button{margin-left:var(--pfx-settings-panel-footer-gap, 12px)}praxis-settings-panel .settings-panel-footer button{display:inline-flex;align-items:center}praxis-settings-panel .settings-panel-footer button .mat-icon{flex:0 0 20px;font-size:20px;width:20px;height:20px;line-height:1;display:inline-flex;align-items:center;justify-content:center;overflow:hidden}praxis-settings-panel .settings-panel-footer .mat-button-wrapper{display:inline-flex;align-items:center;gap:var(--pfx-settings-panel-button-gap, 8px)}praxis-settings-panel .settings-panel-footer .mat-progress-spinner{margin-right:8px}praxis-settings-panel .settings-panel-footer .mat-flat-button[color=primary]{font-weight:600}praxis-settings-panel .settings-panel .mdc-button__label{display:inline-flex;align-items:center;gap:var(--pfx-settings-panel-button-gap, 8px);line-height:1}praxis-settings-panel .settings-panel .mdc-button__label>span{display:inline-flex;align-items:center;line-height:1}praxis-settings-panel .settings-panel .mdc-button__label .mat-icon{display:inline-flex;align-items:center;justify-content:center;line-height:1}@media(max-width:520px){praxis-settings-panel .settings-panel-footer{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:stretch}praxis-settings-panel .settings-panel-footer .spacer{display:none}praxis-settings-panel .settings-panel-footer button{justify-content:center;width:100%;min-width:0}praxis-settings-panel .settings-panel-footer button+button{margin-left:0}}praxis-settings-panel .settings-panel .mat-divider{background-color:var(--pfx-settings-panel-outline-variant)!important}praxis-settings-panel .settings-panel .mat-expansion-panel{background:var(--pfx-settings-panel-surface-container)!important;border:1px solid var(--pfx-settings-panel-outline-variant);border-radius:var(--md-sys-shape-corner-medium, 12px);box-shadow:var(--md-sys-elevation-level1, 0 2px 8px rgba(0, 0, 0, .08));color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-expansion-panel-header{background:var(--pfx-settings-panel-surface-container)!important;color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-content{color:var(--pfx-settings-panel-on-surface);flex-wrap:wrap;gap:4px 12px;min-width:0;overflow:visible}praxis-settings-panel .settings-panel .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:hover{background:color-mix(in srgb,var(--pfx-settings-panel-surface-container-high) 84%,var(--pfx-settings-panel-primary) 16%)}praxis-settings-panel .settings-panel .mat-expansion-panel.mat-expanded>.mat-expansion-panel-header{background:var(--pfx-settings-panel-surface-container-high)!important}praxis-settings-panel .settings-panel .mat-expansion-panel-header mat-icon,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-icon{color:var(--pfx-settings-panel-on-surface)!important}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-title,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-description{color:var(--pfx-settings-panel-on-surface);min-width:0;overflow:visible;white-space:normal}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-description{color:var(--pfx-settings-panel-on-surface-variant);flex-wrap:wrap;gap:8px}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-title>*,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-description>*{color:inherit}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-title small,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-description small{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-indicator,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-indicator:after{color:var(--pfx-settings-panel-on-surface-variant);border-color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-expansion-panel .mat-action-row{border-top-color:var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-low)}praxis-settings-panel .settings-panel .mat-accordion,praxis-settings-panel .settings-panel .mat-accordion .mat-expansion-panel-spacing{background:transparent!important}praxis-settings-panel .settings-panel .mat-expansion-panel-content,praxis-settings-panel .settings-panel .mat-expansion-panel-content-wrapper,praxis-settings-panel .settings-panel .mat-expansion-panel-body{background:var(--pfx-settings-panel-surface-container)!important;color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-expansion-panel .mat-expansion-panel-body{padding:8px}praxis-settings-panel .settings-panel .mat-expansion-panel .mat-expansion-panel-body>*{color:inherit}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mat-mdc-tab-header{border-bottom:1px solid var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-low)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab{min-width:0}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab .mdc-tab__text-label{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab:hover .mdc-tab__text-label,praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab:focus .mdc-tab__text-label{color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab.mdc-tab--active .mdc-tab__text-label{color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mat-mdc-tab-header-pagination{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mat-mdc-tab-header-pagination-chevron{border-color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mat-mdc-tab-header-pagination:not(.mat-mdc-tab-header-pagination-disabled):hover{background:color-mix(in srgb,var(--pfx-settings-panel-surface-container-high) 84%,var(--pfx-settings-panel-primary) 16%)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab-indicator__content--underline{border-color:var(--pfx-settings-panel-primary)}praxis-settings-panel .settings-panel .mat-mdc-card{background:var(--pfx-settings-panel-surface-container-low);border:1px solid var(--pfx-settings-panel-outline-variant);color:var(--pfx-settings-panel-on-surface);box-shadow:var(--md-sys-elevation-level1, 0 2px 8px rgba(0, 0, 0, .08))}praxis-settings-panel .settings-panel .mat-mdc-card-subtitle,praxis-settings-panel .settings-panel .mat-mdc-card-content{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-mdc-card-title{color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-mdc-form-field{width:100%;--mdc-filled-text-field-container-color: var( --pfx-settings-panel-surface-container );--mdc-filled-text-field-hover-container-color: var( --pfx-settings-panel-surface-container-high );--mdc-filled-text-field-focus-container-color: var( --pfx-settings-panel-surface-container-high );--mdc-filled-text-field-active-indicator-color: var( --pfx-settings-panel-outline-variant );--mdc-filled-text-field-hover-active-indicator-color: var( --pfx-settings-panel-secondary );--mdc-filled-text-field-focus-active-indicator-color: var( --pfx-settings-panel-primary );--mdc-filled-text-field-label-text-color: var( --pfx-settings-panel-on-surface-variant );--mdc-filled-text-field-focus-label-text-color: var( --pfx-settings-panel-primary );--mdc-filled-text-field-input-text-color: var( --pfx-settings-panel-on-surface );--mdc-filled-text-field-caret-color: var(--pfx-settings-panel-primary);--mdc-outlined-text-field-outline-color: var( --pfx-settings-panel-outline-variant );--mdc-outlined-text-field-hover-outline-color: var( --pfx-settings-panel-secondary );--mdc-outlined-text-field-focus-outline-color: var( --pfx-settings-panel-primary );--mdc-outlined-text-field-label-text-color: var( --pfx-settings-panel-on-surface-variant );--mdc-outlined-text-field-focus-label-text-color: var( --pfx-settings-panel-primary );--mdc-outlined-text-field-input-text-color: var( --pfx-settings-panel-on-surface );--mdc-outlined-text-field-caret-color: var(--pfx-settings-panel-primary);--mat-form-field-focus-select-arrow-color: var( --pfx-settings-panel-primary );--mat-form-field-enabled-select-arrow-color: var( --pfx-settings-panel-on-surface-variant )}praxis-settings-panel .settings-panel .mdc-text-field--filled{background-color:var(--pfx-settings-panel-surface-container)!important;border-radius:var(--md-sys-shape-corner-small, 8px) var(--md-sys-shape-corner-small, 8px) 0 0}praxis-settings-panel .settings-panel .mat-mdc-text-field-wrapper,praxis-settings-panel .settings-panel .mat-mdc-form-field-flex,praxis-settings-panel .settings-panel .mat-mdc-form-field-infix,praxis-settings-panel .settings-panel .mat-mdc-form-field-focus-overlay{background:var(--pfx-settings-panel-surface-container)!important;color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-mdc-form-field-focus-overlay{opacity:0}praxis-settings-panel .settings-panel .mdc-text-field--filled .mdc-text-field__input,praxis-settings-panel .settings-panel .mdc-text-field--filled .mdc-floating-label,praxis-settings-panel .settings-panel .mat-mdc-select-value,praxis-settings-panel .settings-panel .mat-mdc-select-arrow,praxis-settings-panel .settings-panel .mat-mdc-form-field .mat-mdc-floating-label{color:var(--pfx-settings-panel-on-surface-variant)!important}praxis-settings-panel .settings-panel .mdc-text-field--filled.mdc-text-field--focused .mdc-floating-label,praxis-settings-panel .settings-panel .mdc-text-field--filled .mdc-text-field__input{color:var(--pfx-settings-panel-on-surface)!important}praxis-settings-panel .settings-panel .mat-mdc-form-field input,praxis-settings-panel .settings-panel .mat-mdc-form-field textarea,praxis-settings-panel .settings-panel .mat-mdc-form-field .mdc-text-field__input{color:var(--pfx-settings-panel-on-surface)!important}praxis-settings-panel .settings-panel .mat-mdc-form-field-subscript-wrapper,praxis-settings-panel .settings-panel .mat-mdc-form-field-hint-wrapper,praxis-settings-panel .settings-panel .mat-mdc-form-field-error-wrapper,praxis-settings-panel .settings-panel .mat-mdc-hint{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-button-toggle-group{border-color:var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-low)}praxis-settings-panel .settings-panel .mat-button-toggle{background:var(--pfx-settings-panel-surface-container-low);color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-button-toggle+.mat-button-toggle{border-left-color:var(--pfx-settings-panel-outline-variant)}praxis-settings-panel .settings-panel .mat-button-toggle-checked{background:var(--pfx-settings-panel-primary-container)!important;color:var(--pfx-settings-panel-on-primary-container)!important}praxis-settings-panel .settings-panel .mat-button-toggle .mat-icon,praxis-settings-panel .settings-panel .mat-button-toggle-checked .mat-icon{color:inherit}praxis-settings-panel .settings-panel .mat-mdc-slide-toggle .mdc-label{color:var(--pfx-settings-panel-on-surface)}.settings-panel{grid-template-columns:minmax(0,1fr);min-width:0;max-width:100%}.settings-panel-body{overflow-x:hidden;min-width:0}.settings-panel-body>*{min-width:0;max-width:100%}.praxis-settings-panel-backdrop{background:var(--pfx-backdrop, rgba(8, 15, 26, .42));backdrop-filter:blur(var(--pfx-backdrop-blur, 6px)) saturate(110%);-webkit-backdrop-filter:blur(var(--pfx-backdrop-blur, 6px)) saturate(110%)}.praxis-settings-panel-pane{position:fixed!important;top:0!important;right:0!important;display:flex!important;align-items:stretch!important;height:100vh!important;max-width:100vw!important;max-height:100vh!important;z-index:var(--praxis-layer-settings-panel, 1220)!important;transition:width var(--pfx-side-panel-motion-duration-enter, .3s) var(--pfx-side-panel-motion-easing-enter, ease)}.praxis-settings-panel-pane .settings-panel{pointer-events:auto}@media(prefers-reduced-motion:reduce){.praxis-settings-panel-pane{transition:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatDialogModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1013
1021
  }
1014
1022
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SettingsPanelComponent, decorators: [{
1015
1023
  type: Component,
@@ -1024,7 +1032,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1024
1032
  CdkTrapFocus,
1025
1033
  MatProgressSpinnerModule,
1026
1034
  MatDialogModule,
1027
- ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [providePraxisSettingsPanelI18n()], template: "<div\n class=\"settings-panel\"\n data-testid=\"settings-panel-root\"\n [class.expanded]=\"expanded\"\n [class.is-resizable]=\"showResizeHandle\"\n [ngStyle]=\"panelInlineStyles\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-labelledby]=\"titleId\"\n cdkTrapFocus\n cdkTrapFocusAutoCapture\n >\n @if (showResizeHandle) {\n <div\n class=\"settings-panel__resize-handle\"\n role=\"separator\"\n tabindex=\"0\"\n aria-orientation=\"vertical\"\n [attr.aria-label]=\"resizeHandleLabel\"\n (pointerdown)=\"onResizeHandlePointerDown($event)\"\n (keydown)=\"onResizeHandleKeydown($event)\"\n ></div>\n }\n <header class=\"settings-panel-header\">\n <h2 class=\"settings-panel-title\" [id]=\"titleId\">\n @if (titleIcon) {\n <mat-icon class=\"title-icon\" [praxisIcon]=\"titleIcon\"></mat-icon>\n }\n <span>{{ title }}</span>\n </h2>\n <span class=\"spacer\"></span>\n <button\n [praxisIconButton]=\"expanded ? 'close_fullscreen' : 'open_in_full'\"\n size=\"compact\"\n type=\"button\"\n data-testid=\"settings-panel-toggle-expand\"\n [attr.aria-label]=\"expanded ? tx('Collapse panel') : tx('Expand panel')\"\n [attr.aria-expanded]=\"expanded\"\n [matTooltip]=\"expanded ? tx('Collapse panel') : tx('Expand panel')\"\n (click)=\"toggleExpand()\"\n ></button>\n <button\n praxisIconButton=\"close\"\n size=\"compact\"\n type=\"button\"\n data-testid=\"settings-panel-close-icon\"\n [attr.aria-label]=\"tx('Close')\"\n [matTooltip]=\"tx('Close')\"\n (click)=\"onCancel()\"\n ></button>\n </header>\n @if (showStatusMessage) {\n <div\n class=\"settings-panel-status\"\n [attr.data-status]=\"statusTone\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <mat-icon\n aria-hidden=\"true\"\n [praxisIcon]=\"\n statusTone === 'dirty' || statusTone === 'invalid'\n ? 'warning'\n : statusTone === 'saved'\n ? 'check_circle'\n : statusTone === 'busy'\n ? 'autorenew'\n : 'info'\n \"\n ></mat-icon>\n <span>{{ statusMessage }}</span>\n </div>\n }\n <div class=\"settings-panel-body\">\n <ng-template #contentHost></ng-template>\n </div>\n <footer class=\"settings-panel-footer\">\n <button\n mat-button\n type=\"button\"\n data-testid=\"settings-panel-reset\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); onReset()\"\n [disabled]=\"isBusy\"\n >\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'restart_alt'\"></mat-icon>\n <span>{{ tx('Reset') }}</span>\n </button>\n <span class=\"spacer\"></span>\n <button\n mat-button\n type=\"button\"\n data-testid=\"settings-panel-cancel\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); onCancel()\"\n [disabled]=\"isBusy\"\n >\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'close'\"></mat-icon>\n <span>{{ tx('Cancel') }}</span>\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n data-testid=\"settings-panel-apply\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); onApply()\"\n [disabled]=\"!canApply\"\n [matTooltip]=\"applySaveDisabledReason\"\n [matTooltipDisabled]=\"canApply || !diagnostics.showDisabledReason\"\n [attr.aria-busy]=\"isBusy\"\n [attr.aria-label]=\"applyActionLabel || 'Apply'\"\n >\n @if (showBusyIndicator) {\n <mat-progress-spinner\n mode=\"indeterminate\"\n diameter=\"20\"\n ></mat-progress-spinner>\n }\n @if (!showBusyIndicator) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'done'\"></mat-icon>\n <span class=\"settings-panel-action-label settings-panel-action-label--apply\">{{ applyActionLabel }}</span>\n }\n </button>\n <button\n mat-flat-button\n color=\"primary\"\n type=\"button\"\n data-testid=\"settings-panel-save\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); onSave()\"\n [disabled]=\"!canSave\"\n [matTooltip]=\"applySaveDisabledReason\"\n [matTooltipDisabled]=\"canSave || !diagnostics.showDisabledReason\"\n [attr.aria-busy]=\"isBusy\"\n [attr.aria-label]=\"saveActionLabel || 'Save & Close'\"\n >\n @if (showBusyIndicator) {\n <mat-progress-spinner\n mode=\"indeterminate\"\n diameter=\"20\"\n ></mat-progress-spinner>\n }\n @if (!showBusyIndicator) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'save'\"></mat-icon>\n <span class=\"settings-panel-action-label settings-panel-action-label--save\">{{ saveActionLabel }}</span>\n }\n </button>\n </footer>\n</div>\n", styles: ["@charset \"UTF-8\";praxis-settings-panel{display:block;height:100%;width:100%;min-width:0;flex:1 1 auto}praxis-settings-panel .settings-panel{position:relative;--pfx-settings-panel-surface-container: var( --md-sys-color-surface-container, #ffffff );--pfx-settings-panel-surface-container-high: var( --md-sys-color-surface-container-high, #f7f7f7 );--pfx-settings-panel-surface-container-low: var( --md-sys-color-surface-container-low, #f2f4f7 );--pfx-settings-panel-surface: var(--md-sys-color-surface, #ffffff);--pfx-settings-panel-on-surface: var(--md-sys-color-on-surface, #111827);--pfx-settings-panel-on-surface-variant: var( --md-sys-color-on-surface-variant, rgba(17, 24, 39, .72) );--pfx-settings-panel-outline: var( --md-sys-color-outline, rgba(15, 23, 42, .24) );--pfx-settings-panel-outline-variant: var( --md-sys-color-outline-variant, rgba(15, 23, 42, .12) );--pfx-settings-panel-primary: var(--md-sys-color-primary, #2563eb);--pfx-settings-panel-primary-container: var( --md-sys-color-primary-container, rgba(37, 99, 235, .14) );--pfx-settings-panel-on-primary-container: var( --md-sys-color-on-primary-container, #0f172a );--pfx-settings-panel-secondary: var( --md-sys-color-secondary, var(--pfx-settings-panel-primary) );--pfx-settings-panel-error: var(--md-sys-color-error, #b3261e);--pfx-settings-panel-error-container: var( --md-sys-color-error-container, rgba(179, 38, 30, .14) );display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto auto 1fr auto;grid-template-areas:\"header\" \"status\" \"body\" \"footer\";height:100%;background:var(--pfx-settings-panel-surface-container);color:var(--pfx-settings-panel-on-surface);border-left:1px solid var(--pfx-settings-panel-outline-variant);width:100%;max-width:100%;min-width:0;box-shadow:var(--pfx-settings-panel-elevation, var(--md-sys-elevation-level2, 0 8px 24px rgba(0, 0, 0, .16)));overflow:hidden}praxis-settings-panel .settings-panel__resize-handle{position:absolute;inset:0 auto 0 0;width:12px;cursor:col-resize;touch-action:none;z-index:3;outline:none}praxis-settings-panel .settings-panel__resize-handle:before{content:\"\";position:absolute;inset:0 auto 0 4px;width:2px;background:transparent;transition:background-color var(--pfx-side-panel-motion-duration, .16s) ease,opacity var(--pfx-side-panel-motion-duration, .16s) ease;opacity:0}praxis-settings-panel .settings-panel.is-resizable:hover .settings-panel__resize-handle:before,praxis-settings-panel .settings-panel__resize-handle:focus-visible:before{opacity:1;background:var(--pfx-settings-panel-outline)}praxis-settings-panel .settings-panel-header{grid-area:header;display:flex;align-items:center;gap:var(--pfx-settings-panel-header-gap, 8px);padding:12px var(--pfx-settings-panel-header-padding-x, 20px);min-height:var(--pfx-settings-panel-header-height, 64px);border-bottom:1px solid var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-high);box-shadow:var(--pfx-settings-panel-header-shadow, var(--md-sys-elevation-level1, 0 2px 6px rgba(0, 0, 0, .08)));flex-shrink:0;min-width:0;max-width:100%}praxis-settings-panel .settings-panel-header .spacer{flex:1 1 auto;min-width:0}praxis-settings-panel .settings-panel-status{grid-area:status;display:flex;align-items:center;gap:8px;min-height:36px;padding:6px var(--pfx-settings-panel-status-padding-x, 20px);border-bottom:1px solid var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-high);color:var(--pfx-settings-panel-on-surface);font-size:.85rem;font-weight:500;min-width:0;max-width:100%}praxis-settings-panel .settings-panel-status mat-icon{width:18px;height:18px;font-size:18px}praxis-settings-panel .settings-panel-status[data-status=dirty],praxis-settings-panel .settings-panel-status[data-status=invalid]{color:var(--pfx-settings-panel-error);background:color-mix(in srgb,var(--pfx-settings-panel-error-container) 30%,var(--pfx-settings-panel-surface-container-high))}praxis-settings-panel .settings-panel-status[data-status=saved]{color:var(--pfx-settings-panel-primary);background:color-mix(in srgb,var(--pfx-settings-panel-primary-container) 28%,var(--pfx-settings-panel-surface-container-high))}praxis-settings-panel .settings-panel-body{grid-area:body;overflow-y:auto;overflow-x:hidden;scroll-padding-top:var(--pfx-settings-panel-scroll-padding-start, 16px);scroll-padding-bottom:var(--pfx-settings-panel-scroll-padding-end, 88px);min-height:0;padding:var(--pfx-settings-panel-body-padding, 8px 16px 24px);background:var(--pfx-settings-panel-surface);display:flex;flex-direction:column;min-width:0;max-width:100%}praxis-settings-panel .settings-panel-body>*{min-width:0;max-width:100%}praxis-settings-panel .settings-panel-content{display:block;min-width:0;max-width:100%}praxis-settings-panel .settings-panel-content>*{min-width:0;max-width:100%;box-sizing:border-box}praxis-settings-panel .settings-panel-footer{grid-area:footer;border-top:1px solid var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-high);box-shadow:var(--pfx-settings-panel-footer-shadow, var(--md-sys-elevation-level1, 0 -2px 6px rgba(0, 0, 0, .08)));display:flex;align-items:center;flex-wrap:wrap;padding:var(--pfx-settings-panel-footer-padding, 12px 20px);column-gap:var(--pfx-settings-panel-footer-gap, 12px);row-gap:8px;flex-shrink:0;min-width:0;max-width:100%}praxis-settings-panel .spacer{flex:1}praxis-settings-panel .settings-panel-title{display:inline-flex;align-items:center;flex:1 1 auto;gap:var(--pfx-settings-panel-title-gap, 8px);font-weight:700;line-height:1.2;letter-spacing:.2px;margin:0;min-width:0;overflow:visible;white-space:normal}praxis-settings-panel .settings-panel-title span{min-width:0;overflow:visible;white-space:normal}praxis-settings-panel .settings-panel-title mat-icon{color:var(--pfx-settings-panel-primary)}praxis-settings-panel .settings-panel-title .title-icon{width:20px;height:20px;font-size:20px}praxis-settings-panel .settings-panel-footer button+button{margin-left:var(--pfx-settings-panel-footer-gap, 12px)}praxis-settings-panel .settings-panel-footer button{display:inline-flex;align-items:center}praxis-settings-panel .settings-panel-footer button .mat-icon{flex:0 0 20px;font-size:20px;width:20px;height:20px;line-height:1;display:inline-flex;align-items:center;justify-content:center;overflow:hidden}praxis-settings-panel .settings-panel-footer .mat-button-wrapper{display:inline-flex;align-items:center;gap:var(--pfx-settings-panel-button-gap, 8px)}praxis-settings-panel .settings-panel-footer .mat-progress-spinner{margin-right:8px}praxis-settings-panel .settings-panel-footer .mat-flat-button[color=primary]{font-weight:600}praxis-settings-panel .settings-panel .mdc-button__label{display:inline-flex;align-items:center;gap:var(--pfx-settings-panel-button-gap, 8px);line-height:1}praxis-settings-panel .settings-panel .mdc-button__label>span{display:inline-flex;align-items:center;line-height:1}praxis-settings-panel .settings-panel .mdc-button__label .mat-icon{display:inline-flex;align-items:center;justify-content:center;line-height:1}@media(max-width:520px){praxis-settings-panel .settings-panel-footer{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:stretch}praxis-settings-panel .settings-panel-footer .spacer{display:none}praxis-settings-panel .settings-panel-footer button{justify-content:center;width:100%;min-width:0}praxis-settings-panel .settings-panel-footer button+button{margin-left:0}}praxis-settings-panel .settings-panel .mat-divider{background-color:var(--pfx-settings-panel-outline-variant)!important}praxis-settings-panel .settings-panel .mat-expansion-panel{background:var(--pfx-settings-panel-surface-container)!important;border:1px solid var(--pfx-settings-panel-outline-variant);border-radius:var(--md-sys-shape-corner-medium, 12px);box-shadow:var(--md-sys-elevation-level1, 0 2px 8px rgba(0, 0, 0, .08));color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-expansion-panel-header{background:var(--pfx-settings-panel-surface-container)!important;color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-content{color:var(--pfx-settings-panel-on-surface);flex-wrap:wrap;gap:4px 12px;min-width:0;overflow:visible}praxis-settings-panel .settings-panel .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:hover{background:color-mix(in srgb,var(--pfx-settings-panel-surface-container-high) 84%,var(--pfx-settings-panel-primary) 16%)}praxis-settings-panel .settings-panel .mat-expansion-panel.mat-expanded>.mat-expansion-panel-header{background:var(--pfx-settings-panel-surface-container-high)!important}praxis-settings-panel .settings-panel .mat-expansion-panel-header mat-icon,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-icon{color:var(--pfx-settings-panel-on-surface)!important}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-title,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-description{color:var(--pfx-settings-panel-on-surface);min-width:0;overflow:visible;white-space:normal}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-description{color:var(--pfx-settings-panel-on-surface-variant);flex-wrap:wrap;gap:8px}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-title>*,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-description>*{color:inherit}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-title small,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-description small{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-indicator,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-indicator:after{color:var(--pfx-settings-panel-on-surface-variant);border-color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-expansion-panel .mat-action-row{border-top-color:var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-low)}praxis-settings-panel .settings-panel .mat-accordion,praxis-settings-panel .settings-panel .mat-accordion .mat-expansion-panel-spacing{background:transparent!important}praxis-settings-panel .settings-panel .mat-expansion-panel-content,praxis-settings-panel .settings-panel .mat-expansion-panel-content-wrapper,praxis-settings-panel .settings-panel .mat-expansion-panel-body{background:var(--pfx-settings-panel-surface-container)!important;color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-expansion-panel .mat-expansion-panel-body{padding:8px}praxis-settings-panel .settings-panel .mat-expansion-panel .mat-expansion-panel-body>*{color:inherit}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mat-mdc-tab-header{border-bottom:1px solid var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-low)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab{min-width:0}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab .mdc-tab__text-label{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab:hover .mdc-tab__text-label,praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab:focus .mdc-tab__text-label{color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab.mdc-tab--active .mdc-tab__text-label{color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mat-mdc-tab-header-pagination{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mat-mdc-tab-header-pagination-chevron{border-color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mat-mdc-tab-header-pagination:not(.mat-mdc-tab-header-pagination-disabled):hover{background:color-mix(in srgb,var(--pfx-settings-panel-surface-container-high) 84%,var(--pfx-settings-panel-primary) 16%)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab-indicator__content--underline{border-color:var(--pfx-settings-panel-primary)}praxis-settings-panel .settings-panel .mat-mdc-card{background:var(--pfx-settings-panel-surface-container-low);border:1px solid var(--pfx-settings-panel-outline-variant);color:var(--pfx-settings-panel-on-surface);box-shadow:var(--md-sys-elevation-level1, 0 2px 8px rgba(0, 0, 0, .08))}praxis-settings-panel .settings-panel .mat-mdc-card-subtitle,praxis-settings-panel .settings-panel .mat-mdc-card-content{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-mdc-card-title{color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-mdc-form-field{width:100%;--mdc-filled-text-field-container-color: var( --pfx-settings-panel-surface-container );--mdc-filled-text-field-hover-container-color: var( --pfx-settings-panel-surface-container-high );--mdc-filled-text-field-focus-container-color: var( --pfx-settings-panel-surface-container-high );--mdc-filled-text-field-active-indicator-color: var( --pfx-settings-panel-outline-variant );--mdc-filled-text-field-hover-active-indicator-color: var( --pfx-settings-panel-secondary );--mdc-filled-text-field-focus-active-indicator-color: var( --pfx-settings-panel-primary );--mdc-filled-text-field-label-text-color: var( --pfx-settings-panel-on-surface-variant );--mdc-filled-text-field-focus-label-text-color: var( --pfx-settings-panel-primary );--mdc-filled-text-field-input-text-color: var( --pfx-settings-panel-on-surface );--mdc-filled-text-field-caret-color: var(--pfx-settings-panel-primary);--mdc-outlined-text-field-outline-color: var( --pfx-settings-panel-outline-variant );--mdc-outlined-text-field-hover-outline-color: var( --pfx-settings-panel-secondary );--mdc-outlined-text-field-focus-outline-color: var( --pfx-settings-panel-primary );--mdc-outlined-text-field-label-text-color: var( --pfx-settings-panel-on-surface-variant );--mdc-outlined-text-field-focus-label-text-color: var( --pfx-settings-panel-primary );--mdc-outlined-text-field-input-text-color: var( --pfx-settings-panel-on-surface );--mdc-outlined-text-field-caret-color: var(--pfx-settings-panel-primary);--mat-form-field-focus-select-arrow-color: var( --pfx-settings-panel-primary );--mat-form-field-enabled-select-arrow-color: var( --pfx-settings-panel-on-surface-variant )}praxis-settings-panel .settings-panel .mdc-text-field--filled{background-color:var(--pfx-settings-panel-surface-container)!important;border-radius:var(--md-sys-shape-corner-small, 8px) var(--md-sys-shape-corner-small, 8px) 0 0}praxis-settings-panel .settings-panel .mat-mdc-text-field-wrapper,praxis-settings-panel .settings-panel .mat-mdc-form-field-flex,praxis-settings-panel .settings-panel .mat-mdc-form-field-infix,praxis-settings-panel .settings-panel .mat-mdc-form-field-focus-overlay{background:var(--pfx-settings-panel-surface-container)!important;color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-mdc-form-field-focus-overlay{opacity:0}praxis-settings-panel .settings-panel .mdc-text-field--filled .mdc-text-field__input,praxis-settings-panel .settings-panel .mdc-text-field--filled .mdc-floating-label,praxis-settings-panel .settings-panel .mat-mdc-select-value,praxis-settings-panel .settings-panel .mat-mdc-select-arrow,praxis-settings-panel .settings-panel .mat-mdc-form-field .mat-mdc-floating-label{color:var(--pfx-settings-panel-on-surface-variant)!important}praxis-settings-panel .settings-panel .mdc-text-field--filled.mdc-text-field--focused .mdc-floating-label,praxis-settings-panel .settings-panel .mdc-text-field--filled .mdc-text-field__input{color:var(--pfx-settings-panel-on-surface)!important}praxis-settings-panel .settings-panel .mat-mdc-form-field input,praxis-settings-panel .settings-panel .mat-mdc-form-field textarea,praxis-settings-panel .settings-panel .mat-mdc-form-field .mdc-text-field__input{color:var(--pfx-settings-panel-on-surface)!important}praxis-settings-panel .settings-panel .mat-mdc-form-field-subscript-wrapper,praxis-settings-panel .settings-panel .mat-mdc-form-field-hint-wrapper,praxis-settings-panel .settings-panel .mat-mdc-form-field-error-wrapper,praxis-settings-panel .settings-panel .mat-mdc-hint{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-button-toggle-group{border-color:var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-low)}praxis-settings-panel .settings-panel .mat-button-toggle{background:var(--pfx-settings-panel-surface-container-low);color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-button-toggle+.mat-button-toggle{border-left-color:var(--pfx-settings-panel-outline-variant)}praxis-settings-panel .settings-panel .mat-button-toggle-checked{background:var(--pfx-settings-panel-primary-container)!important;color:var(--pfx-settings-panel-on-primary-container)!important}praxis-settings-panel .settings-panel .mat-button-toggle .mat-icon,praxis-settings-panel .settings-panel .mat-button-toggle-checked .mat-icon{color:inherit}praxis-settings-panel .settings-panel .mat-mdc-slide-toggle .mdc-label{color:var(--pfx-settings-panel-on-surface)}.settings-panel{grid-template-columns:minmax(0,1fr);min-width:0;max-width:100%}.settings-panel-body{overflow-x:hidden;min-width:0}.settings-panel-body>*{min-width:0;max-width:100%}.praxis-settings-panel-backdrop{background:var(--pfx-backdrop, rgba(8, 15, 26, .42));backdrop-filter:blur(var(--pfx-backdrop-blur, 6px)) saturate(110%);-webkit-backdrop-filter:blur(var(--pfx-backdrop-blur, 6px)) saturate(110%)}.praxis-settings-panel-pane{position:fixed!important;top:0!important;right:0!important;display:flex!important;align-items:stretch!important;height:100vh!important;max-width:100vw!important;max-height:100vh!important;z-index:var(--praxis-layer-settings-panel, 1220)!important;transition:width var(--pfx-side-panel-motion-duration-enter, .3s) var(--pfx-side-panel-motion-easing-enter, ease)}.praxis-settings-panel-pane .settings-panel{pointer-events:auto}@media(prefers-reduced-motion:reduce){.praxis-settings-panel-pane{transition:none}}\n"] }]
1035
+ ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [providePraxisSettingsPanelI18n()], template: "<div\n class=\"settings-panel\"\n data-testid=\"settings-panel-root\"\n [class.expanded]=\"expanded\"\n [class.is-resizable]=\"showResizeHandle\"\n [ngStyle]=\"panelInlineStyles\"\n role=\"dialog\"\n [attr.aria-modal]=\"interactionActive ? 'true' : null\"\n [attr.aria-hidden]=\"interactionActive ? null : 'true'\"\n [attr.inert]=\"interactionActive ? null : ''\"\n [attr.aria-labelledby]=\"titleId\"\n [cdkTrapFocus]=\"interactionActive\"\n [cdkTrapFocusAutoCapture]=\"interactionActive\"\n >\n @if (showResizeHandle) {\n <div\n class=\"settings-panel__resize-handle\"\n role=\"separator\"\n tabindex=\"0\"\n aria-orientation=\"vertical\"\n [attr.aria-label]=\"resizeHandleLabel\"\n (pointerdown)=\"onResizeHandlePointerDown($event)\"\n (keydown)=\"onResizeHandleKeydown($event)\"\n ></div>\n }\n <header class=\"settings-panel-header\">\n <h2 class=\"settings-panel-title\" [id]=\"titleId\">\n @if (titleIcon) {\n <mat-icon class=\"title-icon\" [praxisIcon]=\"titleIcon\"></mat-icon>\n }\n <span>{{ title }}</span>\n </h2>\n <span class=\"spacer\"></span>\n <button\n [praxisIconButton]=\"expanded ? 'close_fullscreen' : 'open_in_full'\"\n size=\"compact\"\n type=\"button\"\n data-testid=\"settings-panel-toggle-expand\"\n [attr.aria-label]=\"expanded ? tx('Collapse panel') : tx('Expand panel')\"\n [attr.aria-expanded]=\"expanded\"\n [matTooltip]=\"expanded ? tx('Collapse panel') : tx('Expand panel')\"\n (click)=\"toggleExpand()\"\n ></button>\n <button\n praxisIconButton=\"close\"\n size=\"compact\"\n type=\"button\"\n data-testid=\"settings-panel-close-icon\"\n [attr.aria-label]=\"tx('Close')\"\n [matTooltip]=\"tx('Close')\"\n (click)=\"onCancel()\"\n ></button>\n </header>\n @if (showStatusMessage) {\n <div\n class=\"settings-panel-status\"\n [attr.data-status]=\"statusTone\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <mat-icon\n aria-hidden=\"true\"\n [praxisIcon]=\"\n statusTone === 'dirty' || statusTone === 'invalid'\n ? 'warning'\n : statusTone === 'saved'\n ? 'check_circle'\n : statusTone === 'busy'\n ? 'autorenew'\n : 'info'\n \"\n ></mat-icon>\n <span>{{ statusMessage }}</span>\n </div>\n }\n <div class=\"settings-panel-body\">\n <ng-template #contentHost></ng-template>\n </div>\n <footer class=\"settings-panel-footer\">\n <button\n mat-button\n type=\"button\"\n data-testid=\"settings-panel-reset\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); onReset()\"\n [disabled]=\"isBusy\"\n >\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'restart_alt'\"></mat-icon>\n <span>{{ tx('Reset') }}</span>\n </button>\n <span class=\"spacer\"></span>\n <button\n mat-button\n type=\"button\"\n data-testid=\"settings-panel-cancel\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); onCancel()\"\n [disabled]=\"isBusy\"\n >\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'close'\"></mat-icon>\n <span>{{ tx('Cancel') }}</span>\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n data-testid=\"settings-panel-apply\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); onApply()\"\n [disabled]=\"!canApply\"\n [matTooltip]=\"applySaveDisabledReason\"\n [matTooltipDisabled]=\"canApply || !diagnostics.showDisabledReason\"\n [attr.aria-busy]=\"isBusy\"\n [attr.aria-label]=\"applyActionLabel || 'Apply'\"\n >\n @if (showBusyIndicator) {\n <mat-progress-spinner\n mode=\"indeterminate\"\n diameter=\"20\"\n ></mat-progress-spinner>\n }\n @if (!showBusyIndicator) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'done'\"></mat-icon>\n <span class=\"settings-panel-action-label settings-panel-action-label--apply\">{{ applyActionLabel }}</span>\n }\n </button>\n <button\n mat-flat-button\n color=\"primary\"\n type=\"button\"\n data-testid=\"settings-panel-save\"\n (mousedown)=\"$event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); onSave()\"\n [disabled]=\"!canSave\"\n [matTooltip]=\"applySaveDisabledReason\"\n [matTooltipDisabled]=\"canSave || !diagnostics.showDisabledReason\"\n [attr.aria-busy]=\"isBusy\"\n [attr.aria-label]=\"saveActionLabel || 'Save & Close'\"\n >\n @if (showBusyIndicator) {\n <mat-progress-spinner\n mode=\"indeterminate\"\n diameter=\"20\"\n ></mat-progress-spinner>\n }\n @if (!showBusyIndicator) {\n <mat-icon aria-hidden=\"true\" [praxisIcon]=\"'save'\"></mat-icon>\n <span class=\"settings-panel-action-label settings-panel-action-label--save\">{{ saveActionLabel }}</span>\n }\n </button>\n </footer>\n</div>\n", styles: ["@charset \"UTF-8\";praxis-settings-panel{display:block;height:100%;width:100%;min-width:0;flex:1 1 auto}praxis-settings-panel .settings-panel{position:relative;--pfx-settings-panel-surface-container: var( --md-sys-color-surface-container, #ffffff );--pfx-settings-panel-surface-container-high: var( --md-sys-color-surface-container-high, #f7f7f7 );--pfx-settings-panel-surface-container-low: var( --md-sys-color-surface-container-low, #f2f4f7 );--pfx-settings-panel-surface: var(--md-sys-color-surface, #ffffff);--pfx-settings-panel-on-surface: var(--md-sys-color-on-surface, #111827);--pfx-settings-panel-on-surface-variant: var( --md-sys-color-on-surface-variant, rgba(17, 24, 39, .72) );--pfx-settings-panel-outline: var( --md-sys-color-outline, rgba(15, 23, 42, .24) );--pfx-settings-panel-outline-variant: var( --md-sys-color-outline-variant, rgba(15, 23, 42, .12) );--pfx-settings-panel-primary: var(--md-sys-color-primary, #2563eb);--pfx-settings-panel-primary-container: var( --md-sys-color-primary-container, rgba(37, 99, 235, .14) );--pfx-settings-panel-on-primary-container: var( --md-sys-color-on-primary-container, #0f172a );--pfx-settings-panel-secondary: var( --md-sys-color-secondary, var(--pfx-settings-panel-primary) );--pfx-settings-panel-error: var(--md-sys-color-error, #b3261e);--pfx-settings-panel-error-container: var( --md-sys-color-error-container, rgba(179, 38, 30, .14) );display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto auto 1fr auto;grid-template-areas:\"header\" \"status\" \"body\" \"footer\";height:100%;background:var(--pfx-settings-panel-surface-container);color:var(--pfx-settings-panel-on-surface);border-left:1px solid var(--pfx-settings-panel-outline-variant);width:100%;max-width:100%;min-width:0;box-shadow:var(--pfx-settings-panel-elevation, var(--md-sys-elevation-level2, 0 8px 24px rgba(0, 0, 0, .16)));overflow:hidden}praxis-settings-panel .settings-panel__resize-handle{position:absolute;inset:0 auto 0 0;width:12px;cursor:col-resize;touch-action:none;z-index:3;outline:none}praxis-settings-panel .settings-panel__resize-handle:before{content:\"\";position:absolute;inset:0 auto 0 4px;width:2px;background:transparent;transition:background-color var(--pfx-side-panel-motion-duration, .16s) ease,opacity var(--pfx-side-panel-motion-duration, .16s) ease;opacity:0}praxis-settings-panel .settings-panel.is-resizable:hover .settings-panel__resize-handle:before,praxis-settings-panel .settings-panel__resize-handle:focus-visible:before{opacity:1;background:var(--pfx-settings-panel-outline)}praxis-settings-panel .settings-panel-header{grid-area:header;display:flex;align-items:center;gap:var(--pfx-settings-panel-header-gap, 8px);padding:12px var(--pfx-settings-panel-header-padding-x, 20px);min-height:var(--pfx-settings-panel-header-height, 64px);border-bottom:1px solid var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-high);box-shadow:var(--pfx-settings-panel-header-shadow, var(--md-sys-elevation-level1, 0 2px 6px rgba(0, 0, 0, .08)));flex-shrink:0;min-width:0;max-width:100%}praxis-settings-panel .settings-panel-header .spacer{flex:1 1 auto;min-width:0}praxis-settings-panel .settings-panel-status{grid-area:status;display:flex;align-items:center;gap:8px;min-height:36px;padding:6px var(--pfx-settings-panel-status-padding-x, 20px);border-bottom:1px solid var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-high);color:var(--pfx-settings-panel-on-surface);font-size:.85rem;font-weight:500;min-width:0;max-width:100%}praxis-settings-panel .settings-panel-status mat-icon{width:18px;height:18px;font-size:18px}praxis-settings-panel .settings-panel-status[data-status=dirty],praxis-settings-panel .settings-panel-status[data-status=invalid]{color:var(--pfx-settings-panel-error);background:color-mix(in srgb,var(--pfx-settings-panel-error-container) 30%,var(--pfx-settings-panel-surface-container-high))}praxis-settings-panel .settings-panel-status[data-status=saved]{color:var(--pfx-settings-panel-primary);background:color-mix(in srgb,var(--pfx-settings-panel-primary-container) 28%,var(--pfx-settings-panel-surface-container-high))}praxis-settings-panel .settings-panel-body{grid-area:body;overflow-y:auto;overflow-x:hidden;scroll-padding-top:var(--pfx-settings-panel-scroll-padding-start, 16px);scroll-padding-bottom:var(--pfx-settings-panel-scroll-padding-end, 88px);min-height:0;padding:var(--pfx-settings-panel-body-padding, 8px 16px 24px);background:var(--pfx-settings-panel-surface);display:flex;flex-direction:column;min-width:0;max-width:100%}praxis-settings-panel .settings-panel-body>*{min-width:0;max-width:100%}praxis-settings-panel .settings-panel-content{display:block;min-width:0;max-width:100%}praxis-settings-panel .settings-panel-content>*{min-width:0;max-width:100%;box-sizing:border-box}praxis-settings-panel .settings-panel-footer{grid-area:footer;border-top:1px solid var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-high);box-shadow:var(--pfx-settings-panel-footer-shadow, var(--md-sys-elevation-level1, 0 -2px 6px rgba(0, 0, 0, .08)));display:flex;align-items:center;flex-wrap:wrap;padding:var(--pfx-settings-panel-footer-padding, 12px 20px);column-gap:var(--pfx-settings-panel-footer-gap, 12px);row-gap:8px;flex-shrink:0;min-width:0;max-width:100%}praxis-settings-panel .spacer{flex:1}praxis-settings-panel .settings-panel-title{display:inline-flex;align-items:center;flex:1 1 auto;gap:var(--pfx-settings-panel-title-gap, 8px);font-weight:700;line-height:1.2;letter-spacing:.2px;margin:0;min-width:0;overflow:visible;white-space:normal}praxis-settings-panel .settings-panel-title span{min-width:0;overflow:visible;white-space:normal}praxis-settings-panel .settings-panel-title mat-icon{color:var(--pfx-settings-panel-primary)}praxis-settings-panel .settings-panel-title .title-icon{width:20px;height:20px;font-size:20px}praxis-settings-panel .settings-panel-footer button+button{margin-left:var(--pfx-settings-panel-footer-gap, 12px)}praxis-settings-panel .settings-panel-footer button{display:inline-flex;align-items:center}praxis-settings-panel .settings-panel-footer button .mat-icon{flex:0 0 20px;font-size:20px;width:20px;height:20px;line-height:1;display:inline-flex;align-items:center;justify-content:center;overflow:hidden}praxis-settings-panel .settings-panel-footer .mat-button-wrapper{display:inline-flex;align-items:center;gap:var(--pfx-settings-panel-button-gap, 8px)}praxis-settings-panel .settings-panel-footer .mat-progress-spinner{margin-right:8px}praxis-settings-panel .settings-panel-footer .mat-flat-button[color=primary]{font-weight:600}praxis-settings-panel .settings-panel .mdc-button__label{display:inline-flex;align-items:center;gap:var(--pfx-settings-panel-button-gap, 8px);line-height:1}praxis-settings-panel .settings-panel .mdc-button__label>span{display:inline-flex;align-items:center;line-height:1}praxis-settings-panel .settings-panel .mdc-button__label .mat-icon{display:inline-flex;align-items:center;justify-content:center;line-height:1}@media(max-width:520px){praxis-settings-panel .settings-panel-footer{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:stretch}praxis-settings-panel .settings-panel-footer .spacer{display:none}praxis-settings-panel .settings-panel-footer button{justify-content:center;width:100%;min-width:0}praxis-settings-panel .settings-panel-footer button+button{margin-left:0}}praxis-settings-panel .settings-panel .mat-divider{background-color:var(--pfx-settings-panel-outline-variant)!important}praxis-settings-panel .settings-panel .mat-expansion-panel{background:var(--pfx-settings-panel-surface-container)!important;border:1px solid var(--pfx-settings-panel-outline-variant);border-radius:var(--md-sys-shape-corner-medium, 12px);box-shadow:var(--md-sys-elevation-level1, 0 2px 8px rgba(0, 0, 0, .08));color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-expansion-panel-header{background:var(--pfx-settings-panel-surface-container)!important;color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-content{color:var(--pfx-settings-panel-on-surface);flex-wrap:wrap;gap:4px 12px;min-width:0;overflow:visible}praxis-settings-panel .settings-panel .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:hover{background:color-mix(in srgb,var(--pfx-settings-panel-surface-container-high) 84%,var(--pfx-settings-panel-primary) 16%)}praxis-settings-panel .settings-panel .mat-expansion-panel.mat-expanded>.mat-expansion-panel-header{background:var(--pfx-settings-panel-surface-container-high)!important}praxis-settings-panel .settings-panel .mat-expansion-panel-header mat-icon,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-icon{color:var(--pfx-settings-panel-on-surface)!important}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-title,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-description{color:var(--pfx-settings-panel-on-surface);min-width:0;overflow:visible;white-space:normal}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-description{color:var(--pfx-settings-panel-on-surface-variant);flex-wrap:wrap;gap:8px}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-title>*,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-description>*{color:inherit}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-title small,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-panel-header-description small{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-indicator,praxis-settings-panel .settings-panel .mat-expansion-panel-header .mat-expansion-indicator:after{color:var(--pfx-settings-panel-on-surface-variant);border-color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-expansion-panel .mat-action-row{border-top-color:var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-low)}praxis-settings-panel .settings-panel .mat-accordion,praxis-settings-panel .settings-panel .mat-accordion .mat-expansion-panel-spacing{background:transparent!important}praxis-settings-panel .settings-panel .mat-expansion-panel-content,praxis-settings-panel .settings-panel .mat-expansion-panel-content-wrapper,praxis-settings-panel .settings-panel .mat-expansion-panel-body{background:var(--pfx-settings-panel-surface-container)!important;color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-expansion-panel .mat-expansion-panel-body{padding:8px}praxis-settings-panel .settings-panel .mat-expansion-panel .mat-expansion-panel-body>*{color:inherit}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mat-mdc-tab-header{border-bottom:1px solid var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-low)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab{min-width:0}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab .mdc-tab__text-label{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab:hover .mdc-tab__text-label,praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab:focus .mdc-tab__text-label{color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab.mdc-tab--active .mdc-tab__text-label{color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mat-mdc-tab-header-pagination{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mat-mdc-tab-header-pagination-chevron{border-color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mat-mdc-tab-header-pagination:not(.mat-mdc-tab-header-pagination-disabled):hover{background:color-mix(in srgb,var(--pfx-settings-panel-surface-container-high) 84%,var(--pfx-settings-panel-primary) 16%)}praxis-settings-panel .settings-panel .mat-mdc-tab-group .mdc-tab-indicator__content--underline{border-color:var(--pfx-settings-panel-primary)}praxis-settings-panel .settings-panel .mat-mdc-card{background:var(--pfx-settings-panel-surface-container-low);border:1px solid var(--pfx-settings-panel-outline-variant);color:var(--pfx-settings-panel-on-surface);box-shadow:var(--md-sys-elevation-level1, 0 2px 8px rgba(0, 0, 0, .08))}praxis-settings-panel .settings-panel .mat-mdc-card-subtitle,praxis-settings-panel .settings-panel .mat-mdc-card-content{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-mdc-card-title{color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-mdc-form-field{width:100%;--mdc-filled-text-field-container-color: var( --pfx-settings-panel-surface-container );--mdc-filled-text-field-hover-container-color: var( --pfx-settings-panel-surface-container-high );--mdc-filled-text-field-focus-container-color: var( --pfx-settings-panel-surface-container-high );--mdc-filled-text-field-active-indicator-color: var( --pfx-settings-panel-outline-variant );--mdc-filled-text-field-hover-active-indicator-color: var( --pfx-settings-panel-secondary );--mdc-filled-text-field-focus-active-indicator-color: var( --pfx-settings-panel-primary );--mdc-filled-text-field-label-text-color: var( --pfx-settings-panel-on-surface-variant );--mdc-filled-text-field-focus-label-text-color: var( --pfx-settings-panel-primary );--mdc-filled-text-field-input-text-color: var( --pfx-settings-panel-on-surface );--mdc-filled-text-field-caret-color: var(--pfx-settings-panel-primary);--mdc-outlined-text-field-outline-color: var( --pfx-settings-panel-outline-variant );--mdc-outlined-text-field-hover-outline-color: var( --pfx-settings-panel-secondary );--mdc-outlined-text-field-focus-outline-color: var( --pfx-settings-panel-primary );--mdc-outlined-text-field-label-text-color: var( --pfx-settings-panel-on-surface-variant );--mdc-outlined-text-field-focus-label-text-color: var( --pfx-settings-panel-primary );--mdc-outlined-text-field-input-text-color: var( --pfx-settings-panel-on-surface );--mdc-outlined-text-field-caret-color: var(--pfx-settings-panel-primary);--mat-form-field-focus-select-arrow-color: var( --pfx-settings-panel-primary );--mat-form-field-enabled-select-arrow-color: var( --pfx-settings-panel-on-surface-variant )}praxis-settings-panel .settings-panel .mdc-text-field--filled{background-color:var(--pfx-settings-panel-surface-container)!important;border-radius:var(--md-sys-shape-corner-small, 8px) var(--md-sys-shape-corner-small, 8px) 0 0}praxis-settings-panel .settings-panel .mat-mdc-text-field-wrapper,praxis-settings-panel .settings-panel .mat-mdc-form-field-flex,praxis-settings-panel .settings-panel .mat-mdc-form-field-infix,praxis-settings-panel .settings-panel .mat-mdc-form-field-focus-overlay{background:var(--pfx-settings-panel-surface-container)!important;color:var(--pfx-settings-panel-on-surface)}praxis-settings-panel .settings-panel .mat-mdc-form-field-focus-overlay{opacity:0}praxis-settings-panel .settings-panel .mdc-text-field--filled .mdc-text-field__input,praxis-settings-panel .settings-panel .mdc-text-field--filled .mdc-floating-label,praxis-settings-panel .settings-panel .mat-mdc-select-value,praxis-settings-panel .settings-panel .mat-mdc-select-arrow,praxis-settings-panel .settings-panel .mat-mdc-form-field .mat-mdc-floating-label{color:var(--pfx-settings-panel-on-surface-variant)!important}praxis-settings-panel .settings-panel .mdc-text-field--filled.mdc-text-field--focused .mdc-floating-label,praxis-settings-panel .settings-panel .mdc-text-field--filled .mdc-text-field__input{color:var(--pfx-settings-panel-on-surface)!important}praxis-settings-panel .settings-panel .mat-mdc-form-field input,praxis-settings-panel .settings-panel .mat-mdc-form-field textarea,praxis-settings-panel .settings-panel .mat-mdc-form-field .mdc-text-field__input{color:var(--pfx-settings-panel-on-surface)!important}praxis-settings-panel .settings-panel .mat-mdc-form-field-subscript-wrapper,praxis-settings-panel .settings-panel .mat-mdc-form-field-hint-wrapper,praxis-settings-panel .settings-panel .mat-mdc-form-field-error-wrapper,praxis-settings-panel .settings-panel .mat-mdc-hint{color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-button-toggle-group{border-color:var(--pfx-settings-panel-outline-variant);background:var(--pfx-settings-panel-surface-container-low)}praxis-settings-panel .settings-panel .mat-button-toggle{background:var(--pfx-settings-panel-surface-container-low);color:var(--pfx-settings-panel-on-surface-variant)}praxis-settings-panel .settings-panel .mat-button-toggle+.mat-button-toggle{border-left-color:var(--pfx-settings-panel-outline-variant)}praxis-settings-panel .settings-panel .mat-button-toggle-checked{background:var(--pfx-settings-panel-primary-container)!important;color:var(--pfx-settings-panel-on-primary-container)!important}praxis-settings-panel .settings-panel .mat-button-toggle .mat-icon,praxis-settings-panel .settings-panel .mat-button-toggle-checked .mat-icon{color:inherit}praxis-settings-panel .settings-panel .mat-mdc-slide-toggle .mdc-label{color:var(--pfx-settings-panel-on-surface)}.settings-panel{grid-template-columns:minmax(0,1fr);min-width:0;max-width:100%}.settings-panel-body{overflow-x:hidden;min-width:0}.settings-panel-body>*{min-width:0;max-width:100%}.praxis-settings-panel-backdrop{background:var(--pfx-backdrop, rgba(8, 15, 26, .42));backdrop-filter:blur(var(--pfx-backdrop-blur, 6px)) saturate(110%);-webkit-backdrop-filter:blur(var(--pfx-backdrop-blur, 6px)) saturate(110%)}.praxis-settings-panel-pane{position:fixed!important;top:0!important;right:0!important;display:flex!important;align-items:stretch!important;height:100vh!important;max-width:100vw!important;max-height:100vh!important;z-index:var(--praxis-layer-settings-panel, 1220)!important;transition:width var(--pfx-side-panel-motion-duration-enter, .3s) var(--pfx-side-panel-motion-easing-enter, ease)}.praxis-settings-panel-pane .settings-panel{pointer-events:auto}@media(prefers-reduced-motion:reduce){.praxis-settings-panel-pane{transition:none}}\n"] }]
1028
1036
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.MatDialog }, { type: i0.ElementRef }, { type: i1$1.OverlayContainer }], propDecorators: { contentHost: [{
1029
1037
  type: ViewChild,
1030
1038
  args: ['contentHost', { read: ViewContainerRef, static: true }]
@@ -1696,6 +1704,8 @@ class SettingsPanelService {
1696
1704
  injector;
1697
1705
  currentRef;
1698
1706
  currentPanelInstance;
1707
+ currentScope;
1708
+ childSequence = 0;
1699
1709
  i18n = inject(PraxisI18nService);
1700
1710
  layerScale = inject(PraxisLayerScaleStyleService);
1701
1711
  constructor(baseSidePanelService, injector) {
@@ -1727,13 +1737,36 @@ class SettingsPanelService {
1727
1737
  }
1728
1738
  return this.openFresh(config);
1729
1739
  }
1730
- openFresh(config) {
1740
+ /**
1741
+ * Opens an authoring editor above the current settings panel without
1742
+ * destroying the parent editor and its draft state.
1743
+ */
1744
+ openChild(config) {
1745
+ if (!this.currentRef || !this.currentPanelInstance) {
1746
+ return this.openFresh(config);
1747
+ }
1748
+ const parent = {
1749
+ ref: this.currentRef,
1750
+ panel: this.currentPanelInstance,
1751
+ scope: this.currentScope ?? 'settings-panel',
1752
+ };
1753
+ parent.panel.setInteractionActive(false);
1754
+ const scope = `settings-panel-child-${++this.childSequence}`;
1755
+ try {
1756
+ return this.openFresh(config, scope, parent);
1757
+ }
1758
+ catch (error) {
1759
+ parent.panel.setInteractionActive(true);
1760
+ throw error;
1761
+ }
1762
+ }
1763
+ openFresh(config, scope = 'settings-panel', parent) {
1731
1764
  this.layerScale.ensureInstalled();
1732
1765
  const ref = this.baseSidePanelService.openHost({
1733
1766
  component: SettingsPanelComponent,
1734
1767
  config: {
1735
1768
  id: config.id,
1736
- scope: 'settings-panel',
1769
+ scope,
1737
1770
  title: config.title,
1738
1771
  titleIcon: config.titleIcon,
1739
1772
  width: '720px',
@@ -1774,6 +1807,7 @@ class SettingsPanelService {
1774
1807
  });
1775
1808
  panelRef.instance.configureDiagnostics(config.diagnostics);
1776
1809
  this.currentPanelInstance = panelRef.instance;
1810
+ this.currentScope = scope;
1777
1811
  const inputs = config.content.inputs;
1778
1812
  const injector = Injector.create({
1779
1813
  providers: [
@@ -1791,17 +1825,17 @@ class SettingsPanelService {
1791
1825
  });
1792
1826
  ref.closed$.subscribe(() => {
1793
1827
  if (this.currentRef === ref) {
1794
- this.currentRef = undefined;
1795
- this.currentPanelInstance = undefined;
1828
+ this.currentRef = parent?.ref;
1829
+ this.currentPanelInstance = parent?.panel;
1830
+ this.currentScope = parent?.scope;
1831
+ parent?.panel.setInteractionActive(true);
1796
1832
  }
1797
1833
  });
1798
1834
  this.currentRef = ref;
1799
1835
  return ref;
1800
1836
  }
1801
1837
  close(reason = 'cancel') {
1802
- this.baseSidePanelService.closeScope('settings-panel', reason);
1803
- this.currentRef = undefined;
1804
- this.currentPanelInstance = undefined;
1838
+ this.currentRef?.close(reason);
1805
1839
  }
1806
1840
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SettingsPanelService, deps: [{ token: BaseSidePanelService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
1807
1841
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SettingsPanelService, providedIn: 'root' });
@@ -5148,7 +5182,7 @@ const PRAXIS_SETTINGS_PANEL_AUTHORING_MANIFEST = {
5148
5182
  configSchemaId: 'SettingsPanelConfig',
5149
5183
  manifestVersion: '1.0.0',
5150
5184
  runtimeInputs: [
5151
- { name: 'config', type: 'SettingsPanelConfig', description: 'Canonical settings panel shell config passed to SettingsPanelService.open.' },
5185
+ { name: 'config', type: 'SettingsPanelConfig', description: 'Canonical settings panel shell config passed to SettingsPanelService.open or to openChild for a subordinate editor of the same authoring document.' },
5152
5186
  { name: 'config.diagnostics', type: 'SettingsPanelDiagnosticsConfig', description: 'Optional shell diagnostics visibility config for status, disabled reason, busy state and validation state.' },
5153
5187
  { name: 'content.component', type: 'Type<SettingsValueProvider>', description: 'Standalone editor component hosted inside the authoring shell.' },
5154
5188
  { name: 'content.inputs', type: 'Record<string, unknown>', description: 'Initial editor inputs owned by the consumer component manifest.' },
@@ -5315,7 +5349,7 @@ const PRAXIS_SETTINGS_PANEL_AUTHORING_MANIFEST = {
5315
5349
  failureModes: ['editor-component-not-registered', 'settings-value-provider-missing', 'consumer-manifest-required', 'consumer-config-boundary-violation'],
5316
5350
  description: 'Configures the hosted editor component and input envelope while delegating consumer-specific config edits to the owning component manifest.',
5317
5351
  } }],
5318
- validators: ['editor-component-registered', 'settings-value-provider-contract-present', 'consumer-config-delegated', 'editor-inputs-serializable'],
5352
+ validators: ['editor-component-registered', 'settings-value-provider-contract-present', 'consumer-config-delegated', 'editor-inputs-serializable', 'child-panel-isolates-parent-interaction'],
5319
5353
  affectedPaths: ['config.content.component', 'config.content.inputs', 'delegatedConsumerPatch'],
5320
5354
  submissionImpact: 'config-only',
5321
5355
  destructive: false,
@@ -5360,6 +5394,7 @@ const PRAXIS_SETTINGS_PANEL_AUTHORING_MANIFEST = {
5360
5394
  validators: [
5361
5395
  { validatorId: 'panel-id-stable', level: 'error', code: 'SETTINGS_PANEL_ID_STABLE', description: 'Panel id must remain stable for replacement, persistence and diagnostics.' },
5362
5396
  { validatorId: 'replacement-mediates-before-close', level: 'error', code: 'SETTINGS_PANEL_REPLACEMENT_MEDIATES_CLOSE', description: 'Opening a replacement panel must consult the current editor onBeforeClose before closing.' },
5397
+ { validatorId: 'child-panel-isolates-parent-interaction', level: 'error', code: 'SETTINGS_PANEL_CHILD_ISOLATES_PARENT', description: 'A subordinate authoring panel must preserve the parent draft while making the parent inert and preventing parent keyboard shortcuts until the child closes.' },
5363
5398
  { validatorId: 'title-i18n-compatible', level: 'warning', code: 'SETTINGS_PANEL_TITLE_I18N_COMPATIBLE', description: 'Authoring chrome text must remain compatible with the settings panel i18n namespace.' },
5364
5399
  { validatorId: 'panel-size-safe', level: 'error', code: 'SETTINGS_PANEL_SIZE_SAFE', description: 'Panel sizes must be finite numbers or safe CSS size strings.' },
5365
5400
  { validatorId: 'panel-min-max-consistent', level: 'error', code: 'SETTINGS_PANEL_MIN_MAX_CONSISTENT', description: 'Minimum width must not exceed maximum width.' },
@@ -5388,6 +5423,7 @@ const PRAXIS_SETTINGS_PANEL_AUTHORING_MANIFEST = {
5388
5423
  'Apply must emit applied$ without closing; Save must emit saved$ and close with reason save; Reset must be confirmed and emit reset$.',
5389
5424
  'Busy, dirty and valid state must gate Apply and Save consistently and remain visible through diagnostics.',
5390
5425
  'Opening a replacement panel must pass through the current editor onBeforeClose and dirty-discard mediation.',
5426
+ 'Opening a subordinate editor with openChild must preserve the parent draft, isolate parent focus and shortcuts, and reactivate the parent only after the child closes.',
5391
5427
  ],
5392
5428
  examples: [
5393
5429
  { id: 'open-component-editor', request: 'Open the table settings editor in the settings panel.', operationId: 'editor.host.configure', params: { componentId: 'praxis-table', inputs: { tableId: 'orders' }, configManifestComponentId: 'praxis-table', editorContract: 'SettingsValueProvider' }, isPositive: true },
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@praxisui/settings-panel",
3
- "version": "9.0.5-rc.37",
3
+ "version": "9.0.5-rc.39",
4
4
  "description": "Settings panel for Praxis UI libraries: open editors for configuration at runtime and persist settings.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
7
7
  "@angular/core": "^21.0.0",
8
8
  "@angular/cdk": "^21.0.0",
9
9
  "@angular/material": "^21.0.0",
10
- "@praxisui/ai": "^9.0.5-rc.37",
11
- "@praxisui/core": "^9.0.5-rc.37",
12
- "@praxisui/dynamic-fields": "^9.0.5-rc.37",
10
+ "@praxisui/ai": "^9.0.5-rc.39",
11
+ "@praxisui/core": "^9.0.5-rc.39",
12
+ "@praxisui/dynamic-fields": "^9.0.5-rc.39",
13
13
  "rxjs": "~7.8.0"
14
14
  },
15
15
  "dependencies": {
@@ -334,6 +334,8 @@ declare class SettingsPanelService {
334
334
  private injector;
335
335
  private currentRef?;
336
336
  private currentPanelInstance?;
337
+ private currentScope?;
338
+ private childSequence;
337
339
  private readonly i18n;
338
340
  private readonly layerScale;
339
341
  constructor(baseSidePanelService: BaseSidePanelService, injector: Injector);
@@ -343,6 +345,11 @@ declare class SettingsPanelService {
343
345
  * same overlay when the provided id matches.
344
346
  */
345
347
  open(config: SettingsPanelConfig): SettingsPanelRef;
348
+ /**
349
+ * Opens an authoring editor above the current settings panel without
350
+ * destroying the parent editor and its draft state.
351
+ */
352
+ openChild(config: SettingsPanelConfig): SettingsPanelRef;
346
353
  private openFresh;
347
354
  close(reason?: SettingsPanelCloseReason): void;
348
355
  static ɵfac: i0.ɵɵFactoryDeclaration<SettingsPanelService, never>;
@@ -424,6 +431,7 @@ declare class SettingsPanelComponent {
424
431
  resizable: boolean;
425
432
  persistSizeKey?: string;
426
433
  expanded: boolean;
434
+ interactionActive: boolean;
427
435
  ref: SettingsPanelRef;
428
436
  contentRef?: ComponentRef<any>;
429
437
  private static nextId;
@@ -448,6 +456,7 @@ declare class SettingsPanelComponent {
448
456
  get showResizeHandle(): boolean;
449
457
  get resizeHandleLabel(): string;
450
458
  get canSave(): boolean;
459
+ setInteractionActive(active: boolean): void;
451
460
  get disabledReason(): string;
452
461
  get applySaveDisabledReason(): string;
453
462
  get showStatusMessage(): boolean;