@lifecorner/angular-ui-kit 3.5.1 → 3.6.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.
Files changed (84) hide show
  1. package/README.md +2 -1
  2. package/fesm2022/lifecorner-angular-ui-kit-accordion.mjs +4 -1
  3. package/fesm2022/lifecorner-angular-ui-kit-accordion.mjs.map +1 -1
  4. package/fesm2022/lifecorner-angular-ui-kit-alert.mjs +16 -1
  5. package/fesm2022/lifecorner-angular-ui-kit-alert.mjs.map +1 -1
  6. package/fesm2022/lifecorner-angular-ui-kit-bottom-nav.mjs +4 -1
  7. package/fesm2022/lifecorner-angular-ui-kit-bottom-nav.mjs.map +1 -1
  8. package/fesm2022/lifecorner-angular-ui-kit-button.mjs +4 -4
  9. package/fesm2022/lifecorner-angular-ui-kit-button.mjs.map +1 -1
  10. package/fesm2022/lifecorner-angular-ui-kit-callout.mjs +16 -1
  11. package/fesm2022/lifecorner-angular-ui-kit-callout.mjs.map +1 -1
  12. package/fesm2022/lifecorner-angular-ui-kit-chat.mjs +14 -1
  13. package/fesm2022/lifecorner-angular-ui-kit-chat.mjs.map +1 -1
  14. package/fesm2022/lifecorner-angular-ui-kit-code-block.mjs +4 -1
  15. package/fesm2022/lifecorner-angular-ui-kit-code-block.mjs.map +1 -1
  16. package/fesm2022/lifecorner-angular-ui-kit-combobox.mjs +4 -1
  17. package/fesm2022/lifecorner-angular-ui-kit-combobox.mjs.map +1 -1
  18. package/fesm2022/lifecorner-angular-ui-kit-confirm-dialog.mjs +4 -1
  19. package/fesm2022/lifecorner-angular-ui-kit-confirm-dialog.mjs.map +1 -1
  20. package/fesm2022/lifecorner-angular-ui-kit-copy-field.mjs +4 -1
  21. package/fesm2022/lifecorner-angular-ui-kit-copy-field.mjs.map +1 -1
  22. package/fesm2022/lifecorner-angular-ui-kit-date-range-picker.mjs +4 -1
  23. package/fesm2022/lifecorner-angular-ui-kit-date-range-picker.mjs.map +1 -1
  24. package/fesm2022/lifecorner-angular-ui-kit-document-viewer.mjs +14 -1
  25. package/fesm2022/lifecorner-angular-ui-kit-document-viewer.mjs.map +1 -1
  26. package/fesm2022/lifecorner-angular-ui-kit-drawer.mjs +4 -1
  27. package/fesm2022/lifecorner-angular-ui-kit-drawer.mjs.map +1 -1
  28. package/fesm2022/lifecorner-angular-ui-kit-email-input.mjs +4 -0
  29. package/fesm2022/lifecorner-angular-ui-kit-email-input.mjs.map +1 -1
  30. package/fesm2022/lifecorner-angular-ui-kit-file-upload.mjs +4 -1
  31. package/fesm2022/lifecorner-angular-ui-kit-file-upload.mjs.map +1 -1
  32. package/fesm2022/lifecorner-angular-ui-kit-footer.mjs +4 -1
  33. package/fesm2022/lifecorner-angular-ui-kit-footer.mjs.map +1 -1
  34. package/fesm2022/lifecorner-angular-ui-kit-gallery.mjs +14 -1
  35. package/fesm2022/lifecorner-angular-ui-kit-gallery.mjs.map +1 -1
  36. package/fesm2022/lifecorner-angular-ui-kit-header.mjs +18 -1
  37. package/fesm2022/lifecorner-angular-ui-kit-header.mjs.map +1 -1
  38. package/fesm2022/lifecorner-angular-ui-kit-icon.mjs +186 -275
  39. package/fesm2022/lifecorner-angular-ui-kit-icon.mjs.map +1 -1
  40. package/fesm2022/lifecorner-angular-ui-kit-icons.mjs +803 -0
  41. package/fesm2022/lifecorner-angular-ui-kit-icons.mjs.map +1 -0
  42. package/fesm2022/lifecorner-angular-ui-kit-internal-icon-set.mjs +297 -0
  43. package/fesm2022/lifecorner-angular-ui-kit-internal-icon-set.mjs.map +1 -0
  44. package/fesm2022/lifecorner-angular-ui-kit-internal-navigation.mjs +38 -0
  45. package/fesm2022/lifecorner-angular-ui-kit-internal-navigation.mjs.map +1 -0
  46. package/fesm2022/lifecorner-angular-ui-kit-kanban-board.mjs +4 -1
  47. package/fesm2022/lifecorner-angular-ui-kit-kanban-board.mjs.map +1 -1
  48. package/fesm2022/lifecorner-angular-ui-kit-log-viewer.mjs +4 -1
  49. package/fesm2022/lifecorner-angular-ui-kit-log-viewer.mjs.map +1 -1
  50. package/fesm2022/lifecorner-angular-ui-kit-modal.mjs +4 -1
  51. package/fesm2022/lifecorner-angular-ui-kit-modal.mjs.map +1 -1
  52. package/fesm2022/lifecorner-angular-ui-kit-next-step-card.mjs +12 -1
  53. package/fesm2022/lifecorner-angular-ui-kit-next-step-card.mjs.map +1 -1
  54. package/fesm2022/lifecorner-angular-ui-kit-notification-center.mjs +14 -1
  55. package/fesm2022/lifecorner-angular-ui-kit-notification-center.mjs.map +1 -1
  56. package/fesm2022/lifecorner-angular-ui-kit-number-input.mjs +4 -1
  57. package/fesm2022/lifecorner-angular-ui-kit-number-input.mjs.map +1 -1
  58. package/fesm2022/lifecorner-angular-ui-kit-password-input.mjs +4 -1
  59. package/fesm2022/lifecorner-angular-ui-kit-password-input.mjs.map +1 -1
  60. package/fesm2022/lifecorner-angular-ui-kit-pipeline.mjs +12 -1
  61. package/fesm2022/lifecorner-angular-ui-kit-pipeline.mjs.map +1 -1
  62. package/fesm2022/lifecorner-angular-ui-kit-rating.mjs +4 -1
  63. package/fesm2022/lifecorner-angular-ui-kit-rating.mjs.map +1 -1
  64. package/fesm2022/lifecorner-angular-ui-kit-search-input.mjs +4 -1
  65. package/fesm2022/lifecorner-angular-ui-kit-search-input.mjs.map +1 -1
  66. package/fesm2022/lifecorner-angular-ui-kit-sidenav-placeholder.mjs +262 -0
  67. package/fesm2022/lifecorner-angular-ui-kit-sidenav-placeholder.mjs.map +1 -0
  68. package/fesm2022/lifecorner-angular-ui-kit-sidenav.mjs +18 -40
  69. package/fesm2022/lifecorner-angular-ui-kit-sidenav.mjs.map +1 -1
  70. package/fesm2022/lifecorner-angular-ui-kit-table.mjs +4 -1
  71. package/fesm2022/lifecorner-angular-ui-kit-table.mjs.map +1 -1
  72. package/fesm2022/lifecorner-angular-ui-kit-toast.mjs +16 -1
  73. package/fesm2022/lifecorner-angular-ui-kit-toast.mjs.map +1 -1
  74. package/fesm2022/lifecorner-angular-ui-kit-tree-view.mjs +18 -1
  75. package/fesm2022/lifecorner-angular-ui-kit-tree-view.mjs.map +1 -1
  76. package/fesm2022/lifecorner-angular-ui-kit.mjs +2 -0
  77. package/package.json +17 -1
  78. package/types/lifecorner-angular-ui-kit-icon.d.ts +125 -5
  79. package/types/lifecorner-angular-ui-kit-icons.d.ts +140 -0
  80. package/types/lifecorner-angular-ui-kit-internal-icon-set.d.ts +31 -0
  81. package/types/lifecorner-angular-ui-kit-internal-navigation.d.ts +28 -0
  82. package/types/lifecorner-angular-ui-kit-sidenav-placeholder.d.ts +163 -0
  83. package/types/lifecorner-angular-ui-kit-sidenav.d.ts +2 -1
  84. package/types/lifecorner-angular-ui-kit.d.ts +2 -0
@@ -1 +1 @@
1
- {"version":3,"file":"lifecorner-angular-ui-kit-table.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/table/table-cell.directive.ts","../../../../libs/angular-ui-kit/src/lib/table/table.component.ts","../../../../libs/angular-ui-kit/src/lib/table/table.component.html"],"sourcesContent":["import { Directive, input, TemplateRef, inject } from '@angular/core';\n\n/**\n * Directive for defining custom cell templates in the Table component.\n *\n * @example\n * ```html\n * <lc-table [columns]=\"columns\" [data]=\"data\">\n * <ng-template lcTableCell=\"status\" let-row>\n * <lc-badge [variant]=\"row.status\">{{ row.status }}</lc-badge>\n * </ng-template>\n * </lc-table>\n * ```\n */\n@Directive({\n selector: '[lcTableCell]',\n standalone: true,\n})\nexport class TableCellDirective {\n /** The column key this template applies to */\n readonly columnKey = input('', { alias: 'lcTableCell' });\n\n public template = inject(TemplateRef<{ $implicit: Record<string, unknown> }>);\n}\n","import {\n Component,\n ChangeDetectionStrategy,\n ElementRef,\n input,\n output,\n computed,\n signal,\n linkedSignal,\n viewChild,\n viewChildren,\n afterRenderEffect,\n ContentChildren,\n QueryList,\n} from '@angular/core';\nimport { NgStyle, NgTemplateOutlet } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { TableCellDirective } from './table-cell.directive';\nimport { InputComponent } from '@lifecorner/angular-ui-kit/input';\nimport { SelectComponent } from '@lifecorner/angular-ui-kit/select';\nimport { ButtonComponent, ButtonVariant } from '@lifecorner/angular-ui-kit/button';\nimport { IconComponent } from '@lifecorner/angular-ui-kit/icon';\n\ntype TableCellClass = string | ((\n value: unknown,\n row: Record<string, unknown>,\n column: TableColumn,\n rowIndex: number\n) => string);\n\ntype TableCellStyle = Record<string, string> | ((\n value: unknown,\n row: Record<string, unknown>,\n column: TableColumn,\n rowIndex: number\n) => Record<string, string>);\n\nexport interface TableColumn {\n key: string;\n label: string;\n sortable?: boolean;\n filterable?: boolean;\n editable?: boolean;\n width?: string;\n /** Optional CSS class(es) applied to both th and td cells */\n cssClass?: string;\n /** Optional CSS class(es) for td cells only (string or resolver callback) */\n cellClass?: TableCellClass;\n /** Optional inline styles for td cells only (object or resolver callback) */\n cellStyle?: TableCellStyle;\n /** Optional tooltip shown on hover over the column header */\n tooltip?: string;\n /** Optional formatter for cell output when no custom template is used */\n formatter?: (\n value: unknown,\n row: Record<string, unknown>,\n column: TableColumn,\n rowIndex: number\n ) => unknown;\n /** Input type for inline editing (default: text) */\n editType?: 'text' | 'number' | 'select';\n /** Options for select edit type */\n editOptions?: string[];\n}\n\n/**\n * A row-level action rendered in the table's actions column (e.g. Freigeben, Ablehnen).\n * Action button clicks never trigger the row's `rowClick` output.\n */\nexport interface TableAction {\n /** Unique identifier emitted with the {@link ActionClickEvent} */\n key: string;\n /** Visible button label (omit for icon-only buttons when an `icon` is set) */\n label?: string;\n /** Optional icon name rendered before the label */\n icon?: string;\n /** Button variant (default: 'ghost') */\n variant?: ButtonVariant;\n /** Optional tooltip / aria-label, useful for icon-only actions */\n tooltip?: string;\n /** Hide this action for specific rows */\n hidden?: (row: Record<string, unknown>, rowIndex: number) => boolean;\n /** Disable this action for specific rows */\n disabled?: (row: Record<string, unknown>, rowIndex: number) => boolean;\n}\n\nexport type TableActionsAlign = 'start' | 'center' | 'end';\n\nexport interface ActionClickEvent {\n action: string;\n row: Record<string, unknown>;\n rowIndex: number;\n}\n\nexport interface SortEvent {\n column: string;\n direction: 'asc' | 'desc';\n}\n\nexport interface CellEditEvent {\n row: Record<string, unknown>;\n column: string;\n oldValue: unknown;\n newValue: unknown;\n /** Index of `row` in the `data` input (not its position on screen). */\n rowIndex: number;\n}\n\nexport interface SelectionChangeEvent {\n selected: Record<string, unknown>[];\n allSelected: boolean;\n}\n\n/** Emitted when a parent (group) row is expanded or collapsed in tree mode. */\nexport interface RowToggleEvent {\n id: string;\n expanded: boolean;\n row: Record<string, unknown>;\n}\n\n/**\n * Configuration that enables hierarchical (tree / grouped) rows. Mirrors the\n * discrete `idKey` / `parentKey` / `treeColumn` inputs and is exported for\n * consumers that prefer to pass a single config object around.\n */\nexport interface TableTreeConfig {\n idKey: string;\n parentKey: string;\n treeColumn?: string;\n}\n\nexport type TableVariant = 'default' | 'striped' | 'bordered';\nexport type TableSize = 'sm' | 'md' | 'lg';\n\n/**\n * Internal, render-ready view-model for a single visible table row. In flat\n * mode every row is depth 0 with no tree adornments; in tree mode it carries\n * the disclosure / indentation / aria metadata for the row.\n */\ninterface DisplayRow {\n /** The underlying data object. */\n row: Record<string, unknown>;\n /**\n * The row's index into `data()` — in both modes. It is what action, class,\n * style and formatter callbacks receive as `rowIndex`, and what identifies\n * the row in `CellEditEvent`. (It used to be the *positional* index in flat\n * mode — page offset plus row position — which, once a sort or filter was\n * active, pointed at a different row of `data()` than the one on screen.)\n */\n absIndex: number;\n /**\n * What selection and inline editing are keyed by: the row's `idKey` value\n * when the table has one, otherwise the row object itself. Either survives a\n * re-sort, a filter and a page change; an id also survives the parent\n * replacing its data array with fresh objects.\n */\n key: unknown;\n /** Row id (tree mode only; `null` in flat mode). */\n id: string | null;\n /** Tree depth — 0 for roots and for every row in flat mode. */\n depth: number;\n /** 1-based depth, surfaced as `aria-level` in tree mode. */\n level: number;\n /** Whether this row has visible children (renders a chevron). */\n hasChildren: boolean;\n /** Whether this parent row is currently expanded. */\n expanded: boolean;\n /** 1-based position within its sibling group (`aria-posinset`). */\n posInSet: number;\n /** Size of its sibling group (`aria-setsize`). */\n setSize: number;\n}\n\n/**\n * Table component for displaying structured data in rows and columns.\n *\n * Features:\n * - Column-based sorting with sort direction indicators\n * - Variant styles (default, striped, bordered)\n * - Size presets (sm, md, lg)\n * - Hoverable row highlighting\n * - Per-column formatter callbacks for display values\n * - Per-cell class/style callbacks for conditional styling\n * - Custom cell templates via content projection\n * - Composed cells (e.g. avatar + badge + actions)\n * - Hierarchical \"tree\" rows (grouped / expandable) via `idKey` + `parentKey`\n * - Responsive horizontal scrolling\n * - Empty state text for no data\n * - Accessible with proper table semantics\n *\n * @example\n * ```html\n * <lc-table [columns]=\"columns\" [data]=\"data\" variant=\"striped\" [hoverable]=\"true\"\n * (sort)=\"onSort($event)\" (rowClick)=\"onRowClick($event)\" />\n * ```\n *\n * @example\n * ```ts\n * columns: TableColumn[] = [\n * {\n * key: 'amount',\n * label: 'Amount',\n * formatter: (value) => new Intl.NumberFormat('de-DE', {\n * style: 'currency',\n * currency: 'EUR',\n * }).format(Number(value ?? 0)),\n * },\n * ];\n * ```\n */\n@Component({\n selector: 'lc-table',\n standalone: true,\n imports: [NgTemplateOutlet, NgStyle, FormsModule, SelectComponent, InputComponent, ButtonComponent, IconComponent],\n templateUrl: './table.component.html',\n styleUrl: './table.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class TableComponent {\n /** Custom cell templates */\n @ContentChildren(TableCellDirective) cellTemplates!: QueryList<TableCellDirective>;\n\n /** Array of column definitions */\n columns = input<TableColumn[]>([]);\n\n /** Array of data objects to display */\n data = input<Record<string, unknown>[]>([]);\n\n /** Visual variant of the table */\n variant = input<TableVariant>('default');\n\n /** Size of the table */\n size = input<TableSize>('md');\n\n /** Whether rows should highlight on hover */\n hoverable = input<boolean>(false);\n\n /** Whether table should be responsive (horizontal scroll on mobile) */\n responsive = input<boolean>(true);\n\n /** Text shown when data is empty */\n emptyText = input<string>('No data available');\n\n /** Placeholder prefix of the column filters, followed by the column label (`filterable`). */\n filterPlaceholderLabel = input('Filter');\n\n /** Accessible name of the select-all checkbox (`selectable`). */\n selectAllAriaLabel = input('Select all rows');\n\n /** Accessible name of a row checkbox, followed by the row number. */\n selectRowAriaLabel = input('Select row');\n\n /** Screen-reader state of a column sorted ascending. */\n sortedAscendingLabel = input('sorted ascending');\n\n /** Screen-reader state of a column sorted descending. */\n sortedDescendingLabel = input('sorted descending');\n\n /** Tree mode: accessible name prefix of the expand toggle, followed by the row label. */\n expandRowAriaLabel = input('Aufklappen:');\n\n /** Tree mode: accessible name prefix of the collapse toggle, followed by the row label. */\n collapseRowAriaLabel = input('Einklappen:');\n\n /** Pagination: word between the shown range and the total (`1–10 of 42`). */\n rangeOfLabel = input('of');\n\n /** Accessible name of the page-size select. */\n rowsPerPageAriaLabel = input('Rows per page');\n\n /** Accessible name of the previous-page button. */\n previousPageAriaLabel = input('Previous page');\n\n /** Accessible name of the next-page button. */\n nextPageAriaLabel = input('Next page');\n\n // -- Pagination --\n /** Enable pagination */\n paginate = input<boolean>(false);\n\n /** Rows per page */\n pageSize = input<number>(10);\n\n /** Available page size options */\n pageSizeOptions = input<number[]>([5, 10, 25, 50]);\n\n // -- Selection --\n /** Enable row selection checkboxes */\n selectable = input<boolean>(false);\n\n // -- Column Filters --\n /** Enable per-column text filters */\n filterable = input<boolean>(false);\n\n // -- Inline Editing --\n /** Enable inline cell editing on double-click */\n editable = input<boolean>(false);\n\n // -- Row Actions --\n /**\n * Row-level actions rendered in a trailing actions column (e.g. Freigeben / Ablehnen).\n * Clicking an action button does NOT trigger the row's `rowClick` output.\n */\n actions = input<TableAction[]>([]);\n\n /** Header label for the actions column */\n actionsLabel = input<string>('');\n\n /** Width of the actions column (e.g. '120px') */\n actionsWidth = input<string | undefined>(undefined);\n\n /** Horizontal alignment of the action buttons (and header label) within the cell */\n actionsAlign = input<TableActionsAlign>('start');\n\n // -- Tree / grouped rows --\n /**\n * Row field holding the unique id. Required (together with {@link parentKey})\n * to enable hierarchical \"tree mode\". Absent ⇒ today's flat table.\n */\n idKey = input<string | undefined>(undefined);\n\n /**\n * Row field referencing the parent row's id. Presence of both `idKey` and\n * `parentKey` enables tree mode. Rows with an absent/empty or unknown parent\n * id are treated as roots.\n */\n parentKey = input<string | undefined>(undefined);\n\n /** Column key the chevron + indentation attach to. Default: first column. */\n treeColumn = input<string | undefined>(undefined);\n\n /** Initial expand state for all parent rows when uncontrolled. Default: true. */\n defaultExpanded = input<boolean>(true);\n\n /**\n * Controlled set of expanded parent ids. When provided, the table renders\n * exactly these as expanded; combine with {@link expandedIdsChange} for\n * `[(expandedIds)]`. When omitted, expansion is uncontrolled and seeded by\n * {@link defaultExpanded}.\n */\n expandedIds = input<string[] | undefined>(undefined);\n\n /** Indentation per depth level, in px. Default: 20. */\n indentSize = input<number>(20);\n\n /** Accessible name prefix of a column filter, followed by the column label. */\n filterAriaLabel = input('Filter by');\n\n /** Emitted when a sortable column header is clicked */\n readonly sort = output<SortEvent>();\n\n /** Emitted when a row is clicked */\n readonly rowClick = output<Record<string, unknown>>();\n\n /** Emitted when a cell is edited */\n readonly cellEdit = output<CellEditEvent>();\n\n /** Emitted when row selection changes */\n readonly selectionChange = output<SelectionChangeEvent>();\n\n /** Emitted when a row action button is clicked */\n readonly actionClick = output<ActionClickEvent>();\n\n /** Emitted when a parent row is expanded/collapsed (tree mode). */\n readonly rowToggle = output<RowToggleEvent>();\n\n /** Emitted with the full list of expanded parent ids; enables `[(expandedIds)]`. */\n readonly expandedIdsChange = output<string[]>();\n\n // -- Internal state --\n protected currentSort = signal<{ column: string; direction: 'asc' | 'desc' } | null>(null);\n /**\n * Effective page size. Seeded from the `pageSize` input (resetting if it\n * changes) and overridable by the user via the page-size dropdown.\n */\n protected internalPageSize = linkedSignal(() => this.pageSize());\n /**\n * Current page, kept within range: when the data shrinks or the page size\n * grows so that the page no longer exists, it moves back to the last one\n * (rather than showing an empty page captioned \"31–30 of 30\").\n */\n protected currentPage = linkedSignal<number, number>({\n source: () => this.totalPages(),\n computation: (total, previous) => Math.min(previous?.value ?? 0, total - 1),\n });\n /**\n * Selected row keys (see `DisplayRow.key`). Pruned when `data` changes, so\n * a key whose row is gone doesn't linger and count towards \"all selected\".\n */\n protected selectedRows = linkedSignal<Set<unknown>, Set<unknown>>({\n source: () => this.rowKeys(),\n computation: (keys, previous) => {\n if (!previous) return new Set<unknown>();\n const kept = new Set([...previous.value].filter((k) => keys.has(k)));\n return kept.size === previous.value.size ? previous.value : kept;\n },\n });\n protected columnFilters = signal<Record<string, string>>({});\n protected editingCell = signal<{ key: unknown; column: string } | null>(null);\n protected editValue = signal<string>('');\n\n /** The inline-edit input while a cell is being edited. */\n private readonly editInput = viewChild<ElementRef<HTMLInputElement>>('editInput');\n private focusedEditInput: HTMLInputElement | null = null;\n\n constructor() {\n // The edit input is inserted on double-click. `autofocus` is only honoured\n // for elements present when the page loads, so the input never received\n // focus (and Enter/Escape/blur never reached it); focus it once it renders.\n afterRenderEffect(() => {\n const el = this.editInput()?.nativeElement ?? null;\n if (el && el !== this.focusedEditInput) {\n el.focus();\n }\n this.focusedEditInput = el;\n });\n }\n\n /** The key of every row currently in `data()`. */\n private readonly rowKeys = computed(() => new Set(this.data().map((row) => this.rowKey(row))));\n\n /** See `DisplayRow.key`. */\n private rowKey(row: Record<string, unknown>): unknown {\n const idKey = this.idKey();\n return idKey ? String(row[idKey] ?? '') : row;\n }\n /** User expand/collapse overrides keyed by row id (uncontrolled mode). */\n private readonly expandOverrides = signal<Map<string, boolean>>(new Map());\n\n /**\n * Filtered data (applies column filters)\n */\n protected readonly filteredData = computed(() => {\n let items = this.data();\n const filters = this.columnFilters();\n\n if (this.filterable()) {\n for (const [key, value] of Object.entries(filters)) {\n if (value.trim()) {\n items = items.filter(row =>\n String(row[key] ?? '').toLowerCase().includes(value.toLowerCase())\n );\n }\n }\n }\n\n return items;\n });\n\n /** Comparator for the active sort, shared by flat sorting and tree sibling sorting. */\n private rowComparator(sortState: { column: string; direction: 'asc' | 'desc' }) {\n return (a: Record<string, unknown>, b: Record<string, unknown>): number => {\n const aVal = a[sortState.column];\n const bVal = b[sortState.column];\n let cmp = 0;\n if (aVal == null && bVal == null) cmp = 0;\n else if (aVal == null) cmp = -1;\n else if (bVal == null) cmp = 1;\n else if (typeof aVal === 'number' && typeof bVal === 'number') cmp = aVal - bVal;\n else cmp = String(aVal).localeCompare(String(bVal));\n return sortState.direction === 'asc' ? cmp : -cmp;\n };\n }\n\n /**\n * Sorted data\n */\n protected readonly sortedData = computed(() => {\n const items = [...this.filteredData()];\n const sortState = this.currentSort();\n if (!sortState) return items;\n return items.sort(this.rowComparator(sortState));\n });\n\n /**\n * Paginated data (or all if pagination disabled). Flat mode only.\n */\n protected readonly displayData = computed(() => {\n const items = this.sortedData();\n if (!this.paginate()) return items;\n const ps = this.internalPageSize();\n const start = this.currentPage() * ps;\n return items.slice(start, start + ps);\n });\n\n // -- Tree / grouped rows -----------------------------------------------------\n\n /** Whether hierarchical tree mode is active. */\n protected readonly treeMode = computed(() => !!this.idKey() && !!this.parentKey());\n\n /** Column the chevron + indentation attach to (defaults to the first column). */\n protected readonly effectiveTreeColumn = computed(\n () => this.treeColumn() || this.columns()[0]?.key\n );\n\n /** Stable map of row object → its index in `data()` (row identity for tree mode). */\n private readonly dataIndexMap = computed(() => {\n const map = new Map<Record<string, unknown>, number>();\n this.data().forEach((row, i) => map.set(row, i));\n return map;\n });\n\n /** Parent → ordered children index built from `idKey`/`parentKey`. */\n private readonly treeBuild = computed(() => {\n const idKey = this.idKey();\n const parentKey = this.parentKey();\n const byId = new Map<string, Record<string, unknown>>();\n const childrenOf = new Map<string, Record<string, unknown>[]>();\n const roots: Record<string, unknown>[] = [];\n if (!idKey || !parentKey) return { byId, childrenOf, roots };\n\n const rows = this.data();\n for (const row of rows) {\n const id = String(row[idKey] ?? '');\n if (id) byId.set(id, row);\n }\n for (const row of rows) {\n const parentRaw = row[parentKey];\n const parentId = parentRaw == null ? '' : String(parentRaw);\n if (parentId && byId.has(parentId)) {\n const siblings = childrenOf.get(parentId) ?? [];\n siblings.push(row);\n childrenOf.set(parentId, siblings);\n } else {\n // No parent, empty parent, or orphaned (unknown parent) ⇒ root.\n roots.push(row);\n }\n }\n return { byId, childrenOf, roots };\n });\n\n /**\n * Tree restricted to rows that match the active filters together with their\n * ancestor chain (so the path to a match stays visible).\n */\n private readonly treeFiltered = computed(() => {\n const { byId, childrenOf, roots } = this.treeBuild();\n const parentKey = this.parentKey();\n const filters = this.columnFilters();\n const active =\n this.filterable() && parentKey && Object.values(filters).some((v) => v.trim());\n if (!active) return { childrenOf, roots };\n\n const matches = (row: Record<string, unknown>): boolean =>\n Object.entries(filters).every(\n ([key, value]) =>\n !value.trim() ||\n String(row[key] ?? '').toLowerCase().includes(value.toLowerCase())\n );\n\n // Visible = every matching row plus all of its ancestors.\n const visible = new Set<Record<string, unknown>>();\n for (const row of this.data()) {\n if (!matches(row)) continue;\n let current: Record<string, unknown> | undefined = row;\n while (current && !visible.has(current)) {\n visible.add(current);\n const parentRaw: unknown = current[parentKey];\n const parentId = parentRaw == null ? '' : String(parentRaw);\n current = parentId ? byId.get(parentId) : undefined;\n }\n }\n\n const visibleChildrenOf = new Map<string, Record<string, unknown>[]>();\n const visibleRoots: Record<string, unknown>[] = [];\n for (const row of this.data()) {\n if (!visible.has(row)) continue;\n const parentRaw = row[parentKey];\n const parentId = parentRaw == null ? '' : String(parentRaw);\n const parent = parentId ? byId.get(parentId) : undefined;\n if (parent && visible.has(parent)) {\n const siblings = visibleChildrenOf.get(parentId) ?? [];\n siblings.push(row);\n visibleChildrenOf.set(parentId, siblings);\n } else {\n visibleRoots.push(row);\n }\n }\n return { childrenOf: visibleChildrenOf, roots: visibleRoots };\n });\n\n /** Tree with each sibling group sorted by the active sort (structure kept intact). */\n private readonly treeSorted = computed(() => {\n const { childrenOf, roots } = this.treeFiltered();\n const sortState = this.currentSort();\n if (!sortState) return { childrenOf, roots };\n const cmp = this.rowComparator(sortState);\n const sortedChildrenOf = new Map<string, Record<string, unknown>[]>();\n for (const [parentId, siblings] of childrenOf) {\n sortedChildrenOf.set(parentId, [...siblings].sort(cmp));\n }\n return { childrenOf: sortedChildrenOf, roots: [...roots].sort(cmp) };\n });\n\n /** Root rows after filter/sort — the unit of pagination in tree mode. */\n private readonly treeRoots = computed(() => this.treeSorted().roots);\n\n /**\n * Render-ready rows. In flat mode this wraps the existing paginated data; in\n * tree mode it paginates roots and flattens each visible (expanded) subtree.\n */\n protected readonly displayRows = computed<DisplayRow[]>(() => {\n const dataIndex = this.dataIndexMap();\n if (!this.treeMode()) {\n return this.displayData().map((row) => ({\n row,\n absIndex: dataIndex.get(row) ?? -1,\n key: this.rowKey(row),\n id: null,\n depth: 0,\n level: 0,\n hasChildren: false,\n expanded: false,\n posInSet: 0,\n setSize: 0,\n }));\n }\n\n const idKey = this.idKey() as string;\n const { childrenOf } = this.treeSorted();\n let roots = this.treeRoots();\n if (this.paginate()) {\n const ps = this.internalPageSize();\n const start = this.currentPage() * ps;\n roots = roots.slice(start, start + ps);\n }\n\n const out: DisplayRow[] = [];\n const walk = (group: Record<string, unknown>[], depth: number): void => {\n group.forEach((row, idx) => {\n const id = String(row[idKey] ?? '');\n const children = childrenOf.get(id) ?? [];\n const hasChildren = children.length > 0;\n const expanded = hasChildren && this.isExpanded(id);\n out.push({\n row,\n absIndex: dataIndex.get(row) ?? -1,\n key: this.rowKey(row),\n id,\n depth,\n level: depth + 1,\n hasChildren,\n expanded,\n posInSet: idx + 1,\n setSize: group.length,\n });\n if (expanded) walk(children, depth + 1);\n });\n };\n walk(roots, 0);\n return out;\n });\n\n /** Total pages */\n protected readonly totalPages = computed(() => {\n if (!this.paginate()) return 1;\n const total = this.treeMode() ? this.treeRoots().length : this.filteredData().length;\n return Math.max(1, Math.ceil(total / this.internalPageSize()));\n });\n\n /**\n * Pagination row count. Tree mode counts root rows (the paginated unit); flat\n * mode counts filtered rows.\n */\n protected readonly totalRows = computed(() =>\n this.treeMode() ? this.treeRoots().length : this.filteredData().length\n );\n\n /** Whether all visible rows are selected */\n protected readonly allSelected = computed(() => {\n const rows = this.displayRows();\n if (rows.length === 0) return false;\n const selected = this.selectedRows();\n return rows.every((r) => selected.has(r.key));\n });\n\n /** Whether some, but not all, visible rows are selected — the header box's mixed state. */\n protected readonly someSelected = computed(() => {\n const selected = this.selectedRows();\n return !this.allSelected() && this.displayRows().some((r) => selected.has(r.key));\n });\n\n protected readonly pageSizeSelectOptions = computed(() =>\n this.pageSizeOptions().map((opt) => ({\n value: opt,\n label: `${opt} / page`,\n }))\n );\n\n /**\n * Computed CSS classes for the table element\n */\n tableClasses = computed(() => {\n const classes = ['lc-table'];\n classes.push(`lc-table--${this.variant()}`);\n classes.push(`lc-table--${this.size()}`);\n if (this.hoverable()) classes.push('lc-table--hoverable');\n return classes.join(' ');\n });\n\n /**\n * Computed CSS classes for the wrapper element\n */\n wrapperClasses = computed(() => {\n const classes = ['lc-table-wrapper'];\n if (this.responsive()) classes.push('lc-table-wrapper--responsive');\n return classes.join(' ');\n });\n\n // -- Sort --\n handleSort(columnKey: string): void {\n const column = this.columns().find((col) => col.key === columnKey);\n if (!column || !column.sortable) return;\n\n const current = this.currentSort();\n let direction: 'asc' | 'desc' = 'asc';\n if (current && current.column === columnKey) {\n direction = current.direction === 'asc' ? 'desc' : 'asc';\n }\n\n this.currentSort.set({ column: columnKey, direction });\n this.sort.emit({ column: columnKey, direction });\n }\n\n getSortState(columnKey: string): 'asc' | 'desc' | null {\n const current = this.currentSort();\n if (current && current.column === columnKey) return current.direction;\n return null;\n }\n\n getAriaSort(columnKey: string): string | null {\n const sortState = this.getSortState(columnKey);\n if (sortState === 'asc') return 'ascending';\n if (sortState === 'desc') return 'descending';\n return null;\n }\n\n getHeaderClasses(column: TableColumn): string {\n const classes: string[] = [];\n if (column.sortable) classes.push('sortable');\n const sortState = this.getSortState(column.key);\n if (sortState) classes.push(`sorted-${sortState}`);\n return classes.join(' ');\n }\n\n getCellValue(row: Record<string, unknown>, columnKey: string): unknown {\n return row[columnKey];\n }\n\n getFormattedCellValue(\n row: Record<string, unknown>,\n column: TableColumn,\n rowIndex: number\n ): unknown {\n const value = this.getCellValue(row, column.key);\n if (!column.formatter) return value;\n\n return column.formatter(value, row, column, rowIndex);\n }\n\n getCellClasses(\n row: Record<string, unknown>,\n column: TableColumn,\n rowIndex: number\n ): string {\n const classes: string[] = [];\n if (column.cssClass) classes.push(column.cssClass);\n\n if (typeof column.cellClass === 'string') {\n classes.push(column.cellClass);\n } else if (typeof column.cellClass === 'function') {\n const resolved = column.cellClass(\n this.getCellValue(row, column.key),\n row,\n column,\n rowIndex\n );\n if (resolved) classes.push(resolved);\n }\n\n return classes.join(' ').trim();\n }\n\n getCellStyles(\n row: Record<string, unknown>,\n column: TableColumn,\n rowIndex: number\n ): Record<string, string> | null {\n if (!column.cellStyle) return null;\n\n if (typeof column.cellStyle === 'function') {\n return column.cellStyle(\n this.getCellValue(row, column.key),\n row,\n column,\n rowIndex\n );\n }\n\n return column.cellStyle;\n }\n\n /** Whether the given column is the disclosure/indent column in tree mode. */\n protected isTreeColumn(columnKey: string): boolean {\n return this.treeMode() && columnKey === this.effectiveTreeColumn();\n }\n\n /** Indent levels to render before a row's chevron (one guide per ancestor depth). */\n protected indentLevels(depth: number): number[] {\n return Array.from({ length: depth }, (_, i) => i);\n }\n\n /** Accessible name for a row's disclosure button (the tree column's value). */\n protected treeCellLabel(row: Record<string, unknown>): string {\n const col = this.effectiveTreeColumn();\n return col ? String(row[col] ?? '') : '';\n }\n\n getCellTemplate(columnKey: string): TableCellDirective | undefined {\n return this.cellTemplates?.find((template) => template.columnKey() === columnKey);\n }\n\n hasCustomTemplate(columnKey: string): boolean {\n return !!this.getCellTemplate(columnKey);\n }\n\n onRowClick(row: Record<string, unknown>): void {\n this.rowClick.emit(row);\n }\n\n // -- Row Actions --\n /** Whether the trailing actions column should be rendered */\n protected readonly hasActions = computed(() => this.actions().length > 0);\n\n protected isActionHidden(\n action: TableAction,\n row: Record<string, unknown>,\n rowIndex: number\n ): boolean {\n return action.hidden ? action.hidden(row, rowIndex) : false;\n }\n\n protected isActionDisabled(\n action: TableAction,\n row: Record<string, unknown>,\n rowIndex: number\n ): boolean {\n return action.disabled ? action.disabled(row, rowIndex) : false;\n }\n\n /**\n * Handles an action button click. The DOM click is stopped from propagating\n * (see template `$event.stopPropagation()`), so the row's `rowClick` never fires.\n */\n protected onActionClick(\n action: TableAction,\n row: Record<string, unknown>,\n rowIndex: number\n ): void {\n this.actionClick.emit({\n action: action.key,\n row,\n rowIndex,\n });\n }\n\n // -- Tree keyboard model -----------------------------------------------------\n // `role=\"treegrid\"` promises a composite widget: one tab stop, arrows to move\n // between rows, Right/Left to open/close a group or step into/out of it. The\n // rows carry a roving tabindex; the focused row is remembered by key so it\n // survives re-renders, and falls back to the first row when it is gone.\n\n private readonly rowEls = viewChildren<ElementRef<HTMLTableRowElement>>('dataRow');\n private readonly focusedRowKey = signal<unknown>(null);\n\n /** Key of the row that holds the tab stop. */\n private readonly effectiveFocusedKey = computed(() => {\n const rows = this.displayRows();\n const key = this.focusedRowKey();\n return rows.some((r) => r.key === key) ? key : rows[0]?.key;\n });\n\n protected rowTabindex(dr: DisplayRow): number | null {\n if (!this.treeMode()) return null;\n return dr.key === this.effectiveFocusedKey() ? 0 : -1;\n }\n\n protected onRowFocus(dr: DisplayRow): void {\n if (this.treeMode()) this.focusedRowKey.set(dr.key);\n }\n\n protected onRowKeydown(event: KeyboardEvent, dr: DisplayRow): void {\n if (!this.treeMode()) return;\n // Keys typed into an inline editor or the row's own controls are theirs.\n if ((event.target as HTMLElement).tagName === 'INPUT') return;\n const rows = this.displayRows();\n const index = rows.findIndex((r) => r.key === dr.key);\n if (index < 0) return;\n\n switch (event.key) {\n case 'ArrowDown':\n this.focusRow(index + 1);\n break;\n case 'ArrowUp':\n this.focusRow(index - 1);\n break;\n case 'Home':\n this.focusRow(0);\n break;\n case 'End':\n this.focusRow(rows.length - 1);\n break;\n case 'ArrowRight':\n if (!dr.hasChildren) return;\n if (dr.expanded) this.focusRow(index + 1); // first child\n else if (dr.id) this.toggleRow(dr.id, dr.row);\n break;\n case 'ArrowLeft':\n if (dr.hasChildren && dr.expanded && dr.id) {\n this.toggleRow(dr.id, dr.row);\n } else if (dr.depth > 0) {\n // Step out to the parent: the nearest row above with a smaller depth.\n for (let i = index - 1; i >= 0; i--) {\n if (rows[i].depth < dr.depth) {\n this.focusRow(i);\n break;\n }\n }\n } else {\n return;\n }\n break;\n case 'Enter':\n this.rowClick.emit(dr.row);\n break;\n case ' ':\n if (!this.selectable()) return;\n this.toggleRowSelect(dr.row);\n break;\n default:\n return;\n }\n event.preventDefault();\n }\n\n private focusRow(index: number): void {\n const rows = this.displayRows();\n if (index < 0 || index >= rows.length) return;\n this.focusedRowKey.set(rows[index].key);\n this.rowEls()[index]?.nativeElement.focus();\n }\n\n // -- Tree expand / collapse --------------------------------------------------\n\n /** Whether the parent row with the given id is currently expanded. */\n protected isExpanded(id: string): boolean {\n const controlled = this.expandedIds();\n if (controlled !== undefined) return controlled.includes(id);\n const override = this.expandOverrides().get(id);\n if (override !== undefined) return override;\n return this.defaultExpanded();\n }\n\n /** Chevron click: toggle expand state without triggering the row click. */\n protected onChevronClick(displayRow: DisplayRow, event: Event): void {\n event.stopPropagation();\n if (displayRow.id) this.toggleRow(displayRow.id, displayRow.row);\n }\n\n private toggleRow(id: string, row: Record<string, unknown>): void {\n const expanded = !this.isExpanded(id);\n this.expandOverrides.update((map) => {\n const next = new Map(map);\n next.set(id, expanded);\n return next;\n });\n this.rowToggle.emit({ id, expanded, row });\n this.expandedIdsChange.emit(this.nextExpandedIds(id, expanded));\n }\n\n /** The full list of expanded parent ids after applying a single toggle. */\n private nextExpandedIds(changedId: string, changedExpanded: boolean): string[] {\n const controlled = this.expandedIds();\n const overrides = this.expandOverrides();\n const parentIds = Array.from(this.treeBuild().childrenOf.keys());\n return parentIds.filter((pid) => {\n if (pid === changedId) return changedExpanded;\n if (controlled !== undefined) return controlled.includes(pid);\n const override = overrides.get(pid);\n return override !== undefined ? override : this.defaultExpanded();\n });\n }\n\n // -- Pagination --\n protected goToPage(page: number): void {\n if (page >= 0 && page < this.totalPages()) {\n this.currentPage.set(page);\n }\n }\n\n protected onPageSizeChange(event: Event): void {\n const newSize = Number((event.target as HTMLSelectElement).value);\n this.internalPageSize.set(newSize);\n this.currentPage.set(0);\n }\n\n protected onPageSizeModelChange(value: string | number | null): void {\n if (value == null) {\n return;\n }\n const parsed = typeof value === 'number' ? value : Number(value);\n if (!Number.isFinite(parsed)) {\n return;\n }\n this.internalPageSize.set(parsed);\n this.currentPage.set(0);\n }\n\n protected get paginationStart(): number {\n if (this.totalRows() === 0) return 0;\n return this.currentPage() * this.internalPageSize() + 1;\n }\n\n protected get paginationEnd(): number {\n return Math.min((this.currentPage() + 1) * this.internalPageSize(), this.totalRows());\n }\n\n // -- Selection --\n // Keyed by row identity (see `DisplayRow.key`), never by position: a sort or\n // filter changes where a row is shown, not which row it is.\n protected toggleSelectAll(): void {\n const selected = new Set(this.selectedRows());\n const rows = this.displayRows();\n const allSelected = this.allSelected();\n\n rows.forEach((r) => {\n if (allSelected) selected.delete(r.key);\n else selected.add(r.key);\n });\n\n this.selectedRows.set(selected);\n this.emitSelectionChange();\n }\n\n protected toggleRowSelect(row: Record<string, unknown>): void {\n const key = this.rowKey(row);\n const selected = new Set(this.selectedRows());\n if (selected.has(key)) selected.delete(key);\n else selected.add(key);\n this.selectedRows.set(selected);\n this.emitSelectionChange();\n }\n\n protected isRowSelected(row: Record<string, unknown>): boolean {\n return this.selectedRows().has(this.rowKey(row));\n }\n\n private emitSelectionChange(): void {\n const keys = this.selectedRows();\n // In data order, so the consumer gets a stable list whatever the sort.\n const selected = this.data().filter((row) => keys.has(this.rowKey(row)));\n this.selectionChange.emit({ selected, allSelected: this.allSelected() });\n }\n\n // -- Column Filters --\n protected onFilterChange(columnKey: string, value: string): void {\n const filters = { ...this.columnFilters(), [columnKey]: value };\n this.columnFilters.set(filters);\n this.currentPage.set(0);\n }\n\n protected getFilterValue(columnKey: string): string {\n return this.columnFilters()[columnKey] || '';\n }\n\n // -- Inline Editing --\n // Keyed by row identity too — the edited cell is the one the user clicked,\n // whichever position sorting put it in.\n protected startEdit(row: Record<string, unknown>, column: string, currentValue: unknown): void {\n if (!this.editable()) return;\n const col = this.columns().find(c => c.key === column);\n if (col && col.editable === false) return;\n this.editingCell.set({ key: this.rowKey(row), column });\n this.editValue.set(String(currentValue ?? ''));\n }\n\n protected isEditing(row: Record<string, unknown>, column: string): boolean {\n const cell = this.editingCell();\n return cell !== null && cell.key === this.rowKey(row) && cell.column === column;\n }\n\n protected commitEdit(row: Record<string, unknown>, column: string): void {\n // Only the cell being edited commits: the input's blur arrives after Enter\n // or Escape already ended the edit, and must not commit (or re-commit).\n if (!this.isEditing(row, column)) return;\n const oldValue = row[column];\n const newValue = this.editValue();\n this.editingCell.set(null);\n this.editValue.set('');\n if (String(oldValue ?? '') !== newValue) {\n const rowIndex = this.dataIndexMap().get(row) ?? -1;\n this.cellEdit.emit({ row, column, oldValue, newValue, rowIndex });\n }\n }\n\n protected cancelEdit(): void {\n this.editingCell.set(null);\n this.editValue.set('');\n }\n\n protected onEditKeydown(event: KeyboardEvent, row: Record<string, unknown>, column: string): void {\n if (event.key === 'Enter') {\n this.commitEdit(row, column);\n } else if (event.key === 'Escape') {\n this.cancelEdit();\n }\n }\n\n /** Enter/Space on a focused sortable header sorts, like a click does. */\n protected onHeaderKeydown(event: KeyboardEvent, columnKey: string): void {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.handleSort(columnKey);\n }\n }\n\n protected getInputValue(event: Event): string {\n return (event.target as HTMLInputElement).value;\n }\n}\n","<div [class]=\"wrapperClasses()\">\n <table [class]=\"tableClasses()\" [attr.role]=\"treeMode() ? 'treegrid' : 'table'\">\n <thead>\n <!-- Filter row -->\n @if (filterable()) {\n <tr class=\"lc-table__filter-row\">\n @if (selectable()) {\n <th class=\"lc-table__select-cell\"></th>\n }\n @for (column of columns(); track column.key) {\n <th>\n @if (column.filterable !== false) {\n <lc-input\n class=\"lc-table__filter-input\"\n size=\"xs\"\n [placeholder]=\"filterPlaceholderLabel() + ' ' + column.label\"\n [ariaLabel]=\"filterAriaLabel() + ' ' + column.label\"\n [ngModel]=\"getFilterValue(column.key)\"\n (ngModelChange)=\"onFilterChange(column.key, $event)\"\n />\n }\n </th>\n }\n @if (hasActions()) {\n <th class=\"lc-table__actions-cell\"></th>\n }\n </tr>\n }\n <!-- Header row -->\n <tr>\n @if (selectable()) {\n <th class=\"lc-table__select-cell\" scope=\"col\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"allSelected()\"\n [indeterminate]=\"someSelected()\"\n (change)=\"toggleSelectAll()\"\n [attr.aria-label]=\"selectAllAriaLabel()\"\n />\n </th>\n }\n @for (column of columns(); track column.key) {\n <!-- A sortable header is a keyboard stop too: Enter/Space sort like a click. -->\n <th\n scope=\"col\"\n [class]=\"getHeaderClasses(column) + (column.cssClass ? ' ' + column.cssClass : '')\"\n [attr.aria-sort]=\"getAriaSort(column.key)\"\n [attr.tabindex]=\"column.sortable ? 0 : null\"\n [style.width]=\"column.width\"\n [title]=\"column.tooltip || ''\"\n (click)=\"handleSort(column.key)\"\n (keydown)=\"column.sortable ? onHeaderKeydown($event, column.key) : null\">\n {{ column.label }}\n @if (column.sortable && getSortState(column.key)) {\n <span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? sortedAscendingLabel() : sortedDescendingLabel()\">\n @if (getSortState(column.key) === 'asc') {\n ↑\n } @else {\n ↓\n }\n </span>\n }\n </th>\n }\n @if (hasActions()) {\n <th\n scope=\"col\"\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n [style.width]=\"actionsWidth()\"\n >\n {{ actionsLabel() }}\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (displayRows().length === 0) {\n <tr>\n <td [attr.colspan]=\"columns().length + (selectable() ? 1 : 0) + (hasActions() ? 1 : 0)\" class=\"lc-table__empty\">\n {{ emptyText() }}\n </td>\n </tr>\n } @else {\n @for (dr of displayRows(); track dr.key) {\n <!-- In tree mode the rows form the treegrid's keyboard model: a roving\n tab stop plus Arrow/Home/End/Enter/Space handling (see the\n component). Flat mode keeps plain table rows. -->\n <tr\n #dataRow\n [class.lc-table__row--selected]=\"selectable() && isRowSelected(dr.row)\"\n [class.lc-table__row--group]=\"dr.hasChildren\"\n [attr.role]=\"treeMode() ? 'row' : null\"\n [attr.tabindex]=\"rowTabindex(dr)\"\n [attr.aria-level]=\"treeMode() ? dr.level : null\"\n [attr.aria-expanded]=\"treeMode() && dr.hasChildren ? dr.expanded : null\"\n [attr.aria-posinset]=\"treeMode() ? dr.posInSet : null\"\n [attr.aria-setsize]=\"treeMode() ? dr.setSize : null\"\n [attr.aria-selected]=\"treeMode() && selectable() ? isRowSelected(dr.row) : null\"\n (click)=\"onRowClick(dr.row)\"\n (focus)=\"onRowFocus(dr)\"\n (keydown)=\"onRowKeydown($event, dr)\"\n >\n @if (selectable()) {\n <td class=\"lc-table__select-cell\" [attr.role]=\"treeMode() ? 'gridcell' : null\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"isRowSelected(dr.row)\"\n (change)=\"toggleRowSelect(dr.row)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"selectRowAriaLabel() + ' ' + (dr.absIndex + 1)\"\n />\n </td>\n }\n @for (column of columns(); track column.key) {\n <td\n [class]=\"getCellClasses(dr.row, column, dr.absIndex)\"\n [ngStyle]=\"getCellStyles(dr.row, column, dr.absIndex)\"\n [attr.role]=\"treeMode() ? 'gridcell' : null\"\n (dblclick)=\"editable() ? startEdit(dr.row, column.key, getCellValue(dr.row, column.key)) : null\"\n >\n @if (isTreeColumn(column.key)) {\n <span class=\"lc-table__tree-cell\">\n @for (lvl of indentLevels(dr.depth); track lvl) {\n <span class=\"lc-table__tree-indent\" [style.width.px]=\"indentSize()\"></span>\n }\n <span class=\"lc-table__tree-chevron\" [style.width.px]=\"indentSize()\">\n @if (dr.hasChildren) {\n <button\n type=\"button\"\n class=\"lc-table__chevron-btn\"\n [class.lc-table__chevron-btn--expanded]=\"dr.expanded\"\n [attr.aria-label]=\"(dr.expanded ? collapseRowAriaLabel() : expandRowAriaLabel()) + ' ' + treeCellLabel(dr.row)\"\n [attr.aria-expanded]=\"dr.expanded\"\n (click)=\"onChevronClick(dr, $event)\"\n >\n <lc-icon name=\"chevron-right\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </span>\n <span class=\"lc-table__tree-content\">\n <ng-container\n *ngTemplateOutlet=\"cellContent; context: { row: dr.row, column: column, absIndex: dr.absIndex }\"\n ></ng-container>\n </span>\n </span>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"cellContent; context: { row: dr.row, column: column, absIndex: dr.absIndex }\"\n ></ng-container>\n }\n </td>\n }\n @if (hasActions()) {\n <td\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n [attr.role]=\"treeMode() ? 'gridcell' : null\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"lc-table__actions\">\n @for (action of actions(); track action.key) {\n @if (!isActionHidden(action, dr.row, dr.absIndex)) {\n <lc-button\n [variant]=\"action.variant ?? 'ghost'\"\n size=\"xs\"\n [iconOnly]=\"!action.label\"\n [disabled]=\"isActionDisabled(action, dr.row, dr.absIndex)\"\n [ariaLabel]=\"action.tooltip ?? action.label ?? action.key\"\n (clicked)=\"onActionClick(action, dr.row, dr.absIndex)\"\n >\n @if (action.icon) {\n <lc-icon [name]=\"action.icon\" size=\"sm\" [decorative]=\"true\" />\n }\n @if (action.label) {\n {{ action.label }}\n }\n </lc-button>\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Shared cell content (edit input / custom template / formatted value) -->\n<ng-template #cellContent let-row=\"row\" let-column=\"column\" let-absIndex=\"absIndex\">\n @if (isEditing(row, column.key)) {\n <input\n #editInput\n type=\"text\"\n class=\"lc-table__edit-input\"\n [value]=\"editValue()\"\n (input)=\"editValue.set(getInputValue($event))\"\n (blur)=\"commitEdit(row, column.key)\"\n (keydown)=\"onEditKeydown($event, row, column.key)\"\n />\n } @else if (hasCustomTemplate(column.key)) {\n <ng-container *ngTemplateOutlet=\"getCellTemplate(column.key)!.template; context: { $implicit: row }\"></ng-container>\n } @else {\n {{ getFormattedCellValue(row, column, absIndex) }}\n }\n</ng-template>\n\n<!-- Pagination -->\n@if (paginate()) {\n <div class=\"lc-table-pagination\">\n <div class=\"lc-table-pagination__info\">\n {{ paginationStart }}–{{ paginationEnd }} {{ rangeOfLabel() }} {{ totalRows() }}\n </div>\n <div class=\"lc-table-pagination__controls\">\n <lc-select\n class=\"lc-table-pagination__size\"\n [size]=\"size() === 'sm' ? 'sm' : size() === 'lg' ? 'lg' : 'md'\"\n [options]=\"pageSizeSelectOptions()\"\n [ngModel]=\"internalPageSize()\"\n [ariaLabel]=\"rowsPerPageAriaLabel()\"\n (ngModelChange)=\"onPageSizeModelChange($event)\"\n />\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() === 0\"\n (click)=\"goToPage(currentPage() - 1)\"\n [attr.aria-label]=\"previousPageAriaLabel()\"\n >‹</button>\n <span class=\"lc-table-pagination__page\">\n {{ currentPage() + 1 }} / {{ totalPages() }}\n </span>\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() >= totalPages() - 1\"\n (click)=\"goToPage(currentPage() + 1)\"\n [attr.aria-label]=\"nextPageAriaLabel()\"\n >›</button>\n </div>\n </div>\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"lifecorner-angular-ui-kit-table.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/table/table-cell.directive.ts","../../../../libs/angular-ui-kit/src/lib/table/table.component.ts","../../../../libs/angular-ui-kit/src/lib/table/table.component.html"],"sourcesContent":["import { Directive, input, TemplateRef, inject } from '@angular/core';\n\n/**\n * Directive for defining custom cell templates in the Table component.\n *\n * @example\n * ```html\n * <lc-table [columns]=\"columns\" [data]=\"data\">\n * <ng-template lcTableCell=\"status\" let-row>\n * <lc-badge [variant]=\"row.status\">{{ row.status }}</lc-badge>\n * </ng-template>\n * </lc-table>\n * ```\n */\n@Directive({\n selector: '[lcTableCell]',\n standalone: true,\n})\nexport class TableCellDirective {\n /** The column key this template applies to */\n readonly columnKey = input('', { alias: 'lcTableCell' });\n\n public template = inject(TemplateRef<{ $implicit: Record<string, unknown> }>);\n}\n","import {\n Component,\n ChangeDetectionStrategy,\n ElementRef,\n input,\n output,\n computed,\n signal,\n linkedSignal,\n viewChild,\n viewChildren,\n afterRenderEffect,\n ContentChildren,\n QueryList,\n} from '@angular/core';\nimport { NgStyle, NgTemplateOutlet } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { TableCellDirective } from './table-cell.directive';\nimport { InputComponent } from '@lifecorner/angular-ui-kit/input';\nimport { SelectComponent } from '@lifecorner/angular-ui-kit/select';\nimport { ButtonComponent, ButtonVariant } from '@lifecorner/angular-ui-kit/button';\nimport { IconComponent, ɵprovideKitIcons } from '@lifecorner/angular-ui-kit/icon';\nimport { ICON_CHEVRON_RIGHT } from '@lifecorner/angular-ui-kit/icons';\n\ntype TableCellClass = string | ((\n value: unknown,\n row: Record<string, unknown>,\n column: TableColumn,\n rowIndex: number\n) => string);\n\ntype TableCellStyle = Record<string, string> | ((\n value: unknown,\n row: Record<string, unknown>,\n column: TableColumn,\n rowIndex: number\n) => Record<string, string>);\n\nexport interface TableColumn {\n key: string;\n label: string;\n sortable?: boolean;\n filterable?: boolean;\n editable?: boolean;\n width?: string;\n /** Optional CSS class(es) applied to both th and td cells */\n cssClass?: string;\n /** Optional CSS class(es) for td cells only (string or resolver callback) */\n cellClass?: TableCellClass;\n /** Optional inline styles for td cells only (object or resolver callback) */\n cellStyle?: TableCellStyle;\n /** Optional tooltip shown on hover over the column header */\n tooltip?: string;\n /** Optional formatter for cell output when no custom template is used */\n formatter?: (\n value: unknown,\n row: Record<string, unknown>,\n column: TableColumn,\n rowIndex: number\n ) => unknown;\n /** Input type for inline editing (default: text) */\n editType?: 'text' | 'number' | 'select';\n /** Options for select edit type */\n editOptions?: string[];\n}\n\n/**\n * A row-level action rendered in the table's actions column (e.g. Freigeben, Ablehnen).\n * Action button clicks never trigger the row's `rowClick` output.\n */\nexport interface TableAction {\n /** Unique identifier emitted with the {@link ActionClickEvent} */\n key: string;\n /** Visible button label (omit for icon-only buttons when an `icon` is set) */\n label?: string;\n /** Optional icon name rendered before the label */\n icon?: string;\n /** Button variant (default: 'ghost') */\n variant?: ButtonVariant;\n /** Optional tooltip / aria-label, useful for icon-only actions */\n tooltip?: string;\n /** Hide this action for specific rows */\n hidden?: (row: Record<string, unknown>, rowIndex: number) => boolean;\n /** Disable this action for specific rows */\n disabled?: (row: Record<string, unknown>, rowIndex: number) => boolean;\n}\n\nexport type TableActionsAlign = 'start' | 'center' | 'end';\n\nexport interface ActionClickEvent {\n action: string;\n row: Record<string, unknown>;\n rowIndex: number;\n}\n\nexport interface SortEvent {\n column: string;\n direction: 'asc' | 'desc';\n}\n\nexport interface CellEditEvent {\n row: Record<string, unknown>;\n column: string;\n oldValue: unknown;\n newValue: unknown;\n /** Index of `row` in the `data` input (not its position on screen). */\n rowIndex: number;\n}\n\nexport interface SelectionChangeEvent {\n selected: Record<string, unknown>[];\n allSelected: boolean;\n}\n\n/** Emitted when a parent (group) row is expanded or collapsed in tree mode. */\nexport interface RowToggleEvent {\n id: string;\n expanded: boolean;\n row: Record<string, unknown>;\n}\n\n/**\n * Configuration that enables hierarchical (tree / grouped) rows. Mirrors the\n * discrete `idKey` / `parentKey` / `treeColumn` inputs and is exported for\n * consumers that prefer to pass a single config object around.\n */\nexport interface TableTreeConfig {\n idKey: string;\n parentKey: string;\n treeColumn?: string;\n}\n\nexport type TableVariant = 'default' | 'striped' | 'bordered';\nexport type TableSize = 'sm' | 'md' | 'lg';\n\n/**\n * Internal, render-ready view-model for a single visible table row. In flat\n * mode every row is depth 0 with no tree adornments; in tree mode it carries\n * the disclosure / indentation / aria metadata for the row.\n */\ninterface DisplayRow {\n /** The underlying data object. */\n row: Record<string, unknown>;\n /**\n * The row's index into `data()` — in both modes. It is what action, class,\n * style and formatter callbacks receive as `rowIndex`, and what identifies\n * the row in `CellEditEvent`. (It used to be the *positional* index in flat\n * mode — page offset plus row position — which, once a sort or filter was\n * active, pointed at a different row of `data()` than the one on screen.)\n */\n absIndex: number;\n /**\n * What selection and inline editing are keyed by: the row's `idKey` value\n * when the table has one, otherwise the row object itself. Either survives a\n * re-sort, a filter and a page change; an id also survives the parent\n * replacing its data array with fresh objects.\n */\n key: unknown;\n /** Row id (tree mode only; `null` in flat mode). */\n id: string | null;\n /** Tree depth — 0 for roots and for every row in flat mode. */\n depth: number;\n /** 1-based depth, surfaced as `aria-level` in tree mode. */\n level: number;\n /** Whether this row has visible children (renders a chevron). */\n hasChildren: boolean;\n /** Whether this parent row is currently expanded. */\n expanded: boolean;\n /** 1-based position within its sibling group (`aria-posinset`). */\n posInSet: number;\n /** Size of its sibling group (`aria-setsize`). */\n setSize: number;\n}\n\n/**\n * Table component for displaying structured data in rows and columns.\n *\n * Features:\n * - Column-based sorting with sort direction indicators\n * - Variant styles (default, striped, bordered)\n * - Size presets (sm, md, lg)\n * - Hoverable row highlighting\n * - Per-column formatter callbacks for display values\n * - Per-cell class/style callbacks for conditional styling\n * - Custom cell templates via content projection\n * - Composed cells (e.g. avatar + badge + actions)\n * - Hierarchical \"tree\" rows (grouped / expandable) via `idKey` + `parentKey`\n * - Responsive horizontal scrolling\n * - Empty state text for no data\n * - Accessible with proper table semantics\n *\n * @example\n * ```html\n * <lc-table [columns]=\"columns\" [data]=\"data\" variant=\"striped\" [hoverable]=\"true\"\n * (sort)=\"onSort($event)\" (rowClick)=\"onRowClick($event)\" />\n * ```\n *\n * @example\n * ```ts\n * columns: TableColumn[] = [\n * {\n * key: 'amount',\n * label: 'Amount',\n * formatter: (value) => new Intl.NumberFormat('de-DE', {\n * style: 'currency',\n * currency: 'EUR',\n * }).format(Number(value ?? 0)),\n * },\n * ];\n * ```\n */\n@Component({\n selector: 'lc-table',\n standalone: true,\n imports: [NgTemplateOutlet, NgStyle, FormsModule, SelectComponent, InputComponent, ButtonComponent, IconComponent],\n viewProviders: [ɵprovideKitIcons([ICON_CHEVRON_RIGHT])],\n templateUrl: './table.component.html',\n styleUrl: './table.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class TableComponent {\n /** Custom cell templates */\n @ContentChildren(TableCellDirective) cellTemplates!: QueryList<TableCellDirective>;\n\n /** Array of column definitions */\n columns = input<TableColumn[]>([]);\n\n /** Array of data objects to display */\n data = input<Record<string, unknown>[]>([]);\n\n /** Visual variant of the table */\n variant = input<TableVariant>('default');\n\n /** Size of the table */\n size = input<TableSize>('md');\n\n /** Whether rows should highlight on hover */\n hoverable = input<boolean>(false);\n\n /** Whether table should be responsive (horizontal scroll on mobile) */\n responsive = input<boolean>(true);\n\n /** Text shown when data is empty */\n emptyText = input<string>('No data available');\n\n /** Placeholder prefix of the column filters, followed by the column label (`filterable`). */\n filterPlaceholderLabel = input('Filter');\n\n /** Accessible name of the select-all checkbox (`selectable`). */\n selectAllAriaLabel = input('Select all rows');\n\n /** Accessible name of a row checkbox, followed by the row number. */\n selectRowAriaLabel = input('Select row');\n\n /** Screen-reader state of a column sorted ascending. */\n sortedAscendingLabel = input('sorted ascending');\n\n /** Screen-reader state of a column sorted descending. */\n sortedDescendingLabel = input('sorted descending');\n\n /** Tree mode: accessible name prefix of the expand toggle, followed by the row label. */\n expandRowAriaLabel = input('Aufklappen:');\n\n /** Tree mode: accessible name prefix of the collapse toggle, followed by the row label. */\n collapseRowAriaLabel = input('Einklappen:');\n\n /** Pagination: word between the shown range and the total (`1–10 of 42`). */\n rangeOfLabel = input('of');\n\n /** Accessible name of the page-size select. */\n rowsPerPageAriaLabel = input('Rows per page');\n\n /** Accessible name of the previous-page button. */\n previousPageAriaLabel = input('Previous page');\n\n /** Accessible name of the next-page button. */\n nextPageAriaLabel = input('Next page');\n\n // -- Pagination --\n /** Enable pagination */\n paginate = input<boolean>(false);\n\n /** Rows per page */\n pageSize = input<number>(10);\n\n /** Available page size options */\n pageSizeOptions = input<number[]>([5, 10, 25, 50]);\n\n // -- Selection --\n /** Enable row selection checkboxes */\n selectable = input<boolean>(false);\n\n // -- Column Filters --\n /** Enable per-column text filters */\n filterable = input<boolean>(false);\n\n // -- Inline Editing --\n /** Enable inline cell editing on double-click */\n editable = input<boolean>(false);\n\n // -- Row Actions --\n /**\n * Row-level actions rendered in a trailing actions column (e.g. Freigeben / Ablehnen).\n * Clicking an action button does NOT trigger the row's `rowClick` output.\n */\n actions = input<TableAction[]>([]);\n\n /** Header label for the actions column */\n actionsLabel = input<string>('');\n\n /** Width of the actions column (e.g. '120px') */\n actionsWidth = input<string | undefined>(undefined);\n\n /** Horizontal alignment of the action buttons (and header label) within the cell */\n actionsAlign = input<TableActionsAlign>('start');\n\n // -- Tree / grouped rows --\n /**\n * Row field holding the unique id. Required (together with {@link parentKey})\n * to enable hierarchical \"tree mode\". Absent ⇒ today's flat table.\n */\n idKey = input<string | undefined>(undefined);\n\n /**\n * Row field referencing the parent row's id. Presence of both `idKey` and\n * `parentKey` enables tree mode. Rows with an absent/empty or unknown parent\n * id are treated as roots.\n */\n parentKey = input<string | undefined>(undefined);\n\n /** Column key the chevron + indentation attach to. Default: first column. */\n treeColumn = input<string | undefined>(undefined);\n\n /** Initial expand state for all parent rows when uncontrolled. Default: true. */\n defaultExpanded = input<boolean>(true);\n\n /**\n * Controlled set of expanded parent ids. When provided, the table renders\n * exactly these as expanded; combine with {@link expandedIdsChange} for\n * `[(expandedIds)]`. When omitted, expansion is uncontrolled and seeded by\n * {@link defaultExpanded}.\n */\n expandedIds = input<string[] | undefined>(undefined);\n\n /** Indentation per depth level, in px. Default: 20. */\n indentSize = input<number>(20);\n\n /** Accessible name prefix of a column filter, followed by the column label. */\n filterAriaLabel = input('Filter by');\n\n /** Emitted when a sortable column header is clicked */\n readonly sort = output<SortEvent>();\n\n /** Emitted when a row is clicked */\n readonly rowClick = output<Record<string, unknown>>();\n\n /** Emitted when a cell is edited */\n readonly cellEdit = output<CellEditEvent>();\n\n /** Emitted when row selection changes */\n readonly selectionChange = output<SelectionChangeEvent>();\n\n /** Emitted when a row action button is clicked */\n readonly actionClick = output<ActionClickEvent>();\n\n /** Emitted when a parent row is expanded/collapsed (tree mode). */\n readonly rowToggle = output<RowToggleEvent>();\n\n /** Emitted with the full list of expanded parent ids; enables `[(expandedIds)]`. */\n readonly expandedIdsChange = output<string[]>();\n\n // -- Internal state --\n protected currentSort = signal<{ column: string; direction: 'asc' | 'desc' } | null>(null);\n /**\n * Effective page size. Seeded from the `pageSize` input (resetting if it\n * changes) and overridable by the user via the page-size dropdown.\n */\n protected internalPageSize = linkedSignal(() => this.pageSize());\n /**\n * Current page, kept within range: when the data shrinks or the page size\n * grows so that the page no longer exists, it moves back to the last one\n * (rather than showing an empty page captioned \"31–30 of 30\").\n */\n protected currentPage = linkedSignal<number, number>({\n source: () => this.totalPages(),\n computation: (total, previous) => Math.min(previous?.value ?? 0, total - 1),\n });\n /**\n * Selected row keys (see `DisplayRow.key`). Pruned when `data` changes, so\n * a key whose row is gone doesn't linger and count towards \"all selected\".\n */\n protected selectedRows = linkedSignal<Set<unknown>, Set<unknown>>({\n source: () => this.rowKeys(),\n computation: (keys, previous) => {\n if (!previous) return new Set<unknown>();\n const kept = new Set([...previous.value].filter((k) => keys.has(k)));\n return kept.size === previous.value.size ? previous.value : kept;\n },\n });\n protected columnFilters = signal<Record<string, string>>({});\n protected editingCell = signal<{ key: unknown; column: string } | null>(null);\n protected editValue = signal<string>('');\n\n /** The inline-edit input while a cell is being edited. */\n private readonly editInput = viewChild<ElementRef<HTMLInputElement>>('editInput');\n private focusedEditInput: HTMLInputElement | null = null;\n\n constructor() {\n // The edit input is inserted on double-click. `autofocus` is only honoured\n // for elements present when the page loads, so the input never received\n // focus (and Enter/Escape/blur never reached it); focus it once it renders.\n afterRenderEffect(() => {\n const el = this.editInput()?.nativeElement ?? null;\n if (el && el !== this.focusedEditInput) {\n el.focus();\n }\n this.focusedEditInput = el;\n });\n }\n\n /** The key of every row currently in `data()`. */\n private readonly rowKeys = computed(() => new Set(this.data().map((row) => this.rowKey(row))));\n\n /** See `DisplayRow.key`. */\n private rowKey(row: Record<string, unknown>): unknown {\n const idKey = this.idKey();\n return idKey ? String(row[idKey] ?? '') : row;\n }\n /** User expand/collapse overrides keyed by row id (uncontrolled mode). */\n private readonly expandOverrides = signal<Map<string, boolean>>(new Map());\n\n /**\n * Filtered data (applies column filters)\n */\n protected readonly filteredData = computed(() => {\n let items = this.data();\n const filters = this.columnFilters();\n\n if (this.filterable()) {\n for (const [key, value] of Object.entries(filters)) {\n if (value.trim()) {\n items = items.filter(row =>\n String(row[key] ?? '').toLowerCase().includes(value.toLowerCase())\n );\n }\n }\n }\n\n return items;\n });\n\n /** Comparator for the active sort, shared by flat sorting and tree sibling sorting. */\n private rowComparator(sortState: { column: string; direction: 'asc' | 'desc' }) {\n return (a: Record<string, unknown>, b: Record<string, unknown>): number => {\n const aVal = a[sortState.column];\n const bVal = b[sortState.column];\n let cmp = 0;\n if (aVal == null && bVal == null) cmp = 0;\n else if (aVal == null) cmp = -1;\n else if (bVal == null) cmp = 1;\n else if (typeof aVal === 'number' && typeof bVal === 'number') cmp = aVal - bVal;\n else cmp = String(aVal).localeCompare(String(bVal));\n return sortState.direction === 'asc' ? cmp : -cmp;\n };\n }\n\n /**\n * Sorted data\n */\n protected readonly sortedData = computed(() => {\n const items = [...this.filteredData()];\n const sortState = this.currentSort();\n if (!sortState) return items;\n return items.sort(this.rowComparator(sortState));\n });\n\n /**\n * Paginated data (or all if pagination disabled). Flat mode only.\n */\n protected readonly displayData = computed(() => {\n const items = this.sortedData();\n if (!this.paginate()) return items;\n const ps = this.internalPageSize();\n const start = this.currentPage() * ps;\n return items.slice(start, start + ps);\n });\n\n // -- Tree / grouped rows -----------------------------------------------------\n\n /** Whether hierarchical tree mode is active. */\n protected readonly treeMode = computed(() => !!this.idKey() && !!this.parentKey());\n\n /** Column the chevron + indentation attach to (defaults to the first column). */\n protected readonly effectiveTreeColumn = computed(\n () => this.treeColumn() || this.columns()[0]?.key\n );\n\n /** Stable map of row object → its index in `data()` (row identity for tree mode). */\n private readonly dataIndexMap = computed(() => {\n const map = new Map<Record<string, unknown>, number>();\n this.data().forEach((row, i) => map.set(row, i));\n return map;\n });\n\n /** Parent → ordered children index built from `idKey`/`parentKey`. */\n private readonly treeBuild = computed(() => {\n const idKey = this.idKey();\n const parentKey = this.parentKey();\n const byId = new Map<string, Record<string, unknown>>();\n const childrenOf = new Map<string, Record<string, unknown>[]>();\n const roots: Record<string, unknown>[] = [];\n if (!idKey || !parentKey) return { byId, childrenOf, roots };\n\n const rows = this.data();\n for (const row of rows) {\n const id = String(row[idKey] ?? '');\n if (id) byId.set(id, row);\n }\n for (const row of rows) {\n const parentRaw = row[parentKey];\n const parentId = parentRaw == null ? '' : String(parentRaw);\n if (parentId && byId.has(parentId)) {\n const siblings = childrenOf.get(parentId) ?? [];\n siblings.push(row);\n childrenOf.set(parentId, siblings);\n } else {\n // No parent, empty parent, or orphaned (unknown parent) ⇒ root.\n roots.push(row);\n }\n }\n return { byId, childrenOf, roots };\n });\n\n /**\n * Tree restricted to rows that match the active filters together with their\n * ancestor chain (so the path to a match stays visible).\n */\n private readonly treeFiltered = computed(() => {\n const { byId, childrenOf, roots } = this.treeBuild();\n const parentKey = this.parentKey();\n const filters = this.columnFilters();\n const active =\n this.filterable() && parentKey && Object.values(filters).some((v) => v.trim());\n if (!active) return { childrenOf, roots };\n\n const matches = (row: Record<string, unknown>): boolean =>\n Object.entries(filters).every(\n ([key, value]) =>\n !value.trim() ||\n String(row[key] ?? '').toLowerCase().includes(value.toLowerCase())\n );\n\n // Visible = every matching row plus all of its ancestors.\n const visible = new Set<Record<string, unknown>>();\n for (const row of this.data()) {\n if (!matches(row)) continue;\n let current: Record<string, unknown> | undefined = row;\n while (current && !visible.has(current)) {\n visible.add(current);\n const parentRaw: unknown = current[parentKey];\n const parentId = parentRaw == null ? '' : String(parentRaw);\n current = parentId ? byId.get(parentId) : undefined;\n }\n }\n\n const visibleChildrenOf = new Map<string, Record<string, unknown>[]>();\n const visibleRoots: Record<string, unknown>[] = [];\n for (const row of this.data()) {\n if (!visible.has(row)) continue;\n const parentRaw = row[parentKey];\n const parentId = parentRaw == null ? '' : String(parentRaw);\n const parent = parentId ? byId.get(parentId) : undefined;\n if (parent && visible.has(parent)) {\n const siblings = visibleChildrenOf.get(parentId) ?? [];\n siblings.push(row);\n visibleChildrenOf.set(parentId, siblings);\n } else {\n visibleRoots.push(row);\n }\n }\n return { childrenOf: visibleChildrenOf, roots: visibleRoots };\n });\n\n /** Tree with each sibling group sorted by the active sort (structure kept intact). */\n private readonly treeSorted = computed(() => {\n const { childrenOf, roots } = this.treeFiltered();\n const sortState = this.currentSort();\n if (!sortState) return { childrenOf, roots };\n const cmp = this.rowComparator(sortState);\n const sortedChildrenOf = new Map<string, Record<string, unknown>[]>();\n for (const [parentId, siblings] of childrenOf) {\n sortedChildrenOf.set(parentId, [...siblings].sort(cmp));\n }\n return { childrenOf: sortedChildrenOf, roots: [...roots].sort(cmp) };\n });\n\n /** Root rows after filter/sort — the unit of pagination in tree mode. */\n private readonly treeRoots = computed(() => this.treeSorted().roots);\n\n /**\n * Render-ready rows. In flat mode this wraps the existing paginated data; in\n * tree mode it paginates roots and flattens each visible (expanded) subtree.\n */\n protected readonly displayRows = computed<DisplayRow[]>(() => {\n const dataIndex = this.dataIndexMap();\n if (!this.treeMode()) {\n return this.displayData().map((row) => ({\n row,\n absIndex: dataIndex.get(row) ?? -1,\n key: this.rowKey(row),\n id: null,\n depth: 0,\n level: 0,\n hasChildren: false,\n expanded: false,\n posInSet: 0,\n setSize: 0,\n }));\n }\n\n const idKey = this.idKey() as string;\n const { childrenOf } = this.treeSorted();\n let roots = this.treeRoots();\n if (this.paginate()) {\n const ps = this.internalPageSize();\n const start = this.currentPage() * ps;\n roots = roots.slice(start, start + ps);\n }\n\n const out: DisplayRow[] = [];\n const walk = (group: Record<string, unknown>[], depth: number): void => {\n group.forEach((row, idx) => {\n const id = String(row[idKey] ?? '');\n const children = childrenOf.get(id) ?? [];\n const hasChildren = children.length > 0;\n const expanded = hasChildren && this.isExpanded(id);\n out.push({\n row,\n absIndex: dataIndex.get(row) ?? -1,\n key: this.rowKey(row),\n id,\n depth,\n level: depth + 1,\n hasChildren,\n expanded,\n posInSet: idx + 1,\n setSize: group.length,\n });\n if (expanded) walk(children, depth + 1);\n });\n };\n walk(roots, 0);\n return out;\n });\n\n /** Total pages */\n protected readonly totalPages = computed(() => {\n if (!this.paginate()) return 1;\n const total = this.treeMode() ? this.treeRoots().length : this.filteredData().length;\n return Math.max(1, Math.ceil(total / this.internalPageSize()));\n });\n\n /**\n * Pagination row count. Tree mode counts root rows (the paginated unit); flat\n * mode counts filtered rows.\n */\n protected readonly totalRows = computed(() =>\n this.treeMode() ? this.treeRoots().length : this.filteredData().length\n );\n\n /** Whether all visible rows are selected */\n protected readonly allSelected = computed(() => {\n const rows = this.displayRows();\n if (rows.length === 0) return false;\n const selected = this.selectedRows();\n return rows.every((r) => selected.has(r.key));\n });\n\n /** Whether some, but not all, visible rows are selected — the header box's mixed state. */\n protected readonly someSelected = computed(() => {\n const selected = this.selectedRows();\n return !this.allSelected() && this.displayRows().some((r) => selected.has(r.key));\n });\n\n protected readonly pageSizeSelectOptions = computed(() =>\n this.pageSizeOptions().map((opt) => ({\n value: opt,\n label: `${opt} / page`,\n }))\n );\n\n /**\n * Computed CSS classes for the table element\n */\n tableClasses = computed(() => {\n const classes = ['lc-table'];\n classes.push(`lc-table--${this.variant()}`);\n classes.push(`lc-table--${this.size()}`);\n if (this.hoverable()) classes.push('lc-table--hoverable');\n return classes.join(' ');\n });\n\n /**\n * Computed CSS classes for the wrapper element\n */\n wrapperClasses = computed(() => {\n const classes = ['lc-table-wrapper'];\n if (this.responsive()) classes.push('lc-table-wrapper--responsive');\n return classes.join(' ');\n });\n\n // -- Sort --\n handleSort(columnKey: string): void {\n const column = this.columns().find((col) => col.key === columnKey);\n if (!column || !column.sortable) return;\n\n const current = this.currentSort();\n let direction: 'asc' | 'desc' = 'asc';\n if (current && current.column === columnKey) {\n direction = current.direction === 'asc' ? 'desc' : 'asc';\n }\n\n this.currentSort.set({ column: columnKey, direction });\n this.sort.emit({ column: columnKey, direction });\n }\n\n getSortState(columnKey: string): 'asc' | 'desc' | null {\n const current = this.currentSort();\n if (current && current.column === columnKey) return current.direction;\n return null;\n }\n\n getAriaSort(columnKey: string): string | null {\n const sortState = this.getSortState(columnKey);\n if (sortState === 'asc') return 'ascending';\n if (sortState === 'desc') return 'descending';\n return null;\n }\n\n getHeaderClasses(column: TableColumn): string {\n const classes: string[] = [];\n if (column.sortable) classes.push('sortable');\n const sortState = this.getSortState(column.key);\n if (sortState) classes.push(`sorted-${sortState}`);\n return classes.join(' ');\n }\n\n getCellValue(row: Record<string, unknown>, columnKey: string): unknown {\n return row[columnKey];\n }\n\n getFormattedCellValue(\n row: Record<string, unknown>,\n column: TableColumn,\n rowIndex: number\n ): unknown {\n const value = this.getCellValue(row, column.key);\n if (!column.formatter) return value;\n\n return column.formatter(value, row, column, rowIndex);\n }\n\n getCellClasses(\n row: Record<string, unknown>,\n column: TableColumn,\n rowIndex: number\n ): string {\n const classes: string[] = [];\n if (column.cssClass) classes.push(column.cssClass);\n\n if (typeof column.cellClass === 'string') {\n classes.push(column.cellClass);\n } else if (typeof column.cellClass === 'function') {\n const resolved = column.cellClass(\n this.getCellValue(row, column.key),\n row,\n column,\n rowIndex\n );\n if (resolved) classes.push(resolved);\n }\n\n return classes.join(' ').trim();\n }\n\n getCellStyles(\n row: Record<string, unknown>,\n column: TableColumn,\n rowIndex: number\n ): Record<string, string> | null {\n if (!column.cellStyle) return null;\n\n if (typeof column.cellStyle === 'function') {\n return column.cellStyle(\n this.getCellValue(row, column.key),\n row,\n column,\n rowIndex\n );\n }\n\n return column.cellStyle;\n }\n\n /** Whether the given column is the disclosure/indent column in tree mode. */\n protected isTreeColumn(columnKey: string): boolean {\n return this.treeMode() && columnKey === this.effectiveTreeColumn();\n }\n\n /** Indent levels to render before a row's chevron (one guide per ancestor depth). */\n protected indentLevels(depth: number): number[] {\n return Array.from({ length: depth }, (_, i) => i);\n }\n\n /** Accessible name for a row's disclosure button (the tree column's value). */\n protected treeCellLabel(row: Record<string, unknown>): string {\n const col = this.effectiveTreeColumn();\n return col ? String(row[col] ?? '') : '';\n }\n\n getCellTemplate(columnKey: string): TableCellDirective | undefined {\n return this.cellTemplates?.find((template) => template.columnKey() === columnKey);\n }\n\n hasCustomTemplate(columnKey: string): boolean {\n return !!this.getCellTemplate(columnKey);\n }\n\n onRowClick(row: Record<string, unknown>): void {\n this.rowClick.emit(row);\n }\n\n // -- Row Actions --\n /** Whether the trailing actions column should be rendered */\n protected readonly hasActions = computed(() => this.actions().length > 0);\n\n protected isActionHidden(\n action: TableAction,\n row: Record<string, unknown>,\n rowIndex: number\n ): boolean {\n return action.hidden ? action.hidden(row, rowIndex) : false;\n }\n\n protected isActionDisabled(\n action: TableAction,\n row: Record<string, unknown>,\n rowIndex: number\n ): boolean {\n return action.disabled ? action.disabled(row, rowIndex) : false;\n }\n\n /**\n * Handles an action button click. The DOM click is stopped from propagating\n * (see template `$event.stopPropagation()`), so the row's `rowClick` never fires.\n */\n protected onActionClick(\n action: TableAction,\n row: Record<string, unknown>,\n rowIndex: number\n ): void {\n this.actionClick.emit({\n action: action.key,\n row,\n rowIndex,\n });\n }\n\n // -- Tree keyboard model -----------------------------------------------------\n // `role=\"treegrid\"` promises a composite widget: one tab stop, arrows to move\n // between rows, Right/Left to open/close a group or step into/out of it. The\n // rows carry a roving tabindex; the focused row is remembered by key so it\n // survives re-renders, and falls back to the first row when it is gone.\n\n private readonly rowEls = viewChildren<ElementRef<HTMLTableRowElement>>('dataRow');\n private readonly focusedRowKey = signal<unknown>(null);\n\n /** Key of the row that holds the tab stop. */\n private readonly effectiveFocusedKey = computed(() => {\n const rows = this.displayRows();\n const key = this.focusedRowKey();\n return rows.some((r) => r.key === key) ? key : rows[0]?.key;\n });\n\n protected rowTabindex(dr: DisplayRow): number | null {\n if (!this.treeMode()) return null;\n return dr.key === this.effectiveFocusedKey() ? 0 : -1;\n }\n\n protected onRowFocus(dr: DisplayRow): void {\n if (this.treeMode()) this.focusedRowKey.set(dr.key);\n }\n\n protected onRowKeydown(event: KeyboardEvent, dr: DisplayRow): void {\n if (!this.treeMode()) return;\n // Keys typed into an inline editor or the row's own controls are theirs.\n if ((event.target as HTMLElement).tagName === 'INPUT') return;\n const rows = this.displayRows();\n const index = rows.findIndex((r) => r.key === dr.key);\n if (index < 0) return;\n\n switch (event.key) {\n case 'ArrowDown':\n this.focusRow(index + 1);\n break;\n case 'ArrowUp':\n this.focusRow(index - 1);\n break;\n case 'Home':\n this.focusRow(0);\n break;\n case 'End':\n this.focusRow(rows.length - 1);\n break;\n case 'ArrowRight':\n if (!dr.hasChildren) return;\n if (dr.expanded) this.focusRow(index + 1); // first child\n else if (dr.id) this.toggleRow(dr.id, dr.row);\n break;\n case 'ArrowLeft':\n if (dr.hasChildren && dr.expanded && dr.id) {\n this.toggleRow(dr.id, dr.row);\n } else if (dr.depth > 0) {\n // Step out to the parent: the nearest row above with a smaller depth.\n for (let i = index - 1; i >= 0; i--) {\n if (rows[i].depth < dr.depth) {\n this.focusRow(i);\n break;\n }\n }\n } else {\n return;\n }\n break;\n case 'Enter':\n this.rowClick.emit(dr.row);\n break;\n case ' ':\n if (!this.selectable()) return;\n this.toggleRowSelect(dr.row);\n break;\n default:\n return;\n }\n event.preventDefault();\n }\n\n private focusRow(index: number): void {\n const rows = this.displayRows();\n if (index < 0 || index >= rows.length) return;\n this.focusedRowKey.set(rows[index].key);\n this.rowEls()[index]?.nativeElement.focus();\n }\n\n // -- Tree expand / collapse --------------------------------------------------\n\n /** Whether the parent row with the given id is currently expanded. */\n protected isExpanded(id: string): boolean {\n const controlled = this.expandedIds();\n if (controlled !== undefined) return controlled.includes(id);\n const override = this.expandOverrides().get(id);\n if (override !== undefined) return override;\n return this.defaultExpanded();\n }\n\n /** Chevron click: toggle expand state without triggering the row click. */\n protected onChevronClick(displayRow: DisplayRow, event: Event): void {\n event.stopPropagation();\n if (displayRow.id) this.toggleRow(displayRow.id, displayRow.row);\n }\n\n private toggleRow(id: string, row: Record<string, unknown>): void {\n const expanded = !this.isExpanded(id);\n this.expandOverrides.update((map) => {\n const next = new Map(map);\n next.set(id, expanded);\n return next;\n });\n this.rowToggle.emit({ id, expanded, row });\n this.expandedIdsChange.emit(this.nextExpandedIds(id, expanded));\n }\n\n /** The full list of expanded parent ids after applying a single toggle. */\n private nextExpandedIds(changedId: string, changedExpanded: boolean): string[] {\n const controlled = this.expandedIds();\n const overrides = this.expandOverrides();\n const parentIds = Array.from(this.treeBuild().childrenOf.keys());\n return parentIds.filter((pid) => {\n if (pid === changedId) return changedExpanded;\n if (controlled !== undefined) return controlled.includes(pid);\n const override = overrides.get(pid);\n return override !== undefined ? override : this.defaultExpanded();\n });\n }\n\n // -- Pagination --\n protected goToPage(page: number): void {\n if (page >= 0 && page < this.totalPages()) {\n this.currentPage.set(page);\n }\n }\n\n protected onPageSizeChange(event: Event): void {\n const newSize = Number((event.target as HTMLSelectElement).value);\n this.internalPageSize.set(newSize);\n this.currentPage.set(0);\n }\n\n protected onPageSizeModelChange(value: string | number | null): void {\n if (value == null) {\n return;\n }\n const parsed = typeof value === 'number' ? value : Number(value);\n if (!Number.isFinite(parsed)) {\n return;\n }\n this.internalPageSize.set(parsed);\n this.currentPage.set(0);\n }\n\n protected get paginationStart(): number {\n if (this.totalRows() === 0) return 0;\n return this.currentPage() * this.internalPageSize() + 1;\n }\n\n protected get paginationEnd(): number {\n return Math.min((this.currentPage() + 1) * this.internalPageSize(), this.totalRows());\n }\n\n // -- Selection --\n // Keyed by row identity (see `DisplayRow.key`), never by position: a sort or\n // filter changes where a row is shown, not which row it is.\n protected toggleSelectAll(): void {\n const selected = new Set(this.selectedRows());\n const rows = this.displayRows();\n const allSelected = this.allSelected();\n\n rows.forEach((r) => {\n if (allSelected) selected.delete(r.key);\n else selected.add(r.key);\n });\n\n this.selectedRows.set(selected);\n this.emitSelectionChange();\n }\n\n protected toggleRowSelect(row: Record<string, unknown>): void {\n const key = this.rowKey(row);\n const selected = new Set(this.selectedRows());\n if (selected.has(key)) selected.delete(key);\n else selected.add(key);\n this.selectedRows.set(selected);\n this.emitSelectionChange();\n }\n\n protected isRowSelected(row: Record<string, unknown>): boolean {\n return this.selectedRows().has(this.rowKey(row));\n }\n\n private emitSelectionChange(): void {\n const keys = this.selectedRows();\n // In data order, so the consumer gets a stable list whatever the sort.\n const selected = this.data().filter((row) => keys.has(this.rowKey(row)));\n this.selectionChange.emit({ selected, allSelected: this.allSelected() });\n }\n\n // -- Column Filters --\n protected onFilterChange(columnKey: string, value: string): void {\n const filters = { ...this.columnFilters(), [columnKey]: value };\n this.columnFilters.set(filters);\n this.currentPage.set(0);\n }\n\n protected getFilterValue(columnKey: string): string {\n return this.columnFilters()[columnKey] || '';\n }\n\n // -- Inline Editing --\n // Keyed by row identity too — the edited cell is the one the user clicked,\n // whichever position sorting put it in.\n protected startEdit(row: Record<string, unknown>, column: string, currentValue: unknown): void {\n if (!this.editable()) return;\n const col = this.columns().find(c => c.key === column);\n if (col && col.editable === false) return;\n this.editingCell.set({ key: this.rowKey(row), column });\n this.editValue.set(String(currentValue ?? ''));\n }\n\n protected isEditing(row: Record<string, unknown>, column: string): boolean {\n const cell = this.editingCell();\n return cell !== null && cell.key === this.rowKey(row) && cell.column === column;\n }\n\n protected commitEdit(row: Record<string, unknown>, column: string): void {\n // Only the cell being edited commits: the input's blur arrives after Enter\n // or Escape already ended the edit, and must not commit (or re-commit).\n if (!this.isEditing(row, column)) return;\n const oldValue = row[column];\n const newValue = this.editValue();\n this.editingCell.set(null);\n this.editValue.set('');\n if (String(oldValue ?? '') !== newValue) {\n const rowIndex = this.dataIndexMap().get(row) ?? -1;\n this.cellEdit.emit({ row, column, oldValue, newValue, rowIndex });\n }\n }\n\n protected cancelEdit(): void {\n this.editingCell.set(null);\n this.editValue.set('');\n }\n\n protected onEditKeydown(event: KeyboardEvent, row: Record<string, unknown>, column: string): void {\n if (event.key === 'Enter') {\n this.commitEdit(row, column);\n } else if (event.key === 'Escape') {\n this.cancelEdit();\n }\n }\n\n /** Enter/Space on a focused sortable header sorts, like a click does. */\n protected onHeaderKeydown(event: KeyboardEvent, columnKey: string): void {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.handleSort(columnKey);\n }\n }\n\n protected getInputValue(event: Event): string {\n return (event.target as HTMLInputElement).value;\n }\n}\n","<div [class]=\"wrapperClasses()\">\n <table [class]=\"tableClasses()\" [attr.role]=\"treeMode() ? 'treegrid' : 'table'\">\n <thead>\n <!-- Filter row -->\n @if (filterable()) {\n <tr class=\"lc-table__filter-row\">\n @if (selectable()) {\n <th class=\"lc-table__select-cell\"></th>\n }\n @for (column of columns(); track column.key) {\n <th>\n @if (column.filterable !== false) {\n <lc-input\n class=\"lc-table__filter-input\"\n size=\"xs\"\n [placeholder]=\"filterPlaceholderLabel() + ' ' + column.label\"\n [ariaLabel]=\"filterAriaLabel() + ' ' + column.label\"\n [ngModel]=\"getFilterValue(column.key)\"\n (ngModelChange)=\"onFilterChange(column.key, $event)\"\n />\n }\n </th>\n }\n @if (hasActions()) {\n <th class=\"lc-table__actions-cell\"></th>\n }\n </tr>\n }\n <!-- Header row -->\n <tr>\n @if (selectable()) {\n <th class=\"lc-table__select-cell\" scope=\"col\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"allSelected()\"\n [indeterminate]=\"someSelected()\"\n (change)=\"toggleSelectAll()\"\n [attr.aria-label]=\"selectAllAriaLabel()\"\n />\n </th>\n }\n @for (column of columns(); track column.key) {\n <!-- A sortable header is a keyboard stop too: Enter/Space sort like a click. -->\n <th\n scope=\"col\"\n [class]=\"getHeaderClasses(column) + (column.cssClass ? ' ' + column.cssClass : '')\"\n [attr.aria-sort]=\"getAriaSort(column.key)\"\n [attr.tabindex]=\"column.sortable ? 0 : null\"\n [style.width]=\"column.width\"\n [title]=\"column.tooltip || ''\"\n (click)=\"handleSort(column.key)\"\n (keydown)=\"column.sortable ? onHeaderKeydown($event, column.key) : null\">\n {{ column.label }}\n @if (column.sortable && getSortState(column.key)) {\n <span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? sortedAscendingLabel() : sortedDescendingLabel()\">\n @if (getSortState(column.key) === 'asc') {\n ↑\n } @else {\n ↓\n }\n </span>\n }\n </th>\n }\n @if (hasActions()) {\n <th\n scope=\"col\"\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n [style.width]=\"actionsWidth()\"\n >\n {{ actionsLabel() }}\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (displayRows().length === 0) {\n <tr>\n <td [attr.colspan]=\"columns().length + (selectable() ? 1 : 0) + (hasActions() ? 1 : 0)\" class=\"lc-table__empty\">\n {{ emptyText() }}\n </td>\n </tr>\n } @else {\n @for (dr of displayRows(); track dr.key) {\n <!-- In tree mode the rows form the treegrid's keyboard model: a roving\n tab stop plus Arrow/Home/End/Enter/Space handling (see the\n component). Flat mode keeps plain table rows. -->\n <tr\n #dataRow\n [class.lc-table__row--selected]=\"selectable() && isRowSelected(dr.row)\"\n [class.lc-table__row--group]=\"dr.hasChildren\"\n [attr.role]=\"treeMode() ? 'row' : null\"\n [attr.tabindex]=\"rowTabindex(dr)\"\n [attr.aria-level]=\"treeMode() ? dr.level : null\"\n [attr.aria-expanded]=\"treeMode() && dr.hasChildren ? dr.expanded : null\"\n [attr.aria-posinset]=\"treeMode() ? dr.posInSet : null\"\n [attr.aria-setsize]=\"treeMode() ? dr.setSize : null\"\n [attr.aria-selected]=\"treeMode() && selectable() ? isRowSelected(dr.row) : null\"\n (click)=\"onRowClick(dr.row)\"\n (focus)=\"onRowFocus(dr)\"\n (keydown)=\"onRowKeydown($event, dr)\"\n >\n @if (selectable()) {\n <td class=\"lc-table__select-cell\" [attr.role]=\"treeMode() ? 'gridcell' : null\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"isRowSelected(dr.row)\"\n (change)=\"toggleRowSelect(dr.row)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"selectRowAriaLabel() + ' ' + (dr.absIndex + 1)\"\n />\n </td>\n }\n @for (column of columns(); track column.key) {\n <td\n [class]=\"getCellClasses(dr.row, column, dr.absIndex)\"\n [ngStyle]=\"getCellStyles(dr.row, column, dr.absIndex)\"\n [attr.role]=\"treeMode() ? 'gridcell' : null\"\n (dblclick)=\"editable() ? startEdit(dr.row, column.key, getCellValue(dr.row, column.key)) : null\"\n >\n @if (isTreeColumn(column.key)) {\n <span class=\"lc-table__tree-cell\">\n @for (lvl of indentLevels(dr.depth); track lvl) {\n <span class=\"lc-table__tree-indent\" [style.width.px]=\"indentSize()\"></span>\n }\n <span class=\"lc-table__tree-chevron\" [style.width.px]=\"indentSize()\">\n @if (dr.hasChildren) {\n <button\n type=\"button\"\n class=\"lc-table__chevron-btn\"\n [class.lc-table__chevron-btn--expanded]=\"dr.expanded\"\n [attr.aria-label]=\"(dr.expanded ? collapseRowAriaLabel() : expandRowAriaLabel()) + ' ' + treeCellLabel(dr.row)\"\n [attr.aria-expanded]=\"dr.expanded\"\n (click)=\"onChevronClick(dr, $event)\"\n >\n <lc-icon name=\"chevron-right\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </span>\n <span class=\"lc-table__tree-content\">\n <ng-container\n *ngTemplateOutlet=\"cellContent; context: { row: dr.row, column: column, absIndex: dr.absIndex }\"\n ></ng-container>\n </span>\n </span>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"cellContent; context: { row: dr.row, column: column, absIndex: dr.absIndex }\"\n ></ng-container>\n }\n </td>\n }\n @if (hasActions()) {\n <td\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n [attr.role]=\"treeMode() ? 'gridcell' : null\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"lc-table__actions\">\n @for (action of actions(); track action.key) {\n @if (!isActionHidden(action, dr.row, dr.absIndex)) {\n <lc-button\n [variant]=\"action.variant ?? 'ghost'\"\n size=\"xs\"\n [iconOnly]=\"!action.label\"\n [disabled]=\"isActionDisabled(action, dr.row, dr.absIndex)\"\n [ariaLabel]=\"action.tooltip ?? action.label ?? action.key\"\n (clicked)=\"onActionClick(action, dr.row, dr.absIndex)\"\n >\n @if (action.icon) {\n <lc-icon [name]=\"action.icon\" size=\"sm\" [decorative]=\"true\" />\n }\n @if (action.label) {\n {{ action.label }}\n }\n </lc-button>\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Shared cell content (edit input / custom template / formatted value) -->\n<ng-template #cellContent let-row=\"row\" let-column=\"column\" let-absIndex=\"absIndex\">\n @if (isEditing(row, column.key)) {\n <input\n #editInput\n type=\"text\"\n class=\"lc-table__edit-input\"\n [value]=\"editValue()\"\n (input)=\"editValue.set(getInputValue($event))\"\n (blur)=\"commitEdit(row, column.key)\"\n (keydown)=\"onEditKeydown($event, row, column.key)\"\n />\n } @else if (hasCustomTemplate(column.key)) {\n <ng-container *ngTemplateOutlet=\"getCellTemplate(column.key)!.template; context: { $implicit: row }\"></ng-container>\n } @else {\n {{ getFormattedCellValue(row, column, absIndex) }}\n }\n</ng-template>\n\n<!-- Pagination -->\n@if (paginate()) {\n <div class=\"lc-table-pagination\">\n <div class=\"lc-table-pagination__info\">\n {{ paginationStart }}–{{ paginationEnd }} {{ rangeOfLabel() }} {{ totalRows() }}\n </div>\n <div class=\"lc-table-pagination__controls\">\n <lc-select\n class=\"lc-table-pagination__size\"\n [size]=\"size() === 'sm' ? 'sm' : size() === 'lg' ? 'lg' : 'md'\"\n [options]=\"pageSizeSelectOptions()\"\n [ngModel]=\"internalPageSize()\"\n [ariaLabel]=\"rowsPerPageAriaLabel()\"\n (ngModelChange)=\"onPageSizeModelChange($event)\"\n />\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() === 0\"\n (click)=\"goToPage(currentPage() - 1)\"\n [attr.aria-label]=\"previousPageAriaLabel()\"\n >‹</button>\n <span class=\"lc-table-pagination__page\">\n {{ currentPage() + 1 }} / {{ totalPages() }}\n </span>\n <button\n type=\"button\"\n class=\"lc-table-pagination__btn\"\n [disabled]=\"currentPage() >= totalPages() - 1\"\n (click)=\"goToPage(currentPage() + 1)\"\n [attr.aria-label]=\"nextPageAriaLabel()\"\n >›</button>\n </div>\n </div>\n}\n"],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  import * as i0 from "@angular/core";
2
2
  import { ChangeDetectionStrategy, Component, Injectable, PLATFORM_ID, ViewEncapsulation, computed, inject, input, output, signal } from "@angular/core";
3
3
  import { isPlatformBrowser } from "@angular/common";
4
- import { IconComponent } from "@lifecorner/angular-ui-kit/icon";
4
+ import { IconComponent, ɵprovideKitIcons } from "@lifecorner/angular-ui-kit/icon";
5
+ import { ICON_CHECK_CIRCLE, ICON_CIRCLE_X, ICON_EXCLAMATION_TRIANGLE, ICON_INFORMATION_CIRCLE, ICON_X_MARK } from "@lifecorner/angular-ui-kit/icons";
5
6
  var ToastService = class ToastService {
6
7
  toasts;
7
8
  toastList = signal([], ...ngDevMode ? [{ debugName: "toastList" }] : /* istanbul ignore next */ []);
@@ -194,6 +195,13 @@ var ToastComponent = class ToastComponent {
194
195
  "strict"
195
196
  ]
196
197
  }],
198
+ viewProviders: [ɵprovideKitIcons([
199
+ ICON_X_MARK,
200
+ ICON_CHECK_CIRCLE,
201
+ ICON_CIRCLE_X,
202
+ ICON_EXCLAMATION_TRIANGLE,
203
+ ICON_INFORMATION_CIRCLE
204
+ ])],
197
205
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
198
206
  encapsulation: i0.ViewEncapsulation.None
199
207
  });
@@ -209,6 +217,13 @@ i0.ɵɵngDeclareClassMetadata({
209
217
  selector: "lc-toast",
210
218
  standalone: true,
211
219
  imports: [IconComponent],
220
+ viewProviders: [ɵprovideKitIcons([
221
+ ICON_X_MARK,
222
+ ICON_CHECK_CIRCLE,
223
+ ICON_CIRCLE_X,
224
+ ICON_EXCLAMATION_TRIANGLE,
225
+ ICON_INFORMATION_CIRCLE
226
+ ])],
212
227
  encapsulation: ViewEncapsulation.None,
213
228
  changeDetection: ChangeDetectionStrategy.OnPush,
214
229
  host: {
@@ -1 +1 @@
1
- {"version":3,"file":"lifecorner-angular-ui-kit-toast.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/toast/toast.service.ts","../../../../libs/angular-ui-kit/src/lib/toast/toast.component.ts","../../../../libs/angular-ui-kit/src/lib/toast/toast.component.html","../../../../libs/angular-ui-kit/src/lib/toast/toast-outlet.component.ts","../../../../libs/angular-ui-kit/src/lib/toast/toast-outlet.component.html"],"sourcesContent":["import { Injectable, PLATFORM_ID, inject, signal, Signal } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\n\nexport type ToastVariant = 'success' | 'error' | 'warning' | 'info';\nexport type ToastPosition =\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right';\n\nexport interface ToastAction {\n label: string;\n onClick: () => void;\n}\n\nexport interface ToastConfig {\n message: string;\n variant?: ToastVariant;\n position?: ToastPosition;\n duration?: number;\n showCloseButton?: boolean;\n action?: ToastAction;\n}\n\nexport interface Toast extends Required<Omit<ToastConfig, 'action'>> {\n id: string;\n action?: ToastAction;\n}\n\n/**\n * Toast service for showing ephemeral notifications.\n *\n * The toasts are rendered by `<lc-toast-outlet />`, which the application\n * places once (e.g. in its shell); without it nothing is shown.\n *\n * @example\n * ```typescript\n * private readonly toastService = inject(ToastService);\n *\n * showSuccess() {\n * this.toastService.show({\n * message: 'Changes saved successfully!',\n * variant: 'success',\n * duration: 3000\n * });\n * }\n * ```\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class ToastService {\n /**\n * Public readonly signal for toasts\n */\n public readonly toasts: Signal<readonly Toast[]>;\n\n /**\n * Internal signal for toast list\n */\n private readonly toastList = signal<Toast[]>([]);\n\n private readonly MAX_TOASTS = 5;\n private toastIdCounter = 0;\n private activeTimeouts = new Map<string, ReturnType<typeof setTimeout>>();\n /** Auto-dismiss timers only make sense in the browser (and `window` does not exist on the server). */\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n constructor() {\n this.toasts = this.toastList.asReadonly();\n }\n\n /**\n * Show a toast notification\n */\n show(config: ToastConfig): string {\n const toast: Toast = {\n id: this.generateId(),\n message: config.message,\n variant: config.variant || 'info',\n position: config.position || 'top-right',\n duration: config.duration !== undefined ? config.duration : 3000,\n showCloseButton: config.showCloseButton !== undefined ? config.showCloseButton : true,\n action: config.action,\n };\n\n // Add toast to list\n let currentToasts = this.toastList();\n\n // Remove oldest toast if at max capacity\n if (currentToasts.length >= this.MAX_TOASTS) {\n const oldestToast = currentToasts[0];\n if (oldestToast) {\n this.clearTimeout(oldestToast.id);\n currentToasts = currentToasts.slice(1);\n }\n }\n\n this.toastList.set([...currentToasts, toast]);\n\n // Auto-dismiss if duration > 0\n if (toast.duration > 0 && this.isBrowser) {\n const timeoutId = setTimeout(() => {\n this.close(toast.id);\n }, toast.duration);\n\n this.activeTimeouts.set(toast.id, timeoutId);\n }\n\n return toast.id;\n }\n\n /**\n * Close a specific toast\n */\n close(id: string): void {\n this.removeToast(id);\n }\n\n /**\n * Close all toasts\n */\n closeAll(): void {\n const currentToasts = this.toastList();\n currentToasts.forEach((toast) => {\n this.clearTimeout(toast.id);\n });\n this.toastList.set([]);\n }\n\n /**\n * Generate unique toast ID\n */\n private generateId(): string {\n return `toast-${++this.toastIdCounter}-${Date.now()}`;\n }\n\n /**\n * Remove a toast from the list\n */\n private removeToast(id: string): void {\n this.clearTimeout(id);\n const currentToasts = this.toastList();\n this.toastList.set(currentToasts.filter((t) => t.id !== id));\n }\n\n /**\n * Clear timeout for a toast\n */\n private clearTimeout(id: string): void {\n const timeoutId = this.activeTimeouts.get(id);\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n this.activeTimeouts.delete(id);\n }\n }\n}\n","import {\n Component,\n ChangeDetectionStrategy,\n input,\n output,\n computed,\n ViewEncapsulation,\n} from '@angular/core';\nimport { IconComponent } from '@lifecorner/angular-ui-kit/icon';\nimport type { Toast, ToastVariant } from './toast.service';\n\n/**\n * Toast component for displaying ephemeral notification messages.\n *\n * Features:\n * - Semantic variants (success, warning, error, info)\n * - Auto-dismiss with configurable duration\n * - Manual dismiss with close button\n * - Icon display per variant\n * - Stacked toast positioning via ToastService + `<lc-toast-outlet />`\n * - Animated enter/exit transitions\n *\n * Usually rendered by `<lc-toast-outlet />`; can also be placed directly:\n *\n * @example\n * ```html\n * <lc-toast [toast]=\"toast\" (closed)=\"dismiss($event)\" />\n * ```\n */\n@Component({\n selector: 'lc-toast',\n standalone: true,\n imports: [IconComponent],\n templateUrl: './toast.component.html',\n styleUrls: ['./toast.component.scss'],\n encapsulation: ViewEncapsulation.None, // Required for dynamic variant class styling\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'hostClasses()',\n '[attr.role]': 'ariaRole()',\n '[attr.aria-live]': 'ariaLive()',\n '[attr.aria-atomic]': 'announce() ? \"true\" : null',\n },\n})\nexport class ToastComponent {\n /**\n * Toast data\n */\n toast = input.required<Toast>();\n\n /**\n * Whether the toast is its own live region (`role=\"status\"`/`\"alert\"` on the\n * host). `lc-toast-outlet` sets this to false because its persistent live\n * regions already announce the toast — announcing twice would be noise.\n * @default true\n */\n announce = input<boolean>(true);\n\n /** Accessible name of the close button (`toast.showCloseButton`). */\n closeAriaLabel = input('Close notification');\n\n /**\n * Emitted when toast is closed\n */\n readonly closed = output<string>();\n\n /**\n * Computed host classes\n */\n protected hostClasses = computed(() => {\n const toast = this.toast();\n return `lc-toast lc-toast--${toast.variant}`;\n });\n\n /**\n * Computed container classes\n */\n protected containerClasses = computed(() => {\n return 'lc-toast__container';\n });\n\n /**\n * Computed ARIA role\n */\n protected ariaRole = computed(() => {\n if (!this.announce()) return null;\n const variant = this.toast().variant;\n return variant === 'error' || variant === 'warning' ? 'alert' : 'status';\n });\n\n /**\n * Computed ARIA live region priority\n */\n protected ariaLive = computed(() => {\n if (!this.announce()) return null;\n const variant = this.toast().variant;\n return variant === 'error' || variant === 'warning' ? 'assertive' : 'polite';\n });\n\n /**\n * Computed default icon based on variant\n */\n protected defaultIcon = computed(() => {\n const icons: Record<ToastVariant, string> = {\n success: 'check-circle',\n error: 'x-circle',\n warning: 'exclamation-triangle',\n info: 'information-circle',\n };\n return icons[this.toast().variant];\n });\n\n /**\n * Handle close button click\n */\n protected onCloseClick(event: Event): void {\n event.preventDefault();\n event.stopPropagation();\n this.closed.emit(this.toast().id);\n }\n\n /**\n * Handle action button click\n */\n protected onActionClick(event: Event): void {\n event.preventDefault();\n event.stopPropagation();\n const action = this.toast().action;\n if (action) {\n action.onClick();\n this.closed.emit(this.toast().id);\n }\n }\n}\n","<div [class]=\"containerClasses()\">\n <div class=\"lc-toast__icon\">\n <lc-icon [name]=\"defaultIcon()\" size=\"md\" />\n </div>\n \n <div class=\"lc-toast__message\">\n {{ toast().message }}\n </div>\n \n @if (toast().action) {\n <button\n type=\"button\"\n class=\"lc-toast__action\"\n (click)=\"onActionClick($event)\"\n >\n {{ toast().action?.label }}\n </button>\n }\n \n @if (toast().showCloseButton) {\n <button\n type=\"button\"\n class=\"lc-toast__close\"\n [attr.aria-label]=\"closeAriaLabel()\"\n (click)=\"onCloseClick($event)\"\n >\n <lc-icon name=\"x-mark\" size=\"sm\" />\n </button>\n }\n</div>\n","import { Component, ChangeDetectionStrategy, computed, inject, input } from '@angular/core';\nimport { ToastComponent } from './toast.component';\nimport { ToastService, type Toast, type ToastPosition } from './toast.service';\n\n/** Politeness of the live region a toast is announced from. */\ntype ToastLive = 'polite' | 'assertive';\n\nconst POSITIONS: readonly ToastPosition[] = [\n 'top-left',\n 'top-center',\n 'top-right',\n 'bottom-left',\n 'bottom-center',\n 'bottom-right',\n];\n\n/**\n * Renders the toasts of {@link ToastService}. Place it once in the application\n * shell; without it `ToastService.show()` has no visible effect.\n *\n * ```html\n * <lc-toast-outlet />\n * ```\n *\n * Toasts are stacked per `position`. Every position owns two live regions that\n * exist from the start — screen readers only announce content that is inserted\n * into an *existing* live region — one `polite` for success/info toasts and one\n * `assertive` for error/warning toasts. Dismissing a toast (close button,\n * action, auto-dismiss) removes it from the service.\n */\n@Component({\n selector: 'lc-toast-outlet',\n standalone: true,\n imports: [ToastComponent],\n templateUrl: './toast-outlet.component.html',\n styleUrls: ['./toast-outlet.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ToastOutletComponent {\n protected readonly positions = POSITIONS;\n protected readonly liveLevels: readonly ToastLive[] = ['assertive', 'polite'];\n\n private readonly toastService = inject(ToastService);\n\n /** Accessible name of every toast's close button (forwarded to lc-toast). */\n readonly closeAriaLabel = input('Close notification');\n\n /** Toasts keyed by `${position}:${politeness}` in the order they were shown. */\n private readonly groups = computed(() => {\n const groups = new Map<string, Toast[]>();\n for (const toast of this.toastService.toasts()) {\n const key = `${toast.position}:${ToastOutletComponent.liveFor(toast)}`;\n const group = groups.get(key);\n if (group) {\n group.push(toast);\n } else {\n groups.set(key, [toast]);\n }\n }\n return groups;\n });\n\n protected toastsFor(position: ToastPosition, live: ToastLive): readonly Toast[] {\n return this.groups().get(`${position}:${live}`) ?? [];\n }\n\n protected onClosed(id: string): void {\n this.toastService.close(id);\n }\n\n /** Errors and warnings interrupt (assertive), everything else waits its turn. */\n private static liveFor(toast: Toast): ToastLive {\n return toast.variant === 'error' || toast.variant === 'warning' ? 'assertive' : 'polite';\n }\n}\n","@for (position of positions; track position) {\n <div class=\"lc-toast-outlet__stack\" [class]=\"'lc-toast-outlet__stack lc-toast-outlet__stack--' + position\">\n <!-- Both regions are always present (even empty) so that toasts inserted\n later are announced; the toasts themselves do not announce again. -->\n @for (live of liveLevels; track live) {\n <div class=\"lc-toast-outlet__region\" [attr.aria-live]=\"live\" aria-atomic=\"false\">\n @for (toast of toastsFor(position, live); track toast.id) {\n <lc-toast [toast]=\"toast\" [announce]=\"false\" [closeAriaLabel]=\"closeAriaLabel()\" (closed)=\"onClosed($event)\" />\n }\n </div>\n }\n </div>\n}\n"],"mappings":";;;;AAqDA,IAAa,eAAb,MAAa,aAAY;CAIP;CAKC,YAAY,OAAgB,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CAE/B,aAAa;CACtB,iBAAiB;CACjB,iCAAiB,IAAI,IAAG;CAEf,YAAY,kBAAkB,OAAO,WAAW,CAAC;CAElE,cAAA;EACE,KAAK,SAAS,KAAK,UAAU,WAAU;CACzC;CAKA,KAAK,QAAmB;EACtB,MAAM,QAAe;GACnB,IAAI,KAAK,WAAU;GACnB,SAAS,OAAO;GAChB,SAAS,OAAO,WAAW;GAC3B,UAAU,OAAO,YAAY;GAC7B,UAAU,OAAO,aAAa,SAAY,OAAO,WAAW;GAC5D,iBAAiB,OAAO,oBAAoB,SAAY,OAAO,kBAAkB;GACjF,QAAQ,OAAO;EAChB;EAGD,IAAI,gBAAgB,KAAK,UAAS;EAGlC,IAAI,cAAc,UAAU,KAAK,YAAY;GAC3C,MAAM,cAAc,cAAc;GAClC,IAAI,aAAa;IACf,KAAK,aAAa,YAAY,EAAE;IAChC,gBAAgB,cAAc,MAAM,CAAC;GACvC;EACF;EAEA,KAAK,UAAU,IAAI,CAAC,GAAG,eAAe,KAAK,CAAC;EAG5C,IAAI,MAAM,WAAW,KAAK,KAAK,WAAW;GACxC,MAAM,YAAY,iBAAgB;IAChC,KAAK,MAAM,MAAM,EAAE;GACrB,GAAG,MAAM,QAAQ;GAEjB,KAAK,eAAe,IAAI,MAAM,IAAI,SAAS;EAC7C;EAEA,OAAO,MAAM;CACf;CAKA,MAAM,IAAU;EACd,KAAK,YAAY,EAAE;CACrB;CAKA,WAAQ;EAEN,AADsB,KAAK,UAC3B,CAAA,CAAc,SAAS,UAAS;GAC9B,KAAK,aAAa,MAAM,EAAE;EAC5B,CAAC;EACD,KAAK,UAAU,IAAI,CAAA,CAAE;CACvB;CAKQ,aAAU;EAChB,OAAO,SAAS,EAAE,KAAK,eAAc,GAAI,KAAK,IAAG;CACnD;CAKQ,YAAY,IAAU;EAC5B,KAAK,aAAa,EAAE;EACpB,MAAM,gBAAgB,KAAK,UAAS;EACpC,KAAK,UAAU,IAAI,cAAc,QAAQ,MAAM,EAAE,OAAO,EAAE,CAAC;CAC7D;CAKQ,aAAa,IAAU;EAC7B,MAAM,YAAY,KAAK,eAAe,IAAI,EAAE;EAC5C,IAAI,cAAc,QAAW;GAC3B,aAAa,SAAS;GACtB,KAAK,eAAe,OAAO,EAAE;EAC/B;CACF;CAxGW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAY,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAZ,OAAA,QAAA,GAAA,sBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAY,YAFX;CAAM,CAAA;;AAEP,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAY,YAAA,CAAA;EAHxB,MAAA;EAAW,MAAA,CAAA,EACV,YAAY,OACb,CAAA;;;;ACRD,IAAa,iBAAb,MAAa,eAAc;CAIzB,QAAQ,MAAM,SAAiB,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;CAQ/B,WAAW,MAAe,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAG/B,iBAAiB,MAAM,sBAAqB,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAKnC,SAAS,OAAM;CAKd,cAAc,eAAc;EAEpC,OAAO,sBADO,KAAK,MACU,CAAA,CAAM;CACrC,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAKQ,mBAAmB,eAAc;EACzC,OAAO;CACT,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,mBAAA,CAAA,+BAAA,CAAA,CAAA;CAKQ,WAAW,eAAc;EACjC,IAAI,CAAC,KAAK,SAAQ,GAAI,OAAO;EAC7B,MAAM,UAAU,KAAK,MAAK,CAAE,CAAC;EAC7B,OAAO,YAAY,WAAW,YAAY,YAAY,UAAU;CAClE,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAKQ,WAAW,eAAc;EACjC,IAAI,CAAC,KAAK,SAAQ,GAAI,OAAO;EAC7B,MAAM,UAAU,KAAK,MAAK,CAAE,CAAC;EAC7B,OAAO,YAAY,WAAW,YAAY,YAAY,cAAc;CACtE,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAKQ,cAAc,eAAc;EAOpC,OAAO;GALL,SAAS;GACT,OAAO;GACP,SAAS;GACT,MAAM;EAED,EAAM,KAAK,MAAK,CAAE,CAAC;CAC5B,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAKQ,aAAa,OAAY;EACjC,MAAM,eAAc;EACpB,MAAM,gBAAe;EACrB,KAAK,OAAO,KAAK,KAAK,MAAK,CAAE,CAAC,EAAE;CAClC;CAKU,cAAc,OAAY;EAClC,MAAM,eAAc;EACpB,MAAM,gBAAe;EACrB,MAAM,SAAS,KAAK,MAAK,CAAE,CAAC;EAC5B,IAAI,QAAQ;GACV,OAAO,QAAO;GACd,KAAK,OAAO,KAAK,KAAK,MAAK,CAAE,CAAC,EAAE;EAClC;CACF;CAxFW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAc,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAd,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAc,cAAA;EAAA,UAAA;EAAA,QAAA;GAAA,OAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,UAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;GAAA,gBAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA;EAAA;EAAA,SAAA,EAAA,QAAA,SAAA;EAAA,MAAA,EAAA,YAAA;GAAA,SAAA;GAAA,aAAA;GAAA,kBAAA;GAAA,oBAAA;EAAA,EAAA;EAAA,UAAA;EAAA,UC5C3B;EA8BA,QAAA,CAAA,i2GAAA;EAAA,cAAA,CAAA;GAAA,MAAA;GAAA,MDEY;GAAa,UAAA;GAAA,QAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;IAAA;GAAA;EAAA,CAAA;EAAA,iBAAA,GAAA,wBAAA;EAAA,eAAA,GAAA,kBAAA;CAAA,CAAA;;AAYZ,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAc,YAAA,CAAA;EAf1B,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAU,YACR;GAAI,SACP,CAAC,aAAa;GAAC,eAGT,kBAAkB;GAAI,iBACpB,wBAAwB;GAAM,MACzC;IACJ,WAAW;IACX,eAAe;IACf,oBAAoB;IACpB,sBAAsB;GACvB;GAAA,UAAA;GAAA,QAAA,CAAA,i2GAAA;EAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AEnCH,MAAM,YAAsC;CAC1C;CACA;CACA;CACA;CACA;CACA;AACD;AAwBD,IAAa,uBAAb,MAAa,qBAAoB;CACZ,YAAY;CACZ,aAAmC,CAAC,aAAa,QAAQ;CAE3D,eAAe,OAAO,YAAY;CAG1C,iBAAiB,MAAM,sBAAqB,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAGpC,SAAS,eAAc;EACtC,MAAM,yBAAS,IAAI,IAAG;EACtB,KAAK,MAAM,SAAS,KAAK,aAAa,OAAM,GAAI;GAC9C,MAAM,MAAM,GAAG,MAAM,SAAQ,GAAI,qBAAqB,QAAQ,KAAK;GACnE,MAAM,QAAQ,OAAO,IAAI,GAAG;GAC5B,IAAI,OACF,MAAM,KAAK,KAAK;QAEhB,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC;EAE3B;EACA,OAAO;CACT,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CAEQ,UAAU,UAAyB,MAAe;EAC1D,OAAO,KAAK,OAAM,CAAE,CAAC,IAAI,GAAG,SAAQ,GAAI,MAAM,KAAK,CAAA;CACrD;CAEU,SAAS,IAAU;EAC3B,KAAK,aAAa,MAAM,EAAE;CAC5B;CAGQ,OAAO,QAAQ,OAAY;EACjC,OAAO,MAAM,YAAY,WAAW,MAAM,YAAY,YAAY,cAAc;CAClF;CAnCW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAoB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAApB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAoB,cAAA;EAAA,UAAA;EAAA,QAAA,EAAA,gBAAA;GAAA,mBAAA;GAAA,YAAA;GAAA,UAAA;GAAA,YAAA;GAAA,mBAAA;EAAA,EAAA;EAAA,UAAA;EAAA,UCtCjC;EAaA,QAAA,CAAA,65BAAA;EAAA,cAAA,CAAA;GAAA,MAAA;GAAA,MDoBY;GAAc,UAAA;GAAA,QAAA;IAAA;IAAA;IAAA;GAAA;GAAA,SAAA,CAAA,QAAA;EAAA,CAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AAKb,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAoB,YAAA,CAAA;EARhC,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAiB,YACf;GAAI,SACP,CAAC,cAAc;GAAC,iBAGR,wBAAwB;GAAM,UAAA;GAAA,QAAA,CAAA,65BAAA;EAAA,CAAA"}
1
+ {"version":3,"file":"lifecorner-angular-ui-kit-toast.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/toast/toast.service.ts","../../../../libs/angular-ui-kit/src/lib/toast/toast.component.ts","../../../../libs/angular-ui-kit/src/lib/toast/toast.component.html","../../../../libs/angular-ui-kit/src/lib/toast/toast-outlet.component.ts","../../../../libs/angular-ui-kit/src/lib/toast/toast-outlet.component.html"],"sourcesContent":["import { Injectable, PLATFORM_ID, inject, signal, Signal } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\n\nexport type ToastVariant = 'success' | 'error' | 'warning' | 'info';\nexport type ToastPosition =\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right';\n\nexport interface ToastAction {\n label: string;\n onClick: () => void;\n}\n\nexport interface ToastConfig {\n message: string;\n variant?: ToastVariant;\n position?: ToastPosition;\n duration?: number;\n showCloseButton?: boolean;\n action?: ToastAction;\n}\n\nexport interface Toast extends Required<Omit<ToastConfig, 'action'>> {\n id: string;\n action?: ToastAction;\n}\n\n/**\n * Toast service for showing ephemeral notifications.\n *\n * The toasts are rendered by `<lc-toast-outlet />`, which the application\n * places once (e.g. in its shell); without it nothing is shown.\n *\n * @example\n * ```typescript\n * private readonly toastService = inject(ToastService);\n *\n * showSuccess() {\n * this.toastService.show({\n * message: 'Changes saved successfully!',\n * variant: 'success',\n * duration: 3000\n * });\n * }\n * ```\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class ToastService {\n /**\n * Public readonly signal for toasts\n */\n public readonly toasts: Signal<readonly Toast[]>;\n\n /**\n * Internal signal for toast list\n */\n private readonly toastList = signal<Toast[]>([]);\n\n private readonly MAX_TOASTS = 5;\n private toastIdCounter = 0;\n private activeTimeouts = new Map<string, ReturnType<typeof setTimeout>>();\n /** Auto-dismiss timers only make sense in the browser (and `window` does not exist on the server). */\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n constructor() {\n this.toasts = this.toastList.asReadonly();\n }\n\n /**\n * Show a toast notification\n */\n show(config: ToastConfig): string {\n const toast: Toast = {\n id: this.generateId(),\n message: config.message,\n variant: config.variant || 'info',\n position: config.position || 'top-right',\n duration: config.duration !== undefined ? config.duration : 3000,\n showCloseButton: config.showCloseButton !== undefined ? config.showCloseButton : true,\n action: config.action,\n };\n\n // Add toast to list\n let currentToasts = this.toastList();\n\n // Remove oldest toast if at max capacity\n if (currentToasts.length >= this.MAX_TOASTS) {\n const oldestToast = currentToasts[0];\n if (oldestToast) {\n this.clearTimeout(oldestToast.id);\n currentToasts = currentToasts.slice(1);\n }\n }\n\n this.toastList.set([...currentToasts, toast]);\n\n // Auto-dismiss if duration > 0\n if (toast.duration > 0 && this.isBrowser) {\n const timeoutId = setTimeout(() => {\n this.close(toast.id);\n }, toast.duration);\n\n this.activeTimeouts.set(toast.id, timeoutId);\n }\n\n return toast.id;\n }\n\n /**\n * Close a specific toast\n */\n close(id: string): void {\n this.removeToast(id);\n }\n\n /**\n * Close all toasts\n */\n closeAll(): void {\n const currentToasts = this.toastList();\n currentToasts.forEach((toast) => {\n this.clearTimeout(toast.id);\n });\n this.toastList.set([]);\n }\n\n /**\n * Generate unique toast ID\n */\n private generateId(): string {\n return `toast-${++this.toastIdCounter}-${Date.now()}`;\n }\n\n /**\n * Remove a toast from the list\n */\n private removeToast(id: string): void {\n this.clearTimeout(id);\n const currentToasts = this.toastList();\n this.toastList.set(currentToasts.filter((t) => t.id !== id));\n }\n\n /**\n * Clear timeout for a toast\n */\n private clearTimeout(id: string): void {\n const timeoutId = this.activeTimeouts.get(id);\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n this.activeTimeouts.delete(id);\n }\n }\n}\n","import {\n Component,\n ChangeDetectionStrategy,\n input,\n output,\n computed,\n ViewEncapsulation,\n} from '@angular/core';\nimport { IconComponent, ɵprovideKitIcons } from '@lifecorner/angular-ui-kit/icon';\nimport {\n ICON_CHECK_CIRCLE,\n ICON_CIRCLE_X,\n ICON_EXCLAMATION_TRIANGLE,\n ICON_INFORMATION_CIRCLE,\n ICON_X_MARK,\n} from '@lifecorner/angular-ui-kit/icons';\nimport type { Toast, ToastVariant } from './toast.service';\n\n/**\n * Toast component for displaying ephemeral notification messages.\n *\n * Features:\n * - Semantic variants (success, warning, error, info)\n * - Auto-dismiss with configurable duration\n * - Manual dismiss with close button\n * - Icon display per variant\n * - Stacked toast positioning via ToastService + `<lc-toast-outlet />`\n * - Animated enter/exit transitions\n *\n * Usually rendered by `<lc-toast-outlet />`; can also be placed directly:\n *\n * @example\n * ```html\n * <lc-toast [toast]=\"toast\" (closed)=\"dismiss($event)\" />\n * ```\n */\n@Component({\n selector: 'lc-toast',\n standalone: true,\n imports: [IconComponent],\n viewProviders: [\n ɵprovideKitIcons([ICON_X_MARK, ICON_CHECK_CIRCLE, ICON_CIRCLE_X, ICON_EXCLAMATION_TRIANGLE, ICON_INFORMATION_CIRCLE]),\n ],\n templateUrl: './toast.component.html',\n styleUrls: ['./toast.component.scss'],\n encapsulation: ViewEncapsulation.None, // Required for dynamic variant class styling\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'hostClasses()',\n '[attr.role]': 'ariaRole()',\n '[attr.aria-live]': 'ariaLive()',\n '[attr.aria-atomic]': 'announce() ? \"true\" : null',\n },\n})\nexport class ToastComponent {\n /**\n * Toast data\n */\n toast = input.required<Toast>();\n\n /**\n * Whether the toast is its own live region (`role=\"status\"`/`\"alert\"` on the\n * host). `lc-toast-outlet` sets this to false because its persistent live\n * regions already announce the toast — announcing twice would be noise.\n * @default true\n */\n announce = input<boolean>(true);\n\n /** Accessible name of the close button (`toast.showCloseButton`). */\n closeAriaLabel = input('Close notification');\n\n /**\n * Emitted when toast is closed\n */\n readonly closed = output<string>();\n\n /**\n * Computed host classes\n */\n protected hostClasses = computed(() => {\n const toast = this.toast();\n return `lc-toast lc-toast--${toast.variant}`;\n });\n\n /**\n * Computed container classes\n */\n protected containerClasses = computed(() => {\n return 'lc-toast__container';\n });\n\n /**\n * Computed ARIA role\n */\n protected ariaRole = computed(() => {\n if (!this.announce()) return null;\n const variant = this.toast().variant;\n return variant === 'error' || variant === 'warning' ? 'alert' : 'status';\n });\n\n /**\n * Computed ARIA live region priority\n */\n protected ariaLive = computed(() => {\n if (!this.announce()) return null;\n const variant = this.toast().variant;\n return variant === 'error' || variant === 'warning' ? 'assertive' : 'polite';\n });\n\n /**\n * Computed default icon based on variant\n */\n protected defaultIcon = computed(() => {\n const icons: Record<ToastVariant, string> = {\n success: 'check-circle',\n error: 'x-circle',\n warning: 'exclamation-triangle',\n info: 'information-circle',\n };\n return icons[this.toast().variant];\n });\n\n /**\n * Handle close button click\n */\n protected onCloseClick(event: Event): void {\n event.preventDefault();\n event.stopPropagation();\n this.closed.emit(this.toast().id);\n }\n\n /**\n * Handle action button click\n */\n protected onActionClick(event: Event): void {\n event.preventDefault();\n event.stopPropagation();\n const action = this.toast().action;\n if (action) {\n action.onClick();\n this.closed.emit(this.toast().id);\n }\n }\n}\n","<div [class]=\"containerClasses()\">\n <div class=\"lc-toast__icon\">\n <lc-icon [name]=\"defaultIcon()\" size=\"md\" />\n </div>\n \n <div class=\"lc-toast__message\">\n {{ toast().message }}\n </div>\n \n @if (toast().action) {\n <button\n type=\"button\"\n class=\"lc-toast__action\"\n (click)=\"onActionClick($event)\"\n >\n {{ toast().action?.label }}\n </button>\n }\n \n @if (toast().showCloseButton) {\n <button\n type=\"button\"\n class=\"lc-toast__close\"\n [attr.aria-label]=\"closeAriaLabel()\"\n (click)=\"onCloseClick($event)\"\n >\n <lc-icon name=\"x-mark\" size=\"sm\" />\n </button>\n }\n</div>\n","import { Component, ChangeDetectionStrategy, computed, inject, input } from '@angular/core';\nimport { ToastComponent } from './toast.component';\nimport { ToastService, type Toast, type ToastPosition } from './toast.service';\n\n/** Politeness of the live region a toast is announced from. */\ntype ToastLive = 'polite' | 'assertive';\n\nconst POSITIONS: readonly ToastPosition[] = [\n 'top-left',\n 'top-center',\n 'top-right',\n 'bottom-left',\n 'bottom-center',\n 'bottom-right',\n];\n\n/**\n * Renders the toasts of {@link ToastService}. Place it once in the application\n * shell; without it `ToastService.show()` has no visible effect.\n *\n * ```html\n * <lc-toast-outlet />\n * ```\n *\n * Toasts are stacked per `position`. Every position owns two live regions that\n * exist from the start — screen readers only announce content that is inserted\n * into an *existing* live region — one `polite` for success/info toasts and one\n * `assertive` for error/warning toasts. Dismissing a toast (close button,\n * action, auto-dismiss) removes it from the service.\n */\n@Component({\n selector: 'lc-toast-outlet',\n standalone: true,\n imports: [ToastComponent],\n templateUrl: './toast-outlet.component.html',\n styleUrls: ['./toast-outlet.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ToastOutletComponent {\n protected readonly positions = POSITIONS;\n protected readonly liveLevels: readonly ToastLive[] = ['assertive', 'polite'];\n\n private readonly toastService = inject(ToastService);\n\n /** Accessible name of every toast's close button (forwarded to lc-toast). */\n readonly closeAriaLabel = input('Close notification');\n\n /** Toasts keyed by `${position}:${politeness}` in the order they were shown. */\n private readonly groups = computed(() => {\n const groups = new Map<string, Toast[]>();\n for (const toast of this.toastService.toasts()) {\n const key = `${toast.position}:${ToastOutletComponent.liveFor(toast)}`;\n const group = groups.get(key);\n if (group) {\n group.push(toast);\n } else {\n groups.set(key, [toast]);\n }\n }\n return groups;\n });\n\n protected toastsFor(position: ToastPosition, live: ToastLive): readonly Toast[] {\n return this.groups().get(`${position}:${live}`) ?? [];\n }\n\n protected onClosed(id: string): void {\n this.toastService.close(id);\n }\n\n /** Errors and warnings interrupt (assertive), everything else waits its turn. */\n private static liveFor(toast: Toast): ToastLive {\n return toast.variant === 'error' || toast.variant === 'warning' ? 'assertive' : 'polite';\n }\n}\n","@for (position of positions; track position) {\n <div class=\"lc-toast-outlet__stack\" [class]=\"'lc-toast-outlet__stack lc-toast-outlet__stack--' + position\">\n <!-- Both regions are always present (even empty) so that toasts inserted\n later are announced; the toasts themselves do not announce again. -->\n @for (live of liveLevels; track live) {\n <div class=\"lc-toast-outlet__region\" [attr.aria-live]=\"live\" aria-atomic=\"false\">\n @for (toast of toastsFor(position, live); track toast.id) {\n <lc-toast [toast]=\"toast\" [announce]=\"false\" [closeAriaLabel]=\"closeAriaLabel()\" (closed)=\"onClosed($event)\" />\n }\n </div>\n }\n </div>\n}\n"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import * as i0 from "@angular/core";
2
2
  import { ChangeDetectionStrategy, Component, ElementRef, computed, inject, input, model, output, signal } from "@angular/core";
3
- import { IconComponent } from "@lifecorner/angular-ui-kit/icon";
3
+ import { IconComponent, ɵprovideKitIcons } from "@lifecorner/angular-ui-kit/icon";
4
+ import { ICON_CHECK, ICON_CHEVRON_RIGHT, ICON_FILE, ICON_FILE_TEXT, ICON_KEY, ICON_SETTINGS } from "@lifecorner/angular-ui-kit/icons";
4
5
  const FOLDER_ICON = "folder";
5
6
  const FOLDER_OPEN_ICON = "folder-open";
6
7
  const FILE_FALLBACK_ICON = "file";
@@ -402,6 +403,14 @@ var TreeViewComponent = class TreeViewComponent {
402
403
  "strict"
403
404
  ]
404
405
  }],
406
+ viewProviders: [ɵprovideKitIcons([
407
+ ICON_CHEVRON_RIGHT,
408
+ ICON_CHECK,
409
+ ICON_FILE,
410
+ ICON_FILE_TEXT,
411
+ ICON_KEY,
412
+ ICON_SETTINGS
413
+ ])],
405
414
  changeDetection: i0.ChangeDetectionStrategy.OnPush
406
415
  });
407
416
  };
@@ -416,6 +425,14 @@ i0.ɵɵngDeclareClassMetadata({
416
425
  selector: "lc-tree-view",
417
426
  standalone: true,
418
427
  imports: [IconComponent],
428
+ viewProviders: [ɵprovideKitIcons([
429
+ ICON_CHEVRON_RIGHT,
430
+ ICON_CHECK,
431
+ ICON_FILE,
432
+ ICON_FILE_TEXT,
433
+ ICON_KEY,
434
+ ICON_SETTINGS
435
+ ])],
419
436
  changeDetection: ChangeDetectionStrategy.OnPush,
420
437
  host: { class: "lc-tree-view" },
421
438
  template: "@if (showToolbar()) {\n <div class=\"lc-tree-view__toolbar\">\n <button type=\"button\" class=\"lc-tree-view__tool-btn\" (click)=\"expandAll()\" [attr.title]=\"expandAllLabel()\">\n <lc-icon name=\"fold-down\" size=\"xs\" [decorative]=\"true\" />\n <span>{{ expandAllLabel() }}</span>\n </button>\n <button type=\"button\" class=\"lc-tree-view__tool-btn\" (click)=\"collapseAll()\" [attr.title]=\"collapseAllLabel()\">\n <lc-icon name=\"fold-up\" size=\"xs\" [decorative]=\"true\" />\n <span>{{ collapseAllLabel() }}</span>\n </button>\n </div>\n}\n\n<ul class=\"lc-tree-view__list\" role=\"tree\">\n @for (node of visibleNodes(); track trackById($index, node)) {\n <li\n class=\"lc-tree-view__item\"\n [class.lc-tree-view__item--selected]=\"node.id === selectedId()\"\n [class.lc-tree-view__item--disabled]=\"node.disabled\"\n [class.lc-tree-view__item--folder]=\"node.type === 'folder'\"\n role=\"treeitem\"\n [attr.aria-level]=\"node.depth + 1\"\n [attr.aria-posinset]=\"node.posInSet\"\n [attr.aria-setsize]=\"node.setSize\"\n [attr.aria-expanded]=\"node.hasChildren ? node.expanded : null\"\n [attr.aria-selected]=\"node.id === selectedId()\"\n [attr.aria-disabled]=\"node.disabled ? true : null\"\n [attr.aria-busy]=\"node.status === 'busy' ? true : null\"\n [tabindex]=\"node.id === tabStopId() ? 0 : -1\"\n (focus)=\"onFocus(node)\"\n (click)=\"onNodeClick(node)\"\n (keydown)=\"onKeydown(node, $event)\"\n >\n <!-- indentation + guide lines -->\n @for (hasSibling of node.ancestorHasSibling; track $index) {\n <span\n class=\"lc-tree-view__indent\"\n [class.lc-tree-view__indent--guide]=\"showGuides() && hasSibling\"\n ></span>\n }\n\n <!-- expand / collapse chevron -->\n <span class=\"lc-tree-view__chevron\">\n @if (node.hasChildren) {\n <button\n type=\"button\"\n class=\"lc-tree-view__chevron-btn\"\n [class.lc-tree-view__chevron-btn--expanded]=\"node.expanded\"\n (click)=\"onToggleClick(node, $event)\"\n [attr.aria-label]=\"node.expanded ? collapseAriaLabel() : expandAriaLabel()\"\n tabindex=\"-1\"\n >\n <lc-icon name=\"chevron-right\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </span>\n\n <!-- type / file icon, or type dot for custom node types -->\n <span\n class=\"lc-tree-view__icon\"\n [style.color]=\"\n node.color ?? (node.status === 'default' ? null : badgeColor(node.status))\n \"\n >\n @if (node.icon; as icon) {\n <lc-icon [name]=\"icon\" [size]=\"iconSize()\" [decorative]=\"true\" />\n } @else {\n <span\n class=\"lc-tree-view__type-dot\"\n [style.background-color]=\"node.color ?? null\"\n ></span>\n }\n </span>\n\n <!-- label -->\n <span class=\"lc-tree-view__label\">{{ node.name }}</span>\n\n <!-- badge -->\n @if (node.badge) {\n <span\n class=\"lc-tree-view__badge\"\n [style.color]=\"badgeColor(node.status)\"\n [style.border-color]=\"badgeColor(node.status)\"\n >{{ node.badge }}</span\n >\n }\n\n <!-- status indicator -->\n @if (node.status === 'success') {\n <span class=\"lc-tree-view__status lc-tree-view__status--success\">\n <lc-icon name=\"check\" size=\"xs\" [decorative]=\"true\" />\n </span>\n } @else if (node.status === 'busy') {\n <span class=\"lc-tree-view__status lc-tree-view__status--busy\"></span>\n }\n </li>\n }\n</ul>\n",