@tekus/design-system 5.38.1 → 5.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"tekus-design-system-components-table.mjs","sources":["../../../projects/design-system/components/table/src/table.component.ts","../../../projects/design-system/components/table/src/table.component.html","../../../projects/design-system/components/table/tekus-design-system-components-table.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n input,\n model,\n signal,\n viewChild,\n} from '@angular/core';\nimport { Table, TableModule } from 'primeng/table';\nimport { TagModule } from 'primeng/tag';\nimport { ButtonModule } from 'primeng/button';\nimport { TableColumn } from './table.interface';\nimport { TagComponent } from '@tekus/design-system/components/tag';\nimport { SortEvent } from 'primeng/api';\nimport { ButtonComponent } from '@tekus/design-system/components/button';\nimport { CheckboxComponent } from '@tekus/design-system/components/checkbox';\nimport {\n ActionGroupComponent,\n TkAction,\n} from '@tekus/design-system/components/action-group';\nimport { IconComponent } from '@tekus/design-system/components/icon';\nimport { TimeAgoComponent } from '@tekus/design-system/components/time-ago';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'tk-table',\n imports: [\n TableModule,\n TagModule,\n ButtonModule,\n TagComponent,\n ButtonComponent,\n CheckboxComponent,\n ActionGroupComponent,\n IconComponent,\n TimeAgoComponent,\n ],\n templateUrl: './table.component.html',\n styleUrl: './table.component.scss',\n})\n/**\n * @component TableComponent\n * @description\n * Generic table wrapper around PrimeNG Table component.\n * Displays tabular data with configurable columns and support for custom rendering via template.\n *\n * @usage\n * ```html\n * <tk-table [data]=\"items\" [columns]=\"columnConfig\"></tk-table>\n * ```\n */\nexport class TableComponent<T = unknown> {\n /**\n * @property {InputSignal<T[]>} data\n * @description\n * Array of data objects to display in the table rows.\n * Each object corresponds to one row; properties are mapped to columns via the `columns` input.\n *\n * @default []\n *\n * @example\n * [data]=\"[\n * { id: 1, name: 'John', status: 'active' },\n * { id: 2, name: 'Jane', status: 'inactive' }\n * ]\"\n */\n data = input<T[]>([]);\n\n /**\n * @property {viewChild} tableRef\n * @description\n * Reference to the PrimeNG Table component instance.\n * Used to access table methods and properties directly.\n */\n readonly tableRef = viewChild<Table>('tableRef');\n\n /**\n * @property {InputSignal<TableColumn<T>[]>} columns\n * @description\n * Array of column definitions that describe how to render each column.\n * Each column object specifies the field name, header label, and optional rendering behavior.\n *\n * @default []\n *\n * @example\n * [columns]=\"[\n * { field: 'id', header: 'ID' },\n * { field: 'name', header: 'Name' },\n * { field: 'status', header: 'Status', renderAs: 'tag' }\n * ]\"\n */\n columns = input<TableColumn<T>[]>([]);\n\n /**\n * @property {InputSignal<'single' | 'multiple' | undefined>} selectionMode\n * @description\n * Selection mode of the table.\n */\n selectionMode = input<'single' | 'multiple' | undefined>(undefined);\n\n /**\n * @property {ModelSignal<any[]>} selection\n * @description\n * Selected row(s) in the table.\n */\n selection = model<T[]>([]);\n\n /**\n * @property {InputSignal<string | undefined>} dataKey\n * @description\n * Property name to uniquely identify a row.\n */\n dataKey = input<string | undefined>(undefined);\n\n readonly initialData = signal<T[]>([]);\n readonly internalData = signal<T[]>([]);\n readonly isSorted = signal<boolean | null>(null);\n\n /** Tracks which column's filter overlay is currently open */\n readonly activeFilterColumn = signal<string | null>(null);\n\n /** Stores the selected filter value per column field (null = no filter) */\n readonly columnFilters = model<Record<string, string | null>>({});\n\n /** Two-way bindable signal for the active sort field */\n readonly sortField = model<string | null>(null);\n\n /** Two-way bindable signal for the active sort order (1 for asc, -1 for desc) */\n readonly sortOrder = model<1 | -1 | null>(null);\n\n /** Position of the filter overlay (fixed, relative to viewport) */\n readonly filterOverlayPosition = signal<{ top: number; left: number }>({\n top: 0,\n left: 0,\n });\n\n /**\n * @computed isAllSelected\n * @description\n * Returns true if all visible rows are selected.\n */\n isAllSelected = computed(() => {\n const data = this.internalData();\n const selected = this.selection();\n if (data.length === 0 || selected.length === 0) return false;\n\n // We strictly use full objects for selection now.\n return data.every(row => selected.includes(row));\n });\n\n /**\n * @computed isPartiallySelected\n * @description\n * Returns true if some but not all rows are selected.\n */\n isPartiallySelected = computed(() => {\n const data = this.internalData();\n const selected = this.selection();\n if (data.length === 0 || selected.length === 0) return false;\n\n const allSelected = this.isAllSelected();\n return !allSelected && selected.length > 0;\n });\n\n constructor() {\n /**\n * @effect data → initialData sync\n * @description\n * Whenever the data input changes, update initialData.\n */\n effect(() => {\n this.initialData.set([...this.data()]);\n });\n\n /**\n * @effect filters/data → internalData sync\n * @description\n * Re-apply all filters whenever the initial data or the column filters change.\n * Also applies sorting if there is an active sort.\n */\n effect(() => {\n const filtered = this.getFilteredData();\n const field = this.sortField();\n const order = this.sortOrder();\n\n if (field && order && filtered.length > 0) {\n const event: SortEvent = {\n data: filtered,\n field,\n order,\n };\n this.sortTableData(event);\n }\n this.internalData.set(filtered);\n });\n\n /**\n * @effect sortField/sortOrder → table sort sync\n * @description\n * Listen to external changes to the sortField and sortOrder models, and trigger PrimeNG Table's sort/reset.\n */\n effect(() => {\n const field = this.sortField();\n const order = this.sortOrder();\n const table = this.tableRef();\n if (!table) return;\n\n // Only apply sorting if it is different from the table's current internal state\n if (table.sortField !== field || table.sortOrder !== order) {\n if (field && order) {\n table.sort({ field, order });\n } else if (!field && !order && (table.sortField || table.sortOrder)) {\n table.reset();\n }\n }\n });\n }\n\n /**\n * @method toggleAll\n * @description\n * Toggles selection of all visible rows using full objects.\n * @param checked {unknown}\n */\n toggleAll(checked: unknown) {\n if (checked) {\n this.selection.set([...this.internalData()]);\n } else {\n this.selection.set([]);\n }\n }\n\n /**\n * @method updateSelection\n * @description\n * Updates row selection state from checkbox interaction.\n * @param value {any[]}\n */\n updateSelection(value: T[]) {\n this.selection.set([...value]);\n }\n\n private readonly actionGroupCache = new Map<\n unknown,\n Map<unknown, TkAction[]>\n >();\n\n getActionGroup(\n actions: NonNullable<TableColumn<T>['actionGroup']>,\n row: T\n ): TkAction[] {\n if (!actions) return [];\n if (!this.actionGroupCache.has(actions)) {\n this.actionGroupCache.set(actions, new Map());\n }\n const rowCache = this.actionGroupCache.get(actions)!;\n if (!rowCache.has(row)) {\n rowCache.set(\n row,\n actions.map(a => ({\n icon: a.icon,\n label: a.label,\n action: () => a.action(row),\n disabled: typeof a.disabled === 'function' ? a.disabled(row) : (a.disabled ?? false),\n }))\n );\n }\n return rowCache.get(row)!;\n }\n\n customSort(event: SortEvent) {\n const extField = this.sortField();\n const extOrder = this.sortOrder();\n\n // If this is triggered by the external model updates, apply it directly without cycling\n if (event.field === extField && event.order === extOrder) {\n if (extOrder === 1) {\n this.isSorted.set(true);\n this.sortTableData(event);\n } else if (extOrder === -1) {\n this.isSorted.set(false);\n this.sortTableData(event);\n } else {\n this.isSorted.set(null);\n this.internalData.set(this.getFilteredData());\n }\n return;\n }\n\n // Otherwise, it is a user click: run the cycling logic\n if (this.isSorted() === null || this.isSorted() === undefined) {\n this.isSorted.set(true);\n this.sortField.set(event.field ?? null);\n this.sortOrder.set(1);\n this.sortTableData(event);\n } else if (this.isSorted()) {\n this.isSorted.set(false);\n this.sortField.set(event.field ?? null);\n this.sortOrder.set(-1);\n this.sortTableData(event);\n } else {\n this.isSorted.set(null);\n this.sortField.set(null);\n this.sortOrder.set(null);\n this.internalData.set(this.getFilteredData());\n this.tableRef()?.reset();\n }\n }\n\n sortTableData(event: SortEvent) {\n if (!event.data || !event.field) return;\n\n event.data.sort((data1, data2) => {\n const value1 = data1[event.field!];\n const value2 = data2[event.field!];\n let result = null;\n if (value1 == null && value2 != null) result = -1;\n else if (value1 != null && value2 == null) result = 1;\n else if (value1 == null && value2 == null) result = 0;\n else if (typeof value1 === 'string' && typeof value2 === 'string')\n result = value1.localeCompare(value2);\n else if (value1 < value2) {\n result = -1;\n } else if (value1 > value2) {\n result = 1;\n } else {\n result = 0;\n }\n\n return (event.order ?? 1) * result;\n });\n }\n\n // ─── Filter Methods ───────────────────────────────────────────────────────────\n\n /**\n * @method toggleFilterOverlay\n * @description\n * Opens or closes the filter overlay for a given column.\n * Captures the trigger button position to render the overlay in fixed position.\n */\n toggleFilterOverlay(field: string, event: MouseEvent): void {\n event.stopPropagation();\n if (this.activeFilterColumn() === field) {\n this.activeFilterColumn.set(null);\n } else {\n const trigger = event.currentTarget as HTMLElement;\n const rect = trigger.getBoundingClientRect();\n this.filterOverlayPosition.set({\n top: rect.bottom + 4,\n left: rect.left,\n });\n this.activeFilterColumn.set(field);\n }\n }\n\n /**\n * @method closeFilterOverlay\n * @description\n * Closes the filter overlay.\n */\n closeFilterOverlay(): void {\n this.activeFilterColumn.set(null);\n }\n\n /**\n * @method getUniqueColumnValues\n * @description\n * Returns the unique values for a given column, considering active filters\n * on other columns. This ensures the list only shows values that exist\n * in the currently filtered dataset.\n */\n getUniqueColumnValues(field: string): string[] {\n const filters = this.columnFilters();\n let data = [...this.initialData()];\n\n // Apply all filters EXCEPT the one for the current field\n for (const filterField of Object.keys(filters)) {\n if (filterField === field) continue;\n const selectedValue = filters[filterField];\n if (selectedValue == null) continue;\n\n data = data.filter(row => {\n const cellValue = (row as Record<string, unknown>)[filterField];\n return (\n cellValue != null && this.cellToString(cellValue) === selectedValue\n );\n });\n }\n\n const values = data\n .map(row => (row as Record<string, unknown>)[field])\n .filter(\n (v): v is string | number | boolean =>\n v != null && typeof v !== 'object'\n )\n .map(String);\n\n return [...new Set(values)].sort((a, b) => a.localeCompare(b));\n }\n\n /**\n * @method selectFilterValue\n * @description\n * Selects a value from the filter list and applies the filter.\n */\n selectFilterValue(field: string, value: string): void {\n const filters = { ...this.columnFilters() };\n filters[field] = value;\n this.columnFilters.set(filters);\n this.applyAllFilters();\n this.activeFilterColumn.set(null);\n }\n\n /**\n * @method clearFilter\n * @description\n * Clears the filter for a specific column and re-applies remaining filters.\n */\n clearFilter(field: string): void {\n const filters = { ...this.columnFilters() };\n delete filters[field];\n this.columnFilters.set(filters);\n this.applyAllFilters();\n this.activeFilterColumn.set(null);\n }\n\n /**\n * @method isColumnFiltered\n * @description\n * Returns whether a column currently has an active filter.\n */\n isColumnFiltered(field: string): boolean {\n return this.columnFilters()[field] != null;\n }\n\n /**\n * @method getActiveFilterValue\n * @description\n * Returns the currently selected filter value for a column, or null.\n */\n getActiveFilterValue(field: string): string | null {\n return this.columnFilters()[field] ?? null;\n }\n\n /**\n * @method applyAllFilters\n * @description\n * Applies all active column filters to the initial data set.\n */\n private applyAllFilters(): void {\n this.internalData.set(this.getFilteredData());\n }\n\n /**\n * @method getFilteredData\n * @description\n * Returns the initial data filtered by all active column filters.\n * Used by both applyAllFilters and customSort (reset) to ensure\n * sorting never discards active filters.\n */\n private getFilteredData(): T[] {\n const filters = this.columnFilters();\n let filtered = [...this.initialData()];\n\n for (const field of Object.keys(filters)) {\n const selectedValue = filters[field];\n if (selectedValue == null) continue;\n\n filtered = filtered.filter(row => {\n const cellValue = (row as Record<string, unknown>)[field];\n return (\n cellValue != null && this.cellToString(cellValue) === selectedValue\n );\n });\n }\n\n return filtered;\n }\n\n /**\n * @method cellToString\n * @description\n * Safely converts a cell value to its string representation.\n * Handles primitives directly and avoids [object Object] for complex types.\n */\n private cellToString(value: unknown): string {\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean')\n return `${value}`;\n return JSON.stringify(value);\n }\n\n /**\n * @method handleImageClick\n * @description\n * Handles click events on image-type cells.\n * Stops row selection propagation and invokes the column's imageAction callback when defined.\n * No-op when imageAction is not set, preserving default row-click behavior.\n * @param event {Event} - The native click event.\n * @param col {TableColumn<T>} - The column definition that may carry an imageAction.\n * @param row {T} - The data row associated with the clicked image.\n */\n handleImageClick(event: Event, col: TableColumn<T>, row: T): void {\n if (col.imageAction) {\n event.stopPropagation();\n col.imageAction(row);\n }\n }\n\n /**\n * @method onImageError\n * @description\n * Handles image load errors by replacing the broken src with a fallback URL.\n * Called from the template's (error) binding on image-type columns.\n * @param event {Event} - The native error event from the <img> element.\n * @param fallback {string | undefined} - Optional URL to use as replacement src.\n */\n onImageError(event: Event, fallback?: string): void {\n if (fallback) {\n (event.target as HTMLImageElement).src = fallback;\n }\n }\n}\n","<p-table #tableRef [selection]=\"selection()\" (selectionChange)=\"updateSelection($any($event))\"\n [selectionMode]=\"selectionMode()\" [dataKey]=\"dataKey()\" [value]=\"internalData()\" [customSort]=\"true\"\n (sortFunction)=\"customSort($event)\" [tableStyle]=\"{ 'min-width': '60rem' }\" responsiveLayout=\"scroll\">\n <!-- HEADER -->\n <ng-template pTemplate=\"header\">\n <tr>\n @for (col of columns(); track col.header) {\n <th [id]=\"col.field\" [style.width]=\"col.width\"\n [pSortableColumn]=\"col.sortable ? col.field : undefined\"\n [class.tk-table__header--active]=\"activeFilterColumn() === col.field || isColumnFiltered(col.field!)\">\n <div class=\"tk-table__header-content\">\n @if (col.type === 'selection' && selectionMode() === 'multiple') {\n <div class=\"tk-table__actions hide-validation-messages\">\n <tk-checkbox [binary]=\"true\" [model]=\"isAllSelected()\" [indeterminate]=\"isPartiallySelected()\"\n (click)=\"$event.stopPropagation()\" (keypress)=\"$event.stopPropagation()\"\n (modelChange)=\"toggleAll($event)\"></tk-checkbox>\n </div>\n } @else if (col.type !== 'selection') {\n <span class=\"tk-table__header-label\">{{ col.header }}</span>\n @if (col.sortable) {\n <p-sortIcon [field]=\"col.field\"></p-sortIcon>\n }\n @if (col.filterable && col.field) {\n <button\n class=\"tk-table__filter-trigger\"\n [class.tk-table__filter-trigger--active]=\"isColumnFiltered(col.field)\"\n (click)=\"toggleFilterOverlay(col.field, $event)\"\n type=\"button\"\n [attr.aria-label]=\"'Filter ' + col.header\">\n <tk-icon icon=\"filter\" size=\"sm\"></tk-icon>\n </button>\n }\n }\n </div>\n </th>\n }\n </tr>\n </ng-template>\n\n <!-- BODY -->\n <ng-template pTemplate=\"body\" let-row>\n <tr [pSelectableRow]=\"row\">\n @for (col of columns(); track col.header) {\n <!-- SELECTION -->\n @if (col.type === 'selection') {\n <td>\n @if (selectionMode() === 'multiple') {\n <tk-checkbox [model]=\"selection()\" [value]=\"row\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (modelChange)=\"updateSelection($any($event))\"></tk-checkbox>\n }\n </td>\n }\n\n <!-- CHECKBOX (Boolean field) -->\n @if (col.type === 'checkbox') {\n <td>\n <tk-checkbox [binary]=\"true\" [(model)]=\"row[col.field!]\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"></tk-checkbox>\n </td>\n }\n\n <!-- TEXT (default) -->\n @if (!col.type || col.type === 'text') {\n <td>{{ row[col.field!] }}</td>\n }\n\n <!-- TAG -->\n @if (col.type === 'tag') {\n <td>\n <tk-tag [value]=\"row[col.field!]\" [severity]=\"col.tagSeverity!(row)\" />\n </td>\n }\n\n <!-- ACTIONS -->\n @if (col.type === 'actions') {\n <td>\n <div class=\"tk-table__actions\">\n @for (action of col.actions!; track action.icon) {\n <tk-button [icon]=\"action.icon\" severity=\"secondary\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (clicked)=\"action?.action(row)\"></tk-button>\n }\n </div>\n </td>\n }\n\n <!-- ACTION GROUP -->\n @if (col.type === 'action-group') {\n <td>\n <div class=\"tk-table__actions\">\n <tk-action-group\n [actions]=\"getActionGroup(col.actionGroup!, row)\"\n [maxVisible]=\"col.actionGroupMaxVisible ?? 2\"\n [disabled]=\"col.actionGroupDisabled ?? false\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n ></tk-action-group>\n </div>\n </td>\n }\n\n <!-- CONNECTION STATUS -->\n @if (col.type === 'connection-status') {\n <td>\n <tk-time-ago\n [dateTime]=\"row[col.field!]\"\n [severity]=\"col.connectionStatusSeverity ? col.connectionStatusSeverity(row) : 'success'\"\n [tooltipText]=\"col.connectionStatusTooltipText ? col.connectionStatusTooltipText(row) : undefined\" />\n </td>\n }\n\n <!-- IMAGE -->\n @if (col.type === 'image') {\n <td>\n <img\n class=\"tk-table__cell-img\"\n [class.tk-table__cell-img--clickable]=\"!!col.imageAction\"\n [src]=\"row[col.field!]\"\n [alt]=\"col.imageAlt ? col.imageAlt(row) : ''\"\n [style.width]=\"col.imageWidth ?? '40px'\"\n [style.height]=\"col.imageHeight ?? '40px'\"\n [attr.tabindex]=\"col.imageAction ? 0 : null\"\n [attr.role]=\"col.imageAction ? 'button' : null\"\n (click)=\"handleImageClick($event, col, row)\"\n (keydown.enter)=\"col.imageAction && col.imageAction(row)\"\n (error)=\"onImageError($event, col.imageFallback)\"\n />\n </td>\n }\n }\n </tr>\n </ng-template>\n</p-table>\n\n<!-- Filter Overlay rendered outside the table to avoid overflow clipping -->\n@if (activeFilterColumn()) {\n<div class=\"tk-table__filter-backdrop\"\n tabindex=\"-1\"\n (click)=\"closeFilterOverlay()\"\n (keydown.escape)=\"closeFilterOverlay()\"></div>\n<div\n class=\"tk-table__filter-overlay\"\n tabindex=\"-1\"\n [style.top.px]=\"filterOverlayPosition().top\"\n [style.left.px]=\"filterOverlayPosition().left\"\n (click)=\"$event.stopPropagation()\"\n (keydown.escape)=\"closeFilterOverlay()\">\n <div class=\"tk-table__filter-list\">\n @for (option of getUniqueColumnValues(activeFilterColumn()!); track option) {\n <button\n class=\"tk-table__filter-option\"\n [class.tk-table__filter-option--selected]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n type=\"button\"\n [attr.aria-pressed]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n (click)=\"selectFilterValue(activeFilterColumn()!, option)\">\n {{ option }}\n </button>\n }\n </div>\n @if (isColumnFiltered(activeFilterColumn()!)) {\n <div class=\"tk-table__filter-clear\">\n <button\n class=\"tk-table__filter-clear-btn\"\n type=\"button\"\n (click)=\"clearFilter(activeFilterColumn()!)\">\n Clear filter\n </button>\n </div>\n }\n</div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tekus-design-system-components-table.mjs","sources":["../../../projects/design-system/components/table/src/table.component.ts","../../../projects/design-system/components/table/src/table.component.html","../../../projects/design-system/components/table/tekus-design-system-components-table.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n input,\n model,\n signal,\n viewChild,\n} from '@angular/core';\nimport { Table, TableModule } from 'primeng/table';\nimport { TagModule } from 'primeng/tag';\nimport { ButtonModule } from 'primeng/button';\nimport { TableColumn } from './table.interface';\nimport { TagComponent } from '@tekus/design-system/components/tag';\nimport { SortEvent } from 'primeng/api';\nimport { ButtonComponent } from '@tekus/design-system/components/button';\nimport { CheckboxComponent } from '@tekus/design-system/components/checkbox';\nimport {\n ActionGroupComponent,\n TkAction,\n} from '@tekus/design-system/components/action-group';\nimport { IconComponent } from '@tekus/design-system/components/icon';\nimport { TimeAgoComponent } from '@tekus/design-system/components/time-ago';\nimport { CounterComponent } from '@tekus/design-system/components/counter';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'tk-table',\n imports: [\n TableModule,\n TagModule,\n ButtonModule,\n TagComponent,\n ButtonComponent,\n CheckboxComponent,\n ActionGroupComponent,\n IconComponent,\n TimeAgoComponent,\n CounterComponent,\n ],\n templateUrl: './table.component.html',\n styleUrl: './table.component.scss',\n})\n/**\n * @component TableComponent\n * @description\n * Generic table wrapper around PrimeNG Table component.\n * Displays tabular data with configurable columns and support for custom rendering via template.\n *\n * @usage\n * ```html\n * <tk-table [data]=\"items\" [columns]=\"columnConfig\"></tk-table>\n * ```\n */\nexport class TableComponent<T = unknown> {\n /**\n * @property {InputSignal<T[]>} data\n * @description\n * Array of data objects to display in the table rows.\n * Each object corresponds to one row; properties are mapped to columns via the `columns` input.\n *\n * @default []\n *\n * @example\n * [data]=\"[\n * { id: 1, name: 'John', status: 'active' },\n * { id: 2, name: 'Jane', status: 'inactive' }\n * ]\"\n */\n data = input<T[]>([]);\n\n /**\n * @property {viewChild} tableRef\n * @description\n * Reference to the PrimeNG Table component instance.\n * Used to access table methods and properties directly.\n */\n readonly tableRef = viewChild<Table>('tableRef');\n\n /**\n * @property {InputSignal<TableColumn<T>[]>} columns\n * @description\n * Array of column definitions that describe how to render each column.\n * Each column object specifies the field name, header label, and optional rendering behavior.\n *\n * @default []\n *\n * @example\n * [columns]=\"[\n * { field: 'id', header: 'ID' },\n * { field: 'name', header: 'Name' },\n * { field: 'status', header: 'Status', renderAs: 'tag' }\n * ]\"\n */\n columns = input<TableColumn<T>[]>([]);\n\n /**\n * @property {InputSignal<'single' | 'multiple' | undefined>} selectionMode\n * @description\n * Selection mode of the table.\n */\n selectionMode = input<'single' | 'multiple' | undefined>(undefined);\n\n /**\n * @property {ModelSignal<any[]>} selection\n * @description\n * Selected row(s) in the table.\n */\n selection = model<T[]>([]);\n\n /**\n * @property {InputSignal<string | undefined>} dataKey\n * @description\n * Property name to uniquely identify a row.\n */\n dataKey = input<string | undefined>(undefined);\n\n readonly initialData = signal<T[]>([]);\n readonly internalData = signal<T[]>([]);\n readonly isSorted = signal<boolean | null>(null);\n\n /** Tracks which column's filter overlay is currently open */\n readonly activeFilterColumn = signal<string | null>(null);\n\n /** Stores the selected filter value per column field (null = no filter) */\n readonly columnFilters = model<Record<string, string | null>>({});\n\n /** Two-way bindable signal for the active sort field */\n readonly sortField = model<string | null>(null);\n\n /** Two-way bindable signal for the active sort order (1 for asc, -1 for desc) */\n readonly sortOrder = model<1 | -1 | null>(null);\n\n /** Position of the filter overlay (fixed, relative to viewport) */\n readonly filterOverlayPosition = signal<{ top: number; left: number }>({\n top: 0,\n left: 0,\n });\n\n /**\n * @computed isAllSelected\n * @description\n * Returns true if all visible rows are selected.\n */\n isAllSelected = computed(() => {\n const data = this.internalData();\n const selected = this.selection();\n if (data.length === 0 || selected.length === 0) return false;\n\n // We strictly use full objects for selection now.\n return data.every(row => selected.includes(row));\n });\n\n /**\n * @computed isPartiallySelected\n * @description\n * Returns true if some but not all rows are selected.\n */\n isPartiallySelected = computed(() => {\n const data = this.internalData();\n const selected = this.selection();\n if (data.length === 0 || selected.length === 0) return false;\n\n const allSelected = this.isAllSelected();\n return !allSelected && selected.length > 0;\n });\n\n constructor() {\n /**\n * @effect data → initialData sync\n * @description\n * Whenever the data input changes, update initialData.\n */\n effect(() => {\n this.initialData.set([...this.data()]);\n });\n\n /**\n * @effect filters/data → internalData sync\n * @description\n * Re-apply all filters whenever the initial data or the column filters change.\n * Also applies sorting if there is an active sort.\n */\n effect(() => {\n const filtered = this.getFilteredData();\n const field = this.sortField();\n const order = this.sortOrder();\n\n if (field && order && filtered.length > 0) {\n const event: SortEvent = {\n data: filtered,\n field,\n order,\n };\n this.sortTableData(event);\n }\n this.internalData.set(filtered);\n });\n\n /**\n * @effect sortField/sortOrder → table sort sync\n * @description\n * Listen to external changes to the sortField and sortOrder models, and trigger PrimeNG Table's sort/reset.\n */\n effect(() => {\n const field = this.sortField();\n const order = this.sortOrder();\n const table = this.tableRef();\n if (!table) return;\n\n // Only apply sorting if it is different from the table's current internal state\n if (table.sortField !== field || table.sortOrder !== order) {\n if (field && order) {\n table.sort({ field, order });\n } else if (!field && !order && (table.sortField || table.sortOrder)) {\n table.reset();\n }\n }\n });\n }\n\n /**\n * @method toggleAll\n * @description\n * Toggles selection of all visible rows using full objects.\n * @param checked {unknown}\n */\n toggleAll(checked: unknown) {\n if (checked) {\n this.selection.set([...this.internalData()]);\n } else {\n this.selection.set([]);\n }\n }\n\n /**\n * @method updateSelection\n * @description\n * Updates row selection state from checkbox interaction.\n * @param value {any[]}\n */\n updateSelection(value: T[]) {\n this.selection.set([...value]);\n }\n\n private readonly actionGroupCache = new Map<\n unknown,\n Map<unknown, TkAction[]>\n >();\n\n getActionGroup(\n actions: NonNullable<TableColumn<T>['actionGroup']>,\n row: T\n ): TkAction[] {\n if (!actions) return [];\n if (!this.actionGroupCache.has(actions)) {\n this.actionGroupCache.set(actions, new Map());\n }\n const rowCache = this.actionGroupCache.get(actions)!;\n if (!rowCache.has(row)) {\n rowCache.set(\n row,\n actions.map(a => ({\n icon: a.icon,\n label: a.label,\n action: () => a.action(row),\n disabled: typeof a.disabled === 'function' ? a.disabled(row) : (a.disabled ?? false),\n }))\n );\n }\n return rowCache.get(row)!;\n }\n\n customSort(event: SortEvent) {\n const extField = this.sortField();\n const extOrder = this.sortOrder();\n\n // If this is triggered by the external model updates, apply it directly without cycling\n if (event.field === extField && event.order === extOrder) {\n if (extOrder === 1) {\n this.isSorted.set(true);\n this.sortTableData(event);\n } else if (extOrder === -1) {\n this.isSorted.set(false);\n this.sortTableData(event);\n } else {\n this.isSorted.set(null);\n this.internalData.set(this.getFilteredData());\n }\n return;\n }\n\n // Otherwise, it is a user click: run the cycling logic\n if (this.isSorted() === null || this.isSorted() === undefined) {\n this.isSorted.set(true);\n this.sortField.set(event.field ?? null);\n this.sortOrder.set(1);\n this.sortTableData(event);\n } else if (this.isSorted()) {\n this.isSorted.set(false);\n this.sortField.set(event.field ?? null);\n this.sortOrder.set(-1);\n this.sortTableData(event);\n } else {\n this.isSorted.set(null);\n this.sortField.set(null);\n this.sortOrder.set(null);\n this.internalData.set(this.getFilteredData());\n this.tableRef()?.reset();\n }\n }\n\n sortTableData(event: SortEvent) {\n if (!event.data || !event.field) return;\n\n event.data.sort((data1, data2) => {\n const value1 = data1[event.field!];\n const value2 = data2[event.field!];\n let result = null;\n if (value1 == null && value2 != null) result = -1;\n else if (value1 != null && value2 == null) result = 1;\n else if (value1 == null && value2 == null) result = 0;\n else if (typeof value1 === 'string' && typeof value2 === 'string')\n result = value1.localeCompare(value2);\n else if (value1 < value2) {\n result = -1;\n } else if (value1 > value2) {\n result = 1;\n } else {\n result = 0;\n }\n\n return (event.order ?? 1) * result;\n });\n }\n\n // ─── Filter Methods ───────────────────────────────────────────────────────────\n\n /**\n * @method toggleFilterOverlay\n * @description\n * Opens or closes the filter overlay for a given column.\n * Captures the trigger button position to render the overlay in fixed position.\n */\n toggleFilterOverlay(field: string, event: MouseEvent): void {\n event.stopPropagation();\n if (this.activeFilterColumn() === field) {\n this.activeFilterColumn.set(null);\n } else {\n const trigger = event.currentTarget as HTMLElement;\n const rect = trigger.getBoundingClientRect();\n this.filterOverlayPosition.set({\n top: rect.bottom + 4,\n left: rect.left,\n });\n this.activeFilterColumn.set(field);\n }\n }\n\n /**\n * @method closeFilterOverlay\n * @description\n * Closes the filter overlay.\n */\n closeFilterOverlay(): void {\n this.activeFilterColumn.set(null);\n }\n\n /**\n * @method getUniqueColumnValues\n * @description\n * Returns the unique values for a given column, considering active filters\n * on other columns. This ensures the list only shows values that exist\n * in the currently filtered dataset.\n */\n getUniqueColumnValues(field: string): string[] {\n const filters = this.columnFilters();\n let data = [...this.initialData()];\n\n // Apply all filters EXCEPT the one for the current field\n for (const filterField of Object.keys(filters)) {\n if (filterField === field) continue;\n const selectedValue = filters[filterField];\n if (selectedValue == null) continue;\n\n data = data.filter(row => {\n const cellValue = (row as Record<string, unknown>)[filterField];\n return (\n cellValue != null && this.cellToString(cellValue) === selectedValue\n );\n });\n }\n\n const values = data\n .map(row => (row as Record<string, unknown>)[field])\n .filter(\n (v): v is string | number | boolean =>\n v != null && typeof v !== 'object'\n )\n .map(String);\n\n return [...new Set(values)].sort((a, b) => a.localeCompare(b));\n }\n\n /**\n * @method selectFilterValue\n * @description\n * Selects a value from the filter list and applies the filter.\n */\n selectFilterValue(field: string, value: string): void {\n const filters = { ...this.columnFilters() };\n filters[field] = value;\n this.columnFilters.set(filters);\n this.applyAllFilters();\n this.activeFilterColumn.set(null);\n }\n\n /**\n * @method clearFilter\n * @description\n * Clears the filter for a specific column and re-applies remaining filters.\n */\n clearFilter(field: string): void {\n const filters = { ...this.columnFilters() };\n delete filters[field];\n this.columnFilters.set(filters);\n this.applyAllFilters();\n this.activeFilterColumn.set(null);\n }\n\n /**\n * @method isColumnFiltered\n * @description\n * Returns whether a column currently has an active filter.\n */\n isColumnFiltered(field: string): boolean {\n return this.columnFilters()[field] != null;\n }\n\n /**\n * @method getActiveFilterValue\n * @description\n * Returns the currently selected filter value for a column, or null.\n */\n getActiveFilterValue(field: string): string | null {\n return this.columnFilters()[field] ?? null;\n }\n\n /**\n * @method applyAllFilters\n * @description\n * Applies all active column filters to the initial data set.\n */\n private applyAllFilters(): void {\n this.internalData.set(this.getFilteredData());\n }\n\n /**\n * @method getFilteredData\n * @description\n * Returns the initial data filtered by all active column filters.\n * Used by both applyAllFilters and customSort (reset) to ensure\n * sorting never discards active filters.\n */\n private getFilteredData(): T[] {\n const filters = this.columnFilters();\n let filtered = [...this.initialData()];\n\n for (const field of Object.keys(filters)) {\n const selectedValue = filters[field];\n if (selectedValue == null) continue;\n\n filtered = filtered.filter(row => {\n const cellValue = (row as Record<string, unknown>)[field];\n return (\n cellValue != null && this.cellToString(cellValue) === selectedValue\n );\n });\n }\n\n return filtered;\n }\n\n /**\n * @method cellToString\n * @description\n * Safely converts a cell value to its string representation.\n * Handles primitives directly and avoids [object Object] for complex types.\n */\n private cellToString(value: unknown): string {\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean')\n return `${value}`;\n return JSON.stringify(value);\n }\n\n /**\n * @method handleImageClick\n * @description\n * Handles click events on image-type cells.\n * Stops row selection propagation and invokes the column's imageAction callback when defined.\n * No-op when imageAction is not set, preserving default row-click behavior.\n * @param event {Event} - The native click event.\n * @param col {TableColumn<T>} - The column definition that may carry an imageAction.\n * @param row {T} - The data row associated with the clicked image.\n */\n handleImageClick(event: Event, col: TableColumn<T>, row: T): void {\n if (col.imageAction) {\n event.stopPropagation();\n col.imageAction(row);\n }\n }\n\n /**\n * @method isCounterDisabled\n * @description\n * Resolves a counter column's `counterDisabled`, which may be a boolean or a\n * per-row predicate — the same shape `getActionGroup` already accepts.\n * @param col {TableColumn<T>} - The counter column definition.\n * @param row {T} - The data row being rendered.\n * @returns Whether this row's counter should be disabled.\n */\n isCounterDisabled(col: TableColumn<T>, row: T): boolean {\n return typeof col.counterDisabled === 'function'\n ? col.counterDisabled(row)\n : (col.counterDisabled ?? false);\n }\n\n /**\n * @method onCounterChange\n * @description\n * Writes a counter cell's new value into the row and notifies the consumer.\n * The value arrives already clamped into the column's range by `tk-counter`.\n * Mutating the row in place matches how the `checkbox` column type behaves.\n * @param col {TableColumn<T>} - The counter column definition.\n * @param row {T} - The data row being edited.\n * @param value {number} - The new, clamped value.\n */\n onCounterChange(col: TableColumn<T>, row: T, value: number): void {\n if (col.field) {\n (row as Record<string, unknown>)[col.field] = value;\n }\n col.counterChange?.(row, value);\n }\n\n /**\n * @method onImageError\n * @description\n * Handles image load errors by replacing the broken src with a fallback URL.\n * Called from the template's (error) binding on image-type columns.\n * @param event {Event} - The native error event from the <img> element.\n * @param fallback {string | undefined} - Optional URL to use as replacement src.\n */\n onImageError(event: Event, fallback?: string): void {\n if (fallback) {\n (event.target as HTMLImageElement).src = fallback;\n }\n }\n}\n","<p-table #tableRef [selection]=\"selection()\" (selectionChange)=\"updateSelection($any($event))\"\n [selectionMode]=\"selectionMode()\" [dataKey]=\"dataKey()\" [value]=\"internalData()\" [customSort]=\"true\"\n (sortFunction)=\"customSort($event)\" [tableStyle]=\"{ 'min-width': '60rem' }\" responsiveLayout=\"scroll\">\n <!-- HEADER -->\n <ng-template pTemplate=\"header\">\n <tr>\n @for (col of columns(); track col.header) {\n <th [id]=\"col.field\" [style.width]=\"col.width\"\n [pSortableColumn]=\"col.sortable ? col.field : undefined\"\n [class.tk-table__header--active]=\"activeFilterColumn() === col.field || isColumnFiltered(col.field!)\">\n <div class=\"tk-table__header-content\">\n @if (col.type === 'selection' && selectionMode() === 'multiple') {\n <div class=\"tk-table__actions hide-validation-messages\">\n <tk-checkbox [binary]=\"true\" [model]=\"isAllSelected()\" [indeterminate]=\"isPartiallySelected()\"\n (click)=\"$event.stopPropagation()\" (keypress)=\"$event.stopPropagation()\"\n (modelChange)=\"toggleAll($event)\"></tk-checkbox>\n </div>\n } @else if (col.type !== 'selection') {\n <span class=\"tk-table__header-label\">{{ col.header }}</span>\n @if (col.sortable) {\n <p-sortIcon [field]=\"col.field\"></p-sortIcon>\n }\n @if (col.filterable && col.field) {\n <button\n class=\"tk-table__filter-trigger\"\n [class.tk-table__filter-trigger--active]=\"isColumnFiltered(col.field)\"\n (click)=\"toggleFilterOverlay(col.field, $event)\"\n type=\"button\"\n [attr.aria-label]=\"'Filter ' + col.header\">\n <tk-icon icon=\"filter\" size=\"sm\"></tk-icon>\n </button>\n }\n }\n </div>\n </th>\n }\n </tr>\n </ng-template>\n\n <!-- BODY -->\n <ng-template pTemplate=\"body\" let-row>\n <tr [pSelectableRow]=\"row\">\n @for (col of columns(); track col.header) {\n <!-- SELECTION -->\n @if (col.type === 'selection') {\n <td>\n @if (selectionMode() === 'multiple') {\n <tk-checkbox [model]=\"selection()\" [value]=\"row\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (modelChange)=\"updateSelection($any($event))\"></tk-checkbox>\n }\n </td>\n }\n\n <!-- CHECKBOX (Boolean field) -->\n @if (col.type === 'checkbox') {\n <td>\n <tk-checkbox [binary]=\"true\" [(model)]=\"row[col.field!]\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"></tk-checkbox>\n </td>\n }\n\n <!-- COUNTER (editable integer field) -->\n @if (col.type === 'counter') {\n <td>\n <tk-counter\n [value]=\"$any(row[col.field!]) ?? 0\"\n [min]=\"col.counterMin ?? 0\"\n [max]=\"col.counterMax ?? 99\"\n [step]=\"col.counterStep ?? 1\"\n [disabled]=\"isCounterDisabled(col, row)\"\n [ariaLabel]=\"col.counterAriaLabel ? col.counterAriaLabel(row) : col.header\"\n [decreaseLabel]=\"col.counterDecreaseLabel ?? 'Decrease'\"\n [increaseLabel]=\"col.counterIncreaseLabel ?? 'Increase'\"\n (valueChange)=\"onCounterChange(col, row, $event)\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"></tk-counter>\n </td>\n }\n\n <!-- TEXT (default) -->\n @if (!col.type || col.type === 'text') {\n <td>{{ row[col.field!] }}</td>\n }\n\n <!-- TAG -->\n @if (col.type === 'tag') {\n <td>\n <tk-tag [value]=\"row[col.field!]\" [severity]=\"col.tagSeverity!(row)\" />\n </td>\n }\n\n <!-- ACTIONS -->\n @if (col.type === 'actions') {\n <td>\n <div class=\"tk-table__actions\">\n @for (action of col.actions!; track action.icon) {\n <tk-button [icon]=\"action.icon\" severity=\"secondary\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (clicked)=\"action?.action(row)\"></tk-button>\n }\n </div>\n </td>\n }\n\n <!-- ACTION GROUP -->\n @if (col.type === 'action-group') {\n <td>\n <div class=\"tk-table__actions\">\n <tk-action-group\n [actions]=\"getActionGroup(col.actionGroup!, row)\"\n [maxVisible]=\"col.actionGroupMaxVisible ?? 2\"\n [disabled]=\"col.actionGroupDisabled ?? false\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n ></tk-action-group>\n </div>\n </td>\n }\n\n <!-- CONNECTION STATUS -->\n @if (col.type === 'connection-status') {\n <td>\n <tk-time-ago\n [dateTime]=\"row[col.field!]\"\n [severity]=\"col.connectionStatusSeverity ? col.connectionStatusSeverity(row) : 'success'\"\n [tooltipText]=\"col.connectionStatusTooltipText ? col.connectionStatusTooltipText(row) : undefined\" />\n </td>\n }\n\n <!-- IMAGE -->\n @if (col.type === 'image') {\n <td>\n <img\n class=\"tk-table__cell-img\"\n [class.tk-table__cell-img--clickable]=\"!!col.imageAction\"\n [src]=\"row[col.field!]\"\n [alt]=\"col.imageAlt ? col.imageAlt(row) : ''\"\n [style.width]=\"col.imageWidth ?? '40px'\"\n [style.height]=\"col.imageHeight ?? '40px'\"\n [attr.tabindex]=\"col.imageAction ? 0 : null\"\n [attr.role]=\"col.imageAction ? 'button' : null\"\n (click)=\"handleImageClick($event, col, row)\"\n (keydown.enter)=\"col.imageAction && col.imageAction(row)\"\n (error)=\"onImageError($event, col.imageFallback)\"\n />\n </td>\n }\n }\n </tr>\n </ng-template>\n</p-table>\n\n<!-- Filter Overlay rendered outside the table to avoid overflow clipping -->\n@if (activeFilterColumn()) {\n<div class=\"tk-table__filter-backdrop\"\n tabindex=\"-1\"\n (click)=\"closeFilterOverlay()\"\n (keydown.escape)=\"closeFilterOverlay()\"></div>\n<div\n class=\"tk-table__filter-overlay\"\n tabindex=\"-1\"\n [style.top.px]=\"filterOverlayPosition().top\"\n [style.left.px]=\"filterOverlayPosition().left\"\n (click)=\"$event.stopPropagation()\"\n (keydown.escape)=\"closeFilterOverlay()\">\n <div class=\"tk-table__filter-list\">\n @for (option of getUniqueColumnValues(activeFilterColumn()!); track option) {\n <button\n class=\"tk-table__filter-option\"\n [class.tk-table__filter-option--selected]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n type=\"button\"\n [attr.aria-pressed]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n (click)=\"selectFilterValue(activeFilterColumn()!, option)\">\n {{ option }}\n </button>\n }\n </div>\n @if (isColumnFiltered(activeFilterColumn()!)) {\n <div class=\"tk-table__filter-clear\">\n <button\n class=\"tk-table__filter-clear-btn\"\n type=\"button\"\n (click)=\"clearFilter(activeFilterColumn()!)\">\n Clear filter\n </button>\n </div>\n }\n</div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tekus/design-system",
3
3
  "description": "Tekus design system library",
4
- "version": "5.38.1",
4
+ "version": "5.40.0",
5
5
  "license": "UNLICENSED",
6
6
  "peerDependencies": {
7
7
  "@angular/core": "^21.0.0",
@@ -88,6 +88,14 @@
88
88
  "types": "./types/tekus-design-system-components-color-picker.d.ts",
89
89
  "default": "./fesm2022/tekus-design-system-components-color-picker.mjs"
90
90
  },
91
+ "./components/counter": {
92
+ "types": "./types/tekus-design-system-components-counter.d.ts",
93
+ "default": "./fesm2022/tekus-design-system-components-counter.mjs"
94
+ },
95
+ "./components/data-list": {
96
+ "types": "./types/tekus-design-system-components-data-list.d.ts",
97
+ "default": "./fesm2022/tekus-design-system-components-data-list.mjs"
98
+ },
91
99
  "./components/date-picker": {
92
100
  "types": "./types/tekus-design-system-components-date-picker.d.ts",
93
101
  "default": "./fesm2022/tekus-design-system-components-date-picker.mjs"
@@ -176,6 +184,10 @@
176
184
  "types": "./types/tekus-design-system-components-sidebar-layout.d.ts",
177
185
  "default": "./fesm2022/tekus-design-system-components-sidebar-layout.mjs"
178
186
  },
187
+ "./components/stat": {
188
+ "types": "./types/tekus-design-system-components-stat.d.ts",
189
+ "default": "./fesm2022/tekus-design-system-components-stat.mjs"
190
+ },
179
191
  "./components/status-bar": {
180
192
  "types": "./types/tekus-design-system-components-status-bar.d.ts",
181
193
  "default": "./fesm2022/tekus-design-system-components-status-bar.mjs"
@@ -0,0 +1,286 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { OnInit } from '@angular/core';
3
+ import { ControlValueAccessor, NgControl, FormControl } from '@angular/forms';
4
+
5
+ /**
6
+ * @component CounterComponent
7
+ * @description
8
+ * Compact control for selecting an integer value within a bounded range using
9
+ * icon-only decrement and increment buttons, with an editable value in the center.
10
+ * It has its own distinct visual identity so it reads as a standalone element rather
11
+ * than blending into the standard input family.
12
+ *
13
+ * This component supports:
14
+ * - `value`: the current integer. Never null; always rendered clamped into `[min, max]`.
15
+ * - `min` / `max`: the inclusive bounds. Buttons **disable** at a limit, never hide,
16
+ * and the value never wraps around.
17
+ * - `step`: the amount added or subtracted per action.
18
+ * - `disabled` / `readonly`: `disabled` blocks interaction and applies a distinct
19
+ * treatment to the value; `readonly` looks normal but cannot change.
20
+ * - Holding a button auto-repeats the step.
21
+ *
22
+ * It implements `ControlValueAccessor`, so it works with `[(ngModel)]` and reactive forms.
23
+ *
24
+ * @usage
25
+ * ### Basic Usage
26
+ * ```html
27
+ * <tk-counter [(ngModel)]="quantity" />
28
+ * <tk-counter [min]="1" [max]="10" [step]="2" [(value)]="servings" />
29
+ * <tk-counter [control]="quantityControl" (valueChange)="onQuantityChange($event)" />
30
+ * ```
31
+ */
32
+ declare class CounterComponent implements ControlValueAccessor, OnInit {
33
+ readonly ngControl: NgControl | null;
34
+ private readonly destroyRef;
35
+ constructor();
36
+ /**
37
+ * @property {ModelSignal<number>} value
38
+ * @description
39
+ * Current integer value. Never null; always rendered clamped into `[min, max]`.
40
+ * Supports two-way binding via `[(value)]` and emits `(valueChange)` after clamping.
41
+ *
42
+ * @default `0`
43
+ */
44
+ value: _angular_core.ModelSignal<number>;
45
+ /**
46
+ * @property {InputSignal<number>} min
47
+ * @description
48
+ * Lower bound, inclusive. The decrement button disables at this value.
49
+ *
50
+ * @default `0`
51
+ */
52
+ min: _angular_core.InputSignal<number>;
53
+ /**
54
+ * @property {InputSignal<number>} max
55
+ * @description
56
+ * Upper bound, inclusive. The increment button disables at this value.
57
+ *
58
+ * @default `99`
59
+ */
60
+ max: _angular_core.InputSignal<number>;
61
+ /**
62
+ * @property {InputSignal<number>} step
63
+ * @description
64
+ * Amount added or subtracted per action. `PageUp` / `PageDown` apply ten times this.
65
+ *
66
+ * @default `1`
67
+ */
68
+ step: _angular_core.InputSignal<number>;
69
+ /**
70
+ * @property {ModelSignal<boolean>} disabled
71
+ * @description
72
+ * Disables all interaction and applies the distinct disabled treatment to the value.
73
+ *
74
+ * @default `false`
75
+ */
76
+ disabled: _angular_core.ModelSignal<boolean>;
77
+ /**
78
+ * @property {InputSignal<boolean>} readonly
79
+ * @description
80
+ * The value is shown but cannot change. Visually normal, unlike `disabled`.
81
+ *
82
+ * @default `false`
83
+ */
84
+ readonly: _angular_core.InputSignal<boolean>;
85
+ /**
86
+ * @property {InputSignal<FormControl | undefined>} control
87
+ * @description
88
+ * External FormControl used to read/set the value. Optional: when omitted the
89
+ * counter keeps its value in the `value` model alone and creates no control.
90
+ * Not needed when using `formControlName` or `[(ngModel)]`.
91
+ *
92
+ * @default `undefined`
93
+ */
94
+ control: _angular_core.InputSignal<FormControl<any> | undefined>;
95
+ /**
96
+ * @property {InputSignal<string>} decreaseLabel
97
+ * @description
98
+ * Accessible label for the decrement button, which carries no visible text.
99
+ *
100
+ * @default `'Decrease'`
101
+ */
102
+ decreaseLabel: _angular_core.InputSignal<string>;
103
+ /**
104
+ * @property {InputSignal<string>} increaseLabel
105
+ * @description
106
+ * Accessible label for the increment button, which carries no visible text.
107
+ *
108
+ * @default `'Increase'`
109
+ */
110
+ increaseLabel: _angular_core.InputSignal<string>;
111
+ /**
112
+ * @property {InputSignal<string>} ariaLabel
113
+ * @description
114
+ * Accessible name for the value field. The counter renders no visible label, so
115
+ * either this or `ariaLabelledby` must be set unless surrounding text already
116
+ * names the control — otherwise the spinbutton is announced unnamed.
117
+ */
118
+ ariaLabel: _angular_core.InputSignal<string>;
119
+ /**
120
+ * @property {InputSignal<string>} ariaLabelledby
121
+ * @description
122
+ * Id of an existing element that names the value field. Use instead of
123
+ * `ariaLabel` when a visible label already exists elsewhere in the view.
124
+ */
125
+ ariaLabelledby: _angular_core.InputSignal<string>;
126
+ /** The value field, used to resync its text after the model clamps a typed entry. */
127
+ private readonly valueInput;
128
+ /**
129
+ * The effective upper bound. Guards against a `max` lower than `min` so the range
130
+ * is never inverted and `clamp` stays well defined.
131
+ */
132
+ readonly safeMax: _angular_core.Signal<number>;
133
+ /**
134
+ * The effective step. Guards against `0`, a negative, or a non-finite `step`, any
135
+ * of which would make stepping a no-op — and would let a held button repeat forever
136
+ * without ever reaching a limit.
137
+ */
138
+ readonly effectiveStep: _angular_core.Signal<number>;
139
+ /** The amount applied by `PageUp` / `PageDown`: ten times `step`. */
140
+ readonly pageStep: _angular_core.Signal<number>;
141
+ /**
142
+ * Character budget for the value field: the widest number the range can produce,
143
+ * never fewer than `MIN_VALUE_WIDTH_CH`.
144
+ *
145
+ * Derived from the **range**, not from the current value, so that every counter
146
+ * sharing a range renders exactly the same width. That is what keeps the buttons
147
+ * aligned down a column when one row shows `1` and the next shows `44` — sizing to
148
+ * the current value instead would make each row a different width.
149
+ */
150
+ readonly valueWidthCh: _angular_core.Signal<number>;
151
+ /**
152
+ * The rendered value: always a valid integer inside `[min, safeMax]`, even when a
153
+ * parent binds something out of range. Deliberately a `computed` rather than an
154
+ * `effect` writing back into `value`, which would fight a two-way `[(value)]`
155
+ * binding; the first interaction commits the clamped number and converges the two.
156
+ */
157
+ readonly displayValue: _angular_core.Signal<number>;
158
+ /** Whether the value sits at the lower bound, which disables the decrement button. */
159
+ readonly atMin: _angular_core.Signal<boolean>;
160
+ /** Whether the value sits at the upper bound, which disables the increment button. */
161
+ readonly atMax: _angular_core.Signal<boolean>;
162
+ /** Computed host class: the BEM block plus the disabled and readonly modifiers. */
163
+ readonly hostClass: _angular_core.Signal<string>;
164
+ get effectiveControl(): FormControl | null;
165
+ onChange: (value: number) => void;
166
+ onTouched: () => void;
167
+ private isWriting;
168
+ private holdTimeout;
169
+ private holdInterval;
170
+ ngOnInit(): void;
171
+ /**
172
+ * @method writeValue
173
+ * @description
174
+ * Writes a new value to the element, clamped into range.
175
+ * @param value The new value.
176
+ */
177
+ writeValue(value: number | null): void;
178
+ /**
179
+ * @method registerOnChange
180
+ * @description
181
+ * Registers a callback called when the value changes in the UI.
182
+ * @param fn The callback function.
183
+ */
184
+ registerOnChange(fn: (value: number) => void): void;
185
+ /**
186
+ * @method registerOnTouched
187
+ * @description
188
+ * Registers a callback called by the forms API to update the form model on blur.
189
+ * @param fn The callback function.
190
+ */
191
+ registerOnTouched(fn: () => void): void;
192
+ /**
193
+ * @method setDisabledState
194
+ * @description
195
+ * Called by the forms API when the control status changes to or from 'DISABLED'.
196
+ * @param isDisabled The disabled status to set on the element.
197
+ */
198
+ setDisabledState(isDisabled: boolean): void;
199
+ /**
200
+ * @method stepBy
201
+ * @description
202
+ * Moves the value by `step` in the given direction, clamped into range.
203
+ * @param direction `1` to increment, `-1` to decrement.
204
+ */
205
+ stepBy(direction: 1 | -1): void;
206
+ /**
207
+ * @method startHold
208
+ * @description
209
+ * Steps once immediately, then begins auto-repeating after `HOLD_DELAY_MS`.
210
+ * No-ops when the counter cannot change or is already at that limit.
211
+ * @param direction `1` to increment, `-1` to decrement.
212
+ */
213
+ startHold(direction: 1 | -1): void;
214
+ /**
215
+ * @method stopHold
216
+ * @description
217
+ * Cancels any pending or running auto-repeat. Safe to call when none is active.
218
+ */
219
+ stopHold(): void;
220
+ /**
221
+ * @method onButtonKeydown
222
+ * @description
223
+ * Handles keyboard activation of a stepper button. `Enter` and `Space` are handled
224
+ * here — and their default prevented — so the button steps exactly once per press
225
+ * and relies on native key auto-repeat while held.
226
+ * @param event The keyboard event.
227
+ * @param direction `1` to increment, `-1` to decrement.
228
+ */
229
+ onButtonKeydown(event: KeyboardEvent, direction: 1 | -1): void;
230
+ /**
231
+ * @method onValueKeydown
232
+ * @description
233
+ * Handles the spinbutton keyboard contract: arrows step by `step`, Home / End jump
234
+ * to the bounds, PageUp / PageDown apply a larger step, and Enter commits the
235
+ * currently typed text.
236
+ * @param event The keyboard event.
237
+ */
238
+ onValueKeydown(event: KeyboardEvent): void;
239
+ /**
240
+ * @method onInput
241
+ * @description
242
+ * Rejects non-numeric characters as they are typed, without clamping — clamping
243
+ * mid-keystroke would fight the user on the way to a valid number (typing `1`
244
+ * toward `12` when `min` is `5`). The value is committed on blur or Enter.
245
+ * @param event The input event.
246
+ */
247
+ onInput(event: Event): void;
248
+ /**
249
+ * @method onValueBlur
250
+ * @description
251
+ * Commits the typed text, marks the control touched, and resyncs the field so its
252
+ * text always matches the clamped value.
253
+ */
254
+ onValueBlur(): void;
255
+ /**
256
+ * Keeps digits only, plus a single leading `-` when the range includes negatives.
257
+ * Applied to whatever lands in the field, so it also covers paste and drop.
258
+ */
259
+ private sanitize;
260
+ /** Whether the counter currently accepts changes. */
261
+ private canInteract;
262
+ /** Whether stepping in `direction` would move past an already-reached bound. */
263
+ private isAtLimit;
264
+ /**
265
+ * Rounds and clamps an arbitrary value into `[min, safeMax]`. Non-finite input
266
+ * (an empty or unparseable field) falls back to `min`, so the value is never empty.
267
+ */
268
+ private clamp;
269
+ /**
270
+ * The single write path: clamps, updates the model, notifies the forms API, and
271
+ * emits `(valueChange)` — so clamping and emission happen in exactly one place.
272
+ */
273
+ private commit;
274
+ /** Parses the field's current text, commits it, and resyncs the displayed text. */
275
+ private commitTypedValue;
276
+ /**
277
+ * Rewrites the field's text from `displayValue`. Required because the `[value]`
278
+ * binding will not update the DOM when the model is unchanged — typing `150` with
279
+ * `max` `99` while the value is already `99` leaves stale text behind otherwise.
280
+ */
281
+ private syncInputText;
282
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<CounterComponent, never>;
283
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<CounterComponent, "tk-counter", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "control": { "alias": "control"; "required": false; "isSignal": true; }; "decreaseLabel": { "alias": "decreaseLabel"; "required": false; "isSignal": true; }; "increaseLabel": { "alias": "increaseLabel"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "ariaLabelledby"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "disabled": "disabledChange"; }, never, never, true, never>;
284
+ }
285
+
286
+ export { CounterComponent };