@praxisui/crud 9.0.4-rc.36 → 9.0.4-rc.38

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
@@ -103,7 +103,7 @@ It emits:
103
103
  - `configureRequested`
104
104
  - `afterOpen`, `afterClose`, `afterSave`, `afterDelete`
105
105
  - `error`
106
- - `rowClick`, `selectionChange`
106
+ - `rowClick`, `rowAction`, `selectionChange`. `rowAction` preserves the canonical table envelope (`row`, `action`, `resourceIdentity`) so a governed composition can update task context without forcing visual row selection.
107
107
  - `tableRuntimeConfigChange`
108
108
  - `crudAuthoringDocumentApplied`, `crudAuthoringDocumentSaved`
109
109
 
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-08-08T10:35:56.871Z",
3
+ "generatedAt": "2026-08-10T00:53:13.101Z",
4
4
  "packageName": "@praxisui/crud",
5
- "packageVersion": "9.0.4-rc.36",
5
+ "packageVersion": "9.0.4-rc.38",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 2,
@@ -130,6 +130,12 @@
130
130
  "required": false,
131
131
  "description": "Encaminha o clique de linha da tabela interna para composição master-detail e seleção local."
132
132
  },
133
+ {
134
+ "name": "rowAction",
135
+ "type": "CrudActionRuntimeEvent",
136
+ "required": false,
137
+ "description": "Encaminha a ação contextual da linha com row, action e resourceIdentity para composição governada."
138
+ },
133
139
  {
134
140
  "name": "selectionChange",
135
141
  "type": "unknown",
@@ -7218,9 +7224,9 @@
7218
7224
  {
7219
7225
  "chunkIndex": 0,
7220
7226
  "chunkKind": "summary",
7221
- "content": "Component ID: praxis-crud\nSelector: praxis-crud\nFriendly Name: Praxis CRUD\nDescription: Tabela com operações de CRUD via metadados.\nLib/Package: @praxisui/crud\nTags: widget, crud, configurable, hasWizard, stable\nInputs:\n - metadata (CrudMetadata | string)\n - crudId (string)\n - componentInstanceId (string)\n - tableConfigPersistenceStrategy ('local-first' | 'input-first' | 'volatile')\n - context (Record<string, unknown>)\n - metadata.queryContext (PraxisDataQueryContext | null)\n - metadata.resource.schemaPath (string | null)\n - metadata.resource.title (string | null)\n - metadata.resource.formTitle (string | null)\n - metadata.filterCriteria (Record<string, unknown> | null)\n - metadata.form (FormConfig)\n - metadata.actions[].form (CrudActionFormContract)\n - enableCustomization (boolean)\n - authoringCapability (string | null)\nOutputs:\n - afterOpen ({ mode: FormOpenMode; action: string })\n - afterClose (void)\n - afterSave ({ id: string | number; data: unknown })\n - afterDelete ({ id: string | number })\n - rowClick ({ row: unknown; index: number })\n - selectionChange (unknown)\n - error (unknown)\n - configureRequested (void)\n - crudAuthoringDocumentApplied (CrudAuthoringWidgetPersistenceEvent)\n - crudAuthoringDocumentSaved (CrudAuthoringWidgetPersistenceEvent)\n",
7227
+ "content": "Component ID: praxis-crud\nSelector: praxis-crud\nFriendly Name: Praxis CRUD\nDescription: Tabela com operações de CRUD via metadados.\nLib/Package: @praxisui/crud\nTags: widget, crud, configurable, hasWizard, stable\nInputs:\n - metadata (CrudMetadata | string)\n - crudId (string)\n - componentInstanceId (string)\n - tableConfigPersistenceStrategy ('local-first' | 'input-first' | 'volatile')\n - context (Record<string, unknown>)\n - metadata.queryContext (PraxisDataQueryContext | null)\n - metadata.resource.schemaPath (string | null)\n - metadata.resource.title (string | null)\n - metadata.resource.formTitle (string | null)\n - metadata.filterCriteria (Record<string, unknown> | null)\n - metadata.form (FormConfig)\n - metadata.actions[].form (CrudActionFormContract)\n - enableCustomization (boolean)\n - authoringCapability (string | null)\nOutputs:\n - afterOpen ({ mode: FormOpenMode; action: string })\n - afterClose (void)\n - afterSave ({ id: string | number; data: unknown })\n - afterDelete ({ id: string | number })\n - rowClick ({ row: unknown; index: number })\n - rowAction (CrudActionRuntimeEvent)\n - selectionChange (unknown)\n - error (unknown)\n - configureRequested (void)\n - crudAuthoringDocumentApplied (CrudAuthoringWidgetPersistenceEvent)\n - crudAuthoringDocumentSaved (CrudAuthoringWidgetPersistenceEvent)\n",
7222
7228
  "sourcePointer": "projects/praxis-crud/src/lib/praxis-crud.metadata.ts",
7223
- "contentHash": "a9d744b92ff6f475de4d870e57bc963200a7b68688a8ea5159cc02496a8967be",
7229
+ "contentHash": "5f18e01c2da358f033eb9b8ee4616dac8a348addc3ce3e56bcb077b094c13300",
7224
7230
  "sourceKind": "component_definition",
7225
7231
  "sourceId": "praxis-crud",
7226
7232
  "corpusVersion": "1.0.0"
@@ -97,6 +97,35 @@ function debugCrudLauncher(message, ...data) {
97
97
  }
98
98
  catch { }
99
99
  }
100
+ /**
101
+ * Captures the interaction origin before metadata, capability, or lazy-host
102
+ * work yields the event loop. Material can restore focus to an explicit
103
+ * element, which is essential when the action originated in a closing menu.
104
+ */
105
+ function captureCrudActionFocusOrigin() {
106
+ if (typeof document === 'undefined') {
107
+ return null;
108
+ }
109
+ const active = document.activeElement;
110
+ if (!(active instanceof HTMLElement) || active === document.body || !active.isConnected) {
111
+ return null;
112
+ }
113
+ return active;
114
+ }
115
+ function isRuntimeFocusOrigin(value) {
116
+ return typeof HTMLElement !== 'undefined'
117
+ && value instanceof HTMLElement
118
+ && typeof value.focus === 'function';
119
+ }
120
+ function resolveCrudRestoreFocus(configured, actionFocusOrigin) {
121
+ if (configured === false || typeof configured === 'string') {
122
+ return configured;
123
+ }
124
+ if (typeof HTMLElement !== 'undefined' && configured instanceof HTMLElement) {
125
+ return configured;
126
+ }
127
+ return actionFocusOrigin ?? true;
128
+ }
100
129
  class CrudLauncherService {
101
130
  router = inject(Router);
102
131
  dialog = inject(DialogService);
@@ -115,6 +144,15 @@ class CrudLauncherService {
115
144
  }
116
145
  })();
117
146
  async launch(action, row, metadata, componentKeyId, drawerCallbacks, runtime) {
147
+ // Capture before every await below. A toolbar/row menu closes before the
148
+ // form host is resolved, so the browser's later activeElement is not a
149
+ // reliable representation of the user-facing action trigger.
150
+ // A responsive host can replace the menu trigger while the menu is
151
+ // closing. Keep the original runtime-only reference even when detached:
152
+ // the overlay host resolves its stable data-praxis-focus-key on close.
153
+ const actionFocusOrigin = isRuntimeFocusOrigin(runtime?.focusOrigin)
154
+ ? runtime.focusOrigin
155
+ : captureCrudActionFocusOrigin();
118
156
  const prefetchedDialogHost = this.isLikelyOverlayAction(action, metadata)
119
157
  ? this.loadDialogHost()
120
158
  : undefined;
@@ -156,6 +194,8 @@ class CrudLauncherService {
156
194
  resourceIdentity,
157
195
  contextIdentity,
158
196
  };
197
+ const modalCfg = { ...(merged.metadata.defaults?.modal || {}) };
198
+ const restoreFocus = resolveCrudRestoreFocus(modalCfg.restoreFocus, actionFocusOrigin);
159
199
  if (mode === 'drawer' && runtime?.surfaceRuntime?.push) {
160
200
  const frameId = this.buildSurfaceFrameId(actionForLaunch);
161
201
  const frameRef = await runtime.surfaceRuntime.push({
@@ -163,6 +203,9 @@ class CrudLauncherService {
163
203
  title: this.resolveSurfaceFrameTitle(actionForLaunch, merged.metadata),
164
204
  titleIcon: stringOrUndefined$1(actionForLaunch['icon']),
165
205
  subtitle: this.resolveSurfaceFrameSubtitle(actionForLaunch, merged.metadata),
206
+ ...(actionFocusOrigin
207
+ ? { returnFocusTo: actionFocusOrigin }
208
+ : {}),
166
209
  content: {
167
210
  component: await (prefetchedDialogHost ?? this.loadDialogHost()),
168
211
  inputs: { data: dialogData },
@@ -197,12 +240,12 @@ class CrudLauncherService {
197
240
  inputs,
198
241
  resourceIdentity,
199
242
  contextIdentity,
243
+ restoreFocus,
200
244
  onClose: drawerCallbacks?.onClose,
201
245
  onResult: drawerCallbacks?.onResult,
202
246
  }));
203
247
  return { mode };
204
248
  }
205
- const modalCfg = { ...(merged.metadata.defaults?.modal || {}) };
206
249
  debugCrudLauncher('[CRUD:Launcher] opening dialog with:', {
207
250
  action: merged.action.action,
208
251
  formId: actionForLaunch.formId,
@@ -233,7 +276,7 @@ class CrudLauncherService {
233
276
  panelClass: panelClasses,
234
277
  backdropClass: mergedBackdropClasses,
235
278
  autoFocus: modalCfg.autoFocus ?? true,
236
- restoreFocus: modalCfg.restoreFocus ?? true,
279
+ restoreFocus,
237
280
  minWidth: drawerMode
238
281
  ? (modalCfg.minWidth ?? DEFAULT_CRUD_DRAWER_MODAL_CONFIG.minWidth)
239
282
  : '360px',
@@ -3764,6 +3807,8 @@ class PraxisCrudComponent {
3764
3807
  afterDelete = new EventEmitter();
3765
3808
  error = new EventEmitter();
3766
3809
  rowClick = new EventEmitter();
3810
+ /** Emits the canonical table row-action envelope before the CRUD handles its surface/action. */
3811
+ rowAction = new EventEmitter();
3767
3812
  selectionChange = new EventEmitter();
3768
3813
  tableRuntimeConfigChange = new EventEmitter();
3769
3814
  crudAuthoringDocumentApplied = new EventEmitter();
@@ -3834,6 +3879,10 @@ class PraxisCrudComponent {
3834
3879
  collectionCapabilitiesRequestSeq = 0;
3835
3880
  currentAuthoringDocument;
3836
3881
  selectedRow = null;
3882
+ onTableRowAction(event) {
3883
+ this.rowAction.emit(event);
3884
+ void this.onAction(event.action || '', event.row, event);
3885
+ }
3837
3886
  getResourceDiscovery() {
3838
3887
  const assigned = this.resourceDiscovery;
3839
3888
  return assigned ?? (this.resourceDiscoveryInstance ??= this.injector.get(ResourceDiscoveryService));
@@ -4006,6 +4055,7 @@ class PraxisCrudComponent {
4006
4055
  links: this.resolveCrudRuntimeLinks(effectiveAction.action, contextualRow),
4007
4056
  resourceIdentity,
4008
4057
  contextIdentity,
4058
+ focusOrigin: runtimeEvent?.focusOrigin ?? null,
4009
4059
  surfaceRuntime: this.resolveSurfaceRuntime(),
4010
4060
  });
4011
4061
  this.afterOpen.emit({ mode, action: effectiveAction.action });
@@ -4467,6 +4517,17 @@ class PraxisCrudComponent {
4467
4517
  const first = Array.isArray(event?.selectedRows) ? event.selectedRows[0] : null;
4468
4518
  return this.isRecord(first) ? first : null;
4469
4519
  }
4520
+ /**
4521
+ * Keeps the DOM trigger exclusively in transient runtime context. Discovery
4522
+ * payloads remain JSON-safe and can still be authored, inspected and
4523
+ * persisted independently from the browser that opened the surface.
4524
+ */
4525
+ resolveRuntimeFocusOrigin(event) {
4526
+ const focusOrigin = event?.focusOrigin;
4527
+ return focusOrigin && typeof focusOrigin.focus === 'function'
4528
+ ? focusOrigin
4529
+ : undefined;
4530
+ }
4470
4531
  extractDiscoveryActionConfig(event) {
4471
4532
  const config = event?.actionConfig;
4472
4533
  return this.isRecord(config) && typeof config['resourceKey'] === 'string'
@@ -4509,6 +4570,7 @@ class PraxisCrudComponent {
4509
4570
  presentation: 'drawer',
4510
4571
  title: surface.title,
4511
4572
  subtitle: surface.description ?? undefined,
4573
+ parentIdentity: runtimeEvent?.resourceIdentity ?? null,
4512
4574
  });
4513
4575
  }
4514
4576
  catch (error) {
@@ -4516,6 +4578,7 @@ class PraxisCrudComponent {
4516
4578
  this.snack.open(this.txWithParams('crud.surface.openFailed', 'Não foi possível abrir {title}. Tente novamente ou confirme se esse recurso continua disponível.', { title: surface.title || surface.id }), undefined, { duration: 4500 });
4517
4579
  return true;
4518
4580
  }
4581
+ const focusOrigin = this.resolveRuntimeFocusOrigin(runtimeEvent);
4519
4582
  let openPromise;
4520
4583
  try {
4521
4584
  const surfaceContext = {
@@ -4534,6 +4597,7 @@ class PraxisCrudComponent {
4534
4597
  action: normalizedAction,
4535
4598
  resourcePath,
4536
4599
  },
4600
+ ...(focusOrigin ? { focusOrigin } : {}),
4537
4601
  },
4538
4602
  };
4539
4603
  const handledInline = await this.surfaceOutlets.tryActivate(payload, surfaceContext);
@@ -4610,6 +4674,7 @@ class PraxisCrudComponent {
4610
4674
  }
4611
4675
  return false;
4612
4676
  }
4677
+ const focusOrigin = this.resolveRuntimeFocusOrigin(runtimeEvent);
4613
4678
  let openPromise;
4614
4679
  try {
4615
4680
  openPromise = Promise.resolve(this.surfaceService.open(payload, {
@@ -4628,6 +4693,7 @@ class PraxisCrudComponent {
4628
4693
  action: normalizedAction,
4629
4694
  resourcePath,
4630
4695
  },
4696
+ ...(focusOrigin ? { focusOrigin } : {}),
4631
4697
  },
4632
4698
  }));
4633
4699
  }
@@ -5383,7 +5449,7 @@ class PraxisCrudComponent {
5383
5449
  return Object.entries(params).reduce((current, [name, value]) => current.split(`{${name}}`).join(value), text);
5384
5450
  }
5385
5451
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisCrudComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5386
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisCrudComponent, isStandalone: true, selector: "praxis-crud", inputs: { metadata: "metadata", crudId: "crudId", componentInstanceId: "componentInstanceId", tableConfigPersistenceStrategy: "tableConfigPersistenceStrategy", context: "context", enableCustomization: "enableCustomization", authoringCapability: "authoringCapability" }, outputs: { configureRequested: "configureRequested", afterOpen: "afterOpen", afterClose: "afterClose", afterSave: "afterSave", afterDelete: "afterDelete", error: "error", rowClick: "rowClick", selectionChange: "selectionChange", tableRuntimeConfigChange: "tableRuntimeConfigChange", crudAuthoringDocumentApplied: "crudAuthoringDocumentApplied", crudAuthoringDocumentSaved: "crudAuthoringDocumentSaved" }, providers: [
5452
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisCrudComponent, isStandalone: true, selector: "praxis-crud", inputs: { metadata: "metadata", crudId: "crudId", componentInstanceId: "componentInstanceId", tableConfigPersistenceStrategy: "tableConfigPersistenceStrategy", context: "context", enableCustomization: "enableCustomization", authoringCapability: "authoringCapability" }, outputs: { configureRequested: "configureRequested", afterOpen: "afterOpen", afterClose: "afterClose", afterSave: "afterSave", afterDelete: "afterDelete", error: "error", rowClick: "rowClick", rowAction: "rowAction", selectionChange: "selectionChange", tableRuntimeConfigChange: "tableRuntimeConfigChange", crudAuthoringDocumentApplied: "crudAuthoringDocumentApplied", crudAuthoringDocumentSaved: "crudAuthoringDocumentSaved" }, providers: [
5387
5453
  providePraxisI18nConfig(RESOURCE_DISCOVERY_I18N_CONFIG),
5388
5454
  providePraxisI18nConfig(PRAXIS_CRUD_RUNTIME_I18N_CONFIG),
5389
5455
  ], viewQueries: [{ propertyName: "table", first: true, predicate: PraxisTable, descendants: true }], usesOnChanges: true, ngImport: i0, template: `
@@ -5408,7 +5474,7 @@ class PraxisCrudComponent {
5408
5474
  [authoringCapability]="authoringCapability"
5409
5475
  (rowClick)="onTableRowClick($event)"
5410
5476
  (selectionChange)="onTableSelectionChange($event)"
5411
- (rowAction)="onAction($event.action, $event.row, $event)"
5477
+ (rowAction)="onTableRowAction($event)"
5412
5478
  (toolbarAction)="onToolbarAction($event)"
5413
5479
  (bulkAction)="onBulkAction($event)"
5414
5480
  (collectionLinksChange)="onCollectionLinksChange($event)"
@@ -5456,7 +5522,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
5456
5522
  [authoringCapability]="authoringCapability"
5457
5523
  (rowClick)="onTableRowClick($event)"
5458
5524
  (selectionChange)="onTableSelectionChange($event)"
5459
- (rowAction)="onAction($event.action, $event.row, $event)"
5525
+ (rowAction)="onTableRowAction($event)"
5460
5526
  (toolbarAction)="onToolbarAction($event)"
5461
5527
  (bulkAction)="onBulkAction($event)"
5462
5528
  (collectionLinksChange)="onCollectionLinksChange($event)"
@@ -5506,6 +5572,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
5506
5572
  type: Output
5507
5573
  }], rowClick: [{
5508
5574
  type: Output
5575
+ }], rowAction: [{
5576
+ type: Output
5509
5577
  }], selectionChange: [{
5510
5578
  type: Output
5511
5579
  }], tableRuntimeConfigChange: [{
@@ -6625,6 +6693,11 @@ const PRAXIS_CRUD_COMPONENT_METADATA = {
6625
6693
  type: '{ row: unknown; index: number }',
6626
6694
  description: 'Encaminha o clique de linha da tabela interna para composição master-detail e seleção local.',
6627
6695
  },
6696
+ {
6697
+ name: 'rowAction',
6698
+ type: 'CrudActionRuntimeEvent',
6699
+ description: 'Encaminha a ação contextual da linha com row, action e resourceIdentity para composição governada.',
6700
+ },
6628
6701
  {
6629
6702
  name: 'selectionChange',
6630
6703
  type: 'unknown',
package/package.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "name": "@praxisui/crud",
3
- "version": "9.0.4-rc.36",
3
+ "version": "9.0.4-rc.38",
4
4
  "description": "CRUD building blocks for Praxis UI: integrates dynamic forms and tables with unified configuration and services.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
7
7
  "@angular/core": "^21.0.0",
8
- "@praxisui/dynamic-form": "^9.0.4-rc.36",
9
- "@praxisui/table": "^9.0.4-rc.36",
10
- "@praxisui/core": "^9.0.4-rc.36",
11
- "@praxisui/dynamic-fields": "^9.0.4-rc.36",
12
- "@praxisui/settings-panel": "^9.0.4-rc.36",
8
+ "@praxisui/dynamic-form": "^9.0.4-rc.38",
9
+ "@praxisui/table": "^9.0.4-rc.38",
10
+ "@praxisui/core": "^9.0.4-rc.38",
11
+ "@praxisui/dynamic-fields": "^9.0.4-rc.38",
12
+ "@praxisui/settings-panel": "^9.0.4-rc.38",
13
13
  "@angular/cdk": "^21.0.0",
14
14
  "@angular/forms": "^21.0.0",
15
15
  "@angular/material": "^21.0.0",
16
16
  "@angular/router": "^21.0.0",
17
- "@praxisui/ai": "^9.0.4-rc.36",
17
+ "@praxisui/ai": "^9.0.4-rc.38",
18
18
  "rxjs": "~7.8.0"
19
19
  },
20
20
  "dependencies": {
@@ -149,6 +149,8 @@ type CrudActionRuntimeEvent = {
149
149
  selectedRows?: Record<string, unknown>[];
150
150
  rows?: Record<string, unknown>[];
151
151
  resourceIdentity?: MaterializedResourceIdentity | null;
152
+ /** Ephemeral focus origin provided by a runtime surface, never persisted. */
153
+ focusOrigin?: HTMLElement;
152
154
  };
153
155
  type CrudContextAction = {
154
156
  action: string;
@@ -192,6 +194,8 @@ declare class PraxisCrudComponent implements OnChanges {
192
194
  }>;
193
195
  error: EventEmitter<unknown>;
194
196
  rowClick: EventEmitter<unknown>;
197
+ /** Emits the canonical table row-action envelope before the CRUD handles its surface/action. */
198
+ rowAction: EventEmitter<CrudActionRuntimeEvent>;
195
199
  selectionChange: EventEmitter<unknown>;
196
200
  tableRuntimeConfigChange: EventEmitter<_praxisui_core.TableConfigModern>;
197
201
  crudAuthoringDocumentApplied: EventEmitter<CrudAuthoringWidgetPersistenceEvent>;
@@ -238,6 +242,7 @@ declare class PraxisCrudComponent implements OnChanges {
238
242
  private collectionCapabilitiesRequestSeq;
239
243
  private currentAuthoringDocument?;
240
244
  selectedRow: Record<string, unknown> | null;
245
+ onTableRowAction(event: CrudActionRuntimeEvent): void;
241
246
  private getResourceDiscovery;
242
247
  private getActionOpenAdapter;
243
248
  private getSurfaceOpenAdapter;
@@ -285,6 +290,12 @@ declare class PraxisCrudComponent implements OnChanges {
285
290
  private extractSelectedRowFromEvent;
286
291
  private extractSelectedRowFromBulkAction;
287
292
  private extractSelectedRowFromToolbarAction;
293
+ /**
294
+ * Keeps the DOM trigger exclusively in transient runtime context. Discovery
295
+ * payloads remain JSON-safe and can still be authored, inspected and
296
+ * persisted independently from the browser that opened the surface.
297
+ */
298
+ private resolveRuntimeFocusOrigin;
288
299
  private extractDiscoveryActionConfig;
289
300
  private resolveSelectedRowForAction;
290
301
  private tryOpenDiscoveredCrudSurface;
@@ -340,7 +351,7 @@ declare class PraxisCrudComponent implements OnChanges {
340
351
  private txWithParams;
341
352
  private interpolateTranslationParams;
342
353
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<PraxisCrudComponent, never>;
343
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<PraxisCrudComponent, "praxis-crud", never, { "metadata": { "alias": "metadata"; "required": true; }; "crudId": { "alias": "crudId"; "required": true; }; "componentInstanceId": { "alias": "componentInstanceId"; "required": false; }; "tableConfigPersistenceStrategy": { "alias": "tableConfigPersistenceStrategy"; "required": false; }; "context": { "alias": "context"; "required": false; }; "enableCustomization": { "alias": "enableCustomization"; "required": false; }; "authoringCapability": { "alias": "authoringCapability"; "required": false; }; }, { "configureRequested": "configureRequested"; "afterOpen": "afterOpen"; "afterClose": "afterClose"; "afterSave": "afterSave"; "afterDelete": "afterDelete"; "error": "error"; "rowClick": "rowClick"; "selectionChange": "selectionChange"; "tableRuntimeConfigChange": "tableRuntimeConfigChange"; "crudAuthoringDocumentApplied": "crudAuthoringDocumentApplied"; "crudAuthoringDocumentSaved": "crudAuthoringDocumentSaved"; }, never, never, true, never>;
354
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<PraxisCrudComponent, "praxis-crud", never, { "metadata": { "alias": "metadata"; "required": true; }; "crudId": { "alias": "crudId"; "required": true; }; "componentInstanceId": { "alias": "componentInstanceId"; "required": false; }; "tableConfigPersistenceStrategy": { "alias": "tableConfigPersistenceStrategy"; "required": false; }; "context": { "alias": "context"; "required": false; }; "enableCustomization": { "alias": "enableCustomization"; "required": false; }; "authoringCapability": { "alias": "authoringCapability"; "required": false; }; }, { "configureRequested": "configureRequested"; "afterOpen": "afterOpen"; "afterClose": "afterClose"; "afterSave": "afterSave"; "afterDelete": "afterDelete"; "error": "error"; "rowClick": "rowClick"; "rowAction": "rowAction"; "selectionChange": "selectionChange"; "tableRuntimeConfigChange": "tableRuntimeConfigChange"; "crudAuthoringDocumentApplied": "crudAuthoringDocumentApplied"; "crudAuthoringDocumentSaved": "crudAuthoringDocumentSaved"; }, never, never, true, never>;
344
355
  }
345
356
 
346
357
  type CrudDrawerResultType = 'save' | 'delete' | 'close';
@@ -356,6 +367,8 @@ interface CrudLaunchRuntime {
356
367
  contextIdentity?: MaterializedResourceIdentity | null;
357
368
  /** Active runtime drawer session. It is never persisted in CRUD metadata. */
358
369
  surfaceRuntime?: SurfaceDrawerRef | null;
370
+ /** Stable runtime trigger for restoring focus after a form overlay closes. */
371
+ focusOrigin?: HTMLElement | null;
359
372
  }
360
373
  declare class CrudLauncherService {
361
374
  private readonly router;