@life-cockpit/angular-ui-kit 1.11.9 → 1.11.11
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.
|
@@ -7002,6 +7002,18 @@ class TableComponent {
|
|
|
7002
7002
|
// -- Inline Editing --
|
|
7003
7003
|
/** Enable inline cell editing on double-click */
|
|
7004
7004
|
editable = input(false, ...(ngDevMode ? [{ debugName: "editable" }] : /* istanbul ignore next */ []));
|
|
7005
|
+
// -- Row Actions --
|
|
7006
|
+
/**
|
|
7007
|
+
* Row-level actions rendered in a trailing actions column (e.g. Freigeben / Ablehnen).
|
|
7008
|
+
* Clicking an action button does NOT trigger the row's `rowClick` output.
|
|
7009
|
+
*/
|
|
7010
|
+
actions = input([], ...(ngDevMode ? [{ debugName: "actions" }] : /* istanbul ignore next */ []));
|
|
7011
|
+
/** Header label for the actions column */
|
|
7012
|
+
actionsLabel = input('', ...(ngDevMode ? [{ debugName: "actionsLabel" }] : /* istanbul ignore next */ []));
|
|
7013
|
+
/** Width of the actions column (e.g. '120px') */
|
|
7014
|
+
actionsWidth = input(undefined, ...(ngDevMode ? [{ debugName: "actionsWidth" }] : /* istanbul ignore next */ []));
|
|
7015
|
+
/** Horizontal alignment of the action buttons (and header label) within the cell */
|
|
7016
|
+
actionsAlign = input('start', ...(ngDevMode ? [{ debugName: "actionsAlign" }] : /* istanbul ignore next */ []));
|
|
7005
7017
|
/** Emitted when a sortable column header is clicked */
|
|
7006
7018
|
sort = output();
|
|
7007
7019
|
/** Emitted when a row is clicked */
|
|
@@ -7010,6 +7022,8 @@ class TableComponent {
|
|
|
7010
7022
|
cellEdit = output();
|
|
7011
7023
|
/** Emitted when row selection changes */
|
|
7012
7024
|
selectionChange = output();
|
|
7025
|
+
/** Emitted when a row action button is clicked */
|
|
7026
|
+
actionClick = output();
|
|
7013
7027
|
// -- Internal state --
|
|
7014
7028
|
currentSort = signal(null, ...(ngDevMode ? [{ debugName: "currentSort" }] : /* istanbul ignore next */ []));
|
|
7015
7029
|
currentPage = signal(0, ...(ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []));
|
|
@@ -7185,6 +7199,26 @@ class TableComponent {
|
|
|
7185
7199
|
onRowClick(row) {
|
|
7186
7200
|
this.rowClick.emit(row);
|
|
7187
7201
|
}
|
|
7202
|
+
// -- Row Actions --
|
|
7203
|
+
/** Whether the trailing actions column should be rendered */
|
|
7204
|
+
hasActions = computed(() => this.actions().length > 0, ...(ngDevMode ? [{ debugName: "hasActions" }] : /* istanbul ignore next */ []));
|
|
7205
|
+
isActionHidden(action, row, relativeRowIndex) {
|
|
7206
|
+
return action.hidden ? action.hidden(row, this.getAbsoluteIndex(relativeRowIndex)) : false;
|
|
7207
|
+
}
|
|
7208
|
+
isActionDisabled(action, row, relativeRowIndex) {
|
|
7209
|
+
return action.disabled ? action.disabled(row, this.getAbsoluteIndex(relativeRowIndex)) : false;
|
|
7210
|
+
}
|
|
7211
|
+
/**
|
|
7212
|
+
* Handles an action button click. The DOM click is stopped from propagating
|
|
7213
|
+
* (see template `$event.stopPropagation()`), so the row's `rowClick` never fires.
|
|
7214
|
+
*/
|
|
7215
|
+
onActionClick(action, row, relativeRowIndex) {
|
|
7216
|
+
this.actionClick.emit({
|
|
7217
|
+
action: action.key,
|
|
7218
|
+
row,
|
|
7219
|
+
rowIndex: this.getAbsoluteIndex(relativeRowIndex),
|
|
7220
|
+
});
|
|
7221
|
+
}
|
|
7188
7222
|
// -- Pagination --
|
|
7189
7223
|
goToPage(page) {
|
|
7190
7224
|
if (page >= 0 && page < this.totalPages()) {
|
|
@@ -7301,15 +7335,15 @@ class TableComponent {
|
|
|
7301
7335
|
return event.target.value;
|
|
7302
7336
|
}
|
|
7303
7337
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7304
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: TableComponent, isStandalone: true, selector: "lc-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, hoverable: { classPropertyName: "hoverable", publicName: "hoverable", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, paginate: { classPropertyName: "paginate", publicName: "paginate", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sort: "sort", rowClick: "rowClick", cellEdit: "cellEdit", selectionChange: "selectionChange" }, queries: [{ propertyName: "cellTemplates", predicate: TableCellDirective }], ngImport: i0, template: "<div [class]=\"wrapperClasses()\">\n <table [class]=\"tableClasses()\" role=\"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]=\"'Filter ' + column.label\"\n [ariaLabel]=\"'Filter by ' + column.label\"\n [ngModel]=\"getFilterValue(column.key)\"\n (ngModelChange)=\"onFilterChange(column.key, $event)\"\n />\n }\n </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 (change)=\"toggleSelectAll()\"\n aria-label=\"Select all rows\"\n />\n </th>\n }\n @for (column of columns(); track column.key) {\n <th\n scope=\"col\"\n [class]=\"getHeaderClasses(column) + (column.cssClass ? ' ' + column.cssClass : '')\"\n [attr.aria-sort]=\"getAriaSort(column.key)\"\n [style.width]=\"column.width\"\n [title]=\"column.tooltip || ''\"\n (click)=\"handleSort(column.key)\">\n {{ column.label }}\n @if (column.sortable && getSortState(column.key)) {\n <span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? 'sorted ascending' : 'sorted descending'\">\n @if (getSortState(column.key) === 'asc') {\n \u2191\n } @else {\n \u2193\n }\n </span>\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (displayData().length === 0) {\n <tr>\n <td [attr.colspan]=\"columns().length + (selectable() ? 1 : 0)\" class=\"lc-table__empty\">\n {{ emptyText() }}\n </td>\n </tr>\n } @else {\n @for (row of displayData(); track $index; let i = $index) {\n <tr\n [class.lc-table__row--selected]=\"selectable() && isRowSelected(i)\"\n (click)=\"onRowClick(row)\"\n >\n @if (selectable()) {\n <td class=\"lc-table__select-cell\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"isRowSelected($index)\"\n (change)=\"toggleRowSelect($index)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"'Select row ' + ($index + 1)\"\n />\n </td>\n }\n @for (column of columns(); track column.key) {\n <td\n [class]=\"getCellClasses(row, column, i)\"\n [ngStyle]=\"getCellStyles(row, column, i)\"\n (dblclick)=\"editable() ? startEdit($index, column.key, getCellValue(row, column.key)) : null\"\n >\n @if (isEditing($index, column.key)) {\n <input\n type=\"text\"\n class=\"lc-table__edit-input\"\n [value]=\"editValue()\"\n (input)=\"editValue.set(getInputValue($event))\"\n (blur)=\"commitEdit($index, column.key)\"\n (keydown)=\"onEditKeydown($event, $index, column.key)\"\n autofocus\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, i) }}\n }\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Pagination -->\n@if (paginate()) {\n <div class=\"lc-table-pagination\">\n <div class=\"lc-table-pagination__info\">\n {{ paginationStart }}\u2013{{ paginationEnd }} of {{ 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]=\"'Rows per page'\"\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 aria-label=\"Previous page\"\n >\u2039</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 aria-label=\"Next page\"\n >\u203A</button>\n </div>\n </div>\n}\n", styles: [".lc-table-wrapper{width:100%}.lc-table-wrapper--responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:768px){.lc-table-wrapper--responsive::-webkit-scrollbar{height:8px}.lc-table-wrapper--responsive::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:var(--border-radius-sm)}}.lc-table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--color-background);color:var(--color-text-primary);font-family:var(--typography-font-family)}.lc-table thead{background-color:var(--color-surface);border-bottom:2px solid var(--color-border)}.lc-table thead tr th{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));text-align:left;font-weight:var(--typography-font-weight-semibold);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary);white-space:nowrap;-webkit-user-select:none;user-select:none}.lc-table thead tr th.sortable{cursor:pointer;position:relative;padding-right:var(--spacing-8);transition:background-color .2s ease}.lc-table thead tr th.sortable:hover{background-color:var(--color-neutral-100);color:var(--color-text-primary)}.lc-table thead tr th.sortable .sort-indicator{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);font-size:var(--typography-font-size-xs);color:var(--color-primary)}.lc-table thead tr th.sorted-asc,.lc-table thead tr th.sorted-desc{background-color:var(--color-neutral-100);color:var(--color-text-primary)}.lc-table tbody tr{border-bottom:1px solid var(--color-divider)}.lc-table tbody tr:last-child{border-bottom:none}.lc-table tbody tr td{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));font-size:var(--typography-font-size-sm);color:var(--color-text-primary)}.lc-table__empty{text-align:center;padding:var(--spacing-8) var(--spacing-4)!important;color:var(--color-text-secondary);font-style:italic}.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-neutral-50)}.lc-table--bordered{border:1px solid var(--color-border)}.lc-table--bordered thead tr th,.lc-table--bordered tbody tr td{border-right:1px solid var(--color-divider)}.lc-table--bordered thead tr th:last-child,.lc-table--bordered tbody tr td:last-child{border-right:none}.lc-table--bordered tbody tr{border-bottom:1px solid var(--color-border)}.lc-table--hoverable tbody tr{transition:background-color .15s ease;cursor:pointer}.lc-table--hoverable tbody tr:hover{background-color:var(--color-neutral-100)}.lc-table--sm thead tr th,.lc-table--sm tbody tr td{padding:var(--lc-density-padding-xs, var(--spacing-2)) var(--lc-density-padding-sm, var(--spacing-3));font-size:var(--typography-font-size-xs)}.lc-table--lg thead tr th,.lc-table--lg tbody tr td{padding:var(--lc-density-padding-md, var(--spacing-4)) var(--spacing-5);font-size:var(--typography-font-size-base)}[data-theme=dark] .lc-table,:root[data-theme=dark] .lc-table{background-color:var(--color-neutral-900)}[data-theme=dark] .lc-table thead,:root[data-theme=dark] .lc-table thead{background-color:var(--color-neutral-800);border-bottom-color:var(--color-neutral-700)}[data-theme=dark] .lc-table thead tr th,:root[data-theme=dark] .lc-table thead tr th{color:var(--color-text-primary);background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table thead tr th.sortable:hover,:root[data-theme=dark] .lc-table thead tr th.sortable:hover{background-color:var(--color-neutral-700)}[data-theme=dark] .lc-table thead tr th.sorted-asc,[data-theme=dark] .lc-table thead tr th.sorted-desc,:root[data-theme=dark] .lc-table thead tr th.sorted-asc,:root[data-theme=dark] .lc-table thead tr th.sorted-desc{background-color:var(--color-neutral-700)}[data-theme=dark] .lc-table.lc-table--striped tbody tr:nth-child(2n),:root[data-theme=dark] .lc-table.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table.lc-table--hoverable tbody tr:hover,:root[data-theme=dark] .lc-table.lc-table--hoverable tbody tr:hover{background-color:var(--color-neutral-700)}.lc-table__filter-row th{padding:var(--spacing-2) var(--spacing-4)!important;background-color:var(--color-background)!important;border-bottom:1px solid var(--color-divider)!important}.lc-table__filter-input{width:100%;display:block}.lc-table__filter-input .input-field{font-size:var(--typography-font-size-xs)}.lc-table__select-cell{width:40px;text-align:center!important;padding:var(--spacing-2)!important}.lc-table__checkbox{width:16px;height:16px;cursor:pointer;accent-color:var(--color-primary)}.lc-table__row--selected{background-color:var(--color-primary-50, rgba(59, 130, 246, .08))!important}.lc-table__edit-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:2px solid var(--color-primary);border-radius:var(--border-radius-sm);font-size:inherit;background-color:var(--color-background);color:var(--color-text-primary);outline:none}.lc-table-pagination{display:flex;align-items:center;justify-content:space-between;padding:var(--spacing-3) var(--spacing-1);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary)}.lc-table-pagination__info{white-space:nowrap}.lc-table-pagination__controls{display:flex;align-items:center;gap:var(--spacing-2)}.lc-table-pagination__size{display:block;min-width:110px}.lc-table-pagination__btn{appearance:none;border:1px solid var(--color-border);background-color:var(--color-surface);color:var(--color-text-primary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--border-radius-sm);font-size:var(--typography-font-size-base);cursor:pointer;transition:background-color .15s ease}.lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-neutral-100)}.lc-table-pagination__btn:disabled{opacity:.4;cursor:not-allowed}.lc-table-pagination__page{white-space:nowrap;min-width:60px;text-align:center}@media(max-width:640px){.lc-table-wrapper--stack .lc-table thead{display:none}.lc-table-wrapper--stack .lc-table tbody tr{display:block;margin-bottom:var(--spacing-4);border:1px solid var(--color-border);border-radius:var(--border-radius-md)}.lc-table-wrapper--stack .lc-table tbody tr td{display:block;text-align:right;padding:var(--spacing-2) var(--spacing-4);border-bottom:1px solid var(--color-divider)}.lc-table-wrapper--stack .lc-table tbody tr td:last-child{border-bottom:none}.lc-table-wrapper--stack .lc-table tbody tr td:before{content:attr(data-label);float:left;font-weight:var(--typography-font-weight-semibold);color:var(--color-text-secondary)}}[data-theme=dark] .lc-table__filter-input,:root[data-theme=dark] .lc-table__filter-input{background-color:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .lc-table__edit-input,:root[data-theme=dark] .lc-table__edit-input{background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table__row--selected,:root[data-theme=dark] .lc-table__row--selected{background-color:#3b82f61f!important}[data-theme=dark] .lc-table-pagination__btn,:root[data-theme=dark] .lc-table-pagination__btn{background-color:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .lc-table-pagination__btn:hover:not(:disabled),:root[data-theme=dark] .lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-neutral-700)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: SelectComponent, selector: "lc-select", inputs: ["variant", "size", "disabled", "error", "required", "loading", "searchable", "multiple", "placeholder", "helperText", "errorMessage", "ariaLabel", "options"], outputs: ["selectionChange", "opened", "closed"] }, { kind: "component", type: InputComponent, selector: "lc-input", inputs: ["label", "placeholder", "type", "size", "disabled", "readonly", "required", "error", "helperText", "iconBefore", "iconAfter", "maxLength", "showCharCount", "ariaLabel"], outputs: ["valueChange", "focused", "blurred", "enterPressed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
7338
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: TableComponent, isStandalone: true, selector: "lc-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, hoverable: { classPropertyName: "hoverable", publicName: "hoverable", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, paginate: { classPropertyName: "paginate", publicName: "paginate", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, actionsLabel: { classPropertyName: "actionsLabel", publicName: "actionsLabel", isSignal: true, isRequired: false, transformFunction: null }, actionsWidth: { classPropertyName: "actionsWidth", publicName: "actionsWidth", isSignal: true, isRequired: false, transformFunction: null }, actionsAlign: { classPropertyName: "actionsAlign", publicName: "actionsAlign", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sort: "sort", rowClick: "rowClick", cellEdit: "cellEdit", selectionChange: "selectionChange", actionClick: "actionClick" }, queries: [{ propertyName: "cellTemplates", predicate: TableCellDirective }], ngImport: i0, template: "<div [class]=\"wrapperClasses()\">\n <table [class]=\"tableClasses()\" role=\"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]=\"'Filter ' + column.label\"\n [ariaLabel]=\"'Filter by ' + 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 (change)=\"toggleSelectAll()\"\n aria-label=\"Select all rows\"\n />\n </th>\n }\n @for (column of columns(); track column.key) {\n <th\n scope=\"col\"\n [class]=\"getHeaderClasses(column) + (column.cssClass ? ' ' + column.cssClass : '')\"\n [attr.aria-sort]=\"getAriaSort(column.key)\"\n [style.width]=\"column.width\"\n [title]=\"column.tooltip || ''\"\n (click)=\"handleSort(column.key)\">\n {{ column.label }}\n @if (column.sortable && getSortState(column.key)) {\n <span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? 'sorted ascending' : 'sorted descending'\">\n @if (getSortState(column.key) === 'asc') {\n \u2191\n } @else {\n \u2193\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 (displayData().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 (row of displayData(); track $index; let i = $index) {\n <tr\n [class.lc-table__row--selected]=\"selectable() && isRowSelected(i)\"\n (click)=\"onRowClick(row)\"\n >\n @if (selectable()) {\n <td class=\"lc-table__select-cell\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"isRowSelected($index)\"\n (change)=\"toggleRowSelect($index)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"'Select row ' + ($index + 1)\"\n />\n </td>\n }\n @for (column of columns(); track column.key) {\n <td\n [class]=\"getCellClasses(row, column, i)\"\n [ngStyle]=\"getCellStyles(row, column, i)\"\n (dblclick)=\"editable() ? startEdit($index, column.key, getCellValue(row, column.key)) : null\"\n >\n @if (isEditing($index, column.key)) {\n <input\n type=\"text\"\n class=\"lc-table__edit-input\"\n [value]=\"editValue()\"\n (input)=\"editValue.set(getInputValue($event))\"\n (blur)=\"commitEdit($index, column.key)\"\n (keydown)=\"onEditKeydown($event, $index, column.key)\"\n autofocus\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, i) }}\n }\n </td>\n }\n @if (hasActions()) {\n <td\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"lc-table__actions\">\n @for (action of actions(); track action.key) {\n @if (!isActionHidden(action, row, i)) {\n <lc-button\n [variant]=\"action.variant ?? 'ghost'\"\n size=\"xs\"\n [iconOnly]=\"!action.label\"\n [disabled]=\"isActionDisabled(action, row, i)\"\n [ariaLabel]=\"action.tooltip ?? action.label ?? action.key\"\n (clicked)=\"onActionClick(action, row, i)\"\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<!-- Pagination -->\n@if (paginate()) {\n <div class=\"lc-table-pagination\">\n <div class=\"lc-table-pagination__info\">\n {{ paginationStart }}\u2013{{ paginationEnd }} of {{ 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]=\"'Rows per page'\"\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 aria-label=\"Previous page\"\n >\u2039</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 aria-label=\"Next page\"\n >\u203A</button>\n </div>\n </div>\n}\n", styles: [".lc-table-wrapper{width:100%}.lc-table-wrapper--responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:768px){.lc-table-wrapper--responsive::-webkit-scrollbar{height:8px}.lc-table-wrapper--responsive::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:var(--border-radius-sm)}}.lc-table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--color-background);color:var(--color-text-primary);font-family:var(--typography-font-family)}.lc-table thead{background-color:var(--color-surface);border-bottom:2px solid var(--color-border)}.lc-table thead tr th{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));text-align:left;font-weight:var(--typography-font-weight-semibold);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary);white-space:nowrap;-webkit-user-select:none;user-select:none}.lc-table thead tr th.sortable{cursor:pointer;position:relative;padding-right:var(--spacing-8);transition:background-color .2s ease}.lc-table thead tr th.sortable:hover{background-color:var(--color-neutral-100);color:var(--color-text-primary)}.lc-table thead tr th.sortable .sort-indicator{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);font-size:var(--typography-font-size-xs);color:var(--color-primary)}.lc-table thead tr th.sorted-asc,.lc-table thead tr th.sorted-desc{background-color:var(--color-neutral-100);color:var(--color-text-primary)}.lc-table tbody tr{border-bottom:1px solid var(--color-divider)}.lc-table tbody tr:last-child{border-bottom:none}.lc-table tbody tr td{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));font-size:var(--typography-font-size-sm);color:var(--color-text-primary)}.lc-table__empty{text-align:center;padding:var(--spacing-8) var(--spacing-4)!important;color:var(--color-text-secondary);font-style:italic}.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-neutral-50)}.lc-table--bordered{border:1px solid var(--color-border)}.lc-table--bordered thead tr th,.lc-table--bordered tbody tr td{border-right:1px solid var(--color-divider)}.lc-table--bordered thead tr th:last-child,.lc-table--bordered tbody tr td:last-child{border-right:none}.lc-table--bordered tbody tr{border-bottom:1px solid var(--color-border)}.lc-table--hoverable tbody tr{transition:background-color .15s ease;cursor:pointer}.lc-table--hoverable tbody tr:hover{background-color:var(--color-neutral-100)}.lc-table--sm thead tr th,.lc-table--sm tbody tr td{padding:var(--lc-density-padding-xs, var(--spacing-2)) var(--lc-density-padding-sm, var(--spacing-3));font-size:var(--typography-font-size-xs)}.lc-table--lg thead tr th,.lc-table--lg tbody tr td{padding:var(--lc-density-padding-md, var(--spacing-4)) var(--spacing-5);font-size:var(--typography-font-size-base)}[data-theme=dark] .lc-table,:root[data-theme=dark] .lc-table{background-color:var(--color-neutral-900)}[data-theme=dark] .lc-table thead,:root[data-theme=dark] .lc-table thead{background-color:var(--color-neutral-800);border-bottom-color:var(--color-neutral-700)}[data-theme=dark] .lc-table thead tr th,:root[data-theme=dark] .lc-table thead tr th{color:var(--color-text-primary);background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table thead tr th.sortable:hover,:root[data-theme=dark] .lc-table thead tr th.sortable:hover{background-color:var(--color-neutral-700)}[data-theme=dark] .lc-table thead tr th.sorted-asc,[data-theme=dark] .lc-table thead tr th.sorted-desc,:root[data-theme=dark] .lc-table thead tr th.sorted-asc,:root[data-theme=dark] .lc-table thead tr th.sorted-desc{background-color:var(--color-neutral-700)}[data-theme=dark] .lc-table.lc-table--striped tbody tr:nth-child(2n),:root[data-theme=dark] .lc-table.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table.lc-table--hoverable tbody tr:hover,:root[data-theme=dark] .lc-table.lc-table--hoverable tbody tr:hover{background-color:var(--color-neutral-700)}.lc-table__filter-row th{padding:var(--spacing-2) var(--spacing-4)!important;background-color:var(--color-background)!important;border-bottom:1px solid var(--color-divider)!important}.lc-table__filter-input{width:100%;display:block}.lc-table__filter-input .input-field{font-size:var(--typography-font-size-xs)}.lc-table__select-cell{width:40px;text-align:center!important;padding:var(--spacing-2)!important}.lc-table__checkbox{width:16px;height:16px;cursor:pointer;accent-color:var(--color-primary)}.lc-table__row--selected{background-color:var(--color-primary-50, rgba(59, 130, 246, .08))!important}.lc-table__actions-cell{white-space:nowrap}.lc-table th.lc-table__actions-cell--start,.lc-table td.lc-table__actions-cell--start{text-align:left}.lc-table th.lc-table__actions-cell--center,.lc-table td.lc-table__actions-cell--center{text-align:center}.lc-table th.lc-table__actions-cell--end,.lc-table td.lc-table__actions-cell--end{text-align:right}.lc-table__actions{display:flex;align-items:center;gap:var(--spacing-2);justify-content:flex-start}.lc-table__actions-cell--center .lc-table__actions{justify-content:center}.lc-table__actions-cell--end .lc-table__actions{justify-content:flex-end}.lc-table__edit-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:2px solid var(--color-primary);border-radius:var(--border-radius-sm);font-size:inherit;background-color:var(--color-background);color:var(--color-text-primary);outline:none}.lc-table-pagination{display:flex;align-items:center;justify-content:space-between;padding:var(--spacing-3) var(--spacing-1);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary)}.lc-table-pagination__info{white-space:nowrap}.lc-table-pagination__controls{display:flex;align-items:center;gap:var(--spacing-2)}.lc-table-pagination__size{display:block;min-width:110px}.lc-table-pagination__btn{appearance:none;border:1px solid var(--color-border);background-color:var(--color-surface);color:var(--color-text-primary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--border-radius-sm);font-size:var(--typography-font-size-base);cursor:pointer;transition:background-color .15s ease}.lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-neutral-100)}.lc-table-pagination__btn:disabled{opacity:.4;cursor:not-allowed}.lc-table-pagination__page{white-space:nowrap;min-width:60px;text-align:center}@media(max-width:640px){.lc-table-wrapper--stack .lc-table thead{display:none}.lc-table-wrapper--stack .lc-table tbody tr{display:block;margin-bottom:var(--spacing-4);border:1px solid var(--color-border);border-radius:var(--border-radius-md)}.lc-table-wrapper--stack .lc-table tbody tr td{display:block;text-align:right;padding:var(--spacing-2) var(--spacing-4);border-bottom:1px solid var(--color-divider)}.lc-table-wrapper--stack .lc-table tbody tr td:last-child{border-bottom:none}.lc-table-wrapper--stack .lc-table tbody tr td:before{content:attr(data-label);float:left;font-weight:var(--typography-font-weight-semibold);color:var(--color-text-secondary)}}[data-theme=dark] .lc-table__filter-input,:root[data-theme=dark] .lc-table__filter-input{background-color:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .lc-table__edit-input,:root[data-theme=dark] .lc-table__edit-input{background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table__row--selected,:root[data-theme=dark] .lc-table__row--selected{background-color:#3b82f61f!important}[data-theme=dark] .lc-table-pagination__btn,:root[data-theme=dark] .lc-table-pagination__btn{background-color:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .lc-table-pagination__btn:hover:not(:disabled),:root[data-theme=dark] .lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-neutral-700)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: SelectComponent, selector: "lc-select", inputs: ["variant", "size", "disabled", "error", "required", "loading", "searchable", "multiple", "placeholder", "helperText", "errorMessage", "ariaLabel", "options"], outputs: ["selectionChange", "opened", "closed"] }, { kind: "component", type: InputComponent, selector: "lc-input", inputs: ["label", "placeholder", "type", "size", "disabled", "readonly", "required", "error", "helperText", "iconBefore", "iconAfter", "maxLength", "showCharCount", "ariaLabel"], outputs: ["valueChange", "focused", "blurred", "enterPressed"] }, { kind: "component", type: ButtonComponent, selector: "lc-button", inputs: ["variant", "size", "disabled", "loading", "iconOnly", "fullWidth", "ariaLabel", "type"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: IconComponent, selector: "lc-icon", inputs: ["name", "variant", "size", "color", "ariaLabel", "decorative"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
7305
7339
|
}
|
|
7306
7340
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: TableComponent, decorators: [{
|
|
7307
7341
|
type: Component,
|
|
7308
|
-
args: [{ selector: 'lc-table', standalone: true, imports: [NgTemplateOutlet, NgStyle, FormsModule, SelectComponent, InputComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"wrapperClasses()\">\n <table [class]=\"tableClasses()\" role=\"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]=\"'Filter ' + column.label\"\n [ariaLabel]=\"'Filter by ' + column.label\"\n [ngModel]=\"getFilterValue(column.key)\"\n (ngModelChange)=\"onFilterChange(column.key, $event)\"\n />\n }\n </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 (change)=\"toggleSelectAll()\"\n aria-label=\"Select all rows\"\n />\n </th>\n }\n @for (column of columns(); track column.key) {\n <th\n scope=\"col\"\n [class]=\"getHeaderClasses(column) + (column.cssClass ? ' ' + column.cssClass : '')\"\n [attr.aria-sort]=\"getAriaSort(column.key)\"\n [style.width]=\"column.width\"\n [title]=\"column.tooltip || ''\"\n (click)=\"handleSort(column.key)\">\n {{ column.label }}\n @if (column.sortable && getSortState(column.key)) {\n <span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? 'sorted ascending' : 'sorted descending'\">\n @if (getSortState(column.key) === 'asc') {\n \u2191\n } @else {\n \u2193\n }\n </span>\n }\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @if (displayData().length === 0) {\n <tr>\n <td [attr.colspan]=\"columns().length + (selectable() ? 1 : 0)\" class=\"lc-table__empty\">\n {{ emptyText() }}\n </td>\n </tr>\n } @else {\n @for (row of displayData(); track $index; let i = $index) {\n <tr\n [class.lc-table__row--selected]=\"selectable() && isRowSelected(i)\"\n (click)=\"onRowClick(row)\"\n >\n @if (selectable()) {\n <td class=\"lc-table__select-cell\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"isRowSelected($index)\"\n (change)=\"toggleRowSelect($index)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"'Select row ' + ($index + 1)\"\n />\n </td>\n }\n @for (column of columns(); track column.key) {\n <td\n [class]=\"getCellClasses(row, column, i)\"\n [ngStyle]=\"getCellStyles(row, column, i)\"\n (dblclick)=\"editable() ? startEdit($index, column.key, getCellValue(row, column.key)) : null\"\n >\n @if (isEditing($index, column.key)) {\n <input\n type=\"text\"\n class=\"lc-table__edit-input\"\n [value]=\"editValue()\"\n (input)=\"editValue.set(getInputValue($event))\"\n (blur)=\"commitEdit($index, column.key)\"\n (keydown)=\"onEditKeydown($event, $index, column.key)\"\n autofocus\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, i) }}\n }\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n\n<!-- Pagination -->\n@if (paginate()) {\n <div class=\"lc-table-pagination\">\n <div class=\"lc-table-pagination__info\">\n {{ paginationStart }}\u2013{{ paginationEnd }} of {{ 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]=\"'Rows per page'\"\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 aria-label=\"Previous page\"\n >\u2039</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 aria-label=\"Next page\"\n >\u203A</button>\n </div>\n </div>\n}\n", styles: [".lc-table-wrapper{width:100%}.lc-table-wrapper--responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:768px){.lc-table-wrapper--responsive::-webkit-scrollbar{height:8px}.lc-table-wrapper--responsive::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:var(--border-radius-sm)}}.lc-table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--color-background);color:var(--color-text-primary);font-family:var(--typography-font-family)}.lc-table thead{background-color:var(--color-surface);border-bottom:2px solid var(--color-border)}.lc-table thead tr th{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));text-align:left;font-weight:var(--typography-font-weight-semibold);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary);white-space:nowrap;-webkit-user-select:none;user-select:none}.lc-table thead tr th.sortable{cursor:pointer;position:relative;padding-right:var(--spacing-8);transition:background-color .2s ease}.lc-table thead tr th.sortable:hover{background-color:var(--color-neutral-100);color:var(--color-text-primary)}.lc-table thead tr th.sortable .sort-indicator{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);font-size:var(--typography-font-size-xs);color:var(--color-primary)}.lc-table thead tr th.sorted-asc,.lc-table thead tr th.sorted-desc{background-color:var(--color-neutral-100);color:var(--color-text-primary)}.lc-table tbody tr{border-bottom:1px solid var(--color-divider)}.lc-table tbody tr:last-child{border-bottom:none}.lc-table tbody tr td{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));font-size:var(--typography-font-size-sm);color:var(--color-text-primary)}.lc-table__empty{text-align:center;padding:var(--spacing-8) var(--spacing-4)!important;color:var(--color-text-secondary);font-style:italic}.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-neutral-50)}.lc-table--bordered{border:1px solid var(--color-border)}.lc-table--bordered thead tr th,.lc-table--bordered tbody tr td{border-right:1px solid var(--color-divider)}.lc-table--bordered thead tr th:last-child,.lc-table--bordered tbody tr td:last-child{border-right:none}.lc-table--bordered tbody tr{border-bottom:1px solid var(--color-border)}.lc-table--hoverable tbody tr{transition:background-color .15s ease;cursor:pointer}.lc-table--hoverable tbody tr:hover{background-color:var(--color-neutral-100)}.lc-table--sm thead tr th,.lc-table--sm tbody tr td{padding:var(--lc-density-padding-xs, var(--spacing-2)) var(--lc-density-padding-sm, var(--spacing-3));font-size:var(--typography-font-size-xs)}.lc-table--lg thead tr th,.lc-table--lg tbody tr td{padding:var(--lc-density-padding-md, var(--spacing-4)) var(--spacing-5);font-size:var(--typography-font-size-base)}[data-theme=dark] .lc-table,:root[data-theme=dark] .lc-table{background-color:var(--color-neutral-900)}[data-theme=dark] .lc-table thead,:root[data-theme=dark] .lc-table thead{background-color:var(--color-neutral-800);border-bottom-color:var(--color-neutral-700)}[data-theme=dark] .lc-table thead tr th,:root[data-theme=dark] .lc-table thead tr th{color:var(--color-text-primary);background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table thead tr th.sortable:hover,:root[data-theme=dark] .lc-table thead tr th.sortable:hover{background-color:var(--color-neutral-700)}[data-theme=dark] .lc-table thead tr th.sorted-asc,[data-theme=dark] .lc-table thead tr th.sorted-desc,:root[data-theme=dark] .lc-table thead tr th.sorted-asc,:root[data-theme=dark] .lc-table thead tr th.sorted-desc{background-color:var(--color-neutral-700)}[data-theme=dark] .lc-table.lc-table--striped tbody tr:nth-child(2n),:root[data-theme=dark] .lc-table.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table.lc-table--hoverable tbody tr:hover,:root[data-theme=dark] .lc-table.lc-table--hoverable tbody tr:hover{background-color:var(--color-neutral-700)}.lc-table__filter-row th{padding:var(--spacing-2) var(--spacing-4)!important;background-color:var(--color-background)!important;border-bottom:1px solid var(--color-divider)!important}.lc-table__filter-input{width:100%;display:block}.lc-table__filter-input .input-field{font-size:var(--typography-font-size-xs)}.lc-table__select-cell{width:40px;text-align:center!important;padding:var(--spacing-2)!important}.lc-table__checkbox{width:16px;height:16px;cursor:pointer;accent-color:var(--color-primary)}.lc-table__row--selected{background-color:var(--color-primary-50, rgba(59, 130, 246, .08))!important}.lc-table__edit-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:2px solid var(--color-primary);border-radius:var(--border-radius-sm);font-size:inherit;background-color:var(--color-background);color:var(--color-text-primary);outline:none}.lc-table-pagination{display:flex;align-items:center;justify-content:space-between;padding:var(--spacing-3) var(--spacing-1);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary)}.lc-table-pagination__info{white-space:nowrap}.lc-table-pagination__controls{display:flex;align-items:center;gap:var(--spacing-2)}.lc-table-pagination__size{display:block;min-width:110px}.lc-table-pagination__btn{appearance:none;border:1px solid var(--color-border);background-color:var(--color-surface);color:var(--color-text-primary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--border-radius-sm);font-size:var(--typography-font-size-base);cursor:pointer;transition:background-color .15s ease}.lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-neutral-100)}.lc-table-pagination__btn:disabled{opacity:.4;cursor:not-allowed}.lc-table-pagination__page{white-space:nowrap;min-width:60px;text-align:center}@media(max-width:640px){.lc-table-wrapper--stack .lc-table thead{display:none}.lc-table-wrapper--stack .lc-table tbody tr{display:block;margin-bottom:var(--spacing-4);border:1px solid var(--color-border);border-radius:var(--border-radius-md)}.lc-table-wrapper--stack .lc-table tbody tr td{display:block;text-align:right;padding:var(--spacing-2) var(--spacing-4);border-bottom:1px solid var(--color-divider)}.lc-table-wrapper--stack .lc-table tbody tr td:last-child{border-bottom:none}.lc-table-wrapper--stack .lc-table tbody tr td:before{content:attr(data-label);float:left;font-weight:var(--typography-font-weight-semibold);color:var(--color-text-secondary)}}[data-theme=dark] .lc-table__filter-input,:root[data-theme=dark] .lc-table__filter-input{background-color:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .lc-table__edit-input,:root[data-theme=dark] .lc-table__edit-input{background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table__row--selected,:root[data-theme=dark] .lc-table__row--selected{background-color:#3b82f61f!important}[data-theme=dark] .lc-table-pagination__btn,:root[data-theme=dark] .lc-table-pagination__btn{background-color:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .lc-table-pagination__btn:hover:not(:disabled),:root[data-theme=dark] .lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-neutral-700)}\n"] }]
|
|
7342
|
+
args: [{ selector: 'lc-table', standalone: true, imports: [NgTemplateOutlet, NgStyle, FormsModule, SelectComponent, InputComponent, ButtonComponent, IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"wrapperClasses()\">\n <table [class]=\"tableClasses()\" role=\"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]=\"'Filter ' + column.label\"\n [ariaLabel]=\"'Filter by ' + 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 (change)=\"toggleSelectAll()\"\n aria-label=\"Select all rows\"\n />\n </th>\n }\n @for (column of columns(); track column.key) {\n <th\n scope=\"col\"\n [class]=\"getHeaderClasses(column) + (column.cssClass ? ' ' + column.cssClass : '')\"\n [attr.aria-sort]=\"getAriaSort(column.key)\"\n [style.width]=\"column.width\"\n [title]=\"column.tooltip || ''\"\n (click)=\"handleSort(column.key)\">\n {{ column.label }}\n @if (column.sortable && getSortState(column.key)) {\n <span class=\"sort-indicator\" [attr.aria-label]=\"getSortState(column.key) === 'asc' ? 'sorted ascending' : 'sorted descending'\">\n @if (getSortState(column.key) === 'asc') {\n \u2191\n } @else {\n \u2193\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 (displayData().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 (row of displayData(); track $index; let i = $index) {\n <tr\n [class.lc-table__row--selected]=\"selectable() && isRowSelected(i)\"\n (click)=\"onRowClick(row)\"\n >\n @if (selectable()) {\n <td class=\"lc-table__select-cell\">\n <input\n type=\"checkbox\"\n class=\"lc-table__checkbox\"\n [checked]=\"isRowSelected($index)\"\n (change)=\"toggleRowSelect($index)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"'Select row ' + ($index + 1)\"\n />\n </td>\n }\n @for (column of columns(); track column.key) {\n <td\n [class]=\"getCellClasses(row, column, i)\"\n [ngStyle]=\"getCellStyles(row, column, i)\"\n (dblclick)=\"editable() ? startEdit($index, column.key, getCellValue(row, column.key)) : null\"\n >\n @if (isEditing($index, column.key)) {\n <input\n type=\"text\"\n class=\"lc-table__edit-input\"\n [value]=\"editValue()\"\n (input)=\"editValue.set(getInputValue($event))\"\n (blur)=\"commitEdit($index, column.key)\"\n (keydown)=\"onEditKeydown($event, $index, column.key)\"\n autofocus\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, i) }}\n }\n </td>\n }\n @if (hasActions()) {\n <td\n class=\"lc-table__actions-cell\"\n [class]=\"'lc-table__actions-cell--' + actionsAlign()\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"lc-table__actions\">\n @for (action of actions(); track action.key) {\n @if (!isActionHidden(action, row, i)) {\n <lc-button\n [variant]=\"action.variant ?? 'ghost'\"\n size=\"xs\"\n [iconOnly]=\"!action.label\"\n [disabled]=\"isActionDisabled(action, row, i)\"\n [ariaLabel]=\"action.tooltip ?? action.label ?? action.key\"\n (clicked)=\"onActionClick(action, row, i)\"\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<!-- Pagination -->\n@if (paginate()) {\n <div class=\"lc-table-pagination\">\n <div class=\"lc-table-pagination__info\">\n {{ paginationStart }}\u2013{{ paginationEnd }} of {{ 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]=\"'Rows per page'\"\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 aria-label=\"Previous page\"\n >\u2039</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 aria-label=\"Next page\"\n >\u203A</button>\n </div>\n </div>\n}\n", styles: [".lc-table-wrapper{width:100%}.lc-table-wrapper--responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width:768px){.lc-table-wrapper--responsive::-webkit-scrollbar{height:8px}.lc-table-wrapper--responsive::-webkit-scrollbar-thumb{background-color:var(--color-border);border-radius:var(--border-radius-sm)}}.lc-table{width:100%;border-collapse:collapse;border-spacing:0;background-color:var(--color-background);color:var(--color-text-primary);font-family:var(--typography-font-family)}.lc-table thead{background-color:var(--color-surface);border-bottom:2px solid var(--color-border)}.lc-table thead tr th{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));text-align:left;font-weight:var(--typography-font-weight-semibold);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary);white-space:nowrap;-webkit-user-select:none;user-select:none}.lc-table thead tr th.sortable{cursor:pointer;position:relative;padding-right:var(--spacing-8);transition:background-color .2s ease}.lc-table thead tr th.sortable:hover{background-color:var(--color-neutral-100);color:var(--color-text-primary)}.lc-table thead tr th.sortable .sort-indicator{position:absolute;right:var(--spacing-3);top:50%;transform:translateY(-50%);font-size:var(--typography-font-size-xs);color:var(--color-primary)}.lc-table thead tr th.sorted-asc,.lc-table thead tr th.sorted-desc{background-color:var(--color-neutral-100);color:var(--color-text-primary)}.lc-table tbody tr{border-bottom:1px solid var(--color-divider)}.lc-table tbody tr:last-child{border-bottom:none}.lc-table tbody tr td{padding:var(--lc-density-padding-sm, var(--spacing-3)) var(--lc-density-padding-md, var(--spacing-4));font-size:var(--typography-font-size-sm);color:var(--color-text-primary)}.lc-table__empty{text-align:center;padding:var(--spacing-8) var(--spacing-4)!important;color:var(--color-text-secondary);font-style:italic}.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-neutral-50)}.lc-table--bordered{border:1px solid var(--color-border)}.lc-table--bordered thead tr th,.lc-table--bordered tbody tr td{border-right:1px solid var(--color-divider)}.lc-table--bordered thead tr th:last-child,.lc-table--bordered tbody tr td:last-child{border-right:none}.lc-table--bordered tbody tr{border-bottom:1px solid var(--color-border)}.lc-table--hoverable tbody tr{transition:background-color .15s ease;cursor:pointer}.lc-table--hoverable tbody tr:hover{background-color:var(--color-neutral-100)}.lc-table--sm thead tr th,.lc-table--sm tbody tr td{padding:var(--lc-density-padding-xs, var(--spacing-2)) var(--lc-density-padding-sm, var(--spacing-3));font-size:var(--typography-font-size-xs)}.lc-table--lg thead tr th,.lc-table--lg tbody tr td{padding:var(--lc-density-padding-md, var(--spacing-4)) var(--spacing-5);font-size:var(--typography-font-size-base)}[data-theme=dark] .lc-table,:root[data-theme=dark] .lc-table{background-color:var(--color-neutral-900)}[data-theme=dark] .lc-table thead,:root[data-theme=dark] .lc-table thead{background-color:var(--color-neutral-800);border-bottom-color:var(--color-neutral-700)}[data-theme=dark] .lc-table thead tr th,:root[data-theme=dark] .lc-table thead tr th{color:var(--color-text-primary);background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table thead tr th.sortable:hover,:root[data-theme=dark] .lc-table thead tr th.sortable:hover{background-color:var(--color-neutral-700)}[data-theme=dark] .lc-table thead tr th.sorted-asc,[data-theme=dark] .lc-table thead tr th.sorted-desc,:root[data-theme=dark] .lc-table thead tr th.sorted-asc,:root[data-theme=dark] .lc-table thead tr th.sorted-desc{background-color:var(--color-neutral-700)}[data-theme=dark] .lc-table.lc-table--striped tbody tr:nth-child(2n),:root[data-theme=dark] .lc-table.lc-table--striped tbody tr:nth-child(2n){background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table.lc-table--hoverable tbody tr:hover,:root[data-theme=dark] .lc-table.lc-table--hoverable tbody tr:hover{background-color:var(--color-neutral-700)}.lc-table__filter-row th{padding:var(--spacing-2) var(--spacing-4)!important;background-color:var(--color-background)!important;border-bottom:1px solid var(--color-divider)!important}.lc-table__filter-input{width:100%;display:block}.lc-table__filter-input .input-field{font-size:var(--typography-font-size-xs)}.lc-table__select-cell{width:40px;text-align:center!important;padding:var(--spacing-2)!important}.lc-table__checkbox{width:16px;height:16px;cursor:pointer;accent-color:var(--color-primary)}.lc-table__row--selected{background-color:var(--color-primary-50, rgba(59, 130, 246, .08))!important}.lc-table__actions-cell{white-space:nowrap}.lc-table th.lc-table__actions-cell--start,.lc-table td.lc-table__actions-cell--start{text-align:left}.lc-table th.lc-table__actions-cell--center,.lc-table td.lc-table__actions-cell--center{text-align:center}.lc-table th.lc-table__actions-cell--end,.lc-table td.lc-table__actions-cell--end{text-align:right}.lc-table__actions{display:flex;align-items:center;gap:var(--spacing-2);justify-content:flex-start}.lc-table__actions-cell--center .lc-table__actions{justify-content:center}.lc-table__actions-cell--end .lc-table__actions{justify-content:flex-end}.lc-table__edit-input{width:100%;padding:var(--spacing-1) var(--spacing-2);border:2px solid var(--color-primary);border-radius:var(--border-radius-sm);font-size:inherit;background-color:var(--color-background);color:var(--color-text-primary);outline:none}.lc-table-pagination{display:flex;align-items:center;justify-content:space-between;padding:var(--spacing-3) var(--spacing-1);font-size:var(--typography-font-size-sm);color:var(--color-text-secondary)}.lc-table-pagination__info{white-space:nowrap}.lc-table-pagination__controls{display:flex;align-items:center;gap:var(--spacing-2)}.lc-table-pagination__size{display:block;min-width:110px}.lc-table-pagination__btn{appearance:none;border:1px solid var(--color-border);background-color:var(--color-surface);color:var(--color-text-primary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--border-radius-sm);font-size:var(--typography-font-size-base);cursor:pointer;transition:background-color .15s ease}.lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-neutral-100)}.lc-table-pagination__btn:disabled{opacity:.4;cursor:not-allowed}.lc-table-pagination__page{white-space:nowrap;min-width:60px;text-align:center}@media(max-width:640px){.lc-table-wrapper--stack .lc-table thead{display:none}.lc-table-wrapper--stack .lc-table tbody tr{display:block;margin-bottom:var(--spacing-4);border:1px solid var(--color-border);border-radius:var(--border-radius-md)}.lc-table-wrapper--stack .lc-table tbody tr td{display:block;text-align:right;padding:var(--spacing-2) var(--spacing-4);border-bottom:1px solid var(--color-divider)}.lc-table-wrapper--stack .lc-table tbody tr td:last-child{border-bottom:none}.lc-table-wrapper--stack .lc-table tbody tr td:before{content:attr(data-label);float:left;font-weight:var(--typography-font-weight-semibold);color:var(--color-text-secondary)}}[data-theme=dark] .lc-table__filter-input,:root[data-theme=dark] .lc-table__filter-input{background-color:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .lc-table__edit-input,:root[data-theme=dark] .lc-table__edit-input{background-color:var(--color-neutral-800)}[data-theme=dark] .lc-table__row--selected,:root[data-theme=dark] .lc-table__row--selected{background-color:#3b82f61f!important}[data-theme=dark] .lc-table-pagination__btn,:root[data-theme=dark] .lc-table-pagination__btn{background-color:var(--color-neutral-800);border-color:var(--color-neutral-700)}[data-theme=dark] .lc-table-pagination__btn:hover:not(:disabled),:root[data-theme=dark] .lc-table-pagination__btn:hover:not(:disabled){background-color:var(--color-neutral-700)}\n"] }]
|
|
7309
7343
|
}], propDecorators: { cellTemplates: [{
|
|
7310
7344
|
type: ContentChildren,
|
|
7311
7345
|
args: [TableCellDirective]
|
|
7312
|
-
}], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], hoverable: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverable", required: false }] }], responsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "responsive", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], paginate: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginate", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], filterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterable", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], sort: [{ type: i0.Output, args: ["sort"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], cellEdit: [{ type: i0.Output, args: ["cellEdit"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }] } });
|
|
7346
|
+
}], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], hoverable: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverable", required: false }] }], responsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "responsive", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], paginate: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginate", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], filterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterable", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], actionsLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionsLabel", required: false }] }], actionsWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionsWidth", required: false }] }], actionsAlign: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionsAlign", required: false }] }], sort: [{ type: i0.Output, args: ["sort"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], cellEdit: [{ type: i0.Output, args: ["cellEdit"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], actionClick: [{ type: i0.Output, args: ["actionClick"] }] } });
|
|
7313
7347
|
|
|
7314
7348
|
/**
|
|
7315
7349
|
* Field group component for displaying label-value pairs.
|
|
@@ -12179,6 +12213,328 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImpo
|
|
|
12179
12213
|
args: ['document:mouseup']
|
|
12180
12214
|
}] } });
|
|
12181
12215
|
|
|
12216
|
+
/**
|
|
12217
|
+
* File-type → icon mapping for the TreeView component.
|
|
12218
|
+
*
|
|
12219
|
+
* Icon names refer to Tabler Icons (the design system's icon source).
|
|
12220
|
+
* Resolution order for a file node:
|
|
12221
|
+
* 1. explicit `node.icon`
|
|
12222
|
+
* 2. exact file name match (e.g. `package.json`, `Dockerfile`)
|
|
12223
|
+
* 3. file extension match (e.g. `.ts`, `.png`)
|
|
12224
|
+
* 4. generic file fallback
|
|
12225
|
+
*/
|
|
12226
|
+
/** Icon used for collapsed folders. */
|
|
12227
|
+
const FOLDER_ICON = 'folder';
|
|
12228
|
+
/** Icon used for expanded (open) folders. */
|
|
12229
|
+
const FOLDER_OPEN_ICON = 'folder-open';
|
|
12230
|
+
/** Generic fallback icon for files with no specific match. */
|
|
12231
|
+
const FILE_FALLBACK_ICON = 'file';
|
|
12232
|
+
/** Map of well-known file names (lower-cased) to icons. */
|
|
12233
|
+
const FILE_NAME_ICONS = {
|
|
12234
|
+
'package.json': 'brand-npm',
|
|
12235
|
+
'package-lock.json': 'brand-npm',
|
|
12236
|
+
'yarn.lock': 'brand-yarn',
|
|
12237
|
+
'pnpm-lock.yaml': 'brand-pnpm',
|
|
12238
|
+
'dockerfile': 'brand-docker',
|
|
12239
|
+
'docker-compose.yml': 'brand-docker',
|
|
12240
|
+
'docker-compose.yaml': 'brand-docker',
|
|
12241
|
+
'.gitignore': 'brand-git',
|
|
12242
|
+
'.gitattributes': 'brand-git',
|
|
12243
|
+
'.gitmodules': 'brand-git',
|
|
12244
|
+
'readme.md': 'book',
|
|
12245
|
+
'license': 'license',
|
|
12246
|
+
'license.md': 'license',
|
|
12247
|
+
'.env': 'key',
|
|
12248
|
+
'.env.local': 'key',
|
|
12249
|
+
'.editorconfig': 'settings',
|
|
12250
|
+
'.prettierrc': 'settings',
|
|
12251
|
+
'.eslintrc': 'settings',
|
|
12252
|
+
'tsconfig.json': 'brand-typescript',
|
|
12253
|
+
'angular.json': 'brand-angular',
|
|
12254
|
+
'nx.json': 'settings',
|
|
12255
|
+
'makefile': 'terminal',
|
|
12256
|
+
};
|
|
12257
|
+
/** Map of file extensions (without dot, lower-cased) to icons. */
|
|
12258
|
+
const FILE_EXT_ICONS = {
|
|
12259
|
+
// Languages
|
|
12260
|
+
ts: 'brand-typescript',
|
|
12261
|
+
tsx: 'brand-typescript',
|
|
12262
|
+
js: 'brand-javascript',
|
|
12263
|
+
jsx: 'brand-javascript',
|
|
12264
|
+
mjs: 'brand-javascript',
|
|
12265
|
+
cjs: 'brand-javascript',
|
|
12266
|
+
html: 'brand-html5',
|
|
12267
|
+
htm: 'brand-html5',
|
|
12268
|
+
css: 'brand-css3',
|
|
12269
|
+
scss: 'brand-sass',
|
|
12270
|
+
sass: 'brand-sass',
|
|
12271
|
+
less: 'brand-css3',
|
|
12272
|
+
py: 'brand-python',
|
|
12273
|
+
rb: 'diamond',
|
|
12274
|
+
go: 'brand-golang',
|
|
12275
|
+
rs: 'brand-rust',
|
|
12276
|
+
java: 'coffee',
|
|
12277
|
+
kt: 'brand-kotlin',
|
|
12278
|
+
swift: 'brand-swift',
|
|
12279
|
+
c: 'file-code',
|
|
12280
|
+
h: 'file-code',
|
|
12281
|
+
cpp: 'brand-cpp',
|
|
12282
|
+
cs: 'brand-c-sharp',
|
|
12283
|
+
php: 'brand-php',
|
|
12284
|
+
dart: 'brand-flutter',
|
|
12285
|
+
sh: 'terminal-2',
|
|
12286
|
+
bash: 'terminal-2',
|
|
12287
|
+
zsh: 'terminal-2',
|
|
12288
|
+
sql: 'database',
|
|
12289
|
+
// Data / config
|
|
12290
|
+
json: 'braces',
|
|
12291
|
+
jsonc: 'braces',
|
|
12292
|
+
yml: 'file-code',
|
|
12293
|
+
yaml: 'file-code',
|
|
12294
|
+
toml: 'file-code',
|
|
12295
|
+
xml: 'file-code',
|
|
12296
|
+
ini: 'settings',
|
|
12297
|
+
env: 'key',
|
|
12298
|
+
// Docs
|
|
12299
|
+
md: 'markdown',
|
|
12300
|
+
mdx: 'markdown',
|
|
12301
|
+
txt: 'file-text',
|
|
12302
|
+
pdf: 'file-type-pdf',
|
|
12303
|
+
doc: 'file-text',
|
|
12304
|
+
docx: 'file-text',
|
|
12305
|
+
csv: 'file-spreadsheet',
|
|
12306
|
+
xls: 'file-spreadsheet',
|
|
12307
|
+
xlsx: 'file-spreadsheet',
|
|
12308
|
+
// Images
|
|
12309
|
+
png: 'photo',
|
|
12310
|
+
jpg: 'photo',
|
|
12311
|
+
jpeg: 'photo',
|
|
12312
|
+
gif: 'photo',
|
|
12313
|
+
webp: 'photo',
|
|
12314
|
+
svg: 'file-vector',
|
|
12315
|
+
ico: 'photo',
|
|
12316
|
+
bmp: 'photo',
|
|
12317
|
+
// Media
|
|
12318
|
+
mp3: 'music',
|
|
12319
|
+
wav: 'music',
|
|
12320
|
+
mp4: 'video',
|
|
12321
|
+
mov: 'video',
|
|
12322
|
+
webm: 'video',
|
|
12323
|
+
// Archives
|
|
12324
|
+
zip: 'file-zip',
|
|
12325
|
+
tar: 'file-zip',
|
|
12326
|
+
gz: 'file-zip',
|
|
12327
|
+
rar: 'file-zip',
|
|
12328
|
+
'7z': 'file-zip',
|
|
12329
|
+
// Fonts
|
|
12330
|
+
woff: 'typography',
|
|
12331
|
+
woff2: 'typography',
|
|
12332
|
+
ttf: 'typography',
|
|
12333
|
+
otf: 'typography',
|
|
12334
|
+
// Misc
|
|
12335
|
+
lock: 'lock',
|
|
12336
|
+
};
|
|
12337
|
+
/**
|
|
12338
|
+
* Resolve the icon name for a file based on its name.
|
|
12339
|
+
* Performs exact-name then extension lookup, falling back to a generic file icon.
|
|
12340
|
+
*/
|
|
12341
|
+
function resolveFileIcon(fileName) {
|
|
12342
|
+
const lower = fileName.toLowerCase();
|
|
12343
|
+
const byName = FILE_NAME_ICONS[lower];
|
|
12344
|
+
if (byName)
|
|
12345
|
+
return byName;
|
|
12346
|
+
const dotIndex = lower.lastIndexOf('.');
|
|
12347
|
+
if (dotIndex > 0 && dotIndex < lower.length - 1) {
|
|
12348
|
+
const ext = lower.slice(dotIndex + 1);
|
|
12349
|
+
const byExt = FILE_EXT_ICONS[ext];
|
|
12350
|
+
if (byExt)
|
|
12351
|
+
return byExt;
|
|
12352
|
+
}
|
|
12353
|
+
return FILE_FALLBACK_ICON;
|
|
12354
|
+
}
|
|
12355
|
+
|
|
12356
|
+
const BADGE_STATUS_COLOR = {
|
|
12357
|
+
default: 'var(--color-neutral-400)',
|
|
12358
|
+
added: 'var(--color-success-default, #16a34a)',
|
|
12359
|
+
modified: 'var(--color-warning-default, #d97706)',
|
|
12360
|
+
removed: 'var(--color-error-default, #dc2626)',
|
|
12361
|
+
muted: 'var(--color-neutral-300)',
|
|
12362
|
+
};
|
|
12363
|
+
function nodeType(node) {
|
|
12364
|
+
return node.type ?? (node.children ? 'folder' : 'file');
|
|
12365
|
+
}
|
|
12366
|
+
/**
|
|
12367
|
+
* Tree view component for visualizing file / folder hierarchies such as a
|
|
12368
|
+
* complete GitHub project.
|
|
12369
|
+
*
|
|
12370
|
+
* Features:
|
|
12371
|
+
* - Recursive folder / file rendering from a single `nodes` input
|
|
12372
|
+
* - Automatic file-type icons by extension and well-known file name,
|
|
12373
|
+
* with open / closed folder icons
|
|
12374
|
+
* - Expand / collapse folders, with expand-all / collapse-all helpers
|
|
12375
|
+
* - Two-way bound selection and a `nodeClick` event
|
|
12376
|
+
* - Indentation guide lines for readability
|
|
12377
|
+
* - Optional per-node status badges (added / modified / removed)
|
|
12378
|
+
* - Keyboard accessible (Enter / Space to toggle or select)
|
|
12379
|
+
* - Dark / light theme support via design tokens
|
|
12380
|
+
*
|
|
12381
|
+
* @example
|
|
12382
|
+
* ```html
|
|
12383
|
+
* <lc-tree-view [nodes]="projectTree" [(selectedId)]="selected" />
|
|
12384
|
+
* ```
|
|
12385
|
+
*/
|
|
12386
|
+
class TreeViewComponent {
|
|
12387
|
+
/** The root-level nodes of the tree. */
|
|
12388
|
+
nodes = input.required(...(ngDevMode ? [{ debugName: "nodes" }] : /* istanbul ignore next */ []));
|
|
12389
|
+
/** Id (or path) of the currently selected node (two-way bindable). */
|
|
12390
|
+
selectedId = model(null, ...(ngDevMode ? [{ debugName: "selectedId" }] : /* istanbul ignore next */ []));
|
|
12391
|
+
/** Show indentation guide lines. */
|
|
12392
|
+
showGuides = input(true, ...(ngDevMode ? [{ debugName: "showGuides" }] : /* istanbul ignore next */ []));
|
|
12393
|
+
/** Show the expand-all / collapse-all toolbar. */
|
|
12394
|
+
showToolbar = input(true, ...(ngDevMode ? [{ debugName: "showToolbar" }] : /* istanbul ignore next */ []));
|
|
12395
|
+
/** Icon size for node icons. */
|
|
12396
|
+
iconSize = input('sm', ...(ngDevMode ? [{ debugName: "iconSize" }] : /* istanbul ignore next */ []));
|
|
12397
|
+
/** Emitted when a node is clicked / activated. */
|
|
12398
|
+
nodeClick = output();
|
|
12399
|
+
/** Set of node ids the user has explicitly expanded / collapsed. */
|
|
12400
|
+
expandOverrides = signal(new Map(), ...(ngDevMode ? [{ debugName: "expandOverrides" }] : /* istanbul ignore next */ []));
|
|
12401
|
+
/** Flattened, render-ready list of visible nodes. */
|
|
12402
|
+
visibleNodes = computed(() => {
|
|
12403
|
+
const out = [];
|
|
12404
|
+
const overrides = this.expandOverrides();
|
|
12405
|
+
this.flatten(this.nodes(), 0, '', [], overrides, out);
|
|
12406
|
+
return out;
|
|
12407
|
+
}, ...(ngDevMode ? [{ debugName: "visibleNodes" }] : /* istanbul ignore next */ []));
|
|
12408
|
+
badgeColor(status) {
|
|
12409
|
+
return BADGE_STATUS_COLOR[status];
|
|
12410
|
+
}
|
|
12411
|
+
onNodeClick(flat) {
|
|
12412
|
+
if (flat.disabled)
|
|
12413
|
+
return;
|
|
12414
|
+
if (flat.hasChildren) {
|
|
12415
|
+
this.toggle(flat);
|
|
12416
|
+
}
|
|
12417
|
+
this.selectedId.set(flat.id);
|
|
12418
|
+
const original = this.findNode(this.nodes(), '', flat.id);
|
|
12419
|
+
if (original)
|
|
12420
|
+
this.nodeClick.emit(original);
|
|
12421
|
+
}
|
|
12422
|
+
onToggleClick(flat, event) {
|
|
12423
|
+
event.stopPropagation();
|
|
12424
|
+
if (!flat.disabled)
|
|
12425
|
+
this.toggle(flat);
|
|
12426
|
+
}
|
|
12427
|
+
onKeydown(flat, event) {
|
|
12428
|
+
if (flat.disabled)
|
|
12429
|
+
return;
|
|
12430
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
12431
|
+
event.preventDefault();
|
|
12432
|
+
this.onNodeClick(flat);
|
|
12433
|
+
}
|
|
12434
|
+
else if (event.key === 'ArrowRight' && flat.hasChildren && !flat.expanded) {
|
|
12435
|
+
event.preventDefault();
|
|
12436
|
+
this.setExpanded(flat.id, true);
|
|
12437
|
+
}
|
|
12438
|
+
else if (event.key === 'ArrowLeft' && flat.hasChildren && flat.expanded) {
|
|
12439
|
+
event.preventDefault();
|
|
12440
|
+
this.setExpanded(flat.id, false);
|
|
12441
|
+
}
|
|
12442
|
+
}
|
|
12443
|
+
/** Expand every folder in the tree. */
|
|
12444
|
+
expandAll() {
|
|
12445
|
+
this.setAll(true);
|
|
12446
|
+
}
|
|
12447
|
+
/** Collapse every folder in the tree. */
|
|
12448
|
+
collapseAll() {
|
|
12449
|
+
this.setAll(false);
|
|
12450
|
+
}
|
|
12451
|
+
trackById = (_, n) => n.id;
|
|
12452
|
+
// ── internals ──────────────────────────────────────────────────────────────
|
|
12453
|
+
toggle(flat) {
|
|
12454
|
+
this.setExpanded(flat.id, !flat.expanded);
|
|
12455
|
+
}
|
|
12456
|
+
setExpanded(id, value) {
|
|
12457
|
+
this.expandOverrides.update((map) => {
|
|
12458
|
+
const next = new Map(map);
|
|
12459
|
+
next.set(id, value);
|
|
12460
|
+
return next;
|
|
12461
|
+
});
|
|
12462
|
+
}
|
|
12463
|
+
setAll(value) {
|
|
12464
|
+
const next = new Map();
|
|
12465
|
+
const walk = (nodes, parentPath) => {
|
|
12466
|
+
for (const node of nodes) {
|
|
12467
|
+
const id = node.id ?? `${parentPath}/${node.name}`;
|
|
12468
|
+
if (nodeType(node) === 'folder') {
|
|
12469
|
+
next.set(id, value);
|
|
12470
|
+
if (node.children)
|
|
12471
|
+
walk(node.children, id);
|
|
12472
|
+
}
|
|
12473
|
+
}
|
|
12474
|
+
};
|
|
12475
|
+
walk(this.nodes(), '');
|
|
12476
|
+
this.expandOverrides.set(next);
|
|
12477
|
+
}
|
|
12478
|
+
isExpanded(id, node, overrides) {
|
|
12479
|
+
const override = overrides.get(id);
|
|
12480
|
+
if (override !== undefined)
|
|
12481
|
+
return override;
|
|
12482
|
+
return node.expanded ?? false;
|
|
12483
|
+
}
|
|
12484
|
+
flatten(nodes, depth, parentPath, ancestorHasSibling, overrides, out) {
|
|
12485
|
+
nodes.forEach((node, index) => {
|
|
12486
|
+
const id = node.id ?? `${parentPath}/${node.name}`;
|
|
12487
|
+
const type = nodeType(node);
|
|
12488
|
+
const hasChildren = type === 'folder' && !!node.children?.length;
|
|
12489
|
+
const expanded = hasChildren && this.isExpanded(id, node, overrides);
|
|
12490
|
+
const isLast = index === nodes.length - 1;
|
|
12491
|
+
out.push({
|
|
12492
|
+
id,
|
|
12493
|
+
name: node.name,
|
|
12494
|
+
type,
|
|
12495
|
+
depth,
|
|
12496
|
+
hasChildren,
|
|
12497
|
+
expanded,
|
|
12498
|
+
icon: this.resolveIcon(node, type, expanded),
|
|
12499
|
+
badge: node.badge,
|
|
12500
|
+
status: node.status ?? 'default',
|
|
12501
|
+
disabled: node.disabled ?? false,
|
|
12502
|
+
ancestorHasSibling,
|
|
12503
|
+
isLast,
|
|
12504
|
+
});
|
|
12505
|
+
if (expanded && node.children) {
|
|
12506
|
+
this.flatten(node.children, depth + 1, id, [...ancestorHasSibling, !isLast], overrides, out);
|
|
12507
|
+
}
|
|
12508
|
+
});
|
|
12509
|
+
}
|
|
12510
|
+
resolveIcon(node, type, expanded) {
|
|
12511
|
+
if (node.icon)
|
|
12512
|
+
return node.icon;
|
|
12513
|
+
if (type === 'folder')
|
|
12514
|
+
return expanded ? FOLDER_OPEN_ICON : FOLDER_ICON;
|
|
12515
|
+
return node.name ? resolveFileIcon(node.name) : FILE_FALLBACK_ICON;
|
|
12516
|
+
}
|
|
12517
|
+
findNode(nodes, parentPath, targetId) {
|
|
12518
|
+
for (const node of nodes) {
|
|
12519
|
+
const id = node.id ?? `${parentPath}/${node.name}`;
|
|
12520
|
+
if (id === targetId)
|
|
12521
|
+
return node;
|
|
12522
|
+
if (node.children) {
|
|
12523
|
+
const found = this.findNode(node.children, id, targetId);
|
|
12524
|
+
if (found)
|
|
12525
|
+
return found;
|
|
12526
|
+
}
|
|
12527
|
+
}
|
|
12528
|
+
return null;
|
|
12529
|
+
}
|
|
12530
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: TreeViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
12531
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.10", type: TreeViewComponent, isStandalone: true, selector: "lc-tree-view", inputs: { nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: true, transformFunction: null }, selectedId: { classPropertyName: "selectedId", publicName: "selectedId", isSignal: true, isRequired: false, transformFunction: null }, showGuides: { classPropertyName: "showGuides", publicName: "showGuides", isSignal: true, isRequired: false, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "showToolbar", isSignal: true, isRequired: false, transformFunction: null }, iconSize: { classPropertyName: "iconSize", publicName: "iconSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedId: "selectedIdChange", nodeClick: "nodeClick" }, host: { classAttribute: "lc-tree-view" }, ngImport: i0, template: "@if (showToolbar()) {\n <div class=\"lc-tree-view__toolbar\">\n <button type=\"button\" class=\"lc-tree-view__tool-btn\" (click)=\"expandAll()\" title=\"Expand all\">\n <lc-icon name=\"fold-down\" size=\"xs\" [decorative]=\"true\" />\n <span>Expand all</span>\n </button>\n <button type=\"button\" class=\"lc-tree-view__tool-btn\" (click)=\"collapseAll()\" title=\"Collapse all\">\n <lc-icon name=\"fold-up\" size=\"xs\" [decorative]=\"true\" />\n <span>Collapse all</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-expanded]=\"node.hasChildren ? node.expanded : null\"\n [attr.aria-selected]=\"node.id === selectedId()\"\n [attr.aria-disabled]=\"node.disabled ? true : null\"\n [tabindex]=\"node.disabled ? -1 : 0\"\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 ? 'Collapse' : 'Expand'\"\n tabindex=\"-1\"\n >\n <lc-icon name=\"chevron-right\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </span>\n\n <!-- type / file icon -->\n <span\n class=\"lc-tree-view__icon\"\n [style.color]=\"\n node.status === 'default' ? null : badgeColor(node.status)\n \"\n >\n <lc-icon [name]=\"node.icon\" [size]=\"iconSize()\" [decorative]=\"true\" />\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 </li>\n }\n</ul>\n", styles: [":host{display:block;border:1px solid var(--color-neutral-200);border-radius:8px;background:var(--color-neutral-0, #fff);overflow:hidden;font-size:13px;color:var(--color-neutral-900)}.lc-tree-view__toolbar{display:flex;align-items:center;gap:4px;padding:6px 8px;border-bottom:1px solid var(--color-neutral-200);background:var(--color-neutral-50);-webkit-user-select:none;user-select:none}.lc-tree-view__tool-btn{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;border:1px solid transparent;border-radius:4px;background:transparent;color:var(--color-neutral-600);font-size:12px;cursor:pointer;line-height:1}.lc-tree-view__tool-btn:hover{background:var(--color-neutral-100);color:var(--color-neutral-900)}.lc-tree-view__list{list-style:none;margin:0;padding:4px 0}.lc-tree-view__item{display:flex;align-items:center;height:26px;padding-right:8px;cursor:pointer;-webkit-user-select:none;user-select:none;position:relative;outline:none}.lc-tree-view__item:hover{background:var(--color-neutral-100)}.lc-tree-view__item:focus-visible{box-shadow:inset 0 0 0 2px var(--color-primary-400)}.lc-tree-view__item--selected{background:var(--color-primary-50)}.lc-tree-view__item--selected:hover{background:var(--color-primary-100, var(--color-primary-50))}.lc-tree-view__item--selected .lc-tree-view__label{color:var(--color-primary-700);font-weight:500}.lc-tree-view__item--disabled{opacity:.5;cursor:not-allowed}.lc-tree-view__item--disabled:hover{background:transparent}.lc-tree-view__indent{flex:0 0 18px;width:18px;height:100%;position:relative}.lc-tree-view__indent--guide:before{content:\"\";position:absolute;left:50%;top:0;bottom:0;width:1px;background:var(--color-neutral-200)}.lc-tree-view__chevron{flex:0 0 18px;width:18px;display:flex;align-items:center;justify-content:center;color:var(--color-neutral-500)}.lc-tree-view__chevron-btn{display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;background:transparent;color:inherit;cursor:pointer;border-radius:3px;transition:transform .12s ease}.lc-tree-view__chevron-btn:hover{background:var(--color-neutral-200)}.lc-tree-view__chevron-btn--expanded{transform:rotate(90deg)}.lc-tree-view__icon{display:flex;align-items:center;margin-right:6px;color:var(--color-neutral-500)}.lc-tree-view__item--folder .lc-tree-view__icon{color:var(--color-primary-500, #6366f1)}.lc-tree-view__label{flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-neutral-800)}.lc-tree-view__badge{flex:0 0 auto;margin-left:8px;padding:1px 6px;border:1px solid;border-radius:10px;font-size:10px;line-height:1.4;font-weight:600;text-transform:uppercase;letter-spacing:.02em}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "lc-icon", inputs: ["name", "variant", "size", "color", "ariaLabel", "decorative"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
12532
|
+
}
|
|
12533
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImport: i0, type: TreeViewComponent, decorators: [{
|
|
12534
|
+
type: Component,
|
|
12535
|
+
args: [{ selector: 'lc-tree-view', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'lc-tree-view' }, template: "@if (showToolbar()) {\n <div class=\"lc-tree-view__toolbar\">\n <button type=\"button\" class=\"lc-tree-view__tool-btn\" (click)=\"expandAll()\" title=\"Expand all\">\n <lc-icon name=\"fold-down\" size=\"xs\" [decorative]=\"true\" />\n <span>Expand all</span>\n </button>\n <button type=\"button\" class=\"lc-tree-view__tool-btn\" (click)=\"collapseAll()\" title=\"Collapse all\">\n <lc-icon name=\"fold-up\" size=\"xs\" [decorative]=\"true\" />\n <span>Collapse all</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-expanded]=\"node.hasChildren ? node.expanded : null\"\n [attr.aria-selected]=\"node.id === selectedId()\"\n [attr.aria-disabled]=\"node.disabled ? true : null\"\n [tabindex]=\"node.disabled ? -1 : 0\"\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 ? 'Collapse' : 'Expand'\"\n tabindex=\"-1\"\n >\n <lc-icon name=\"chevron-right\" size=\"xs\" [decorative]=\"true\" />\n </button>\n }\n </span>\n\n <!-- type / file icon -->\n <span\n class=\"lc-tree-view__icon\"\n [style.color]=\"\n node.status === 'default' ? null : badgeColor(node.status)\n \"\n >\n <lc-icon [name]=\"node.icon\" [size]=\"iconSize()\" [decorative]=\"true\" />\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 </li>\n }\n</ul>\n", styles: [":host{display:block;border:1px solid var(--color-neutral-200);border-radius:8px;background:var(--color-neutral-0, #fff);overflow:hidden;font-size:13px;color:var(--color-neutral-900)}.lc-tree-view__toolbar{display:flex;align-items:center;gap:4px;padding:6px 8px;border-bottom:1px solid var(--color-neutral-200);background:var(--color-neutral-50);-webkit-user-select:none;user-select:none}.lc-tree-view__tool-btn{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;border:1px solid transparent;border-radius:4px;background:transparent;color:var(--color-neutral-600);font-size:12px;cursor:pointer;line-height:1}.lc-tree-view__tool-btn:hover{background:var(--color-neutral-100);color:var(--color-neutral-900)}.lc-tree-view__list{list-style:none;margin:0;padding:4px 0}.lc-tree-view__item{display:flex;align-items:center;height:26px;padding-right:8px;cursor:pointer;-webkit-user-select:none;user-select:none;position:relative;outline:none}.lc-tree-view__item:hover{background:var(--color-neutral-100)}.lc-tree-view__item:focus-visible{box-shadow:inset 0 0 0 2px var(--color-primary-400)}.lc-tree-view__item--selected{background:var(--color-primary-50)}.lc-tree-view__item--selected:hover{background:var(--color-primary-100, var(--color-primary-50))}.lc-tree-view__item--selected .lc-tree-view__label{color:var(--color-primary-700);font-weight:500}.lc-tree-view__item--disabled{opacity:.5;cursor:not-allowed}.lc-tree-view__item--disabled:hover{background:transparent}.lc-tree-view__indent{flex:0 0 18px;width:18px;height:100%;position:relative}.lc-tree-view__indent--guide:before{content:\"\";position:absolute;left:50%;top:0;bottom:0;width:1px;background:var(--color-neutral-200)}.lc-tree-view__chevron{flex:0 0 18px;width:18px;display:flex;align-items:center;justify-content:center;color:var(--color-neutral-500)}.lc-tree-view__chevron-btn{display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;background:transparent;color:inherit;cursor:pointer;border-radius:3px;transition:transform .12s ease}.lc-tree-view__chevron-btn:hover{background:var(--color-neutral-200)}.lc-tree-view__chevron-btn--expanded{transform:rotate(90deg)}.lc-tree-view__icon{display:flex;align-items:center;margin-right:6px;color:var(--color-neutral-500)}.lc-tree-view__item--folder .lc-tree-view__icon{color:var(--color-primary-500, #6366f1)}.lc-tree-view__label{flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-neutral-800)}.lc-tree-view__badge{flex:0 0 auto;margin-left:8px;padding:1px 6px;border:1px solid;border-radius:10px;font-size:10px;line-height:1.4;font-weight:600;text-transform:uppercase;letter-spacing:.02em}\n"] }]
|
|
12536
|
+
}], propDecorators: { nodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodes", required: true }] }], selectedId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedId", required: false }] }, { type: i0.Output, args: ["selectedIdChange"] }], showGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGuides", required: false }] }], showToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showToolbar", required: false }] }], iconSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconSize", required: false }] }], nodeClick: [{ type: i0.Output, args: ["nodeClick"] }] } });
|
|
12537
|
+
|
|
12182
12538
|
const DEFAULT_COLORS$1 = [
|
|
12183
12539
|
'var(--color-primary-500)',
|
|
12184
12540
|
'var(--color-secondary-500)',
|
|
@@ -14266,5 +14622,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.10", ngImpo
|
|
|
14266
14622
|
* Generated bundle index. Do not edit.
|
|
14267
14623
|
*/
|
|
14268
14624
|
|
|
14269
|
-
export { AccordionComponent, AccordionGroupComponent, AlertComponent, AnimationDurationFast, AnimationEasingEaseIn, AnimationEasingEaseInOut, AnimationEasingEaseOut, AreaChartComponent, AvatarComponent, AvatarGroupComponent, BadgeComponent, BarChartComponent, BorderRadius2xl, BorderRadiusFull, BorderRadiusLg, BorderRadiusMd, BorderRadiusNone, BorderRadiusSm, BorderRadiusXl, BreadcrumbsComponent, ButtonComponent, CalendarComponent, CalloutComponent, CardComponent, ChatComponent, CheckboxComponent, ChipComponent, CodeBlockComponent, ColorAccentOrange, ColorAccentPurple, ColorAccentRed, ColorAccentRust, ColorAccentViolet, ColorErrorDark, ColorErrorDefault, ColorErrorLight, ColorInfoDark, ColorInfoDefault, ColorInfoLight, ColorNeutral100, ColorNeutral200, ColorNeutral300, ColorNeutral400, ColorNeutral50, ColorNeutral500, ColorNeutral600, ColorNeutral700, ColorNeutral800, ColorNeutral900, ColorPickerComponent, ColorPrimary100, ColorPrimary200, ColorPrimary300, ColorPrimary400, ColorPrimary50, ColorPrimary500, ColorPrimary600, ColorPrimary700, ColorPrimary800, ColorPrimary900, ColorSecondary100, ColorSecondary200, ColorSecondary300, ColorSecondary400, ColorSecondary50, ColorSecondary500, ColorSecondary600, ColorSecondary700, ColorSecondary800, ColorSecondary900, ColorSuccessDark, ColorSuccessDefault, ColorSuccessLight, ColorWarningDark, ColorWarningDefault, ColorWarningLight, ComboboxComponent, ConfirmDialogComponent, ConfirmService, ContainerComponent, DateRangePickerComponent, DatepickerComponent, DependencyViewerComponent, DiffViewerComponent, DividerComponent, DocumentViewerComponent, DonutChartComponent, DrawerComponent, Elevation1, Elevation2, Elevation3, Elevation4, EmailInputComponent, EmptyStateComponent, ErrorDisplayComponent, FieldGroupComponent, FileUploadComponent, FilterBarComponent, FooterComponent, FunnelChartComponent, GalleryComponent, GanttChartComponent, GaugeComponent, HeaderComponent, HeatmapComponent, HeroComponent, IconComponent, InputComponent, KanbanBoardComponent, LC_LOGO_BASE_PATH, LineChartComponent, ListComponent, ListItemTemplateDirective, LogViewerComponent, LogoComponent, MarkdownComponent, MenuComponent, ModalComponent, NotificationCenterComponent, NumberInputComponent, PageHeaderComponent, PaginationComponent, PasswordInputComponent, PieChartComponent, PopoverComponent, ProgressBarComponent, ProgressRingComponent, RadarChartComponent, RadioComponent, RatingComponent, RichTextEditorComponent, ScatterPlotComponent, SearchInputComponent, SectionComponent, SelectComponent, SidenavComponent, SizeInteractiveLgFontSize, SizeInteractiveLgHeight, SizeInteractiveLgPadding, SizeInteractiveMdFontSize, SizeInteractiveMdHeight, SizeInteractiveMdPadding, SizeInteractiveSmFontSize, SizeInteractiveSmHeight, SizeInteractiveSmPadding, SizeInteractiveXsFontSize, SizeInteractiveXsHeight, SizeInteractiveXsPadding, SizeMinTouchHeight, SizeMinTouchWidth, SkeletonComponent, SliderComponent, SpacerComponent, Spacing0, Spacing05, Spacing1, Spacing10, Spacing11, Spacing12, Spacing14, Spacing15, Spacing16, Spacing2, Spacing25, Spacing3, Spacing35, Spacing4, Spacing5, Spacing6, Spacing7, Spacing8, Spacing9, SparklineComponent, SpinnerComponent, StackComponent, StackedBarChartComponent, StatTrendComponent, StepperComponent, SwitchComponent, TabComponent, TableCellDirective, TableComponent, TabsComponent, TagInputComponent, TextareaComponent, ThemeService, TimelineComponent, ToastComponent, ToastService, ToggleGroupComponent, ToolbarComponent, TooltipContentComponent, TooltipDirective, TypographyComponent, TypographyFontFamilyBase, TypographyFontFamilyMono, TypographyFontSize2xl, TypographyFontSize3xl, TypographyFontSize4xl, TypographyFontSize5xl, TypographyFontSize6xl, TypographyFontSizeBase, TypographyFontSizeLg, TypographyFontSizeSm, TypographyFontSizeXl, TypographyFontSizeXs, TypographyFontWeightBold, TypographyFontWeightMedium, TypographyFontWeightNormal, TypographyFontWeightSemibold, TypographyLineHeightNormal, TypographyLineHeightRelaxed, TypographyLineHeightTight, VerificationCodeInputComponent, WaterfallChartComponent };
|
|
14625
|
+
export { AccordionComponent, AccordionGroupComponent, AlertComponent, AnimationDurationFast, AnimationEasingEaseIn, AnimationEasingEaseInOut, AnimationEasingEaseOut, AreaChartComponent, AvatarComponent, AvatarGroupComponent, BadgeComponent, BarChartComponent, BorderRadius2xl, BorderRadiusFull, BorderRadiusLg, BorderRadiusMd, BorderRadiusNone, BorderRadiusSm, BorderRadiusXl, BreadcrumbsComponent, ButtonComponent, CalendarComponent, CalloutComponent, CardComponent, ChatComponent, CheckboxComponent, ChipComponent, CodeBlockComponent, ColorAccentOrange, ColorAccentPurple, ColorAccentRed, ColorAccentRust, ColorAccentViolet, ColorErrorDark, ColorErrorDefault, ColorErrorLight, ColorInfoDark, ColorInfoDefault, ColorInfoLight, ColorNeutral100, ColorNeutral200, ColorNeutral300, ColorNeutral400, ColorNeutral50, ColorNeutral500, ColorNeutral600, ColorNeutral700, ColorNeutral800, ColorNeutral900, ColorPickerComponent, ColorPrimary100, ColorPrimary200, ColorPrimary300, ColorPrimary400, ColorPrimary50, ColorPrimary500, ColorPrimary600, ColorPrimary700, ColorPrimary800, ColorPrimary900, ColorSecondary100, ColorSecondary200, ColorSecondary300, ColorSecondary400, ColorSecondary50, ColorSecondary500, ColorSecondary600, ColorSecondary700, ColorSecondary800, ColorSecondary900, ColorSuccessDark, ColorSuccessDefault, ColorSuccessLight, ColorWarningDark, ColorWarningDefault, ColorWarningLight, ComboboxComponent, ConfirmDialogComponent, ConfirmService, ContainerComponent, DateRangePickerComponent, DatepickerComponent, DependencyViewerComponent, DiffViewerComponent, DividerComponent, DocumentViewerComponent, DonutChartComponent, DrawerComponent, Elevation1, Elevation2, Elevation3, Elevation4, EmailInputComponent, EmptyStateComponent, ErrorDisplayComponent, FILE_FALLBACK_ICON, FOLDER_ICON, FOLDER_OPEN_ICON, FieldGroupComponent, FileUploadComponent, FilterBarComponent, FooterComponent, FunnelChartComponent, GalleryComponent, GanttChartComponent, GaugeComponent, HeaderComponent, HeatmapComponent, HeroComponent, IconComponent, InputComponent, KanbanBoardComponent, LC_LOGO_BASE_PATH, LineChartComponent, ListComponent, ListItemTemplateDirective, LogViewerComponent, LogoComponent, MarkdownComponent, MenuComponent, ModalComponent, NotificationCenterComponent, NumberInputComponent, PageHeaderComponent, PaginationComponent, PasswordInputComponent, PieChartComponent, PopoverComponent, ProgressBarComponent, ProgressRingComponent, RadarChartComponent, RadioComponent, RatingComponent, RichTextEditorComponent, ScatterPlotComponent, SearchInputComponent, SectionComponent, SelectComponent, SidenavComponent, SizeInteractiveLgFontSize, SizeInteractiveLgHeight, SizeInteractiveLgPadding, SizeInteractiveMdFontSize, SizeInteractiveMdHeight, SizeInteractiveMdPadding, SizeInteractiveSmFontSize, SizeInteractiveSmHeight, SizeInteractiveSmPadding, SizeInteractiveXsFontSize, SizeInteractiveXsHeight, SizeInteractiveXsPadding, SizeMinTouchHeight, SizeMinTouchWidth, SkeletonComponent, SliderComponent, SpacerComponent, Spacing0, Spacing05, Spacing1, Spacing10, Spacing11, Spacing12, Spacing14, Spacing15, Spacing16, Spacing2, Spacing25, Spacing3, Spacing35, Spacing4, Spacing5, Spacing6, Spacing7, Spacing8, Spacing9, SparklineComponent, SpinnerComponent, StackComponent, StackedBarChartComponent, StatTrendComponent, StepperComponent, SwitchComponent, TabComponent, TableCellDirective, TableComponent, TabsComponent, TagInputComponent, TextareaComponent, ThemeService, TimelineComponent, ToastComponent, ToastService, ToggleGroupComponent, ToolbarComponent, TooltipContentComponent, TooltipDirective, TreeViewComponent, TypographyComponent, TypographyFontFamilyBase, TypographyFontFamilyMono, TypographyFontSize2xl, TypographyFontSize3xl, TypographyFontSize4xl, TypographyFontSize5xl, TypographyFontSize6xl, TypographyFontSizeBase, TypographyFontSizeLg, TypographyFontSizeSm, TypographyFontSizeXl, TypographyFontSizeXs, TypographyFontWeightBold, TypographyFontWeightMedium, TypographyFontWeightNormal, TypographyFontWeightSemibold, TypographyLineHeightNormal, TypographyLineHeightRelaxed, TypographyLineHeightTight, VerificationCodeInputComponent, WaterfallChartComponent, resolveFileIcon };
|
|
14270
14626
|
//# sourceMappingURL=life-cockpit-angular-ui-kit.mjs.map
|