@simple-table/angular 4.2.3 → 4.2.4

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.
@@ -1,9 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
- import { reflectComponentType, createComponent, EventEmitter, inject, ElementRef, ApplicationRef, EnvironmentInjector, Injector, Output, Input, Component, makeEnvironmentProviders } from '@angular/core';
2
+ import { reflectComponentType, createComponent, inject, TemplateRef, Input, Directive, ElementRef, EventEmitter, ApplicationRef, EnvironmentInjector, Injector, NgZone, ContentChildren, Output, ChangeDetectionStrategy, Component, NgModule, makeEnvironmentProviders } from '@angular/core';
3
3
  import { collectHeaderAccessors, asRows, SimpleTableVanilla, headersStructurallyEqual, rowsShallowUnchanged } from 'simple-table-core';
4
4
  export { PIVOT_ACCESSOR_PREFIX, PIVOT_BLANK_LABEL, PIVOT_IS_TOTAL_KEY, asRows, buildPivotAccessor, buildPivotRowTotalAccessor, pivotRows } from 'simple-table-core';
5
5
 
6
- const ST_RENDERER_GENERATION = Symbol.for("simple-table.rendererGeneration");
6
+ const ST_RENDERER_GENERATION$1 = Symbol.for("simple-table.rendererGeneration");
7
7
  /** Declared `@Input` / `input()` names for a component type (template + prop). */
8
8
  function declaredInputNames(component) {
9
9
  const mirror = reflectComponentType(component);
@@ -66,9 +66,8 @@ function mountAngularComponent(component, props, options, host) {
66
66
  * host is discarded. The table adapter always supplies a registry; the public
67
67
  * helper used for one-shot static slots may omit it. Pass `elementInjector` so
68
68
  * dynamically created components see providers on ancestors of `<simple-table>`.
69
- *
70
- * These are injected automatically when the consumer uses
71
- * `provideSimpleTable()` in their application providers.
69
+ * `ApplicationRef` and `EnvironmentInjector` come from Angular's injector;
70
+ * `provideSimpleTable()` is optional.
72
71
  */
73
72
  function wrapAngularRenderer(component, appRef, injector, registry, elementInjector) {
74
73
  const options = {
@@ -119,8 +118,8 @@ function wrapCachedAngularRenderer(component, options, accessor, kind) {
119
118
  if (existing) {
120
119
  if (kind === "cell" && existing.component !== component) {
121
120
  existing.component = component;
122
- const current = existing.wrapped[ST_RENDERER_GENERATION];
123
- existing.wrapped[ST_RENDERER_GENERATION] =
121
+ const current = existing.wrapped[ST_RENDERER_GENERATION$1];
122
+ existing.wrapped[ST_RENDERER_GENERATION$1] =
124
123
  (typeof current === "number" ? current : 0) + 1;
125
124
  }
126
125
  else {
@@ -153,7 +152,7 @@ function wrapCachedAngularRenderer(component, options, accessor, kind) {
153
152
  return mountAngularComponent(slot.component, props, options).host;
154
153
  };
155
154
  slot.wrapped = wrapped;
156
- wrapped[ST_RENDERER_GENERATION] = 0;
155
+ wrapped[ST_RENDERER_GENERATION$1] = 0;
157
156
  cache.set(accessor, slot);
158
157
  return wrapped;
159
158
  }
@@ -177,6 +176,139 @@ function wrapAngularColumnEditorRowRenderer(component, options) {
177
176
  };
178
177
  }
179
178
 
179
+ const ST_RENDERER_GENERATION = Symbol.for("simple-table.rendererGeneration");
180
+ function applyTemplateContext(view, next) {
181
+ const ctx = view.context;
182
+ for (const key of Object.keys(ctx)) {
183
+ if (!(key in next)) {
184
+ delete ctx[key];
185
+ }
186
+ }
187
+ Object.assign(ctx, next);
188
+ view.detectChanges();
189
+ }
190
+ function mountEmbeddedView(template, context, options) {
191
+ const host = document.createElement("div");
192
+ const view = (options.elementInjector
193
+ ? template.createEmbeddedView(context, options.elementInjector)
194
+ : template.createEmbeddedView(context));
195
+ view.detectChanges();
196
+ options.appRef.attachView(view);
197
+ for (const node of view.rootNodes) {
198
+ host.appendChild(node);
199
+ }
200
+ options.registry?.register(host, () => {
201
+ options.appRef.detachView(view);
202
+ view.destroy();
203
+ });
204
+ return { host, view };
205
+ }
206
+ /**
207
+ * Turns an `ng-template` into a core renderer: create the view, attach it so
208
+ * clicks and bindings work, and tear it down when the table discards the host.
209
+ */
210
+ function wrapAngularTemplate(template, options, mapContext) {
211
+ return (props) => {
212
+ return mountEmbeddedView(template, mapContext(props), options).host;
213
+ };
214
+ }
215
+ /**
216
+ * Stable wrapper per column accessor so rebuilds do not swap renderer identity.
217
+ * Header views update in place when the same template is still mounted.
218
+ */
219
+ function wrapCachedAngularTemplate(template, options, accessor, kind, mapContext) {
220
+ const registry = options.registry;
221
+ if (!registry) {
222
+ throw new Error("wrapCachedAngularTemplate requires a MountRegistry");
223
+ }
224
+ const cache = kind === "cell" ? registry.cellTemplateCache : registry.headerTemplateCache;
225
+ const existing = cache.get(accessor);
226
+ if (existing) {
227
+ if (kind === "cell" && existing.component !== template) {
228
+ existing.component = template;
229
+ const current = existing.wrapped[ST_RENDERER_GENERATION];
230
+ existing.wrapped[ST_RENDERER_GENERATION] =
231
+ (typeof current === "number" ? current : 0) + 1;
232
+ }
233
+ else {
234
+ existing.component = template;
235
+ }
236
+ return existing.wrapped;
237
+ }
238
+ const slot = {
239
+ component: template,
240
+ wrapped: null,
241
+ };
242
+ if (kind === "header") {
243
+ let host = null;
244
+ let view = null;
245
+ let mountedTemplate = null;
246
+ const wrapped = (props) => {
247
+ const ctx = mapContext(props);
248
+ if (host &&
249
+ view &&
250
+ registry.isRegistered(host) &&
251
+ mountedTemplate === slot.component) {
252
+ applyTemplateContext(view, ctx);
253
+ return host;
254
+ }
255
+ const mounted = mountEmbeddedView(slot.component, ctx, options);
256
+ host = mounted.host;
257
+ view = mounted.view;
258
+ mountedTemplate = slot.component;
259
+ return host;
260
+ };
261
+ slot.wrapped = wrapped;
262
+ cache.set(accessor, slot);
263
+ return wrapped;
264
+ }
265
+ const wrapped = (props) => {
266
+ return mountEmbeddedView(slot.component, mapContext(props), options).host;
267
+ };
268
+ slot.wrapped = wrapped;
269
+ wrapped[ST_RENDERER_GENERATION] = 0;
270
+ cache.set(accessor, slot);
271
+ return wrapped;
272
+ }
273
+ function cellTemplateContext(props) {
274
+ const record = props;
275
+ return {
276
+ $implicit: record.row,
277
+ ...record,
278
+ };
279
+ }
280
+ function headerTemplateContext(props) {
281
+ const record = props;
282
+ return {
283
+ $implicit: record.header,
284
+ ...record,
285
+ };
286
+ }
287
+ function footerTemplateContext(props) {
288
+ const record = props;
289
+ return {
290
+ $implicit: record.currentPage,
291
+ ...record,
292
+ };
293
+ }
294
+ function loadingTemplateContext(props) {
295
+ const record = props;
296
+ return {
297
+ $implicit: record.parentRow,
298
+ ...record,
299
+ };
300
+ }
301
+ function errorTemplateContext(props) {
302
+ const record = props;
303
+ return {
304
+ $implicit: record.error,
305
+ ...record,
306
+ };
307
+ }
308
+ function emptyTemplateContext(_props) {
309
+ return {};
310
+ }
311
+
180
312
  /** Resolve column definitions. */
181
313
  function resolveAngularColumns(config) {
182
314
  const headers = config.columns;
@@ -194,19 +326,21 @@ function resolveTableEmptyState(value, wrap, registry) {
194
326
  return null;
195
327
  }
196
328
  if (value.ɵcmp) {
197
- const existing = registry.tableEmptyStateMount;
198
- if (existing &&
199
- existing.component === value &&
200
- registry.isRegistered(existing.host)) {
201
- return existing.host;
202
- }
203
- if (existing) {
204
- registry.disposeHost(existing.host);
205
- registry.tableEmptyStateMount = null;
206
- }
207
- const host = wrap(value)({});
208
- registry.tableEmptyStateMount = { component: value, host };
209
- return host;
329
+ return () => {
330
+ const existing = registry.tableEmptyStateMount;
331
+ if (existing &&
332
+ existing.component === value &&
333
+ registry.isRegistered(existing.host)) {
334
+ return existing.host;
335
+ }
336
+ if (existing) {
337
+ registry.disposeHost(existing.host);
338
+ registry.tableEmptyStateMount = null;
339
+ }
340
+ const host = wrap(value)({});
341
+ registry.tableEmptyStateMount = { component: value, host };
342
+ return host;
343
+ };
210
344
  }
211
345
  if (registry.tableEmptyStateMount) {
212
346
  registry.disposeHost(registry.tableEmptyStateMount.host);
@@ -214,7 +348,7 @@ function resolveTableEmptyState(value, wrap, registry) {
214
348
  }
215
349
  return value;
216
350
  }
217
- function buildVanillaConfig(config, registry, appRef, injector, elementInjector) {
351
+ function buildVanillaConfig(config, registry, appRef, injector, elementInjector, slots) {
218
352
  const { columns: _columns, rows, footerRenderer, emptyStateRenderer, errorStateRenderer, loadingStateRenderer, tableEmptyStateRenderer, headerDropdown, columnEditorConfig, icons, rowButtons, onColumnOrderChange, onColumnWidthChange, onHeaderEdit, onColumnSelect, enableColumnEditor, enableColumnEditorInitOpen, enablePagination, onTableReady, hoverRowBackground, oddColumnBackground, oddEvenRowBackground, ...rest } = config;
219
353
  const mountOptions = {
220
354
  appRef,
@@ -258,7 +392,11 @@ function buildVanillaConfig(config, registry, appRef, injector, elementInjector)
258
392
  const { cellRenderer, headerRenderer, children, nestedTable, ...headerRest } = header;
259
393
  const accessor = String(header.accessor);
260
394
  const transformed = { ...headerRest };
261
- if (cellRenderer) {
395
+ const cellTemplate = slots?.cellTemplates?.get(accessor);
396
+ if (cellTemplate) {
397
+ transformed.cellRenderer = wrapCachedAngularTemplate(cellTemplate, mountOptions, accessor, "cell", cellTemplateContext);
398
+ }
399
+ else if (cellRenderer) {
262
400
  if (cellRenderer.ɵcmp) {
263
401
  transformed.cellRenderer = wrapCachedAngularRenderer(cellRenderer, mountOptions, accessor, "cell");
264
402
  }
@@ -266,7 +404,11 @@ function buildVanillaConfig(config, registry, appRef, injector, elementInjector)
266
404
  transformed.cellRenderer = cellRenderer;
267
405
  }
268
406
  }
269
- if (headerRenderer) {
407
+ const headerTemplate = slots?.headerTemplates?.get(accessor);
408
+ if (headerTemplate) {
409
+ transformed.headerRenderer = wrapCachedAngularTemplate(headerTemplate, mountOptions, accessor, "header", headerTemplateContext);
410
+ }
411
+ else if (headerRenderer) {
270
412
  if (headerRenderer.ɵcmp) {
271
413
  transformed.headerRenderer = wrapCachedAngularRenderer(headerRenderer, mountOptions, accessor, "header");
272
414
  }
@@ -315,7 +457,10 @@ function buildVanillaConfig(config, registry, appRef, injector, elementInjector)
315
457
  if (onColumnSelect) {
316
458
  vanillaConfig.onColumnSelect = (header) => onColumnSelect(header);
317
459
  }
318
- if (footerRenderer !== undefined) {
460
+ if (slots?.footerTemplate) {
461
+ vanillaConfig.footerRenderer = wrapAngularTemplate(slots.footerTemplate, mountOptions, footerTemplateContext);
462
+ }
463
+ else if (footerRenderer !== undefined) {
319
464
  if (footerRenderer.ɵcmp) {
320
465
  vanillaConfig.footerRenderer = wrap(footerRenderer);
321
466
  }
@@ -331,7 +476,10 @@ function buildVanillaConfig(config, registry, appRef, injector, elementInjector)
331
476
  vanillaConfig.emptyStateRenderer = emptyStateRenderer;
332
477
  }
333
478
  }
334
- if (errorStateRenderer !== undefined) {
479
+ if (slots?.errorTemplate) {
480
+ vanillaConfig.errorStateRenderer = wrapAngularTemplate(slots.errorTemplate, mountOptions, errorTemplateContext);
481
+ }
482
+ else if (errorStateRenderer !== undefined) {
335
483
  if (errorStateRenderer.ɵcmp) {
336
484
  vanillaConfig.errorStateRenderer = wrap(errorStateRenderer);
337
485
  }
@@ -339,7 +487,10 @@ function buildVanillaConfig(config, registry, appRef, injector, elementInjector)
339
487
  vanillaConfig.errorStateRenderer = errorStateRenderer;
340
488
  }
341
489
  }
342
- if (loadingStateRenderer !== undefined) {
490
+ if (slots?.loadingTemplate) {
491
+ vanillaConfig.loadingStateRenderer = wrapAngularTemplate(slots.loadingTemplate, mountOptions, loadingTemplateContext);
492
+ }
493
+ else if (loadingStateRenderer !== undefined) {
343
494
  if (loadingStateRenderer.ɵcmp) {
344
495
  vanillaConfig.loadingStateRenderer = wrap(loadingStateRenderer);
345
496
  }
@@ -347,7 +498,11 @@ function buildVanillaConfig(config, registry, appRef, injector, elementInjector)
347
498
  vanillaConfig.loadingStateRenderer = loadingStateRenderer;
348
499
  }
349
500
  }
350
- if (tableEmptyStateRenderer !== undefined) {
501
+ if (slots?.emptyTemplate) {
502
+ const renderEmpty = wrapAngularTemplate(slots.emptyTemplate, mountOptions, emptyTemplateContext);
503
+ vanillaConfig.tableEmptyStateRenderer = () => renderEmpty({});
504
+ }
505
+ else if (tableEmptyStateRenderer !== undefined) {
351
506
  vanillaConfig.tableEmptyStateRenderer = resolveTableEmptyState(tableEmptyStateRenderer, wrap, registry);
352
507
  }
353
508
  if (headerDropdown !== undefined) {
@@ -376,6 +531,8 @@ class MountRegistry {
376
531
  this.nextId = 0;
377
532
  this.cellRendererCache = new Map();
378
533
  this.headerRendererCache = new Map();
534
+ this.cellTemplateCache = new Map();
535
+ this.headerTemplateCache = new Map();
379
536
  /** One-shot `tableEmptyStateRenderer` component mount, reused across config rebuilds. */
380
537
  this.tableEmptyStateMount = null;
381
538
  this.disposeHost = (host) => {
@@ -415,6 +572,8 @@ class MountRegistry {
415
572
  clear() {
416
573
  this.cellRendererCache.clear();
417
574
  this.headerRendererCache.clear();
575
+ this.cellTemplateCache.clear();
576
+ this.headerTemplateCache.clear();
418
577
  this.tableEmptyStateMount = null;
419
578
  for (const dispose of this.entries.values()) {
420
579
  dispose();
@@ -422,13 +581,16 @@ class MountRegistry {
422
581
  this.entries.clear();
423
582
  }
424
583
  pruneRendererCaches(liveAccessors) {
425
- for (const key of this.cellRendererCache.keys()) {
426
- if (!liveAccessors.has(key))
427
- this.cellRendererCache.delete(key);
428
- }
429
- for (const key of this.headerRendererCache.keys()) {
430
- if (!liveAccessors.has(key))
431
- this.headerRendererCache.delete(key);
584
+ for (const cache of [
585
+ this.cellRendererCache,
586
+ this.headerRendererCache,
587
+ this.cellTemplateCache,
588
+ this.headerTemplateCache,
589
+ ]) {
590
+ for (const key of cache.keys()) {
591
+ if (!liveAccessors.has(key))
592
+ cache.delete(key);
593
+ }
432
594
  }
433
595
  }
434
596
  get size() {
@@ -436,6 +598,150 @@ class MountRegistry {
436
598
  }
437
599
  }
438
600
 
601
+ /**
602
+ * Page-template cell for a column, matched by `accessor`.
603
+ * Context: `$implicit` is `row`; also `value`, `formattedValue`, and the rest of
604
+ * the core cell renderer props.
605
+ */
606
+ class StCellDirective {
607
+ constructor() {
608
+ this.templateRef = inject(TemplateRef);
609
+ }
610
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StCellDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
611
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.27", type: StCellDirective, isStandalone: true, selector: "ng-template[stCell]", inputs: { stCell: "stCell" }, ngImport: i0 }); }
612
+ }
613
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StCellDirective, decorators: [{
614
+ type: Directive,
615
+ args: [{
616
+ selector: "ng-template[stCell]",
617
+ standalone: true,
618
+ }]
619
+ }], propDecorators: { stCell: [{
620
+ type: Input,
621
+ args: [{ required: true }]
622
+ }] } });
623
+ /**
624
+ * Page-template header for a column, matched by `accessor`.
625
+ * Context: `$implicit` is `header`; also `components` (sort/filter icons).
626
+ */
627
+ class StHeaderDirective {
628
+ constructor() {
629
+ this.templateRef = inject(TemplateRef);
630
+ }
631
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
632
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.27", type: StHeaderDirective, isStandalone: true, selector: "ng-template[stHeader]", inputs: { stHeader: "stHeader" }, ngImport: i0 }); }
633
+ }
634
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StHeaderDirective, decorators: [{
635
+ type: Directive,
636
+ args: [{
637
+ selector: "ng-template[stHeader]",
638
+ standalone: true,
639
+ }]
640
+ }], propDecorators: { stHeader: [{
641
+ type: Input,
642
+ args: [{ required: true }]
643
+ }] } });
644
+ /** Whole-table empty UI. Shown when there are no rows. */
645
+ class StEmptyDirective {
646
+ constructor() {
647
+ this.templateRef = inject(TemplateRef);
648
+ }
649
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StEmptyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
650
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.27", type: StEmptyDirective, isStandalone: true, selector: "ng-template[stEmpty]", ngImport: i0 }); }
651
+ }
652
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StEmptyDirective, decorators: [{
653
+ type: Directive,
654
+ args: [{
655
+ selector: "ng-template[stEmpty]",
656
+ standalone: true,
657
+ }]
658
+ }] });
659
+ /** Pagination / custom footer. Context matches core footer renderer props. */
660
+ class StFooterDirective {
661
+ constructor() {
662
+ this.templateRef = inject(TemplateRef);
663
+ }
664
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
665
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.27", type: StFooterDirective, isStandalone: true, selector: "ng-template[stFooter]", ngImport: i0 }); }
666
+ }
667
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StFooterDirective, decorators: [{
668
+ type: Directive,
669
+ args: [{
670
+ selector: "ng-template[stFooter]",
671
+ standalone: true,
672
+ }]
673
+ }] });
674
+ /** Nested-group loading row (not the table-level skeleton `isLoading` flag). */
675
+ class StLoadingDirective {
676
+ constructor() {
677
+ this.templateRef = inject(TemplateRef);
678
+ }
679
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StLoadingDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
680
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.27", type: StLoadingDirective, isStandalone: true, selector: "ng-template[stLoading]", ngImport: i0 }); }
681
+ }
682
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StLoadingDirective, decorators: [{
683
+ type: Directive,
684
+ args: [{
685
+ selector: "ng-template[stLoading]",
686
+ standalone: true,
687
+ }]
688
+ }] });
689
+ /** Nested-group error row. */
690
+ class StErrorDirective {
691
+ constructor() {
692
+ this.templateRef = inject(TemplateRef);
693
+ }
694
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StErrorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
695
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.27", type: StErrorDirective, isStandalone: true, selector: "ng-template[stError]", ngImport: i0 }); }
696
+ }
697
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StErrorDirective, decorators: [{
698
+ type: Directive,
699
+ args: [{
700
+ selector: "ng-template[stError]",
701
+ standalone: true,
702
+ }]
703
+ }] });
704
+ /**
705
+ * Opt-in: put a core-built DOM node (sort icon, filter icon, …) into the host.
706
+ * Clones the node so the table can still own the original.
707
+ */
708
+ class StDomSlotDirective {
709
+ constructor() {
710
+ this.host = inject(ElementRef);
711
+ }
712
+ ngOnChanges() {
713
+ this.sync();
714
+ }
715
+ ngOnDestroy() {
716
+ this.host.nativeElement.replaceChildren();
717
+ }
718
+ sync() {
719
+ const el = this.host.nativeElement;
720
+ el.replaceChildren();
721
+ const slot = this.stDomSlot;
722
+ if (slot == null)
723
+ return;
724
+ if (typeof slot === "string") {
725
+ el.textContent = slot;
726
+ return;
727
+ }
728
+ if (slot instanceof Node) {
729
+ el.appendChild(slot.cloneNode(true));
730
+ }
731
+ }
732
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StDomSlotDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
733
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.27", type: StDomSlotDirective, isStandalone: true, selector: "[stDomSlot]", inputs: { stDomSlot: "stDomSlot" }, usesOnChanges: true, ngImport: i0 }); }
734
+ }
735
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: StDomSlotDirective, decorators: [{
736
+ type: Directive,
737
+ args: [{
738
+ selector: "[stDomSlot]",
739
+ standalone: true,
740
+ }]
741
+ }], propDecorators: { stDomSlot: [{
742
+ type: Input
743
+ }] } });
744
+
439
745
  /**
440
746
  * SimpleTable — Angular adapter for simple-table-core.
441
747
  *
@@ -445,19 +751,44 @@ class MountRegistry {
445
751
  * Prefer typed `rows` / `columns` (`AngularColumnDef<MyRow>`). For a typed
446
752
  * imperative handle, use `@ViewChild(SimpleTableComponent) table!: SimpleTableComponent<MyRow>`
447
753
  * or listen to `(tableReady)`.
754
+ *
755
+ * Page templates (`stCell`, `stEmpty`, …) and `(sortChange)`-style outputs are
756
+ * the native Angular API. Import `SimpleTableImports` on the page. `class` on
757
+ * this host styles the wrapper; `[className]` styles the inner grid root.
448
758
  */
449
759
  class SimpleTableComponent {
450
760
  constructor() {
451
761
  /** Emits the TableAPI once the table has mounted. */
452
762
  this.tableReady = new EventEmitter();
763
+ this.cellClick = new EventEmitter();
764
+ this.cellEdit = new EventEmitter();
765
+ this.sortChange = new EventEmitter();
766
+ this.filterChange = new EventEmitter();
767
+ this.rowSelectionChange = new EventEmitter();
768
+ this.rowGroupExpand = new EventEmitter();
769
+ this.columnOrderChange = new EventEmitter();
770
+ this.columnVisibilityChange = new EventEmitter();
771
+ this.columnWidthChange = new EventEmitter();
772
+ this.pageChange = new EventEmitter();
773
+ this.loadMore = new EventEmitter();
774
+ this.headerEdit = new EventEmitter();
775
+ this.columnSelect = new EventEmitter();
776
+ this.pivotChange = new EventEmitter();
453
777
  this.instance = null;
454
778
  this.registry = new MountRegistry();
779
+ this.syncedSlotsKey = "";
455
780
  this.wasLoading = false;
456
781
  this.didInitialAutoSize = false;
782
+ this.slotUnsub = [];
457
783
  this.hostEl = inject((ElementRef));
458
784
  this.appRef = inject(ApplicationRef);
459
785
  this.envInjector = inject(EnvironmentInjector);
460
786
  this.elementInjector = inject(Injector);
787
+ this.ngZone = inject(NgZone);
788
+ }
789
+ // Run table event callbacks in Angular's zone so the page template updates.
790
+ inZone(work) {
791
+ return this.ngZone.run(work);
461
792
  }
462
793
  maybeRefitAutoSizeColumns(leftLoading) {
463
794
  if (!this.instance)
@@ -473,29 +804,71 @@ class SimpleTableComponent {
473
804
  this.instance.refitAutoSizeColumns?.();
474
805
  }
475
806
  }
476
- ngOnInit() {
807
+ collectSlots() {
808
+ const cellTemplates = new Map();
809
+ for (const slot of this.cellSlots ?? []) {
810
+ cellTemplates.set(slot.stCell, slot.templateRef);
811
+ }
812
+ const headerTemplates = new Map();
813
+ for (const slot of this.headerSlots ?? []) {
814
+ headerTemplates.set(slot.stHeader, slot.templateRef);
815
+ }
816
+ return {
817
+ cellTemplates,
818
+ headerTemplates,
819
+ emptyTemplate: this.emptySlots?.last?.templateRef,
820
+ footerTemplate: this.footerSlots?.last?.templateRef,
821
+ loadingTemplate: this.loadingSlots?.last?.templateRef,
822
+ errorTemplate: this.errorSlots?.last?.templateRef,
823
+ };
824
+ }
825
+ slotsFingerprint(slots) {
826
+ const cells = [...(slots.cellTemplates?.keys() ?? [])].sort().join(",");
827
+ const headers = [...(slots.headerTemplates?.keys() ?? [])].sort().join(",");
828
+ return [
829
+ `c:${cells}`,
830
+ `h:${headers}`,
831
+ `e:${slots.emptyTemplate ? 1 : 0}`,
832
+ `f:${slots.footerTemplate ? 1 : 0}`,
833
+ `l:${slots.loadingTemplate ? 1 : 0}`,
834
+ `r:${slots.errorTemplate ? 1 : 0}`,
835
+ ].join("|");
836
+ }
837
+ buildConfig() {
838
+ const props = this.getProps();
839
+ const slots = this.collectSlots();
840
+ return {
841
+ props,
842
+ slots,
843
+ slotsKey: this.slotsFingerprint(slots),
844
+ fullConfig: buildVanillaConfig(props, this.registry, this.appRef, this.envInjector, this.elementInjector, slots),
845
+ };
846
+ }
847
+ mountTable() {
477
848
  const container = this.hostEl.nativeElement.querySelector("div");
478
849
  if (!container)
479
850
  return;
480
- const props = this.getProps();
481
- this.instance = new SimpleTableVanilla(container, buildVanillaConfig(props, this.registry, this.appRef, this.envInjector, this.elementInjector));
851
+ const { props, slotsKey, fullConfig } = this.buildConfig();
852
+ this.instance = new SimpleTableVanilla(container, fullConfig);
482
853
  this.instance.mount();
483
854
  this.syncedDefaultHeaders = resolveAngularColumns(props);
484
855
  this.syncedRows = props.rows;
856
+ this.syncedSlotsKey = slotsKey;
485
857
  this.wasLoading = Boolean(props.isLoading);
486
858
  this.maybeRefitAutoSizeColumns(false);
487
859
  this.tableReady.emit(this.instance.getAPI());
488
860
  }
489
- ngOnChanges() {
861
+ applyConfig() {
490
862
  if (!this.instance)
491
863
  return;
492
- const props = this.getProps();
493
- const fullConfig = buildVanillaConfig(props, this.registry, this.appRef, this.envInjector, this.elementInjector);
864
+ const { props, slotsKey, fullConfig } = this.buildConfig();
494
865
  const patch = { ...fullConfig };
495
866
  const resolvedColumns = resolveAngularColumns(props);
496
867
  const headersUnchanged = headersStructurallyEqual(this.syncedDefaultHeaders, resolvedColumns);
497
868
  this.syncedDefaultHeaders = resolvedColumns;
498
- if (headersUnchanged) {
869
+ const slotsChanged = slotsKey !== this.syncedSlotsKey;
870
+ this.syncedSlotsKey = slotsKey;
871
+ if (headersUnchanged && !slotsChanged) {
499
872
  delete patch.columns;
500
873
  }
501
874
  const rowsUnchanged = rowsShallowUnchanged(this.syncedRows, props.rows, props.getRowId);
@@ -509,7 +882,27 @@ class SimpleTableComponent {
509
882
  this.instance.update(patch);
510
883
  this.maybeRefitAutoSizeColumns(leftLoading);
511
884
  }
885
+ ngAfterContentInit() {
886
+ this.mountTable();
887
+ const lists = [
888
+ this.cellSlots,
889
+ this.headerSlots,
890
+ this.emptySlots,
891
+ this.footerSlots,
892
+ this.loadingSlots,
893
+ this.errorSlots,
894
+ ];
895
+ for (const list of lists) {
896
+ this.slotUnsub.push(list.changes.subscribe(() => this.applyConfig()));
897
+ }
898
+ }
899
+ ngOnChanges() {
900
+ this.applyConfig();
901
+ }
512
902
  ngOnDestroy() {
903
+ for (const sub of this.slotUnsub)
904
+ sub.unsubscribe();
905
+ this.slotUnsub = [];
513
906
  this.instance?.destroy();
514
907
  this.instance = null;
515
908
  this.syncedDefaultHeaders = undefined;
@@ -540,30 +933,8 @@ class SimpleTableComponent {
540
933
  props.headerDropdown = this.headerDropdown;
541
934
  if (this.columnEditorConfig !== undefined)
542
935
  props.columnEditorConfig = this.columnEditorConfig;
543
- if (this.onCellClick !== undefined)
544
- props.onCellClick = this.onCellClick;
545
- if (this.onCellEdit !== undefined)
546
- props.onCellEdit = this.onCellEdit;
547
- if (this.onSortChange !== undefined)
548
- props.onSortChange = this.onSortChange;
549
- if (this.onFilterChange !== undefined)
550
- props.onFilterChange = this.onFilterChange;
551
- if (this.onRowSelectionChange !== undefined)
552
- props.onRowSelectionChange = this.onRowSelectionChange;
553
- if (this.onRowGroupExpand !== undefined)
554
- props.onRowGroupExpand = this.onRowGroupExpand;
555
- if (this.onColumnOrderChange !== undefined)
556
- props.onColumnOrderChange = this.onColumnOrderChange;
557
- if (this.onColumnVisibilityChange !== undefined)
558
- props.onColumnVisibilityChange = this.onColumnVisibilityChange;
559
- if (this.onColumnWidthChange !== undefined)
560
- props.onColumnWidthChange = this.onColumnWidthChange;
561
- if (this.onPageChange !== undefined)
562
- props.onPageChange = this.onPageChange;
563
936
  if (this.onNextPage !== undefined)
564
937
  props.onNextPage = this.onNextPage;
565
- if (this.onLoadMore !== undefined)
566
- props.onLoadMore = this.onLoadMore;
567
938
  if (this.onTableReady !== undefined)
568
939
  props.onTableReady = this.onTableReady;
569
940
  if (this.rowGrouping !== undefined)
@@ -574,8 +945,6 @@ class SimpleTableComponent {
574
945
  props.enableStickyParents = this.enableStickyParents;
575
946
  if (this.pivot !== undefined)
576
947
  props.pivot = this.pivot;
577
- if (this.onPivotChange !== undefined)
578
- props.onPivotChange = this.onPivotChange;
579
948
  if (this.enableRowSelection !== undefined)
580
949
  props.enableRowSelection = this.enableRowSelection;
581
950
  if (this.rowSelectionMode !== undefined)
@@ -626,10 +995,6 @@ class SimpleTableComponent {
626
995
  props.selectableColumns = this.selectableColumns;
627
996
  if (this.enableHeaderEditing !== undefined)
628
997
  props.enableHeaderEditing = this.enableHeaderEditing;
629
- if (this.onHeaderEdit !== undefined)
630
- props.onHeaderEdit = this.onHeaderEdit;
631
- if (this.onColumnSelect !== undefined)
632
- props.onColumnSelect = this.onColumnSelect;
633
998
  if (this.customTheme !== undefined)
634
999
  props.customTheme = this.customTheme;
635
1000
  if (this.icons !== undefined)
@@ -672,24 +1037,132 @@ class SimpleTableComponent {
672
1037
  props.enableVirtualization = this.enableVirtualization;
673
1038
  if (this.hoverRowBackground !== undefined)
674
1039
  props.hoverRowBackground = this.hoverRowBackground;
675
- if (this.hoverRowBackground !== undefined)
676
- props.hoverRowBackground = this.hoverRowBackground;
677
- if (this.oddColumnBackground !== undefined)
678
- props.oddColumnBackground = this.oddColumnBackground;
679
1040
  if (this.oddColumnBackground !== undefined)
680
1041
  props.oddColumnBackground = this.oddColumnBackground;
681
1042
  if (this.oddEvenRowBackground !== undefined)
682
1043
  props.oddEvenRowBackground = this.oddEvenRowBackground;
683
- if (this.oddEvenRowBackground !== undefined)
684
- props.oddEvenRowBackground = this.oddEvenRowBackground;
1044
+ if (this.onCellClick || this.cellClick.observed) {
1045
+ props.onCellClick = (event) => {
1046
+ this.inZone(() => {
1047
+ this.onCellClick?.(event);
1048
+ this.cellClick.emit(event);
1049
+ });
1050
+ };
1051
+ }
1052
+ if (this.onCellEdit || this.cellEdit.observed) {
1053
+ props.onCellEdit = (event) => {
1054
+ this.inZone(() => {
1055
+ this.onCellEdit?.(event);
1056
+ this.cellEdit.emit(event);
1057
+ });
1058
+ };
1059
+ }
1060
+ if (this.onSortChange || this.sortChange.observed) {
1061
+ props.onSortChange = (sort) => {
1062
+ this.inZone(() => {
1063
+ this.onSortChange?.(sort);
1064
+ this.sortChange.emit(sort);
1065
+ });
1066
+ };
1067
+ }
1068
+ if (this.onFilterChange || this.filterChange.observed) {
1069
+ props.onFilterChange = (filters) => {
1070
+ this.inZone(() => {
1071
+ this.onFilterChange?.(filters);
1072
+ this.filterChange.emit(filters);
1073
+ });
1074
+ };
1075
+ }
1076
+ if (this.onRowSelectionChange || this.rowSelectionChange.observed) {
1077
+ props.onRowSelectionChange = (event) => {
1078
+ this.inZone(() => {
1079
+ this.onRowSelectionChange?.(event);
1080
+ this.rowSelectionChange.emit(event);
1081
+ });
1082
+ };
1083
+ }
1084
+ if (this.onRowGroupExpand || this.rowGroupExpand.observed) {
1085
+ props.onRowGroupExpand = (event) => {
1086
+ return this.inZone(() => {
1087
+ const result = this.onRowGroupExpand?.(event);
1088
+ this.rowGroupExpand.emit(event);
1089
+ return result;
1090
+ });
1091
+ };
1092
+ }
1093
+ if (this.onColumnOrderChange || this.columnOrderChange.observed) {
1094
+ props.onColumnOrderChange = (headers) => {
1095
+ this.inZone(() => {
1096
+ this.onColumnOrderChange?.(headers);
1097
+ this.columnOrderChange.emit(headers);
1098
+ });
1099
+ };
1100
+ }
1101
+ if (this.onColumnVisibilityChange || this.columnVisibilityChange.observed) {
1102
+ props.onColumnVisibilityChange = (state) => {
1103
+ this.inZone(() => {
1104
+ this.onColumnVisibilityChange?.(state);
1105
+ this.columnVisibilityChange.emit(state);
1106
+ });
1107
+ };
1108
+ }
1109
+ if (this.onColumnWidthChange || this.columnWidthChange.observed) {
1110
+ props.onColumnWidthChange = (headers) => {
1111
+ this.inZone(() => {
1112
+ this.onColumnWidthChange?.(headers);
1113
+ this.columnWidthChange.emit(headers);
1114
+ });
1115
+ };
1116
+ }
1117
+ if (this.onPageChange || this.pageChange.observed) {
1118
+ props.onPageChange = (page) => {
1119
+ return this.inZone(() => {
1120
+ const result = this.onPageChange?.(page);
1121
+ this.pageChange.emit(page);
1122
+ return result;
1123
+ });
1124
+ };
1125
+ }
1126
+ if (this.onLoadMore || this.loadMore.observed) {
1127
+ props.onLoadMore = () => {
1128
+ this.inZone(() => {
1129
+ this.onLoadMore?.();
1130
+ this.loadMore.emit();
1131
+ });
1132
+ };
1133
+ }
1134
+ if (this.onHeaderEdit || this.headerEdit.observed) {
1135
+ props.onHeaderEdit = (header, newLabel) => {
1136
+ this.inZone(() => {
1137
+ this.onHeaderEdit?.(header, newLabel);
1138
+ this.headerEdit.emit({ header, newLabel });
1139
+ });
1140
+ };
1141
+ }
1142
+ if (this.onColumnSelect || this.columnSelect.observed) {
1143
+ props.onColumnSelect = (header) => {
1144
+ this.inZone(() => {
1145
+ this.onColumnSelect?.(header);
1146
+ this.columnSelect.emit(header);
1147
+ });
1148
+ };
1149
+ }
1150
+ if (this.onPivotChange || this.pivotChange.observed) {
1151
+ props.onPivotChange = (pivot) => {
1152
+ this.inZone(() => {
1153
+ this.onPivotChange?.(pivot);
1154
+ this.pivotChange.emit(pivot);
1155
+ });
1156
+ };
1157
+ }
685
1158
  return props;
686
1159
  }
687
1160
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: SimpleTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
688
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.27", type: SimpleTableComponent, isStandalone: true, selector: "simple-table", inputs: { rows: "rows", columns: "columns", footerRenderer: "footerRenderer", loadingStateRenderer: "loadingStateRenderer", errorStateRenderer: "errorStateRenderer", emptyStateRenderer: "emptyStateRenderer", tableEmptyStateRenderer: "tableEmptyStateRenderer", headerDropdown: "headerDropdown", columnEditorConfig: "columnEditorConfig", onCellClick: "onCellClick", onCellEdit: "onCellEdit", onSortChange: "onSortChange", onFilterChange: "onFilterChange", onRowSelectionChange: "onRowSelectionChange", onRowGroupExpand: "onRowGroupExpand", onColumnOrderChange: "onColumnOrderChange", onColumnVisibilityChange: "onColumnVisibilityChange", onColumnWidthChange: "onColumnWidthChange", onPageChange: "onPageChange", onNextPage: "onNextPage", onLoadMore: "onLoadMore", onTableReady: "onTableReady", rowGrouping: "rowGrouping", canExpandRowGroup: "canExpandRowGroup", enableStickyParents: "enableStickyParents", pivot: "pivot", onPivotChange: "onPivotChange", enableRowSelection: "enableRowSelection", rowSelectionMode: "rowSelectionMode", selectRowOnClick: "selectRowOnClick", showRowSelectionColumn: "showRowSelectionColumn", theme: "theme", quickFilter: "quickFilter", isLoading: "isLoading", getRowId: "getRowId", getRowClass: "getRowClass", enablePagination: "enablePagination", rowsPerPage: "rowsPerPage", serverSidePagination: "serverSidePagination", totalRowCount: "totalRowCount", height: "height", maxHeight: "maxHeight", scrollParent: "scrollParent", infiniteScrollThreshold: "infiniteScrollThreshold", columnResizing: "columnResizing", columnReordering: "columnReordering", enableColumnEditor: "enableColumnEditor", enableColumnEditorInitOpen: "enableColumnEditorInitOpen", enablePivotPanel: "enablePivotPanel", selectableCells: "selectableCells", selectableColumns: "selectableColumns", enableHeaderEditing: "enableHeaderEditing", onHeaderEdit: "onHeaderEdit", onColumnSelect: "onColumnSelect", customTheme: "customTheme", icons: "icons", externalFilterHandling: "externalFilterHandling", externalSortHandling: "externalSortHandling", columnBorders: "columnBorders", rowButtons: "rowButtons", hideFooter: "hideFooter", hideHeader: "hideHeader", footerRenderKey: "footerRenderKey", footerPosition: "footerPosition", className: "className", copyHeadersToClipboard: "copyHeadersToClipboard", includeHeadersInCSVExport: "includeHeadersInCSVExport", initialSortColumn: "initialSortColumn", initialSortDirection: "initialSortDirection", expandAll: "expandAll", autoExpandColumns: "autoExpandColumns", animations: "animations", cellUpdateFlash: "cellUpdateFlash", enableVirtualization: "enableVirtualization", hoverRowBackground: "hoverRowBackground", oddColumnBackground: "oddColumnBackground", oddEvenRowBackground: "oddEvenRowBackground" }, outputs: { tableReady: "tableReady" }, usesOnChanges: true, ngImport: i0, template: `<div #host></div>`, isInline: true, styles: [":host{display:block}\n"] }); }
1161
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.27", type: SimpleTableComponent, isStandalone: true, selector: "simple-table", inputs: { rows: "rows", columns: "columns", footerRenderer: "footerRenderer", loadingStateRenderer: "loadingStateRenderer", errorStateRenderer: "errorStateRenderer", emptyStateRenderer: "emptyStateRenderer", tableEmptyStateRenderer: "tableEmptyStateRenderer", headerDropdown: "headerDropdown", columnEditorConfig: "columnEditorConfig", onCellClick: "onCellClick", onCellEdit: "onCellEdit", onSortChange: "onSortChange", onFilterChange: "onFilterChange", onRowSelectionChange: "onRowSelectionChange", onRowGroupExpand: "onRowGroupExpand", onColumnOrderChange: "onColumnOrderChange", onColumnVisibilityChange: "onColumnVisibilityChange", onColumnWidthChange: "onColumnWidthChange", onPageChange: "onPageChange", onNextPage: "onNextPage", onLoadMore: "onLoadMore", onTableReady: "onTableReady", rowGrouping: "rowGrouping", canExpandRowGroup: "canExpandRowGroup", enableStickyParents: "enableStickyParents", pivot: "pivot", onPivotChange: "onPivotChange", enableRowSelection: "enableRowSelection", rowSelectionMode: "rowSelectionMode", selectRowOnClick: "selectRowOnClick", showRowSelectionColumn: "showRowSelectionColumn", theme: "theme", quickFilter: "quickFilter", isLoading: "isLoading", getRowId: "getRowId", getRowClass: "getRowClass", enablePagination: "enablePagination", rowsPerPage: "rowsPerPage", serverSidePagination: "serverSidePagination", totalRowCount: "totalRowCount", height: "height", maxHeight: "maxHeight", scrollParent: "scrollParent", infiniteScrollThreshold: "infiniteScrollThreshold", columnResizing: "columnResizing", columnReordering: "columnReordering", enableColumnEditor: "enableColumnEditor", enableColumnEditorInitOpen: "enableColumnEditorInitOpen", enablePivotPanel: "enablePivotPanel", selectableCells: "selectableCells", selectableColumns: "selectableColumns", enableHeaderEditing: "enableHeaderEditing", onHeaderEdit: "onHeaderEdit", onColumnSelect: "onColumnSelect", customTheme: "customTheme", icons: "icons", externalFilterHandling: "externalFilterHandling", externalSortHandling: "externalSortHandling", columnBorders: "columnBorders", rowButtons: "rowButtons", hideFooter: "hideFooter", hideHeader: "hideHeader", footerRenderKey: "footerRenderKey", footerPosition: "footerPosition", className: "className", copyHeadersToClipboard: "copyHeadersToClipboard", includeHeadersInCSVExport: "includeHeadersInCSVExport", initialSortColumn: "initialSortColumn", initialSortDirection: "initialSortDirection", expandAll: "expandAll", autoExpandColumns: "autoExpandColumns", animations: "animations", cellUpdateFlash: "cellUpdateFlash", enableVirtualization: "enableVirtualization", hoverRowBackground: "hoverRowBackground", oddColumnBackground: "oddColumnBackground", oddEvenRowBackground: "oddEvenRowBackground" }, outputs: { tableReady: "tableReady", cellClick: "cellClick", cellEdit: "cellEdit", sortChange: "sortChange", filterChange: "filterChange", rowSelectionChange: "rowSelectionChange", rowGroupExpand: "rowGroupExpand", columnOrderChange: "columnOrderChange", columnVisibilityChange: "columnVisibilityChange", columnWidthChange: "columnWidthChange", pageChange: "pageChange", loadMore: "loadMore", headerEdit: "headerEdit", columnSelect: "columnSelect", pivotChange: "pivotChange" }, queries: [{ propertyName: "cellSlots", predicate: StCellDirective }, { propertyName: "headerSlots", predicate: StHeaderDirective }, { propertyName: "emptySlots", predicate: StEmptyDirective }, { propertyName: "footerSlots", predicate: StFooterDirective }, { propertyName: "loadingSlots", predicate: StLoadingDirective }, { propertyName: "errorSlots", predicate: StErrorDirective }], usesOnChanges: true, ngImport: i0, template: `<div #host></div><ng-content />`, isInline: true, styles: [":host{display:block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
689
1162
  }
690
1163
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: SimpleTableComponent, decorators: [{
691
1164
  type: Component,
692
- args: [{ selector: "simple-table", standalone: true, template: `<div #host></div>`, styles: [":host{display:block}\n"] }]
1165
+ args: [{ selector: "simple-table", standalone: true, template: `<div #host></div><ng-content />`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}\n"] }]
693
1166
  }], propDecorators: { rows: [{
694
1167
  type: Input,
695
1168
  args: [{ required: true }]
@@ -847,36 +1320,116 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImpo
847
1320
  type: Input
848
1321
  }], tableReady: [{
849
1322
  type: Output
1323
+ }], cellClick: [{
1324
+ type: Output
1325
+ }], cellEdit: [{
1326
+ type: Output
1327
+ }], sortChange: [{
1328
+ type: Output
1329
+ }], filterChange: [{
1330
+ type: Output
1331
+ }], rowSelectionChange: [{
1332
+ type: Output
1333
+ }], rowGroupExpand: [{
1334
+ type: Output
1335
+ }], columnOrderChange: [{
1336
+ type: Output
1337
+ }], columnVisibilityChange: [{
1338
+ type: Output
1339
+ }], columnWidthChange: [{
1340
+ type: Output
1341
+ }], pageChange: [{
1342
+ type: Output
1343
+ }], loadMore: [{
1344
+ type: Output
1345
+ }], headerEdit: [{
1346
+ type: Output
1347
+ }], columnSelect: [{
1348
+ type: Output
1349
+ }], pivotChange: [{
1350
+ type: Output
1351
+ }], cellSlots: [{
1352
+ type: ContentChildren,
1353
+ args: [StCellDirective]
1354
+ }], headerSlots: [{
1355
+ type: ContentChildren,
1356
+ args: [StHeaderDirective]
1357
+ }], emptySlots: [{
1358
+ type: ContentChildren,
1359
+ args: [StEmptyDirective]
1360
+ }], footerSlots: [{
1361
+ type: ContentChildren,
1362
+ args: [StFooterDirective]
1363
+ }], loadingSlots: [{
1364
+ type: ContentChildren,
1365
+ args: [StLoadingDirective]
1366
+ }], errorSlots: [{
1367
+ type: ContentChildren,
1368
+ args: [StErrorDirective]
850
1369
  }] } });
851
1370
 
1371
+ const ST_STANDALONE = [
1372
+ SimpleTableComponent,
1373
+ StCellDirective,
1374
+ StHeaderDirective,
1375
+ StEmptyDirective,
1376
+ StFooterDirective,
1377
+ StLoadingDirective,
1378
+ StErrorDirective,
1379
+ StDomSlotDirective,
1380
+ ];
852
1381
  /**
853
- * Call this in your application's `providers` array (or `bootstrapApplication`
854
- * providers) to register the dependencies that simple-table-angular's renderer
855
- * bridge needs — specifically `ApplicationRef` and `EnvironmentInjector`.
1382
+ * One import for a page that uses `<simple-table>` plus `stCell` / `stEmpty` /
1383
+ * `(sortChange)` and the other template directives.
856
1384
  *
857
- * These are already provided by Angular's platform by default, so in practice
858
- * this function is a no-op placeholder that serves as a clear signal to
859
- * consumers that the adapter has been correctly wired up. If future versions
860
- * need custom providers they will be added here without breaking the call site.
1385
+ * ```ts
1386
+ * @Component({
1387
+ * standalone: true,
1388
+ * imports: [SimpleTableImports],
1389
+ * })
1390
+ * ```
1391
+ */
1392
+ class SimpleTableImports {
1393
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: SimpleTableImports, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1394
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.27", ngImport: i0, type: SimpleTableImports, imports: [SimpleTableComponent,
1395
+ StCellDirective,
1396
+ StHeaderDirective,
1397
+ StEmptyDirective,
1398
+ StFooterDirective,
1399
+ StLoadingDirective,
1400
+ StErrorDirective,
1401
+ StDomSlotDirective], exports: [SimpleTableComponent,
1402
+ StCellDirective,
1403
+ StHeaderDirective,
1404
+ StEmptyDirective,
1405
+ StFooterDirective,
1406
+ StLoadingDirective,
1407
+ StErrorDirective,
1408
+ StDomSlotDirective] }); }
1409
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: SimpleTableImports }); }
1410
+ }
1411
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: SimpleTableImports, decorators: [{
1412
+ type: NgModule,
1413
+ args: [{
1414
+ imports: [...ST_STANDALONE],
1415
+ exports: [...ST_STANDALONE],
1416
+ }]
1417
+ }] });
1418
+
1419
+ /**
1420
+ * Optional. Angular already provides `ApplicationRef` and `EnvironmentInjector`.
1421
+ * The table does not require this in `bootstrapApplication` / `providers`.
1422
+ *
1423
+ * Kept so existing apps that call it keep compiling. Future versions may add
1424
+ * real providers here without changing the call site.
861
1425
  *
862
1426
  * @example
863
- * // main.ts
864
1427
  * bootstrapApplication(AppComponent, {
865
1428
  * providers: [provideSimpleTable()],
866
1429
  * });
867
- *
868
- * @example
869
- * // app.module.ts
870
- * @NgModule({ providers: [provideSimpleTable()] })
871
- * export class AppModule {}
872
1430
  */
873
1431
  function provideSimpleTable() {
874
- return makeEnvironmentProviders([
875
- // ApplicationRef and EnvironmentInjector are part of Angular's core platform
876
- // and are available without any additional registration.
877
- // This factory is intentionally empty — it exists for API symmetry with
878
- // other Angular ecosystem libraries and to allow non-breaking additions later.
879
- ]);
1432
+ return makeEnvironmentProviders([]);
880
1433
  }
881
1434
 
882
1435
  // Component
@@ -885,5 +1438,5 @@ function provideSimpleTable() {
885
1438
  * Generated bundle index. Do not edit.
886
1439
  */
887
1440
 
888
- export { SimpleTableComponent, provideSimpleTable, wrapAngularRenderer };
1441
+ export { SimpleTableComponent, SimpleTableImports, StCellDirective, StDomSlotDirective, StEmptyDirective, StErrorDirective, StFooterDirective, StHeaderDirective, StLoadingDirective, provideSimpleTable, wrapAngularRenderer };
889
1442
  //# sourceMappingURL=simple-table-angular.mjs.map