@truenas/ui-components 0.4.11 → 0.5.0

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,6 +1,6 @@
1
1
  import * as _truenas_ui_components from '@truenas/ui-components';
2
2
  import * as _angular_core from '@angular/core';
3
- import { Signal, InjectionToken, Renderer2, OnDestroy, ElementRef, AfterViewInit, OnInit, TemplateRef, AfterContentInit, Provider, ChangeDetectorRef, TrackByFunction, OnChanges, DoCheck, SimpleChanges, PipeTransform, ViewContainerRef, AfterViewChecked, ComponentRef } from '@angular/core';
3
+ import { Signal, InjectionToken, Renderer2, OnDestroy, ElementRef, AfterViewInit, TemplateRef, AfterContentInit, Provider, ChangeDetectorRef, OnInit, TrackByFunction, OnChanges, DoCheck, SimpleChanges, PipeTransform, ViewContainerRef, AfterViewChecked, ComponentRef } from '@angular/core';
4
4
  import { ControlValueAccessor, NgControl, AbstractControl } from '@angular/forms';
5
5
  import { ComponentHarness, BaseHarnessFilters, HarnessPredicate, TestKey, HarnessLoader, ModifierKeys as ModifierKeys$1 } from '@angular/cdk/testing';
6
6
  import { SafeHtml, SafeResourceUrl, DomSanitizer } from '@angular/platform-browser';
@@ -1300,6 +1300,7 @@ declare class TnButtonComponent implements AfterViewInit {
1300
1300
  classes: _angular_core.Signal<string[]>;
1301
1301
  handleAnchorClick(event: MouseEvent): void;
1302
1302
  private hostRef;
1303
+ constructor();
1303
1304
  private innerRef;
1304
1305
  ngAfterViewInit(): void;
1305
1306
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnButtonComponent, never>;
@@ -1506,7 +1507,7 @@ declare class TnIconComponent {
1506
1507
  }
1507
1508
 
1508
1509
  type TooltipPosition = 'above' | 'below' | 'left' | 'right' | 'before' | 'after';
1509
- declare class TnTooltipDirective implements OnInit, OnDestroy {
1510
+ declare class TnTooltipDirective implements AfterViewInit, OnDestroy {
1510
1511
  message: _angular_core.InputSignal<string>;
1511
1512
  position: _angular_core.InputSignal<TooltipPosition>;
1512
1513
  disabled: _angular_core.InputSignal<boolean>;
@@ -1520,22 +1521,44 @@ declare class TnTooltipDirective implements OnInit, OnDestroy {
1520
1521
  private _isTooltipVisible;
1521
1522
  private _positionSub;
1522
1523
  private _tooltipId;
1523
- /**
1524
- * Only point `aria-describedby` at the tooltip when there is actually a message to
1525
- * describe. Otherwise every host (e.g. an icon button with no tooltip) would carry a
1526
- * dangling reference to a tooltip element that is never rendered.
1527
- */
1528
- protected get _ariaDescribedBy(): string | null;
1529
1524
  private _overlay;
1530
1525
  private _elementRef;
1531
1526
  private _viewContainerRef;
1532
1527
  private _overlayPositionBuilder;
1533
- ngOnInit(): void;
1528
+ private _ariaDescriber;
1529
+ private _viewInitialized;
1530
+ private _describedTarget;
1531
+ private _describedMessage;
1532
+ private _innerObserver;
1533
+ /**
1534
+ * Re-sync the description (see ngAfterViewInit) when the inputs change. The initial
1535
+ * write cannot happen here: on the first run the host's child components (e.g.
1536
+ * tn-button's inner `<button>`) have not rendered yet.
1537
+ */
1538
+ private readonly _syncDescriptionOnInputChange;
1539
+ /**
1540
+ * Expose the message to assistive tech via CDK's AriaDescriber: it keeps the text in
1541
+ * a persistent visually-hidden element (so `aria-describedby` never dangles — the
1542
+ * overlay tooltip only exists while shown) and adds/removes only its own id token,
1543
+ * leaving descriptions the control already carries (form hints, error ids) intact.
1544
+ * The description goes on the interactive element itself: the host when it is one,
1545
+ * otherwise the first interactive descendant (e.g. `<tn-button>`'s inner `<button>`),
1546
+ * because screen readers read descriptions off the focused control, not wrappers.
1547
+ */
1548
+ ngAfterViewInit(): void;
1549
+ private _syncAriaDescription;
1550
+ /**
1551
+ * The overlay tooltip renders its message as HTML (`[innerHTML]`), but AriaDescriber
1552
+ * writes the description as plain text — strip any markup so screen readers never
1553
+ * announce literal tags. DOMParser parses inert markup (no script execution).
1554
+ */
1555
+ private _plainTextMessage;
1556
+ private _removeAriaDescription;
1534
1557
  ngOnDestroy(): void;
1535
1558
  _onMouseEnter(): void;
1536
1559
  _onMouseLeave(): void;
1537
- _onFocus(): void;
1538
- _onBlur(): void;
1560
+ _onFocusIn(): void;
1561
+ _onFocusOut(event: FocusEvent): void;
1539
1562
  _onKeydown(event: KeyboardEvent): void;
1540
1563
  /** Shows the tooltip */
1541
1564
  show(delay?: number): void;
@@ -2977,6 +3000,15 @@ interface TnCardAction {
2977
3000
  handler: () => void;
2978
3001
  disabled?: boolean;
2979
3002
  icon?: string;
3003
+ /**
3004
+ * Tooltip for the action button — useful for explaining why an action is unavailable.
3005
+ * Shows on pointer hover (including while the action is disabled, since hover
3006
+ * retargets to the button's host element) and on keyboard focus while enabled. A
3007
+ * disabled native button is not focusable, so keyboard-only users cannot reach the
3008
+ * reason; screen reader users can still read it when browsing the button via its
3009
+ * persistent `aria-describedby` description.
3010
+ */
3011
+ tooltip?: string;
2980
3012
  /**
2981
3013
  * Test-id applied to the rendered action button. Rendered under whichever attribute name
2982
3014
  * is configured via `TN_TEST_ATTR` (default `data-testid`).
@@ -6289,10 +6321,51 @@ declare class TnTableColumnDirective {
6289
6321
  name: _angular_core.InputSignal<string>;
6290
6322
  sortable: _angular_core.InputSignal<boolean>;
6291
6323
  width: _angular_core.InputSignal<string | undefined>;
6324
+ /**
6325
+ * Human-readable label for the column. Used as the default header text in the
6326
+ * regular table layout AND the default field label in card mode, so a single
6327
+ * annotation serves both — prefer this over a text-only `tnHeaderCellDef`.
6328
+ * A `tnHeaderCellDef` template still overrides the header; `cardLabel` still
6329
+ * overrides the card field label. Falls back to the column `name` when unset.
6330
+ */
6331
+ label: _angular_core.InputSignal<string | undefined>;
6332
+ /**
6333
+ * Relative importance of this column in card mode (see `mobileLayout` on
6334
+ * `tn-table`). Higher numbers render first; fields ranked beyond
6335
+ * `cardPrimaryCount` fold under a "More fields" disclosure. Defaults to `0`,
6336
+ * in which case columns fall back to their `displayedColumns` order. Has no
6337
+ * effect in the regular (wide) table layout.
6338
+ */
6339
+ cardPriority: _angular_core.InputSignal<number>;
6340
+ /**
6341
+ * Marks this column as the card's title in card mode — rendered prominently
6342
+ * in the card header alongside any row actions, never as a label/value field.
6343
+ * If no column sets this, the first displayed column that isn't `cardHidden` is
6344
+ * used, falling back to the first displayed column when every column is hidden —
6345
+ * a column deliberately kept off the card is not promoted to its most prominent
6346
+ * slot.
6347
+ */
6348
+ cardTitle: _angular_core.InputSignal<boolean>;
6349
+ /**
6350
+ * When true, this column is omitted entirely from the card layout (e.g. a
6351
+ * redundant id, or a column whose meaning is already conveyed by the title).
6352
+ * Ignored in the regular table layout.
6353
+ */
6354
+ cardHidden: _angular_core.InputSignal<boolean>;
6355
+ /**
6356
+ * Overrides the field label shown for this column in card mode. Defaults to the
6357
+ * column's `label`, then to the column name.
6358
+ *
6359
+ * A `tnHeaderCellDef` template is NOT used here — it is an `ng-template`, not
6360
+ * text, so there is nothing to read out. A column whose header comes only from
6361
+ * that template renders its bare column name as the card field label; set
6362
+ * `label` (or `cardLabel`) to give the card something readable.
6363
+ */
6364
+ cardLabel: _angular_core.InputSignal<string | undefined>;
6292
6365
  headerTemplate: _angular_core.Signal<TemplateRef<any> | undefined>;
6293
6366
  cellTemplate: _angular_core.Signal<TemplateRef<any> | undefined>;
6294
6367
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTableColumnDirective, never>;
6295
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnTableColumnDirective, "[tnColumnDef]", ["tnColumnDef"], { "name": { "alias": "tnColumnDef"; "required": true; "isSignal": true; }; "sortable": { "alias": "sortable"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; }, {}, ["headerTemplate", "cellTemplate"], never, true, never>;
6368
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnTableColumnDirective, "[tnColumnDef]", ["tnColumnDef"], { "name": { "alias": "tnColumnDef"; "required": true; "isSignal": true; }; "sortable": { "alias": "sortable"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "cardPriority": { "alias": "cardPriority"; "required": false; "isSignal": true; }; "cardTitle": { "alias": "cardTitle"; "required": false; "isSignal": true; }; "cardHidden": { "alias": "cardHidden"; "required": false; "isSignal": true; }; "cardLabel": { "alias": "cardLabel"; "required": false; "isSignal": true; }; }, {}, ["headerTemplate", "cellTemplate"], never, true, never>;
6296
6369
  }
6297
6370
  /**
6298
6371
  * Directive to define the expandable detail row template.
@@ -6313,18 +6386,80 @@ declare class TnDetailRowDefDirective {
6313
6386
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnDetailRowDefDirective, never>;
6314
6387
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnDetailRowDefDirective, "[tnDetailRowDef]", never, {}, {}, never, never, true, never>;
6315
6388
  }
6389
+ /**
6390
+ * Directive to define a row's action controls (e.g. edit/delete buttons).
6391
+ *
6392
+ * Place inside `tn-table` to render a trailing actions column, pinned to the right edge
6393
+ * in `scroll` mode (see `mobileLayout` on `tn-table`) and scrolling with the rest of the
6394
+ * table above `cardBreakpoint`. In card mode the same template is rendered inline beside
6395
+ * the card title, so row actions stay reachable at every viewport width. The template
6396
+ * receives the row as its implicit context.
6397
+ *
6398
+ * @example
6399
+ * ```html
6400
+ * <tn-table [dataSource]="data" [displayedColumns]="columns">
6401
+ * ...column defs...
6402
+ * <ng-template tnRowActionsDef let-row>
6403
+ * <tn-icon-button name="mat-edit" ariaLabel="Edit" (click)="edit(row)" />
6404
+ * <tn-icon-button name="mat-delete" ariaLabel="Delete" (click)="remove(row)" />
6405
+ * </ng-template>
6406
+ * </tn-table>
6407
+ * ```
6408
+ */
6409
+ declare class TnRowActionsDefDirective {
6410
+ template: TemplateRef<any>;
6411
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnRowActionsDefDirective, never>;
6412
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnRowActionsDefDirective, "[tnRowActionsDef]", never, {}, {}, never, never, true, never>;
6413
+ }
6316
6414
 
6317
6415
  interface TnTableDataSource<T = unknown> {
6318
6416
  data?: T[];
6319
6417
  connect?(): T[];
6320
6418
  disconnect?(): void;
6321
6419
  }
6420
+ /** Payload of the table's `sortChange` output. */
6322
6421
  interface TnSortEvent {
6422
+ /**
6423
+ * The column that is sorted *after* the change, or `''` when the sort was cleared — the
6424
+ * third click on a table header, or the "Unsorted" option in card mode. Both layouts
6425
+ * report the resulting state, so a cleared sort never names the column just cleared.
6426
+ */
6323
6427
  column: string;
6428
+ /** Direction after the change; `''` when no sort is active, which is always the case when `column` is `''`. */
6324
6429
  direction: 'asc' | 'desc' | '';
6325
6430
  }
6431
+ /**
6432
+ * How the table adapts when its container is narrower than `cardBreakpoint`:
6433
+ * - `scroll` — the table keeps its columns and scrolls horizontally, with the
6434
+ * first column and the actions column pinned in place *while it overflows*.
6435
+ * Default, and card mode is strictly opt-in — but note this is NOT a no-op for
6436
+ * existing tables: because the default `cardBreakpoint` is 640, any table whose
6437
+ * host content box measures under that (a phone, or a sidebar or dashboard card
6438
+ * on a desktop) gets `tn-table--scroll` and therefore the pinning, where it
6439
+ * previously scrolled all of its columns together. Raise `cardBreakpoint` if a
6440
+ * table should never pin.
6441
+ *
6442
+ * Overflow is not automatic either: `auto` layout (the default) sizes to content
6443
+ * and overflows on its own, but a `fixedLayout` table fits its container exactly,
6444
+ * so it only overflows — and only then pins — once `minColumnWidth` or `minWidth`
6445
+ * gives it a floor.
6446
+ * - `cards` — each row collapses into a stacked card (title + actions header,
6447
+ * priority-ranked label/value fields, optional detail content).
6448
+ * Above the breakpoint both modes render the regular table.
6449
+ */
6450
+ type TnTableMobileLayout = 'cards' | 'scroll';
6326
6451
  declare class TnTableComponent<T = unknown> implements OnInit {
6327
6452
  private destroyRef;
6453
+ private elementRef;
6454
+ private injector;
6455
+ /**
6456
+ * Element that had focus when `loading` went true, so it can be restored afterwards.
6457
+ *
6458
+ * `inert` blurs whatever is focused inside it and refuses focus while set, so without this
6459
+ * a keyboard user who pressed Enter on a sortable header — the flow that *starts* most
6460
+ * loads — was dropped to `<body>` and had to tab back from the top of the document.
6461
+ */
6462
+ private focusBeforeLoading;
6328
6463
  dataSource: _angular_core.InputSignal<TnTableDataSource<T> | T[]>;
6329
6464
  displayedColumns: _angular_core.InputSignal<string[]>;
6330
6465
  trackBy: _angular_core.InputSignal<((index: number, item: T) => unknown) | undefined>;
@@ -6390,6 +6525,12 @@ declare class TnTableComponent<T = unknown> implements OnInit {
6390
6525
  * When true, shows a spinner overlay over the table. Existing rows remain
6391
6526
  * visible (dimmed) so reloads don't cause layout jumps; if there are no rows
6392
6527
  * yet, the spinner replaces the empty state.
6528
+ *
6529
+ * The rendered surfaces are `inert` while this is true, so they leave the tab order *and*
6530
+ * the accessibility tree — a screen-reader user hears the overlay's "Loading..." status
6531
+ * rather than the stale rows. That is deliberate: `pointer-events` alone left every row,
6532
+ * header and projected control activatable by keyboard against data being replaced.
6533
+ * Focus is captured on the way in and restored on the way out.
6393
6534
  */
6394
6535
  loading: _angular_core.InputSignal<boolean>;
6395
6536
  /** Accessible label announced while loading. */
@@ -6398,6 +6539,16 @@ declare class TnTableComponent<T = unknown> implements OnInit {
6398
6539
  * When true, rows become keyboard-focusable (tabindex=0) and clicking or
6399
6540
  * pressing Enter/Space emits `rowClick`. Use this for "click row to view
6400
6541
  * details" patterns. Independent of `selectable` (checkbox) and `expandable`.
6542
+ *
6543
+ * Accessibility limitation in card mode: a card is `role="listitem"`, and the
6544
+ * roles that would announce it as activatable (`button`, `option`) have
6545
+ * presentational children, which would hide the card's own checkbox, row
6546
+ * actions and "Details" toggle from assistive tech. So a clickable card is
6547
+ * focusable and responds to Enter/Space, but is not announced as a control.
6548
+ * Active state is conveyed with `aria-current`, and expansion with
6549
+ * `aria-expanded` when `expandOnRowClick` is set. If an action must be
6550
+ * discoverable by screen-reader users, project an explicit control through
6551
+ * `[tnRowActionsDef]` rather than relying on card activation alone.
6401
6552
  */
6402
6553
  clickable: _angular_core.InputSignal<boolean>;
6403
6554
  /**
@@ -6405,6 +6556,12 @@ declare class TnTableComponent<T = unknown> implements OnInit {
6405
6556
  * chevron. Requires `clickable` — that is what makes rows activatable at all — and `expandable`;
6406
6557
  * rows the `isRowExpandable` predicate rejects are unaffected, since `toggleRowExpansion` gates
6407
6558
  * on it. `rowClick` still emits, so a consumer can both expand and react to the click.
6559
+ *
6560
+ * Applies in card mode too, where activating the card toggles its detail section. Both controls
6561
+ * report the state: the card carries `aria-expanded` while it is the trigger (`listitem` does
6562
+ * permit it, unlike `aria-selected`), and the "Details" button carries it unconditionally,
6563
+ * because that button is what a screen-reader user reaches by tabbing. The redundancy is
6564
+ * deliberate — see the comment above the button in the template.
6408
6565
  */
6409
6566
  expandOnRowClick: _angular_core.InputSignal<boolean>;
6410
6567
  /**
@@ -6451,6 +6608,32 @@ declare class TnTableComponent<T = unknown> implements OnInit {
6451
6608
  minWidth: _angular_core.InputSignal<string>;
6452
6609
  /** The floor actually applied to the table — explicit if given, else derived, else none. */
6453
6610
  protected readonly resolvedMinWidth: _angular_core.Signal<string | null>;
6611
+ /**
6612
+ * How the table adapts when its container is narrower than `cardBreakpoint`.
6613
+ * See {@link TnTableMobileLayout}. Defaults to `scroll`, which preserves the
6614
+ * existing horizontal-scroll behavior; set to `cards` to opt into the stacked
6615
+ * card layout.
6616
+ */
6617
+ mobileLayout: _angular_core.InputSignal<TnTableMobileLayout>;
6618
+ /**
6619
+ * Container width (px) below which `mobileLayout` takes effect. The component
6620
+ * observes its own host width (via `ResizeObserver`), so this responds to the
6621
+ * available container — a table in a narrow sidebar adapts on a wide screen.
6622
+ *
6623
+ * Measured against the host's **content box** — its border and padding are excluded — so a
6624
+ * `[bordered]` table crosses the threshold at the same content width as an unbordered one.
6625
+ */
6626
+ cardBreakpoint: _angular_core.InputSignal<number>;
6627
+ /**
6628
+ * Number of fields shown directly on each card before the rest fold under a
6629
+ * "More fields" disclosure. The title column is not counted. Defaults to `3`.
6630
+ */
6631
+ cardPrimaryCount: _angular_core.InputSignal<number>;
6632
+ /**
6633
+ * Emits the resulting sort state whenever the user changes it, from either layout.
6634
+ * Clearing a sort emits `{ column: '', direction: '' }` rather than naming the column
6635
+ * that was cleared — see {@link TnSortEvent}.
6636
+ */
6454
6637
  sortChange: _angular_core.OutputEmitterRef<TnSortEvent>;
6455
6638
  selectionChange: _angular_core.OutputEmitterRef<T[]>;
6456
6639
  /** Emits the row when a clickable row is activated (click or Enter/Space). */
@@ -6464,6 +6647,10 @@ declare class TnTableComponent<T = unknown> implements OnInit {
6464
6647
  rowDoubleClick: _angular_core.OutputEmitterRef<T>;
6465
6648
  columnDefs: _angular_core.Signal<readonly TnTableColumnDirective[]>;
6466
6649
  detailRowDef: _angular_core.Signal<TnDetailRowDefDirective | undefined>;
6650
+ rowActionsDef: _angular_core.Signal<TnRowActionsDefDirective | undefined>;
6651
+ /** Observed host width in px; drives the switch into card mode. */
6652
+ private containerWidth;
6653
+ private resizeObserver?;
6467
6654
  /**
6468
6655
  * Sorted column and direction. Two-way bindable (`[(sortColumn)]`), so a consumer that owns the
6469
6656
  * sort — a data provider, a table destroyed and rebuilt when its list empties out — can restore
@@ -6478,14 +6665,38 @@ declare class TnTableComponent<T = unknown> implements OnInit {
6478
6665
  * approach could address this.
6479
6666
  */
6480
6667
  expandedRows: _angular_core.WritableSignal<Set<unknown>>;
6668
+ private static instanceCount;
6669
+ private readonly instanceId;
6481
6670
  selection: SelectionModel<T>;
6482
6671
  private selectionCount;
6483
6672
  private initialized;
6484
6673
  private columnDefMap;
6485
6674
  constructor();
6675
+ /**
6676
+ * Reads the host's current **content-box** width into `containerWidth`.
6677
+ *
6678
+ * Content box specifically, to match the `ResizeObserver` callback's `contentRect`. The
6679
+ * initial read used `getBoundingClientRect()` — the border box — so the two paths measured
6680
+ * different quantities, and `[bordered]` puts a 1px border on each side: a bordered table
6681
+ * whose content box is 639px rendered as a table on first paint (641 is not < 640) and
6682
+ * flipped to cards on the observer's first callback, with no resize having happened. Host
6683
+ * padding widens the gap further.
6684
+ */
6685
+ private measureContainer;
6486
6686
  ngOnInit(): void;
6687
+ /** True when the layout should collapse rows into cards. */
6688
+ isCardMode: _angular_core.Signal<boolean>;
6689
+ /** True when the layout should keep the table but pin edge columns and scroll. */
6690
+ isScrollMode: _angular_core.Signal<boolean>;
6487
6691
  data: _angular_core.Signal<T[]>;
6488
6692
  effectiveDisplayedColumns: _angular_core.Signal<string[]>;
6693
+ /**
6694
+ * Every column the table actually renders, including the trailing actions column, which
6695
+ * `effectiveDisplayedColumns` does not track because it comes from a content template rather
6696
+ * than `displayedColumns`. Used for the detail row's `colspan`, so a detail row spans the full
6697
+ * width no matter which structural columns are on.
6698
+ */
6699
+ totalColumnCount: _angular_core.Signal<number>;
6489
6700
  isAllSelected: _angular_core.Signal<boolean>;
6490
6701
  isIndeterminate: _angular_core.Signal<boolean>;
6491
6702
  trackByFn: _angular_core.Signal<(index: number, item: T) => unknown>;
@@ -6509,17 +6720,155 @@ declare class TnTableComponent<T = unknown> implements OnInit {
6509
6720
  * {@link onRowClick} returns before toggling anything.
6510
6721
  */
6511
6722
  isRowExpandTrigger(row: T): boolean;
6723
+ /**
6724
+ * Card-mode counterpart of {@link isRowExpandTrigger}, additionally requiring a detail
6725
+ * template. Card mode renders no expansion affordance at all without one, so `aria-expanded`
6726
+ * on the card would advertise a state change that produces nothing.
6727
+ *
6728
+ * Table mode deliberately keeps the looser check: its rows are asserted to carry
6729
+ * `aria-expanded` from `expandOnRowClick` alone, and that predates this layout.
6730
+ */
6731
+ isCardExpandTrigger(row: T): boolean;
6732
+ /** DOM id for a row's detail panel, so the expand trigger can point `aria-controls` at it. */
6733
+ detailPanelId(rowIndex: number): string;
6512
6734
  isRowActive(row: T): boolean;
6513
- onRowClick(row: T): void;
6514
- onRowDoubleClick(row: T): void;
6735
+ /**
6736
+ * @param row The activated row.
6737
+ * @param event The originating DOM event, when there is one. Optional so a consumer (or a
6738
+ * test) can still activate a row programmatically; the control-target guard only applies
6739
+ * to real events, which is the only case where a projected control can be the source.
6740
+ */
6741
+ onRowClick(row: T, event?: Event): void;
6742
+ /** @param event See {@link onRowClick} — same guard, same optionality. */
6743
+ onRowDoubleClick(row: T, event?: Event): void;
6515
6744
  onRowKeydown(event: KeyboardEvent, row: T): void;
6745
+ onCardClick(event: Event, row: T): void;
6746
+ /** Card-mode counterpart of {@link onRowDoubleClick}, with the same guard. */
6747
+ onCardDoubleClick(event: Event, row: T): void;
6748
+ onCardKeydown(event: KeyboardEvent, row: T): void;
6749
+ /** Anything focusable or otherwise interactive, regardless of layout. */
6750
+ private static readonly INTERACTIVE_SELECTOR;
6751
+ /**
6752
+ * Whether an event originated on a control *within* the activation surface rather than on
6753
+ * the surface itself.
6754
+ *
6755
+ * @param event The DOM event; its `currentTarget` is the activation surface.
6756
+ * @param containerSelectors Layout-specific wrappers that count as controls.
6757
+ */
6758
+ private isControlTarget;
6759
+ /**
6760
+ * Interactive elements plus the card's own controls and its projected detail panel.
6761
+ *
6762
+ * A class allowlist is not enough: the detail panel renders consumer content inside the
6763
+ * clickable card, so an allowlist lets a click on a projected button bubble up and fire
6764
+ * `rowClick` — and with `expandOnRowClick`, collapse the very panel being used. Table mode
6765
+ * never had that problem, because there the detail row is a sibling `<tr>` outside the
6766
+ * clickable row.
6767
+ *
6768
+ * The card's own field values are deliberately not interactive, so they still activate the
6769
+ * card whether primary or folded under "More fields".
6770
+ */
6771
+ private isCardControlTarget;
6772
+ /**
6773
+ * Table-mode counterpart. The cells stop `click` themselves, but nothing stopped `keydown`,
6774
+ * so Enter on a projected action button bubbled to the row and got `preventDefault()`d —
6775
+ * which *is* how Enter activates a `<button>`, so the consumer's handler never ran and
6776
+ * `rowClick` fired for the row instead. Card mode has always guarded this; the two layouts
6777
+ * disagreed about what a projected control does under the keyboard.
6778
+ */
6779
+ private isRowControlTarget;
6780
+ /**
6781
+ * Header-cell activation, guarded like the row and the card.
6782
+ *
6783
+ * A `<th>` is an activation surface too, and a control projected through
6784
+ * `tnHeaderCellDef` broke both ways without this: clicking a filter button re-sorted the
6785
+ * table as well as running the button's own handler, and Space on a checkbox in a
6786
+ * *non-sortable* header was swallowed entirely — `onSortClick` returned early on the
6787
+ * missing `sortable()`, but the template's `preventDefault()` ran regardless, so the
6788
+ * control was simply dead.
6789
+ *
6790
+ * @param column The column the header belongs to.
6791
+ * @param event The originating DOM event.
6792
+ */
6793
+ onSortHeaderClick(column: string, event: Event): void;
6794
+ /**
6795
+ * Keyboard counterpart of {@link onSortHeaderClick}.
6796
+ *
6797
+ * Takes `Event` rather than `KeyboardEvent` because Angular types `$event` as `Event` for
6798
+ * the `keydown.enter` / `keydown.space` pseudo-events; narrowing happens here.
6799
+ */
6800
+ onSortHeaderKeydown(column: string, event: Event): void;
6801
+ /** Handles the card-mode sort `<select>` change. */
6802
+ onSortSelectChange(event: Event): void;
6516
6803
  toggleSelectAll(): void;
6517
6804
  toggleRowSelection(row: T): void;
6518
6805
  isRowSelected(row: T): boolean;
6806
+ /**
6807
+ * The column rendered as the card title. The first `displayedColumns` entry
6808
+ * whose def sets `cardTitle`, else the first column not marked `cardHidden` —
6809
+ * a column the consumer asked to keep off the card must not be promoted to its
6810
+ * most prominent slot. Falls back to the first displayed column only when every
6811
+ * column is hidden, since a card still needs a title.
6812
+ */
6813
+ cardTitleColumn: _angular_core.Signal<string>;
6814
+ /**
6815
+ * Columns rendered as label/value fields in a card, ordered by descending
6816
+ * `cardPriority` (ties keep `displayedColumns` order). Excludes the title column
6817
+ * and any `cardHidden` columns.
6818
+ */
6819
+ cardFieldColumns: _angular_core.Signal<string[]>;
6820
+ /** Fields shown directly on the card (up to `cardPrimaryCount`). */
6821
+ cardPrimaryColumns: _angular_core.Signal<string[]>;
6822
+ /** Fields tucked behind the "More fields" disclosure. */
6823
+ cardSecondaryColumns: _angular_core.Signal<string[]>;
6824
+ /**
6825
+ * Displayed columns that are sortable — populates the card-mode sort menu.
6826
+ *
6827
+ * `cardHidden` columns are excluded, because this menu *is* part of the card layout
6828
+ * and `cardHidden` promises the column is "omitted entirely" from it. Offering one
6829
+ * here would let a user reorder the cards by a value no card shows, with the
6830
+ * direction toggle giving no clue what changed — and such a column often has no
6831
+ * readable label either, since `getCardLabel()` falls back to the raw column name
6832
+ * when the header lives only in a `tnHeaderCellDef` template.
6833
+ *
6834
+ * The title column stays eligible: it is excluded from the *fields*, but it is
6835
+ * displayed, so sorting by it is meaningful.
6836
+ */
6837
+ sortableColumns: _angular_core.Signal<string[]>;
6838
+ /**
6839
+ * Whether the active sort column is one the table can actually sort by.
6840
+ *
6841
+ * `sortableColumns` rescues an active column into the menu so it stays clearable, even
6842
+ * when it is `cardHidden`, absent from `displayedColumns`, or never `sortable()`. That
6843
+ * escape hatch must not hand card mode a capability table mode refuses: clicking a
6844
+ * non-sortable header does nothing, so the direction toggle is hidden — and
6845
+ * {@link toggleSortDirection} refuses — for the same column.
6846
+ */
6847
+ protected readonly canSortActiveColumn: _angular_core.Signal<boolean>;
6848
+ /**
6849
+ * Sets (or clears, when passed `''`) the active sort column for card mode.
6850
+ * Switching columns resets to ascending, and clearing emits an empty `column` —
6851
+ * both matching {@link onSortClick}, since the same `sortChange` contract should
6852
+ * not depend on which layout the container width happens to be showing.
6853
+ */
6854
+ setSortColumn(column: string): void;
6855
+ /**
6856
+ * Flips the active sort direction between ascending and descending.
6857
+ *
6858
+ * Starts from ascending, so a column carrying an empty direction — reachable by restoring only
6859
+ * `sortColumn` through its two-way binding — sorts ascending rather than skipping straight to
6860
+ * descending. Same reading of "empty direction means not sorted" as {@link onSortClick}.
6861
+ */
6862
+ toggleSortDirection(): void;
6519
6863
  getColumnDef(columnName: string): TnTableColumnDirective | undefined;
6864
+ /**
6865
+ * Field label for a column in card mode. Precedence: `cardLabel` override →
6866
+ * shared `label` → the column name.
6867
+ */
6868
+ getCardLabel(column: string): string;
6520
6869
  getCellValue(row: T, column: string): unknown;
6521
6870
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTableComponent<any>, never>;
6522
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnTableComponent<any>, "tn-table", never, { "dataSource": { "alias": "dataSource"; "required": false; "isSignal": true; }; "displayedColumns": { "alias": "displayedColumns"; "required": false; "isSignal": true; }; "trackBy": { "alias": "trackBy"; "required": false; "isSignal": true; }; "emptyMessage": { "alias": "emptyMessage"; "required": false; "isSignal": true; }; "emptyDescription": { "alias": "emptyDescription"; "required": false; "isSignal": true; }; "emptyIcon": { "alias": "emptyIcon"; "required": false; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "expandable": { "alias": "expandable"; "required": false; "isSignal": true; }; "bordered": { "alias": "bordered"; "required": false; "isSignal": true; }; "isRowExpandable": { "alias": "isRowExpandable"; "required": false; "isSignal": true; }; "activeRow": { "alias": "activeRow"; "required": false; "isSignal": true; }; "activeWhen": { "alias": "activeWhen"; "required": false; "isSignal": true; }; "activeBg": { "alias": "activeBg"; "required": false; "isSignal": true; }; "activeIndicator": { "alias": "activeIndicator"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "loadingMessage": { "alias": "loadingMessage"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; "expandOnRowClick": { "alias": "expandOnRowClick"; "required": false; "isSignal": true; }; "singleExpand": { "alias": "singleExpand"; "required": false; "isSignal": true; }; "fixedLayout": { "alias": "fixedLayout"; "required": false; "isSignal": true; }; "minColumnWidth": { "alias": "minColumnWidth"; "required": false; "isSignal": true; }; "minWidth": { "alias": "minWidth"; "required": false; "isSignal": true; }; "sortColumn": { "alias": "sortColumn"; "required": false; "isSignal": true; }; "sortDirection": { "alias": "sortDirection"; "required": false; "isSignal": true; }; }, { "sortChange": "sortChange"; "selectionChange": "selectionChange"; "rowClick": "rowClick"; "rowDoubleClick": "rowDoubleClick"; "sortColumn": "sortColumnChange"; "sortDirection": "sortDirectionChange"; }, ["columnDefs", "detailRowDef"], never, true, [{ directive: typeof TnTestIdDirective; inputs: { "tnTestId": "testId"; }; outputs: {}; }]>;
6871
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnTableComponent<any>, "tn-table", never, { "dataSource": { "alias": "dataSource"; "required": false; "isSignal": true; }; "displayedColumns": { "alias": "displayedColumns"; "required": false; "isSignal": true; }; "trackBy": { "alias": "trackBy"; "required": false; "isSignal": true; }; "emptyMessage": { "alias": "emptyMessage"; "required": false; "isSignal": true; }; "emptyDescription": { "alias": "emptyDescription"; "required": false; "isSignal": true; }; "emptyIcon": { "alias": "emptyIcon"; "required": false; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "expandable": { "alias": "expandable"; "required": false; "isSignal": true; }; "bordered": { "alias": "bordered"; "required": false; "isSignal": true; }; "isRowExpandable": { "alias": "isRowExpandable"; "required": false; "isSignal": true; }; "activeRow": { "alias": "activeRow"; "required": false; "isSignal": true; }; "activeWhen": { "alias": "activeWhen"; "required": false; "isSignal": true; }; "activeBg": { "alias": "activeBg"; "required": false; "isSignal": true; }; "activeIndicator": { "alias": "activeIndicator"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "loadingMessage": { "alias": "loadingMessage"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; "expandOnRowClick": { "alias": "expandOnRowClick"; "required": false; "isSignal": true; }; "singleExpand": { "alias": "singleExpand"; "required": false; "isSignal": true; }; "fixedLayout": { "alias": "fixedLayout"; "required": false; "isSignal": true; }; "minColumnWidth": { "alias": "minColumnWidth"; "required": false; "isSignal": true; }; "minWidth": { "alias": "minWidth"; "required": false; "isSignal": true; }; "mobileLayout": { "alias": "mobileLayout"; "required": false; "isSignal": true; }; "cardBreakpoint": { "alias": "cardBreakpoint"; "required": false; "isSignal": true; }; "cardPrimaryCount": { "alias": "cardPrimaryCount"; "required": false; "isSignal": true; }; "sortColumn": { "alias": "sortColumn"; "required": false; "isSignal": true; }; "sortDirection": { "alias": "sortDirection"; "required": false; "isSignal": true; }; }, { "sortChange": "sortChange"; "selectionChange": "selectionChange"; "rowClick": "rowClick"; "rowDoubleClick": "rowDoubleClick"; "sortColumn": "sortColumnChange"; "sortDirection": "sortDirectionChange"; }, ["columnDefs", "detailRowDef", "rowActionsDef"], never, true, [{ directive: typeof TnTestIdDirective; inputs: { "tnTestId": "testId"; }; outputs: {}; }]>;
6523
6872
  }
6524
6873
 
6525
6874
  /**
@@ -6551,13 +6900,32 @@ declare class TnTableHarness extends ComponentHarness {
6551
6900
  /**
6552
6901
  * Gets the number of data rows (excludes header and detail rows).
6553
6902
  *
6554
- * @returns Promise resolving to the row count.
6903
+ * Layout-aware: counts rendered cards in the card layout, so the count tracks what the
6904
+ * user sees rather than reporting 0 for a container that happens to be narrow.
6905
+ *
6906
+ * @returns Promise resolving to the row count, or the card count in the card layout.
6555
6907
  */
6556
6908
  getRowCount(): Promise<number>;
6909
+ /**
6910
+ * Throws when the rendered layout is `cards`, for queries that have no card equivalent.
6911
+ * The alternative is an empty array or a 0, which reads as "the table is empty" and
6912
+ * greens a test over a rendered card list — the failure mode the selection and
6913
+ * active-row methods were made layout-aware to avoid.
6914
+ */
6915
+ private assertTableLayout;
6916
+ /**
6917
+ * Mirror of {@link assertTableLayout} for the card API. `getCardCount()` answering 0 in
6918
+ * table mode is the same silent-wrong-answer shape rejected for `getRowCount()`: a spec
6919
+ * that forgot to push a sub-breakpoint width would assert emptiness and pass over 20
6920
+ * rendered rows.
6921
+ */
6922
+ private assertCardLayout;
6557
6923
  /**
6558
6924
  * Gets the text content of header cells (excludes sort icons).
6559
6925
  *
6560
6926
  * @returns Promise resolving to an array of header text strings.
6927
+ * @throws Error in the card layout, which renders no header row;
6928
+ * the thrown message names the card API.
6561
6929
  */
6562
6930
  getHeaderTexts(): Promise<string[]>;
6563
6931
  /**
@@ -6565,6 +6933,7 @@ declare class TnTableHarness extends ComponentHarness {
6565
6933
  *
6566
6934
  * @param rowIndex Zero-based index of the data row.
6567
6935
  * @returns Promise resolving to an array of cell text strings.
6936
+ * @throws Error in the card layout, which renders no rows; the thrown message names the card API.
6568
6937
  */
6569
6938
  getRowTexts(rowIndex: number): Promise<string[]>;
6570
6939
  /**
@@ -6573,18 +6942,23 @@ declare class TnTableHarness extends ComponentHarness {
6573
6942
  * @param rowIndex Zero-based index of the data row.
6574
6943
  * @param columnName The column's data-column attribute value.
6575
6944
  * @returns Promise resolving to the cell text.
6945
+ * @throws Error in the card layout, which renders no cells;
6946
+ * the thrown message names the card API.
6576
6947
  */
6577
6948
  getCellText(rowIndex: number, columnName: string): Promise<string>;
6578
6949
  /**
6579
6950
  * Gets all row texts as a 2D string array (data-column cells only).
6580
6951
  *
6581
6952
  * @returns Promise resolving to an array of row text arrays.
6953
+ * @throws Error in the card layout, which renders no rows; the thrown message names the card API.
6582
6954
  */
6583
6955
  getAllRowTexts(): Promise<string[][]>;
6584
6956
  /**
6585
6957
  * Clicks a sortable column header to cycle sort direction.
6586
6958
  *
6587
6959
  * @param columnName The column's data-column attribute value.
6960
+ * @throws Error in the card layout, which renders no column headers;
6961
+ * the thrown message names the card API.
6588
6962
  */
6589
6963
  clickSortHeader(columnName: string): Promise<void>;
6590
6964
  /**
@@ -6592,34 +6966,46 @@ declare class TnTableHarness extends ComponentHarness {
6592
6966
  *
6593
6967
  * @param columnName The column's data-column attribute value.
6594
6968
  * @returns Promise resolving to true if the column is sortable.
6969
+ * @throws Error in the card layout, which renders no column headers;
6970
+ * the thrown message names the card API.
6595
6971
  */
6596
6972
  isSortable(columnName: string): Promise<boolean>;
6597
6973
  /**
6598
6974
  * Gets the current sort direction for a column via aria-sort.
6599
6975
  *
6976
+ * `aria-sort="none"` — which a sortable-but-unsorted header now carries, so it is
6977
+ * discoverable as sortable — is normalised to null, keeping "not sorted" a single value
6978
+ * for callers. Only a non-sortable header has no attribute at all, and both answer null.
6979
+ *
6600
6980
  * @param columnName The column's data-column attribute value.
6601
6981
  * @returns Promise resolving to 'ascending', 'descending', or null.
6982
+ * @throws Error in the card layout, which renders no column headers;
6983
+ * the thrown message names the card API.
6602
6984
  */
6603
6985
  getSortDirection(columnName: string): Promise<string | null>;
6986
+ /** True when the container is narrow enough that card mode is rendered. */
6987
+ private isCards;
6604
6988
  /**
6605
- * Clicks the select-all checkbox in the header.
6989
+ * Clicks the select-all control — the header checkbox in table mode, the card
6990
+ * toolbar's "Select all" in card mode.
6606
6991
  */
6607
6992
  toggleSelectAll(): Promise<void>;
6608
6993
  /**
6609
- * Toggles selection for a specific row by clicking its checkbox cell.
6994
+ * Toggles selection for a specific row (or its card) by clicking its checkbox
6995
+ * wrapper.
6610
6996
  *
6611
6997
  * @param rowIndex Zero-based index of the data row.
6612
6998
  */
6613
6999
  toggleRowSelection(rowIndex: number): Promise<void>;
6614
7000
  /**
6615
- * Checks if a specific row's checkbox is checked.
7001
+ * Checks if a specific row (or its card) is selected.
6616
7002
  *
6617
7003
  * @param rowIndex Zero-based index of the data row.
6618
7004
  * @returns Promise resolving to true if the row's checkbox is checked.
6619
7005
  */
6620
7006
  isRowSelected(rowIndex: number): Promise<boolean>;
6621
7007
  /**
6622
- * Gets the count of currently selected rows.
7008
+ * Gets the count of currently selected rows, in either layout.
6623
7009
  *
6624
7010
  * @returns Promise resolving to the number of checked row checkboxes.
6625
7011
  */
@@ -6628,6 +7014,8 @@ declare class TnTableHarness extends ComponentHarness {
6628
7014
  * Clicks the expand button for a specific row.
6629
7015
  *
6630
7016
  * @param rowIndex Zero-based index of the data row.
7017
+ * @throws Error in the card layout — use `toggleCardDetail()`;
7018
+ * the thrown message names the card API.
6631
7019
  */
6632
7020
  toggleRowExpansion(rowIndex: number): Promise<void>;
6633
7021
  /**
@@ -6635,6 +7023,7 @@ declare class TnTableHarness extends ComponentHarness {
6635
7023
  *
6636
7024
  * @param rowIndex Zero-based index of the data row.
6637
7025
  * @returns Promise resolving to true if the row has the expanded class.
7026
+ * @throws Error in the card layout, which renders no rows; the thrown message names the card API.
6638
7027
  */
6639
7028
  isRowExpanded(rowIndex: number): Promise<boolean>;
6640
7029
  /**
@@ -6643,12 +7032,15 @@ declare class TnTableHarness extends ComponentHarness {
6643
7032
  *
6644
7033
  * @param rowIndex Zero-based index of the data row.
6645
7034
  * @returns Promise resolving to true if the row has an expand button.
7035
+ * @throws Error in the card layout, whose expand control is the card's Details button;
7036
+ * the thrown message names the card API.
6646
7037
  */
6647
7038
  hasExpandControl(rowIndex: number): Promise<boolean>;
6648
7039
  /**
6649
7040
  * Clicks a row (for tables with `clickable` enabled).
6650
7041
  *
6651
7042
  * @param rowIndex Zero-based index of the data row.
7043
+ * @throws Error in the card layout, which renders no rows; use {@link clickCard} there.
6652
7044
  */
6653
7045
  clickRow(rowIndex: number): Promise<void>;
6654
7046
  /**
@@ -6657,6 +7049,7 @@ declare class TnTableHarness extends ComponentHarness {
6657
7049
  * clicks first; this helper dispatches only the `dblclick` event.
6658
7050
  *
6659
7051
  * @param rowIndex Zero-based index of the data row.
7052
+ * @throws Error in the card layout, which renders no rows; use {@link doubleClickCard} there.
6660
7053
  */
6661
7054
  doubleClickRow(rowIndex: number): Promise<void>;
6662
7055
  /**
@@ -6664,12 +7057,14 @@ declare class TnTableHarness extends ComponentHarness {
6664
7057
  *
6665
7058
  * @param rowIndex Zero-based index of the data row.
6666
7059
  * @param key Which key to press — Enter or Space.
7060
+ * @throws Error in the card layout, which renders no rows; use {@link pressKeyOnCard} there.
6667
7061
  */
6668
7062
  pressKeyOnRow(rowIndex: number, key: 'enter' | 'space'): Promise<void>;
6669
7063
  /**
6670
7064
  * Checks if a row is keyboard-focusable (tabindex=0).
6671
7065
  *
6672
7066
  * @param rowIndex Zero-based index of the data row.
7067
+ * @throws Error in the card layout, which renders no rows; use {@link isCardFocusable} there.
6673
7068
  */
6674
7069
  isRowFocusable(rowIndex: number): Promise<boolean>;
6675
7070
  /**
@@ -6681,8 +7076,11 @@ declare class TnTableHarness extends ComponentHarness {
6681
7076
  /**
6682
7077
  * Checks if a data row is currently marked active.
6683
7078
  *
6684
- * @param rowIndex Zero-based index of the data row.
6685
- * @returns Promise resolving to true if the row has the active class.
7079
+ * Layout-aware: reads the card's active class in the card layout, which marks the same
7080
+ * state with `aria-current` rather than the row's `aria-selected`.
7081
+ *
7082
+ * @param rowIndex Zero-based index of the data row (or card).
7083
+ * @returns Promise resolving to true if the row — or card — has the active class.
6686
7084
  */
6687
7085
  isRowActive(rowIndex: number): Promise<boolean>;
6688
7086
  /**
@@ -6696,14 +7094,151 @@ declare class TnTableHarness extends ComponentHarness {
6696
7094
  *
6697
7095
  * @param detailIndex Zero-based index among currently visible detail rows.
6698
7096
  * @returns Promise resolving to the detail row text.
7097
+ * @throws Error in the card layout — use the card detail panel;
7098
+ * the thrown message names the card API.
6699
7099
  */
6700
7100
  getDetailRowContent(detailIndex: number): Promise<string>;
6701
7101
  /**
6702
7102
  * Gets the count of currently expanded detail rows.
6703
7103
  *
6704
- * @returns Promise resolving to the number of visible detail rows.
7104
+ * Layout-aware: counts open card detail panels in the card layout, which renders the same
7105
+ * expansion state without a detail `<tr>`.
7106
+ *
7107
+ * @returns Promise resolving to the number of visible detail rows, or open card detail
7108
+ * panels in the card layout.
6705
7109
  */
6706
7110
  getExpandedRowCount(): Promise<number>;
7111
+ /**
7112
+ * Reports the currently rendered layout: `cards` when the container is narrow
7113
+ * enough that `mobileLayout="cards"` has taken effect, otherwise `table`.
7114
+ *
7115
+ * @returns Promise resolving to 'cards' or 'table'.
7116
+ */
7117
+ getLayoutMode(): Promise<'cards' | 'table'>;
7118
+ /**
7119
+ * Gets the number of rendered cards (card layout only).
7120
+ *
7121
+ * @returns Promise resolving to the card count.
7122
+ */
7123
+ getCardCount(): Promise<number>;
7124
+ /**
7125
+ * Gets the title text of a card.
7126
+ *
7127
+ * @param cardIndex Zero-based index of the card.
7128
+ * @returns Promise resolving to the card title text.
7129
+ */
7130
+ getCardTitle(cardIndex: number): Promise<string>;
7131
+ /**
7132
+ * Gets the value text of a field within a card, by column name. The field
7133
+ * may be a primary field or one tucked under "More fields".
7134
+ *
7135
+ * @param cardIndex Zero-based index of the card.
7136
+ * @param columnName The column's data-column attribute value.
7137
+ * @returns Promise resolving to the field's value text.
7138
+ */
7139
+ getCardFieldValue(cardIndex: number, columnName: string): Promise<string>;
7140
+ /**
7141
+ * Gets the column names of the fields shown directly on a card (i.e. not
7142
+ * those hidden behind the "More fields" disclosure).
7143
+ *
7144
+ * @param cardIndex Zero-based index of the card.
7145
+ * @returns Promise resolving to an array of column names.
7146
+ */
7147
+ getCardPrimaryFieldColumns(cardIndex: number): Promise<string[]>;
7148
+ /**
7149
+ * Expands the "More fields" disclosure on a card to reveal lower-priority
7150
+ * fields. No-op if the card has no secondary fields.
7151
+ *
7152
+ * @param cardIndex Zero-based index of the card.
7153
+ */
7154
+ expandCardMoreFields(cardIndex: number): Promise<void>;
7155
+ /**
7156
+ * Toggles a card's detail section (card layout equivalent of row expansion).
7157
+ *
7158
+ * @param cardIndex Zero-based index of the card.
7159
+ */
7160
+ toggleCardDetail(cardIndex: number): Promise<void>;
7161
+ /**
7162
+ * Gets the currently selected sort column in the card-layout sort menu, or
7163
+ * `''` when unsorted. Returns null if the sort menu isn't rendered.
7164
+ *
7165
+ * @returns Promise resolving to the selected column name, '', or null.
7166
+ */
7167
+ getCardSortColumn(): Promise<string | null>;
7168
+ /**
7169
+ * Gets the active sort direction in the card layout, read from the direction toggle's
7170
+ * `data-sort-direction`. Deliberately not derived from the button's `aria-label`: matching
7171
+ * display text would silently report one direction forever if the wording or locale changed.
7172
+ *
7173
+ * @returns Promise resolving to 'asc' or 'desc'; `''` both when sorted by nothing and when the
7174
+ * active column isn't sortable (the toggle isn't rendered in either case, and this reads the
7175
+ * rendered control — so a non-sortable active column reports `''` even though the component's
7176
+ * `sortDirection()` holds a value); or null when the card sort menu isn't rendered at all
7177
+ * (table layout, or no sortable columns) — the same null-vs-empty distinction
7178
+ * {@link getCardSortColumn} makes.
7179
+ */
7180
+ getCardSortDirection(): Promise<'asc' | 'desc' | '' | null>;
7181
+ /**
7182
+ * Clicks the sort-direction toggle in the card-layout sort menu. No-op when the toggle
7183
+ * isn't rendered, which is three cases: the table layout is showing (the whole card sort
7184
+ * menu is absent — so a call made before the container narrowed does nothing and reports
7185
+ * success), no active sort column, or an active column that isn't `sortable()` — card mode
7186
+ * deliberately declines to reorder by a column whose table header ignores clicks.
7187
+ */
7188
+ toggleCardSortDirection(): Promise<void>;
7189
+ /**
7190
+ * Clicks a card body (card mirror of {@link clickRow}, for tables with `clickable`).
7191
+ *
7192
+ * Targets the card's title rather than the card box, because the card box's centre can sit
7193
+ * on a projected row action or the selection checkbox, and the activation guard ignores
7194
+ * clicks that originate on a control — the click would land and nothing would happen.
7195
+ *
7196
+ * @param cardIndex Zero-based index of the card.
7197
+ * @throws Error in the table layout; use {@link clickRow} there.
7198
+ */
7199
+ clickCard(cardIndex: number): Promise<void>;
7200
+ /**
7201
+ * Double-clicks a card, triggering `rowDoubleClick` (card mirror of
7202
+ * {@link doubleClickRow}). As there, only the `dblclick` event is dispatched — a real
7203
+ * double-click also fires two single clicks first.
7204
+ *
7205
+ * Dispatched on the card rather than on the title {@link clickCard} aims at, because a
7206
+ * synthesised event does not bubble: sent to the title it would never reach the card's
7207
+ * handler. There is no cost to it here — the target is set explicitly, so unlike a real
7208
+ * pointer click it cannot land on a projected control.
7209
+ *
7210
+ * @param cardIndex Zero-based index of the card.
7211
+ * @throws Error in the table layout; use {@link doubleClickRow} there.
7212
+ */
7213
+ doubleClickCard(cardIndex: number): Promise<void>;
7214
+ /**
7215
+ * Sends a keyboard event to a card (Enter/Space activate clickable cards). Card mirror of
7216
+ * {@link pressKeyOnRow}; the key goes to the card itself, which is the element that carries
7217
+ * `tabindex` and the keydown handler.
7218
+ *
7219
+ * @param cardIndex Zero-based index of the card.
7220
+ * @param key Which key to press — Enter or Space.
7221
+ * @throws Error in the table layout; use {@link pressKeyOnRow} there.
7222
+ */
7223
+ pressKeyOnCard(cardIndex: number, key: 'enter' | 'space'): Promise<void>;
7224
+ /**
7225
+ * Checks if a card is keyboard-focusable (tabindex=0). Card mirror of
7226
+ * {@link isRowFocusable}.
7227
+ *
7228
+ * @param cardIndex Zero-based index of the card.
7229
+ * @throws Error in the table layout; use {@link isRowFocusable} there.
7230
+ */
7231
+ isCardFocusable(cardIndex: number): Promise<boolean>;
7232
+ /** The card box itself — the element carrying `tabindex`, the handlers and the ARIA state. */
7233
+ private cardAt;
7234
+ /** The surface pointer activation is aimed at — see {@link clickCard} for why not the card. */
7235
+ private cardActivationTarget;
7236
+ /**
7237
+ * Bounds check for the layout-aware methods. Counts whatever the rendered layout shows, via
7238
+ * `getRowCount()` — unlike {@link assertRowExists}, which deliberately counts rows only,
7239
+ * because its callers refuse card mode outright.
7240
+ */
7241
+ private assertIndexExists;
6707
7242
  private assertRowExists;
6708
7243
  }
6709
7244
  /**
@@ -6712,6 +7247,47 @@ declare class TnTableHarness extends ComponentHarness {
6712
7247
  interface TnTableHarnessFilters extends BaseHarnessFilters {
6713
7248
  }
6714
7249
 
7250
+ /**
7251
+ * Testing utilities for `tn-table`'s container-driven responsive layout.
7252
+ *
7253
+ * Part of the public API because `TnTableHarness`'s layout-mismatch messages tell the caller
7254
+ * to widen or narrow the container past `cardBreakpoint`, and jsdom implements no
7255
+ * `ResizeObserver` — so without a stand-in a consumer's own spec has no supported way to
7256
+ * follow that advice.
7257
+ *
7258
+ * Namespaced rather than exported as loose functions, matching `TnIconTesting` and
7259
+ * `TnToastTesting`: these names live at the top level of the package, and `installObserver`
7260
+ * or `emitContainerWidth` on their own give no hint that they concern tables.
7261
+ *
7262
+ * @example
7263
+ * ```typescript
7264
+ * let restoreResizeObserver: () => void;
7265
+ *
7266
+ * beforeEach(() => { restoreResizeObserver = TnTableTesting.installResizeObserver(); });
7267
+ * afterEach(() => { restoreResizeObserver(); });
7268
+ *
7269
+ * // ...then, inside a test:
7270
+ * TnTableTesting.emitContainerWidth(320);
7271
+ * fixture.detectChanges();
7272
+ * ```
7273
+ */
7274
+ declare const TnTableTesting: {
7275
+ /**
7276
+ * Swaps `globalThis.ResizeObserver` for a stand-in and clears any instances left by a
7277
+ * previous test.
7278
+ *
7279
+ * @returns A function that restores the original global — call it in `afterEach`.
7280
+ */
7281
+ installResizeObserver(): () => void;
7282
+ /**
7283
+ * Pushes `width` through every observer the component under test registered, as its
7284
+ * content-box width — the same quantity `measureContainer` reads on the initial pass.
7285
+ *
7286
+ * @param width Content-box width in px. A 0 reads as unmeasurable, not narrow.
7287
+ */
7288
+ emitContainerWidth(width: number): void;
7289
+ };
7290
+
6715
7291
  /**
6716
7292
  * Default labels rendered inside `tn-table-pager`. Consumers can override any
6717
7293
  * subset of these at the app root by providing a value for the
@@ -11362,5 +11938,5 @@ declare const TN_THEME_DEFINITIONS: readonly TnThemeDefinition[];
11362
11938
  */
11363
11939
  declare const THEME_MAP: Map<TnTheme, TnThemeDefinition>;
11364
11940
 
11365
- export { CommonShortcuts, DEFAULT_THEME, DiskIconComponent, DiskType, FileSizePipe, InputType, LIGHT_THEME, LabelMarkupPipe, LabelTextPipe, LinuxModifierKeys, LinuxShortcuts, ModifierKeys, QuickShortcuts, ShortcutBuilder, THEME_MAP, THEME_STORAGE_KEY, TN_CALENDAR_INTL, TN_CALENDAR_INTL_DEFAULTS, TN_FORM_FIELD_CONTEXT, TN_FORM_FIELD_ERRORS, TN_RADIO_GROUP, TN_TABLE_PAGER_DEFAULT_LABELS, TN_TABLE_PAGER_LABELS, TN_TEST_ATTR, TN_THEME_DEFINITIONS, TnAutocompleteComponent, TnAutocompleteHarness, TnBannerActionDirective, TnBannerComponent, TnBannerHarness, TnBrandedSpinnerComponent, TnButtonComponent, TnButtonHarness, TnButtonToggleComponent, TnButtonToggleGroupComponent, TnButtonToggleGroupHarness, TnButtonToggleHarness, TnCalendarCellHarness, TnCalendarComponent, TnCalendarHarness, TnCalendarHeaderComponent, TnCardComponent, TnCardFooterActionsDirective, TnCardHeaderActionsDirective, TnCardHeaderDirective, TnCellDefDirective, TnCheckboxComponent, TnCheckboxHarness, TnCheckboxLabelDirective, TnChipComponent, TnChipHarness, TnChipInputComponent, TnChipInputHarness, TnConfirmDialogComponent, TnDateInputComponent, TnDateInputHarness, TnDateRangeInputComponent, TnDateRangeInputHarness, TnDetailRowDefDirective, TnDialog, TnDialogHarness, TnDialogShellComponent, TnDialogTesting, TnDividerComponent, TnDividerDirective, TnDrawerComponent, TnDrawerContainerComponent, TnDrawerContainerHarness, TnDrawerContentComponent, TnDrawerHarness, TnEmptyComponent, TnEmptyHarness, TnExpansionPanelComponent, TnExpansionPanelHarness, TnFileInputComponent, TnFileInputHarness, TnFilePickerComponent, TnFilePickerHarness, TnFilePickerPopupComponent, TnFormFieldComponent, TnFormFieldHarness, TnFormSectionComponent, TnFormSectionHarness, TnHeaderCellDefDirective, TnIconButtonComponent, TnIconButtonHarness, TnIconComponent, TnIconHarness, TnIconRegistryService, TnIconTesting, TnInputComponent, TnInputDirective, TnInputHarness, TnKeyboardShortcutComponent, TnKeyboardShortcutService, TnListAvatarDirective, TnListComponent, TnListIconDirective, TnListItemComponent, TnListItemLineDirective, TnListItemPrimaryDirective, TnListItemSecondaryDirective, TnListItemTitleDirective, TnListItemTrailingDirective, TnListOptionComponent, TnListSubheaderComponent, TnMenuActivateHoverDirective, TnMenuComponent, TnMenuHarness, TnMenuItemComponent, TnMenuTesting, TnMenuTriggerDirective, TnMonthViewComponent, TnMultiYearViewComponent, TnNestedTreeDataSource, TnNestedTreeNodeComponent, TnParticleProgressBarComponent, TnProgressBarComponent, TnRadioComponent, TnRadioGroupComponent, TnRadioGroupHarness, TnRadioHarness, TnSelectComponent, TnSelectHarness, TnSelectionListComponent, TnSidePanelActionDirective, TnSidePanelComponent, TnSidePanelHarness, TnSidePanelHeaderActionDirective, TnSlideToggleComponent, TnSlideToggleHarness, TnSliderComponent, TnSliderThumbDirective, TnSliderWithLabelDirective, TnSpinnerComponent, TnSpriteLoaderService, TnStepComponent, TnStepperComponent, TnStepperHarness, TnStepperNextDirective, TnStepperPreviousDirective, TnTabComponent, TnTabHarness, TnTabPanelComponent, TnTabPanelHarness, TnTableColumnDirective, TnTableComponent, TnTableHarness, TnTablePagerComponent, TnTablePagerHarness, TnTabsComponent, TnTabsHarness, TnTestIdDirective, TnTheme, TnThemeService, TnTimeInputComponent, TnToastComponent, TnToastMock, TnToastPosition, TnToastRef, TnToastService, TnToastTesting, TnToastType, TnTooltipComponent, TnTooltipDirective, TnTreeComponent, TnTreeFlatDataSource, TnTreeFlattener, TnTreeHarness, TnTreeNodeComponent, TnTreeNodeHarness, TnTreeNodeOutletDirective, TnTreeVirtualScrollNodeOutletDirective, TnTreeVirtualScrollViewComponent, TnTreeVirtualScrollViewHarness, TruncatePathPipe, WindowsModifierKeys, WindowsShortcuts, allowsCurrentDirectorySelection, composeTestId, controlTestId, createFlatTreeControl, createLucideLibrary, createNestedTreeControl, createShortcut, defaultSpriteBasePath, defaultSpriteConfigPath, defaultTreeItemSize, formatSize, getSelectableTypes, injectTnCalendarIntl, injectTnFormFieldAria, isPathWithinRoot, kebabTestSegment, labelMarkupToHtml, labelMarkupToText, libIconMarker, normalizeRootPath, optionTestId, parseLabelMarkup, parseSize, registerLucideIcons, scopeTestId, setupLucideIntegration, tnIconMarker, writeTestId };
11366
- export type { AutocompleteHarnessFilters, BannerHarnessFilters, ButtonHarnessFilters, ButtonToggleHarnessFilters, CalendarCell, CalendarCellFill, CalendarCellHarnessFilters, CalendarHarnessFilters, CheckboxHarnessFilters, ChipColor, ChipHarnessFilters, DateInputHarnessFilters, DateRange, DateRangeInputHarnessFilters, DialogHarnessFilters, EmptyHarnessFilters, ExpansionPanelHarnessFilters, FileInputHarnessFilters, FilePickerCallbacks, FilePickerCreateAction, FilePickerCreateActionEvent, FilePickerError, FilePickerHarnessFilters, FilePickerMode, FileSystemItem, FileSystemItemType, FlatTreeControlOptions, FormFieldHarnessFilters, FormSectionHarnessFilters, IconButtonHarnessFilters, IconHarnessFilters, IconLibrary, IconLibraryType, IconResult, IconSize, IconSource, IconTestingMockOverrides, InputHarnessFilters, KeyCombination, LabelMarkupSegment, LabelMarkupSegmentType, LabelType, LucideIconOptions, MenuHarnessFilters, MockIconRegistry, MockSpriteLoader, NestedTreeControlOptions, PathSegment, PlatformType, ProgressBarMode, RadioGroupHarnessFilters, RadioHarnessFilters, ResolvedIcon, SelectHarnessFilters, ShortcutHandler, SidePanelHarnessFilters, SizeStandard, SlideToggleColor, SlideToggleHarnessFilters, SpinnerMode, SpriteConfig, StepperHarnessFilters, SubscriptSizing, TabChangeEvent, TabHarnessFilters, TabPanelHarnessFilters, TabsHarnessFilters, TnAutocompleteOption, TnBannerType, TnButtonToggleType, TnCalendarIntl, TnCalendarIntlInput, TnCalendarView, TnCardAction, TnCardControl, TnCardFooterLink, TnCardHeaderStatus, TnChipInputHarnessFilters, TnChipInputOption, TnConfirmDialogData, TnDialogDefaults, TnDialogOpenTarget, TnDrawerMode, TnDrawerPosition, TnEmptySize, TnFlatTreeNode, TnFormFieldAriaBindings, TnFormFieldContext, TnFormFieldErrorMessage, TnFormFieldErrorMessages, TnFormFieldErrorResolver, TnMenuItem, TnOptionTestIdSource, TnRadioGroupApi, TnRadioOption, TnSelectOption, TnSelectOptionGroup, TnSelectionChange, TnSortEvent, TnTableDataProvider, TnTableDataSource, TnTableHarnessFilters, TnTablePagerHarnessFilters, TnTablePagerLabels, TnTablePagination, TnTestAttrName, TnTestIdValue, TnThemeDefinition, TnToastCall, TnToastConfig, TnTreeExpansion, TnTreeHarnessFilters, TnTreeNodeHarnessFilters, TnTreeVirtualNodeData, TnTreeVirtualScrollViewHarnessFilters, TooltipPosition, YearCell };
11941
+ export { CommonShortcuts, DEFAULT_THEME, DiskIconComponent, DiskType, FileSizePipe, InputType, LIGHT_THEME, LabelMarkupPipe, LabelTextPipe, LinuxModifierKeys, LinuxShortcuts, ModifierKeys, QuickShortcuts, ShortcutBuilder, THEME_MAP, THEME_STORAGE_KEY, TN_CALENDAR_INTL, TN_CALENDAR_INTL_DEFAULTS, TN_FORM_FIELD_CONTEXT, TN_FORM_FIELD_ERRORS, TN_RADIO_GROUP, TN_TABLE_PAGER_DEFAULT_LABELS, TN_TABLE_PAGER_LABELS, TN_TEST_ATTR, TN_THEME_DEFINITIONS, TnAutocompleteComponent, TnAutocompleteHarness, TnBannerActionDirective, TnBannerComponent, TnBannerHarness, TnBrandedSpinnerComponent, TnButtonComponent, TnButtonHarness, TnButtonToggleComponent, TnButtonToggleGroupComponent, TnButtonToggleGroupHarness, TnButtonToggleHarness, TnCalendarCellHarness, TnCalendarComponent, TnCalendarHarness, TnCalendarHeaderComponent, TnCardComponent, TnCardFooterActionsDirective, TnCardHeaderActionsDirective, TnCardHeaderDirective, TnCellDefDirective, TnCheckboxComponent, TnCheckboxHarness, TnCheckboxLabelDirective, TnChipComponent, TnChipHarness, TnChipInputComponent, TnChipInputHarness, TnConfirmDialogComponent, TnDateInputComponent, TnDateInputHarness, TnDateRangeInputComponent, TnDateRangeInputHarness, TnDetailRowDefDirective, TnDialog, TnDialogHarness, TnDialogShellComponent, TnDialogTesting, TnDividerComponent, TnDividerDirective, TnDrawerComponent, TnDrawerContainerComponent, TnDrawerContainerHarness, TnDrawerContentComponent, TnDrawerHarness, TnEmptyComponent, TnEmptyHarness, TnExpansionPanelComponent, TnExpansionPanelHarness, TnFileInputComponent, TnFileInputHarness, TnFilePickerComponent, TnFilePickerHarness, TnFilePickerPopupComponent, TnFormFieldComponent, TnFormFieldHarness, TnFormSectionComponent, TnFormSectionHarness, TnHeaderCellDefDirective, TnIconButtonComponent, TnIconButtonHarness, TnIconComponent, TnIconHarness, TnIconRegistryService, TnIconTesting, TnInputComponent, TnInputDirective, TnInputHarness, TnKeyboardShortcutComponent, TnKeyboardShortcutService, TnListAvatarDirective, TnListComponent, TnListIconDirective, TnListItemComponent, TnListItemLineDirective, TnListItemPrimaryDirective, TnListItemSecondaryDirective, TnListItemTitleDirective, TnListItemTrailingDirective, TnListOptionComponent, TnListSubheaderComponent, TnMenuActivateHoverDirective, TnMenuComponent, TnMenuHarness, TnMenuItemComponent, TnMenuTesting, TnMenuTriggerDirective, TnMonthViewComponent, TnMultiYearViewComponent, TnNestedTreeDataSource, TnNestedTreeNodeComponent, TnParticleProgressBarComponent, TnProgressBarComponent, TnRadioComponent, TnRadioGroupComponent, TnRadioGroupHarness, TnRadioHarness, TnRowActionsDefDirective, TnSelectComponent, TnSelectHarness, TnSelectionListComponent, TnSidePanelActionDirective, TnSidePanelComponent, TnSidePanelHarness, TnSidePanelHeaderActionDirective, TnSlideToggleComponent, TnSlideToggleHarness, TnSliderComponent, TnSliderThumbDirective, TnSliderWithLabelDirective, TnSpinnerComponent, TnSpriteLoaderService, TnStepComponent, TnStepperComponent, TnStepperHarness, TnStepperNextDirective, TnStepperPreviousDirective, TnTabComponent, TnTabHarness, TnTabPanelComponent, TnTabPanelHarness, TnTableColumnDirective, TnTableComponent, TnTableHarness, TnTablePagerComponent, TnTablePagerHarness, TnTableTesting, TnTabsComponent, TnTabsHarness, TnTestIdDirective, TnTheme, TnThemeService, TnTimeInputComponent, TnToastComponent, TnToastMock, TnToastPosition, TnToastRef, TnToastService, TnToastTesting, TnToastType, TnTooltipComponent, TnTooltipDirective, TnTreeComponent, TnTreeFlatDataSource, TnTreeFlattener, TnTreeHarness, TnTreeNodeComponent, TnTreeNodeHarness, TnTreeNodeOutletDirective, TnTreeVirtualScrollNodeOutletDirective, TnTreeVirtualScrollViewComponent, TnTreeVirtualScrollViewHarness, TruncatePathPipe, WindowsModifierKeys, WindowsShortcuts, allowsCurrentDirectorySelection, composeTestId, controlTestId, createFlatTreeControl, createLucideLibrary, createNestedTreeControl, createShortcut, defaultSpriteBasePath, defaultSpriteConfigPath, defaultTreeItemSize, formatSize, getSelectableTypes, injectTnCalendarIntl, injectTnFormFieldAria, isPathWithinRoot, kebabTestSegment, labelMarkupToHtml, labelMarkupToText, libIconMarker, normalizeRootPath, optionTestId, parseLabelMarkup, parseSize, registerLucideIcons, scopeTestId, setupLucideIntegration, tnIconMarker, writeTestId };
11942
+ export type { AutocompleteHarnessFilters, BannerHarnessFilters, ButtonHarnessFilters, ButtonToggleHarnessFilters, CalendarCell, CalendarCellFill, CalendarCellHarnessFilters, CalendarHarnessFilters, CheckboxHarnessFilters, ChipColor, ChipHarnessFilters, DateInputHarnessFilters, DateRange, DateRangeInputHarnessFilters, DialogHarnessFilters, EmptyHarnessFilters, ExpansionPanelHarnessFilters, FileInputHarnessFilters, FilePickerCallbacks, FilePickerCreateAction, FilePickerCreateActionEvent, FilePickerError, FilePickerHarnessFilters, FilePickerMode, FileSystemItem, FileSystemItemType, FlatTreeControlOptions, FormFieldHarnessFilters, FormSectionHarnessFilters, IconButtonHarnessFilters, IconHarnessFilters, IconLibrary, IconLibraryType, IconResult, IconSize, IconSource, IconTestingMockOverrides, InputHarnessFilters, KeyCombination, LabelMarkupSegment, LabelMarkupSegmentType, LabelType, LucideIconOptions, MenuHarnessFilters, MockIconRegistry, MockSpriteLoader, NestedTreeControlOptions, PathSegment, PlatformType, ProgressBarMode, RadioGroupHarnessFilters, RadioHarnessFilters, ResolvedIcon, SelectHarnessFilters, ShortcutHandler, SidePanelHarnessFilters, SizeStandard, SlideToggleColor, SlideToggleHarnessFilters, SpinnerMode, SpriteConfig, StepperHarnessFilters, SubscriptSizing, TabChangeEvent, TabHarnessFilters, TabPanelHarnessFilters, TabsHarnessFilters, TnAutocompleteOption, TnBannerType, TnButtonToggleType, TnCalendarIntl, TnCalendarIntlInput, TnCalendarView, TnCardAction, TnCardControl, TnCardFooterLink, TnCardHeaderStatus, TnChipInputHarnessFilters, TnChipInputOption, TnConfirmDialogData, TnDialogDefaults, TnDialogOpenTarget, TnDrawerMode, TnDrawerPosition, TnEmptySize, TnFlatTreeNode, TnFormFieldAriaBindings, TnFormFieldContext, TnFormFieldErrorMessage, TnFormFieldErrorMessages, TnFormFieldErrorResolver, TnMenuItem, TnOptionTestIdSource, TnRadioGroupApi, TnRadioOption, TnSelectOption, TnSelectOptionGroup, TnSelectionChange, TnSortEvent, TnTableDataProvider, TnTableDataSource, TnTableHarnessFilters, TnTableMobileLayout, TnTablePagerHarnessFilters, TnTablePagerLabels, TnTablePagination, TnTestAttrName, TnTestIdValue, TnThemeDefinition, TnToastCall, TnToastConfig, TnTreeExpansion, TnTreeHarnessFilters, TnTreeNodeHarnessFilters, TnTreeVirtualNodeData, TnTreeVirtualScrollViewHarnessFilters, TooltipPosition, YearCell };