@tekus/design-system 5.30.0 → 5.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/fesm2022/tekus-design-system-components-card-list.mjs +1 -1
  2. package/fesm2022/tekus-design-system-components-card-list.mjs.map +1 -1
  3. package/fesm2022/tekus-design-system-components-card.mjs +16 -4
  4. package/fesm2022/tekus-design-system-components-card.mjs.map +1 -1
  5. package/fesm2022/tekus-design-system-components-color-picker.mjs +1028 -0
  6. package/fesm2022/tekus-design-system-components-color-picker.mjs.map +1 -0
  7. package/fesm2022/tekus-design-system-components-date-picker.mjs +269 -204
  8. package/fesm2022/tekus-design-system-components-date-picker.mjs.map +1 -1
  9. package/fesm2022/tekus-design-system-components-icon.mjs +119 -7
  10. package/fesm2022/tekus-design-system-components-icon.mjs.map +1 -1
  11. package/fesm2022/tekus-design-system-components-select.mjs +1 -1
  12. package/fesm2022/tekus-design-system-components-select.mjs.map +1 -1
  13. package/fesm2022/tekus-design-system-components-stepper.mjs +115 -0
  14. package/fesm2022/tekus-design-system-components-stepper.mjs.map +1 -0
  15. package/fesm2022/tekus-design-system-components-table.mjs +40 -6
  16. package/fesm2022/tekus-design-system-components-table.mjs.map +1 -1
  17. package/fesm2022/tekus-design-system-components-time-ago.mjs +154 -0
  18. package/fesm2022/tekus-design-system-components-time-ago.mjs.map +1 -0
  19. package/fesm2022/tekus-design-system-components-time-picker.mjs +443 -0
  20. package/fesm2022/tekus-design-system-components-time-picker.mjs.map +1 -0
  21. package/fesm2022/tekus-design-system-core-types.mjs +23 -0
  22. package/fesm2022/tekus-design-system-core-types.mjs.map +1 -1
  23. package/fesm2022/tekus-design-system-core.mjs +23 -0
  24. package/fesm2022/tekus-design-system-core.mjs.map +1 -1
  25. package/fesm2022/tekus-design-system-utils-wcag-contrast.mjs +97 -0
  26. package/fesm2022/tekus-design-system-utils-wcag-contrast.mjs.map +1 -0
  27. package/package.json +21 -1
  28. package/types/tekus-design-system-components-card.d.ts +9 -1
  29. package/types/tekus-design-system-components-color-picker.d.ts +356 -0
  30. package/types/tekus-design-system-components-date-picker.d.ts +191 -141
  31. package/types/tekus-design-system-components-icon.d.ts +10 -1
  32. package/types/tekus-design-system-components-stepper.d.ts +117 -0
  33. package/types/tekus-design-system-components-table.d.ts +28 -1
  34. package/types/tekus-design-system-components-time-ago.d.ts +53 -0
  35. package/types/tekus-design-system-components-time-picker.d.ts +203 -0
  36. package/types/tekus-design-system-utils-wcag-contrast.d.ts +55 -0
@@ -1 +1 @@
1
- {"version":3,"file":"tekus-design-system-components-select.mjs","sources":["../../../projects/design-system/components/select/src/select.manager.ts","../../../projects/design-system/components/select/src/select.component.ts","../../../projects/design-system/components/select/src/select.component.html","../../../projects/design-system/components/select/src/intersection.directive.ts","../../../projects/design-system/components/select/tekus-design-system-components-select.ts"],"sourcesContent":["import { Injectable, signal } from '@angular/core';\nimport { toObservable, toSignal } from '@angular/core/rxjs-interop';\nimport { auditTime, combineLatest, debounceTime, distinctUntilChanged, map, Observable, of, scan, switchMap, tap } from 'rxjs';\n\n/**\n * Standard request object for fetching data from an asynchronous source.\n * Aligned with PrimeNG LazyLoadEvent patterns.\n */\nexport interface TkSelectRequest {\n filter: string;\n page: number;\n pageSize: number;\n sortField?: string;\n sortOrder?: number;\n params?: Record<string, unknown>;\n}\n\n/**\n * Interface representing the data source for the Select manager.\n */\nexport interface SelectDataSource<T> {\n fetch(request: TkSelectRequest): Observable<T[]>;\n}\n\n@Injectable()\nexport class TkSelectManager<T> {\n /**\n * Reactive signal for the current search query.\n */\n searchQuery = signal<string>('');\n\n /**\n * Reactive signal for the current pagination page.\n */\n page = signal<number>(1);\n\n /**\n * Data source provider for fetching items.\n */\n public dataSource: SelectDataSource<T> | undefined;\n\n /**\n * Additional parameters to send to the data source.\n */\n fetchParams = signal<Record<string, unknown>>({});\n\n /**\n * Sorting field.\n */\n sortField = signal<string | undefined>(undefined);\n\n /**\n * Sorting order (1 for ASC, -1 for DESC).\n */\n sortOrder = signal<number | undefined>(undefined);\n\n /**\n * Reactive signal indicating if data is currently being fetched.\n */\n loading = signal<boolean>(false);\n\n /**\n * Reactive signal indicating if there are more items to fetch.\n */\n hasMore = signal<boolean>(true);\n\n /**\n * Number of items per page to detect the end of data.\n */\n pageSize = 20;\n\n /**\n * Final accumulated list of items exposed as a Signal.\n */\n items = toSignal(\n combineLatest({\n filter: toObservable(this.searchQuery).pipe(debounceTime(200)),\n page: toObservable(this.page),\n params: toObservable(this.fetchParams),\n sortField: toObservable(this.sortField),\n sortOrder: toObservable(this.sortOrder)\n }).pipe(\n auditTime(0),\n distinctUntilChanged((prev, curr) => \n JSON.stringify(prev) === JSON.stringify(curr)\n ),\n map(data => ({ ...data, pageSize: this.pageSize } as TkSelectRequest)),\n tap((request) => {\n if (request.page === 1) {\n this.hasMore.set(true);\n }\n this.loading.set(true);\n }),\n switchMap((request: TkSelectRequest): Observable<{ results: T[]; page: number }> => {\n const fetcher$ = this.dataSource \n ? this.dataSource.fetch(request) \n : of([] as T[]);\n\n return fetcher$.pipe(\n tap(results => {\n if (results.length < this.pageSize) {\n this.hasMore.set(false);\n }\n }),\n map(results => ({ results, page: request.page })),\n tap(() => this.loading.set(false))\n );\n }),\n scan((acc: T[], { results, page }: { results: T[]; page: number }) => {\n return page === 1 ? results : [...acc, ...results];\n }, [] as T[])\n ),\n { initialValue: [] as T[] }\n );\n\n /**\n * Updates the search query and resets pagination.\n * @param query - The new search string.\n */\n updateSearch(query: string): void {\n if (this.searchQuery() !== query) {\n this.searchQuery.set(query);\n this.page.set(1);\n this.hasMore.set(true);\n }\n }\n\n /**\n * Increments the page to trigger the next data chunk.\n */\n loadNextPage(): void {\n this.page.update(p => p + 1);\n }\n\n /**\n * Configures the data provider for the manager.\n * @param provider - Object implementing the SelectDataSource interface.\n */\n setDataSource(provider: SelectDataSource<T>): void {\n this.dataSource = provider;\n }\n\n /**\n * Updates additional fetch parameters and resets pagination.\n * @param params - The new parameters object.\n */\n updateParams(params: Record<string, unknown>): void {\n if (JSON.stringify(this.fetchParams()) !== JSON.stringify(params)) {\n this.fetchParams.set(params);\n this.page.set(1);\n this.hasMore.set(true);\n }\n }\n\n /**\n * Resets the manager state to its initial values.\n */\n reset(): void {\n this.searchQuery.set('');\n this.page.set(1);\n this.hasMore.set(true);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n model,\n input,\n output,\n inject,\n viewChild,\n effect,\n signal,\n OnDestroy,\n} from '@angular/core';\nimport {\n ControlValueAccessor,\n FormsModule,\n NgControl,\n FormControl,\n ReactiveFormsModule,\n} from '@angular/forms';\nimport { FloatLabelModule } from 'primeng/floatlabel';\nimport { Select } from 'primeng/select';\nimport { MessageModule } from 'primeng/message';\nimport { IconComponent } from '@tekus/design-system/components/icon';\nimport { TkSelectManager, SelectDataSource } from './select.manager';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'tk-select',\n providers: [TkSelectManager],\n imports: [\n FormsModule,\n Select,\n FloatLabelModule,\n MessageModule,\n ReactiveFormsModule,\n IconComponent,\n ],\n templateUrl: './select.component.html',\n styleUrl: './select.component.scss',\n})\nexport class SelectComponent<T = unknown> implements ControlValueAccessor, OnDestroy {\n readonly ngControl = inject(NgControl, { self: true, optional: true });\n readonly manager = inject(TkSelectManager<T>);\n\n /** PrimeNG Select instance */\n readonly selectComponent = viewChild<Select>('pSelect');\n\n /** Final reactive list of items */\n\n /**\n * HTML id attribute for the select input.\n * @default 'select'\n */\n id = input<string>('select');\n\n /**\n * External FormControl used to read/set the input value.\n */\n control = input<FormControl>();\n\n /**\n * Static options for synchronous mode.\n * If provided, they take precedence over the manager's async stream.\n */\n options = input<T[]>([]);\n\n /**\n * Data source for asynchronous infinite scroll mode.\n */\n dataSource = model<SelectDataSource<T>>();\n\n /**\n * Name of the property used to display the text of each option.\n * @default 'label'\n */\n optionLabel = input<string>('label');\n\n /**\n * Floating label displayed above the select input.\n */\n label = input<string>('');\n\n /**\n * Enables the clear button to remove the current selection.\n * @default true\n */\n showClear = input<boolean>(true);\n\n /**\n * Determines whether the select field is disabled.\n * @default false\n */\n disabled = input<boolean>(false);\n\n /**\n * Message to display when the control is invalid and touched.\n */\n errorMessage = input<string>('');\n\n /**\n * Hint text to display below the input.\n */\n hint = input<string>('');\n\n /**\n * Enables filtering/search input.\n * @default false\n */\n filter = input<boolean>(false);\n\n /**\n * Placeholder text displayed when no value is selected.\n * @default 'Select an option'\n */\n placeholder = input<string>('Select an option');\n\n /**\n * Loading state for the dropdown.\n */\n loading = input<boolean>(false);\n\n /**\n * Additional parameters for the async data source.\n * Useful for sending context like categoryId, parentId, etc.\n */\n fetchParams = input<Record<string, unknown>>({});\n\n /**\n * Field name to sort by in the async data source.\n */\n sortField = input<string | undefined>(undefined);\n\n /**\n * Order to sort by (1 for ASC, -1 for DESC).\n */\n sortOrder = input<number | undefined>(undefined);\n\n /**\n * Internal writable signal for the disabled state.\n */\n internalDisabled = signal<boolean>(false);\n\n /**\n * Two-way binding model using Angular signals.\n * This is the single source of truth for the selected value.\n */\n model = model<T | null>(null);\n\n /**\n * Text to display when there are no options.\n */\n emptyMessage = input<string>('No data available');\n\n /**\n * Text to display when no results match the filter.\n */\n emptyFilterMessage = input<string>('No results found');\n\n /**\n * Emits whenever the value changes.\n */\n modelChange = output<T | null>();\n\n /**\n * Emits the filter search term.\n */\n filterChange = output<{ filter: string | null }>();\n\n // CVA callbacks\n private onChangeFn: (value: T | null) => void = () => {};\n private onTouchedFn = () => {};\n private scrollHandler = this.handleScroll.bind(this);\n private lastListContainer: HTMLElement | null = null;\n\n constructor() {\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n\n // Synchronize parameters with the manager\n effect(() => {\n this.manager.updateParams(this.fetchParams());\n });\n\n effect(() => {\n this.manager.sortField.set(this.sortField());\n this.manager.sortOrder.set(this.sortOrder());\n });\n\n // Synchronize disabled state\n effect(() => {\n this.internalDisabled.set(this.disabled());\n });\n\n // Synchronize data source (Strictly necessary effect to bridge with manager)\n effect(() => {\n const source = this.dataSource();\n if (source) {\n this.manager.setDataSource(source);\n }\n });\n }\n\n /**\n * Displays the items from the manager if provided, otherwise the static options.\n * Includes a \"Ghost Option\" logic to ensure the selected item is always visible\n * even if it's not in the current loaded chunk of data.\n */\n get items(): T[] {\n const baseItems = this.dataSource()\n ? (this.manager.items() as T[])\n : this.options();\n const selected = this.model();\n\n if (!selected) return baseItems;\n\n // Check if selected item is already in the list to avoid duplicates\n // We compare by stringifying or by a known 'id' field if possible\n const exists = baseItems.some(item => {\n if (item === selected) return true;\n const itemId = (item as Record<string, unknown> | null)?.['id'] || (item as Record<string, unknown> | null)?.['code'];\n const selectedId = (selected as Record<string, unknown> | null)?.['id'] || (selected as Record<string, unknown> | null)?.['code'];\n return itemId !== undefined && itemId === selectedId;\n });\n\n return exists ? baseItems : [selected, ...baseItems];\n }\n\n /**\n * Receives value updates from Angular Forms API.\n * @param value - New value from the forms API.\n */\n writeValue(value: T | null): void {\n this.model.set(value);\n }\n\n /**\n * Registers a callback that is invoked when the component's value changes.\n * @param fn - The callback function.\n */\n registerOnChange(fn: (value: T | null) => void): void {\n this.onChangeFn = fn;\n }\n\n /**\n * Registers a callback invoked when the component is touched.\n * @param fn - The callback function.\n */\n registerOnTouched(fn: () => void): void {\n this.onTouchedFn = fn;\n }\n\n /**\n * Updates the disabled state of the control.\n * @param isDisabled - Whether the component should be disabled.\n */\n setDisabledState(isDisabled: boolean): void {\n this.internalDisabled.set(isDisabled);\n }\n\n /**\n * Handles UI changes from the PrimeNG Select.\n * @param event - Event containing the selected value.\n */\n handleChange(event: { value: T | null }): void {\n const value = event.value ?? null;\n this.model.set(value);\n this.onChangeFn(value);\n this.onTouchedFn();\n this.modelChange.emit(value);\n\n if (this.effectiveControl) {\n this.effectiveControl.setValue(value, { emitEvent: false });\n this.effectiveControl.markAsDirty();\n this.effectiveControl.markAsTouched();\n }\n }\n\n /**\n * Handles filter input changes and notifies the manager.\n * @param event - Filter event containing the search term.\n */\n handleFilter(event: { filter: string | null }): void {\n const query = event.filter || '';\n this.manager.updateSearch(query);\n this.filterChange.emit(event);\n }\n\n /**\n * Returns the underlying FormControl for validation state checking.\n */\n get effectiveControl(): FormControl | null {\n return (this.ngControl?.control as FormControl) || null;\n }\n\n /**\n * Adds a scroll listener to the PrimeNG select list container when the panel opens.\n */\n onPanelShow(): void {\n const listContainer = document.querySelector('.p-select-list-container') as HTMLElement;\n if (listContainer) {\n this.lastListContainer = listContainer;\n listContainer.addEventListener('scroll', this.scrollHandler);\n }\n }\n\n /**\n * Cleans up state, removes listeners and resets the manager when the panel closes.\n */\n onPanelHide(): void {\n this.removeScrollListener();\n this.manager.reset();\n }\n\n /**\n * Cleans up listeners on component destruction.\n */\n ngOnDestroy(): void {\n this.removeScrollListener();\n }\n\n /**\n * Safely removes the scroll event listener.\n */\n private removeScrollListener(): void {\n if (this.lastListContainer) {\n this.lastListContainer.removeEventListener('scroll', this.scrollHandler);\n this.lastListContainer = null;\n }\n }\n\n /**\n * Detects if the user has reached the bottom of the list.\n */\n private handleScroll(event: Event): void {\n const target = event.target as HTMLElement;\n if (!target) return;\n\n // Trigger near the bottom (1px threshold)\n const atBottom =\n target.scrollHeight - target.scrollTop <= target.clientHeight + 1;\n\n if (\n atBottom &&\n this.manager.dataSource &&\n !this.manager.loading() &&\n this.manager.hasMore()\n ) {\n this.manager.loadNextPage();\n }\n }\n}\n","<p-floatlabel class=\"w-full\">\n <p-select\n #pSelect\n [id]=\"id()\"\n class=\"w-full\"\n [options]=\"items\"\n [optionLabel]=\"optionLabel()\"\n [showClear]=\"showClear()\"\n [disabled]=\"disabled()\"\n [ngModel]=\"model()\"\n [filter]=\"filter()\"\n [loading]=\"manager.loading()\"\n [emptyMessage]=\"emptyMessage()\"\n [emptyFilterMessage]=\"emptyFilterMessage()\"\n [class.ng-invalid]=\"\n effectiveControl?.invalid &&\n (effectiveControl?.dirty || effectiveControl?.touched)\n \"\n [class.ng-dirty]=\"effectiveControl?.dirty\"\n [class.ng-touched]=\"effectiveControl?.touched\"\n (onChange)=\"handleChange($event)\"\n (onFilter)=\"handleFilter($event)\"\n (onShow)=\"onPanelShow()\"\n (onHide)=\"onPanelHide()\"\n [resetFilterOnHide]=\"true\">\n \n <ng-template pTemplate=\"selectedItem\" let-selectedOption>\n @if (model()) {\n <div>{{ $any(model())[optionLabel()] }}</div>\n } @else if (placeholder()) {\n <span class=\"text-secondary\">{{ placeholder() }}</span>\n }\n </ng-template>\n\n <ng-template pTemplate=\"empty\">\n <div class=\"tk-select-empty-container\">\n <tk-icon icon=\"info\" size=\"2xl\"></tk-icon>\n <span>{{ emptyMessage() }}</span>\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"emptyfilter\">\n <div class=\"tk-select-empty-container\">\n <tk-icon icon=\"magnifying-glass\" size=\"2xl\"></tk-icon>\n <span>{{ emptyFilterMessage() }}</span>\n </div>\n </ng-template>\n </p-select>\n <label [for]=\"id()\">{{ label() }}</label>\n</p-floatlabel>\n\n<div class=\"tk-select-bottom\">\n <div class=\"tk-select-messages\">\n @if (\n effectiveControl?.invalid &&\n (effectiveControl?.dirty || effectiveControl?.touched) &&\n errorMessage()\n ) {\n <p-message severity=\"error\" size=\"small\" variant=\"simple\">{{\n errorMessage()\n }}</p-message>\n } @else if (hint()) {\n <p-message severity=\"secondary\" size=\"small\" variant=\"simple\">{{\n hint()\n }}</p-message>\n }\n </div>\n</div>\n","import { Directive, ElementRef, output, OnDestroy, OnInit, inject } from '@angular/core';\n\n@Directive({\n selector: '[tkIntersection]',\n standalone: true\n})\nexport class IntersectionDirective implements OnInit, OnDestroy {\n /**\n * Emits when the element enters the viewport.\n */\n intersect = output<void>();\n\n private readonly element = inject(ElementRef);\n private observer?: IntersectionObserver;\n\n constructor() {}\n\n /**\n * Initializes the Intersection Observer on component mount.\n */\n ngOnInit(): void {\n this.observer = new IntersectionObserver(([entry]) => {\n if (entry.isIntersecting) {\n this.intersect.emit();\n }\n }, { threshold: 0.1 });\n\n this.observer.observe(this.element.nativeElement);\n }\n\n /**\n * Cleans up the observer to prevent memory leaks.\n */\n ngOnDestroy(): void {\n this.observer?.disconnect();\n }\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-select.mjs","sources":["../../../projects/design-system/components/select/src/select.manager.ts","../../../projects/design-system/components/select/src/select.component.ts","../../../projects/design-system/components/select/src/select.component.html","../../../projects/design-system/components/select/src/intersection.directive.ts","../../../projects/design-system/components/select/tekus-design-system-components-select.ts"],"sourcesContent":["import { Injectable, signal } from '@angular/core';\nimport { toObservable, toSignal } from '@angular/core/rxjs-interop';\nimport { auditTime, combineLatest, debounceTime, distinctUntilChanged, map, Observable, of, scan, switchMap, tap } from 'rxjs';\n\n/**\n * Standard request object for fetching data from an asynchronous source.\n * Aligned with PrimeNG LazyLoadEvent patterns.\n */\nexport interface TkSelectRequest {\n filter: string;\n page: number;\n pageSize: number;\n sortField?: string;\n sortOrder?: number;\n params?: Record<string, unknown>;\n}\n\n/**\n * Interface representing the data source for the Select manager.\n */\nexport interface SelectDataSource<T> {\n fetch(request: TkSelectRequest): Observable<T[]>;\n}\n\n@Injectable()\nexport class TkSelectManager<T> {\n /**\n * Reactive signal for the current search query.\n */\n searchQuery = signal<string>('');\n\n /**\n * Reactive signal for the current pagination page.\n */\n page = signal<number>(1);\n\n /**\n * Data source provider for fetching items.\n */\n public dataSource: SelectDataSource<T> | undefined;\n\n /**\n * Additional parameters to send to the data source.\n */\n fetchParams = signal<Record<string, unknown>>({});\n\n /**\n * Sorting field.\n */\n sortField = signal<string | undefined>(undefined);\n\n /**\n * Sorting order (1 for ASC, -1 for DESC).\n */\n sortOrder = signal<number | undefined>(undefined);\n\n /**\n * Reactive signal indicating if data is currently being fetched.\n */\n loading = signal<boolean>(false);\n\n /**\n * Reactive signal indicating if there are more items to fetch.\n */\n hasMore = signal<boolean>(true);\n\n /**\n * Number of items per page to detect the end of data.\n */\n pageSize = 20;\n\n /**\n * Final accumulated list of items exposed as a Signal.\n */\n items = toSignal(\n combineLatest({\n filter: toObservable(this.searchQuery).pipe(debounceTime(200)),\n page: toObservable(this.page),\n params: toObservable(this.fetchParams),\n sortField: toObservable(this.sortField),\n sortOrder: toObservable(this.sortOrder)\n }).pipe(\n auditTime(0),\n distinctUntilChanged((prev, curr) => \n JSON.stringify(prev) === JSON.stringify(curr)\n ),\n map(data => ({ ...data, pageSize: this.pageSize } as TkSelectRequest)),\n tap((request) => {\n if (request.page === 1) {\n this.hasMore.set(true);\n }\n this.loading.set(true);\n }),\n switchMap((request: TkSelectRequest): Observable<{ results: T[]; page: number }> => {\n const fetcher$ = this.dataSource \n ? this.dataSource.fetch(request) \n : of([] as T[]);\n\n return fetcher$.pipe(\n tap(results => {\n if (results.length < this.pageSize) {\n this.hasMore.set(false);\n }\n }),\n map(results => ({ results, page: request.page })),\n tap(() => this.loading.set(false))\n );\n }),\n scan((acc: T[], { results, page }: { results: T[]; page: number }) => {\n return page === 1 ? results : [...acc, ...results];\n }, [] as T[])\n ),\n { initialValue: [] as T[] }\n );\n\n /**\n * Updates the search query and resets pagination.\n * @param query - The new search string.\n */\n updateSearch(query: string): void {\n if (this.searchQuery() !== query) {\n this.searchQuery.set(query);\n this.page.set(1);\n this.hasMore.set(true);\n }\n }\n\n /**\n * Increments the page to trigger the next data chunk.\n */\n loadNextPage(): void {\n this.page.update(p => p + 1);\n }\n\n /**\n * Configures the data provider for the manager.\n * @param provider - Object implementing the SelectDataSource interface.\n */\n setDataSource(provider: SelectDataSource<T>): void {\n this.dataSource = provider;\n }\n\n /**\n * Updates additional fetch parameters and resets pagination.\n * @param params - The new parameters object.\n */\n updateParams(params: Record<string, unknown>): void {\n if (JSON.stringify(this.fetchParams()) !== JSON.stringify(params)) {\n this.fetchParams.set(params);\n this.page.set(1);\n this.hasMore.set(true);\n }\n }\n\n /**\n * Resets the manager state to its initial values.\n */\n reset(): void {\n this.searchQuery.set('');\n this.page.set(1);\n this.hasMore.set(true);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n model,\n input,\n output,\n inject,\n viewChild,\n effect,\n signal,\n OnDestroy,\n} from '@angular/core';\nimport {\n ControlValueAccessor,\n FormsModule,\n NgControl,\n FormControl,\n ReactiveFormsModule,\n} from '@angular/forms';\nimport { FloatLabelModule } from 'primeng/floatlabel';\nimport { Select } from 'primeng/select';\nimport { MessageModule } from 'primeng/message';\nimport { IconComponent } from '@tekus/design-system/components/icon';\nimport { TkSelectManager, SelectDataSource } from './select.manager';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'tk-select',\n providers: [TkSelectManager],\n imports: [\n FormsModule,\n Select,\n FloatLabelModule,\n MessageModule,\n ReactiveFormsModule,\n IconComponent,\n ],\n templateUrl: './select.component.html',\n styleUrl: './select.component.scss',\n})\nexport class SelectComponent<T = unknown> implements ControlValueAccessor, OnDestroy {\n readonly ngControl = inject(NgControl, { self: true, optional: true });\n readonly manager = inject(TkSelectManager<T>);\n\n /** PrimeNG Select instance */\n readonly selectComponent = viewChild<Select>('pSelect');\n\n /** Final reactive list of items */\n\n /**\n * HTML id attribute for the select input.\n * @default 'select'\n */\n id = input<string>('select');\n\n /**\n * External FormControl used to read/set the input value.\n */\n control = input<FormControl>();\n\n /**\n * Static options for synchronous mode.\n * If provided, they take precedence over the manager's async stream.\n */\n options = input<T[]>([]);\n\n /**\n * Data source for asynchronous infinite scroll mode.\n */\n dataSource = model<SelectDataSource<T>>();\n\n /**\n * Name of the property used to display the text of each option.\n * @default 'label'\n */\n optionLabel = input<string>('label');\n\n /**\n * Floating label displayed above the select input.\n */\n label = input<string>('');\n\n /**\n * Enables the clear button to remove the current selection.\n * @default true\n */\n showClear = input<boolean>(true);\n\n /**\n * Determines whether the select field is disabled.\n * @default false\n */\n disabled = input<boolean>(false);\n\n /**\n * Message to display when the control is invalid and touched.\n */\n errorMessage = input<string>('');\n\n /**\n * Hint text to display below the input.\n */\n hint = input<string>('');\n\n /**\n * Enables filtering/search input.\n * @default false\n */\n filter = input<boolean>(false);\n\n /**\n * Placeholder text displayed when no value is selected.\n * @default 'Select an option'\n */\n placeholder = input<string>('Select an option');\n\n /**\n * Loading state for the dropdown.\n */\n loading = input<boolean>(false);\n\n /**\n * Additional parameters for the async data source.\n * Useful for sending context like categoryId, parentId, etc.\n */\n fetchParams = input<Record<string, unknown>>({});\n\n /**\n * Field name to sort by in the async data source.\n */\n sortField = input<string | undefined>(undefined);\n\n /**\n * Order to sort by (1 for ASC, -1 for DESC).\n */\n sortOrder = input<number | undefined>(undefined);\n\n /**\n * Internal writable signal for the disabled state.\n */\n internalDisabled = signal<boolean>(false);\n\n /**\n * Two-way binding model using Angular signals.\n * This is the single source of truth for the selected value.\n */\n model = model<T | null>(null);\n\n /**\n * Text to display when there are no options.\n */\n emptyMessage = input<string>('No data available');\n\n /**\n * Text to display when no results match the filter.\n */\n emptyFilterMessage = input<string>('No results found');\n\n /**\n * Emits whenever the value changes.\n */\n modelChange = output<T | null>();\n\n /**\n * Emits the filter search term.\n */\n filterChange = output<{ filter: string | null }>();\n\n // CVA callbacks\n private onChangeFn: (value: T | null) => void = () => {};\n private onTouchedFn = () => {};\n private scrollHandler = this.handleScroll.bind(this);\n private lastListContainer: HTMLElement | null = null;\n\n constructor() {\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n\n // Synchronize parameters with the manager\n effect(() => {\n this.manager.updateParams(this.fetchParams());\n });\n\n effect(() => {\n this.manager.sortField.set(this.sortField());\n this.manager.sortOrder.set(this.sortOrder());\n });\n\n // Synchronize disabled state\n effect(() => {\n this.internalDisabled.set(this.disabled());\n });\n\n // Synchronize data source (Strictly necessary effect to bridge with manager)\n effect(() => {\n const source = this.dataSource();\n if (source) {\n this.manager.setDataSource(source);\n }\n });\n }\n\n /**\n * Displays the items from the manager if provided, otherwise the static options.\n * Includes a \"Ghost Option\" logic to ensure the selected item is always visible\n * even if it's not in the current loaded chunk of data.\n */\n get items(): T[] {\n const baseItems = this.dataSource()\n ? (this.manager.items() as T[])\n : this.options();\n const selected = this.model();\n\n if (!selected) return baseItems;\n\n // Check if selected item is already in the list to avoid duplicates\n // We compare by stringifying or by a known 'id' field if possible\n const exists = baseItems.some(item => {\n if (item === selected) return true;\n const itemId = (item as Record<string, unknown> | null)?.['id'] || (item as Record<string, unknown> | null)?.['code'];\n const selectedId = (selected as Record<string, unknown> | null)?.['id'] || (selected as Record<string, unknown> | null)?.['code'];\n return itemId !== undefined && itemId === selectedId;\n });\n\n return exists ? baseItems : [selected, ...baseItems];\n }\n\n /**\n * Receives value updates from Angular Forms API.\n * @param value - New value from the forms API.\n */\n writeValue(value: T | null): void {\n this.model.set(value);\n }\n\n /**\n * Registers a callback that is invoked when the component's value changes.\n * @param fn - The callback function.\n */\n registerOnChange(fn: (value: T | null) => void): void {\n this.onChangeFn = fn;\n }\n\n /**\n * Registers a callback invoked when the component is touched.\n * @param fn - The callback function.\n */\n registerOnTouched(fn: () => void): void {\n this.onTouchedFn = fn;\n }\n\n /**\n * Updates the disabled state of the control.\n * @param isDisabled - Whether the component should be disabled.\n */\n setDisabledState(isDisabled: boolean): void {\n this.internalDisabled.set(isDisabled);\n }\n\n /**\n * Handles UI changes from the PrimeNG Select.\n * @param event - Event containing the selected value.\n */\n handleChange(event: { value: T | null }): void {\n const value = event.value ?? null;\n this.model.set(value);\n this.onChangeFn(value);\n this.onTouchedFn();\n this.modelChange.emit(value);\n\n if (this.effectiveControl) {\n this.effectiveControl.setValue(value, { emitEvent: false });\n this.effectiveControl.markAsDirty();\n this.effectiveControl.markAsTouched();\n }\n }\n\n /**\n * Handles filter input changes and notifies the manager.\n * @param event - Filter event containing the search term.\n */\n handleFilter(event: { filter: string | null }): void {\n const query = event.filter || '';\n this.manager.updateSearch(query);\n this.filterChange.emit(event);\n }\n\n /**\n * Returns the underlying FormControl for validation state checking.\n */\n get effectiveControl(): FormControl | null {\n return (this.ngControl?.control as FormControl) || this.control() || null;\n }\n\n /**\n * Adds a scroll listener to the PrimeNG select list container when the panel opens.\n */\n onPanelShow(): void {\n const listContainer = document.querySelector('.p-select-list-container') as HTMLElement;\n if (listContainer) {\n this.lastListContainer = listContainer;\n listContainer.addEventListener('scroll', this.scrollHandler);\n }\n }\n\n /**\n * Cleans up state, removes listeners and resets the manager when the panel closes.\n */\n onPanelHide(): void {\n this.removeScrollListener();\n this.manager.reset();\n }\n\n /**\n * Cleans up listeners on component destruction.\n */\n ngOnDestroy(): void {\n this.removeScrollListener();\n }\n\n /**\n * Safely removes the scroll event listener.\n */\n private removeScrollListener(): void {\n if (this.lastListContainer) {\n this.lastListContainer.removeEventListener('scroll', this.scrollHandler);\n this.lastListContainer = null;\n }\n }\n\n /**\n * Detects if the user has reached the bottom of the list.\n */\n private handleScroll(event: Event): void {\n const target = event.target as HTMLElement;\n if (!target) return;\n\n // Trigger near the bottom (1px threshold)\n const atBottom =\n target.scrollHeight - target.scrollTop <= target.clientHeight + 1;\n\n if (\n atBottom &&\n this.manager.dataSource &&\n !this.manager.loading() &&\n this.manager.hasMore()\n ) {\n this.manager.loadNextPage();\n }\n }\n}\n","<p-floatlabel class=\"w-full\">\n <p-select\n #pSelect\n [id]=\"id()\"\n class=\"w-full\"\n [options]=\"items\"\n [optionLabel]=\"optionLabel()\"\n [showClear]=\"showClear()\"\n [disabled]=\"disabled()\"\n [ngModel]=\"model()\"\n [filter]=\"filter()\"\n [loading]=\"manager.loading()\"\n [emptyMessage]=\"emptyMessage()\"\n [emptyFilterMessage]=\"emptyFilterMessage()\"\n [class.ng-invalid]=\"\n effectiveControl?.invalid &&\n (effectiveControl?.dirty || effectiveControl?.touched)\n \"\n [class.ng-dirty]=\"effectiveControl?.dirty\"\n [class.ng-touched]=\"effectiveControl?.touched\"\n (onChange)=\"handleChange($event)\"\n (onFilter)=\"handleFilter($event)\"\n (onShow)=\"onPanelShow()\"\n (onHide)=\"onPanelHide()\"\n [resetFilterOnHide]=\"true\">\n \n <ng-template pTemplate=\"selectedItem\" let-selectedOption>\n @if (model()) {\n <div>{{ $any(model())[optionLabel()] }}</div>\n } @else if (placeholder()) {\n <span class=\"text-secondary\">{{ placeholder() }}</span>\n }\n </ng-template>\n\n <ng-template pTemplate=\"empty\">\n <div class=\"tk-select-empty-container\">\n <tk-icon icon=\"info\" size=\"2xl\"></tk-icon>\n <span>{{ emptyMessage() }}</span>\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"emptyfilter\">\n <div class=\"tk-select-empty-container\">\n <tk-icon icon=\"magnifying-glass\" size=\"2xl\"></tk-icon>\n <span>{{ emptyFilterMessage() }}</span>\n </div>\n </ng-template>\n </p-select>\n <label [for]=\"id()\">{{ label() }}</label>\n</p-floatlabel>\n\n<div class=\"tk-select-bottom\">\n <div class=\"tk-select-messages\">\n @if (\n effectiveControl?.invalid &&\n (effectiveControl?.dirty || effectiveControl?.touched) &&\n errorMessage()\n ) {\n <p-message severity=\"error\" size=\"small\" variant=\"simple\">{{\n errorMessage()\n }}</p-message>\n } @else if (hint()) {\n <p-message severity=\"secondary\" size=\"small\" variant=\"simple\">{{\n hint()\n }}</p-message>\n }\n </div>\n</div>\n","import { Directive, ElementRef, output, OnDestroy, OnInit, inject } from '@angular/core';\n\n@Directive({\n selector: '[tkIntersection]',\n standalone: true\n})\nexport class IntersectionDirective implements OnInit, OnDestroy {\n /**\n * Emits when the element enters the viewport.\n */\n intersect = output<void>();\n\n private readonly element = inject(ElementRef);\n private observer?: IntersectionObserver;\n\n constructor() {}\n\n /**\n * Initializes the Intersection Observer on component mount.\n */\n ngOnInit(): void {\n this.observer = new IntersectionObserver(([entry]) => {\n if (entry.isIntersecting) {\n this.intersect.emit();\n }\n }, { threshold: 0.1 });\n\n this.observer.observe(this.element.nativeElement);\n }\n\n /**\n * Cleans up the observer to prevent memory leaks.\n */\n ngOnDestroy(): void {\n this.observer?.disconnect();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,115 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, model, output, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { NgTemplateOutlet } from '@angular/common';
4
+ import * as i1 from 'primeng/stepper';
5
+ import { StepperModule } from 'primeng/stepper';
6
+ import * as i2 from 'primeng/api';
7
+ import { SharedModule } from 'primeng/api';
8
+ import { ButtonComponent } from '@tekus/design-system/components/button';
9
+
10
+ /**
11
+ * @component StepperComponent
12
+ * @description
13
+ * Reusable stepper component that acts as a wrapper around PrimeNG's Stepper.
14
+ * Supports horizontal and vertical orientations, linear step completion rules,
15
+ * and automated footer action buttons.
16
+ *
17
+ * @usage
18
+ * ```html
19
+ * <tk-stepper
20
+ * [steps]="steps"
21
+ * [(activeStep)]="currentStep"
22
+ * [linear]="true"
23
+ * orientation="horizontal">
24
+ * </tk-stepper>
25
+ * ```
26
+ */
27
+ class StepperComponent {
28
+ constructor() {
29
+ /**
30
+ * @property {InputSignal<StepData[]>} steps
31
+ * @description Array of step configurations to display.
32
+ */
33
+ this.steps = input([], ...(ngDevMode ? [{ debugName: "steps" }] : /* istanbul ignore next */ []));
34
+ /**
35
+ * @property {ModelSignal<number>} activeStep
36
+ * @description The 0-based index of the currently active step. Supports two-way binding.
37
+ * @default 0
38
+ */
39
+ this.activeStep = model(0, ...(ngDevMode ? [{ debugName: "activeStep" }] : /* istanbul ignore next */ []));
40
+ /**
41
+ * @property {InputSignal<boolean>} linear
42
+ * @description If true, blocks navigation to steps ahead of the active step.
43
+ * @default true
44
+ */
45
+ this.linear = input(true, ...(ngDevMode ? [{ debugName: "linear" }] : /* istanbul ignore next */ []));
46
+ /**
47
+ * @property {InputSignal<'horizontal' | 'vertical'>} orientation
48
+ * @description Defines the layout orientation of the stepper.
49
+ * @default 'horizontal'
50
+ */
51
+ this.orientation = input('horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
52
+ /**
53
+ * @property {InputSignal<boolean>} showFooter
54
+ * @description Whether to render the default footer action buttons for each step.
55
+ * @default true
56
+ */
57
+ this.showFooter = input(true, ...(ngDevMode ? [{ debugName: "showFooter" }] : /* istanbul ignore next */ []));
58
+ /**
59
+ * @event stepChange
60
+ * @description Emitted when the active step changes.
61
+ */
62
+ this.stepChange = output();
63
+ }
64
+ /**
65
+ * Checks if a step header should be disabled.
66
+ * Steps ahead of the active index are disabled in linear mode.
67
+ */
68
+ isStepDisabled(index) {
69
+ const step = this.steps()[index];
70
+ if (!step)
71
+ return true;
72
+ if (step.disabled)
73
+ return true;
74
+ if (this.linear() && index > this.activeStep())
75
+ return true;
76
+ return false;
77
+ }
78
+ /**
79
+ * Helper to evaluate button disabled states dynamically.
80
+ */
81
+ evalDisabled(disabled) {
82
+ if (disabled === undefined)
83
+ return false;
84
+ if (typeof disabled === 'function')
85
+ return disabled();
86
+ return disabled;
87
+ }
88
+ /**
89
+ * Handles step transition events.
90
+ */
91
+ onStepChange(index) {
92
+ if (this.activeStep() === index)
93
+ return;
94
+ this.activeStep.set(index);
95
+ if (this.steps()[index]) {
96
+ this.stepChange.emit({
97
+ index,
98
+ step: this.steps()[index],
99
+ });
100
+ }
101
+ }
102
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: StepperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
103
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: StepperComponent, isStandalone: true, selector: "tk-stepper", inputs: { steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: false, transformFunction: null }, activeStep: { classPropertyName: "activeStep", publicName: "activeStep", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeStep: "activeStepChange", stepChange: "stepChange" }, ngImport: i0, template: "<div class=\"tk-stepper-container\" [class.tk-stepper-vertical]=\"orientation() === 'vertical'\" [class.tk-stepper-horizontal]=\"orientation() === 'horizontal'\">\n @if (steps().length > 0) {\n @if (orientation() === 'horizontal') {\n <p-stepper [value]=\"activeStep()\" [linear]=\"linear()\" (valueChange)=\"onStepChange($event !== undefined ? +$event : activeStep())\">\n <p-step-list class=\"tk-step-list-horizontal\">\n @for (step of steps(); track $index) {\n <p-step [value]=\"$index\" [disabled]=\"isStepDisabled($index)\">\n <div class=\"tk-step-header-content\">\n <span class=\"tk-step-number\">{{ $index + 1 }}</span>\n <span class=\"tk-step-title\">{{ step.label }}</span>\n </div>\n </p-step>\n }\n </p-step-list>\n\n <p-step-panels class=\"tk-step-panels-horizontal\">\n @for (step of steps(); track $index) {\n <p-step-panel [value]=\"$index\">\n <ng-template pTemplate=\"content\">\n <div class=\"tk-step-panel-content\">\n <ng-container [ngTemplateOutlet]=\"step.content\"></ng-container>\n </div>\n \n @if (showFooter() && (step.actionsPrimary?.length || step.actionsSecondary?.length)) {\n <div class=\"tk-step-actions-footer\">\n <div class=\"tk-step-actions-secondary\">\n @for (action of step.actionsSecondary; track $index) {\n <tk-button\n [label]=\"action.label\"\n [icon]=\"action.icon\"\n [severity]=\"action.severity || 'secondary'\"\n [variant]=\"action.variant\"\n [disabled]=\"evalDisabled(action.disabled)\"\n (clicked)=\"action.action()\">\n </tk-button>\n }\n </div>\n <div class=\"tk-step-actions-primary\">\n @for (action of step.actionsPrimary; track $index) {\n <tk-button\n [label]=\"action.label\"\n [icon]=\"action.icon\"\n [severity]=\"action.severity || 'primary'\"\n [variant]=\"action.variant\"\n [disabled]=\"evalDisabled(action.disabled)\"\n (clicked)=\"action.action()\">\n </tk-button>\n }\n </div>\n </div>\n }\n </ng-template>\n </p-step-panel>\n }\n </p-step-panels>\n </p-stepper>\n } @else {\n <p-stepper [value]=\"activeStep()\" [linear]=\"linear()\" (valueChange)=\"onStepChange($event !== undefined ? +$event : activeStep())\">\n @for (step of steps(); track $index) {\n <p-step-item [value]=\"$index\">\n <p-step [value]=\"$index\" [disabled]=\"isStepDisabled($index)\">\n <div class=\"tk-step-header-content\">\n <span class=\"tk-step-number\">{{ $index + 1 }}</span>\n <span class=\"tk-step-title\">{{ step.label }}</span>\n </div>\n </p-step>\n <p-step-panel [value]=\"$index\">\n <ng-template pTemplate=\"content\">\n <div class=\"tk-step-panel-content\">\n <ng-container [ngTemplateOutlet]=\"step.content\"></ng-container>\n </div>\n\n @if (showFooter() && (step.actionsPrimary?.length || step.actionsSecondary?.length)) {\n <div class=\"tk-step-actions-footer vertical\">\n @for (action of step.actionsSecondary; track $index) {\n <tk-button\n [label]=\"action.label\"\n [icon]=\"action.icon\"\n [severity]=\"action.severity || 'secondary'\"\n [variant]=\"action.variant\"\n [disabled]=\"evalDisabled(action.disabled)\"\n (clicked)=\"action.action()\">\n </tk-button>\n }\n @for (action of step.actionsPrimary; track $index) {\n <tk-button\n [label]=\"action.label\"\n [icon]=\"action.icon\"\n [severity]=\"action.severity || 'primary'\"\n [variant]=\"action.variant\"\n [disabled]=\"evalDisabled(action.disabled)\"\n (clicked)=\"action.action()\">\n </tk-button>\n }\n </div>\n }\n </ng-template>\n </p-step-panel>\n </p-step-item>\n }\n </p-stepper>\n }\n }\n</div>\n", styles: [":host{display:block;width:100%}.tk-stepper-container{display:block;width:100%;box-sizing:border-box}.tk-stepper-container.tk-stepper-vertical{padding-right:1rem;padding-bottom:.5rem}:host ::ng-deep .p-stepper{display:flex;flex-direction:column;width:100%;background:transparent}:host ::ng-deep .p-steplist{display:flex;align-items:center;width:100%;background:transparent;padding:0;margin-bottom:var(--tk-spacing-base-150, 1.5rem)}:host ::ng-deep .p-step{padding:0;background:transparent;border:none;outline:none!important;box-shadow:none!important;cursor:pointer;display:flex}:host ::ng-deep .p-step:focus,:host ::ng-deep .p-step:focus-visible,:host ::ng-deep .p-step:focus-within{outline:none!important;box-shadow:none!important}:host ::ng-deep .p-step{align-items:center;gap:var(--tk-spacing-base-50, .5rem)}:host ::ng-deep .p-step .p-step-header{outline:none!important;box-shadow:none!important;border:none!important;background:transparent!important}:host ::ng-deep .p-step .p-step-header:focus,:host ::ng-deep .p-step .p-step-header:focus-visible,:host ::ng-deep .p-step .p-step-header:focus-within{outline:none!important;box-shadow:none!important}:host ::ng-deep .p-step .p-step-number{display:none!important}:host ::ng-deep .p-step .tk-step-header-content{display:flex;align-items:center;gap:var(--tk-spacing-base-50, .5rem)}:host ::ng-deep .p-step .tk-step-number{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;border:1px solid var(--tk-color-border-default, #cecdcd);border-radius:var(--tk-borderRadius-full, 50%);color:var(--tk-color-text-muted, #8a8a8b);font-size:var(--tk-font-size-paragraph-s, .875rem);font-weight:var(--tk-font-weight-600, 600);background-color:var(--tk-color-background-default, #ffffff);transition:all .2s ease-in-out}:host ::ng-deep .p-step .tk-step-title{color:var(--tk-color-text-muted, #8a8a8b);font-size:var(--tk-font-size-paragraph-m, 1rem);font-weight:var(--tk-font-weight-400, 400);transition:all .2s ease-in-out}:host ::ng-deep .p-step.p-step-active .tk-step-number,:host ::ng-deep .p-step[data-p-active=true] .tk-step-number{border-color:var(--tk-color-border-default, #cecdcd);color:var(--tk-color-primary-default, #16006f);background-color:var(--tk-color-background-default, #ffffff)}:host ::ng-deep .p-step.p-step-active .tk-step-title,:host ::ng-deep .p-step[data-p-active=true] .tk-step-title{color:var(--tk-color-primary-default, #16006f);font-weight:var(--tk-font-weight-600, 600)}:host ::ng-deep .p-step.p-disabled,:host ::ng-deep .p-step[disabled],:host ::ng-deep .p-step[data-p-disabled=true]{opacity:.6;cursor:not-allowed}:host ::ng-deep .p-stepper-separator{flex:1 1 0;height:1px!important;background-color:var(--tk-color-primary-default, #16006f)!important;margin:0 var(--tk-spacing-base-100, 1rem)!important;border:none!important;transition:background-color .2s ease-in-out}:host ::ng-deep .p-steppanels{width:100%;background:transparent;padding:0}:host ::ng-deep .p-steppanel{width:100%;outline:none}:host ::ng-deep .tk-stepper-vertical .p-stepper{flex-direction:column;gap:0}:host ::ng-deep .tk-stepper-vertical .p-stepitem{display:flex;flex-direction:column;width:calc(100% - .95rem);margin-left:.95rem;padding-left:var(--tk-spacing-base-100, 1rem);padding-bottom:var(--tk-spacing-base-150, 1.5rem);position:relative;box-sizing:border-box}:host ::ng-deep .tk-stepper-vertical .p-stepitem:before{content:\"\";position:absolute;left:0;top:2.6rem;bottom:1rem;width:1px;background-color:transparent;transition:background-color .2s ease-in-out}:host ::ng-deep .tk-stepper-vertical .p-stepitem[data-p-active=true]:before{background-color:var(--tk-color-primary-default, #16006f)}:host ::ng-deep .tk-stepper-vertical .p-stepitem:last-child{padding-bottom:0}:host ::ng-deep .tk-stepper-vertical .p-stepitem:last-child:before{display:none!important}:host ::ng-deep .tk-stepper-vertical .p-stepitem .p-step{margin-left:-2rem;background:transparent;position:relative;z-index:2;margin-bottom:var(--tk-spacing-base-75, .75rem)}:host ::ng-deep .tk-stepper-vertical .p-stepitem .p-steppanel{padding:0;width:100%}:host ::ng-deep .tk-stepper-vertical .p-stepitem .p-steppanel .p-steppanel-content-wrapper,:host ::ng-deep .tk-stepper-vertical .p-stepitem .p-steppanel .p-steppanel-content{margin:0!important;padding:0!important;margin-inline-start:0!important}.tk-step-panel-content{width:100%;min-height:100px}.tk-step-actions-footer{display:flex;justify-content:space-between;align-items:center;margin-top:var(--tk-spacing-base-150, 1.5rem);width:100%}.tk-step-actions-footer .tk-step-actions-secondary{display:flex;gap:var(--tk-spacing-base-50, .5rem)}.tk-step-actions-footer .tk-step-actions-primary{display:flex;gap:var(--tk-spacing-base-50, .5rem);margin-left:auto}.tk-step-actions-footer.vertical{justify-content:flex-start;gap:var(--tk-spacing-base-50, .5rem);margin-top:var(--tk-spacing-base-100, 1rem)}\n"], dependencies: [{ kind: "ngmodule", type: StepperModule }, { kind: "component", type: i1.Stepper, selector: "p-stepper", inputs: ["value", "linear", "transitionOptions", "motionOptions"], outputs: ["valueChange"] }, { kind: "component", type: i1.StepList, selector: "p-step-list" }, { kind: "component", type: i1.StepPanels, selector: "p-step-panels" }, { kind: "component", type: i1.StepPanel, selector: "p-step-panel", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: i1.StepItem, selector: "p-step-item", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: i1.Step, selector: "p-step", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ButtonComponent, selector: "tk-button", inputs: ["label", "disabled", "type", "severity", "variant", "link", "icon", "iconPosition", "tooltipText", "size"], outputs: ["clicked"] }, { kind: "ngmodule", type: SharedModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
104
+ }
105
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: StepperComponent, decorators: [{
106
+ type: Component,
107
+ args: [{ selector: 'tk-stepper', imports: [StepperModule, NgTemplateOutlet, ButtonComponent, SharedModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"tk-stepper-container\" [class.tk-stepper-vertical]=\"orientation() === 'vertical'\" [class.tk-stepper-horizontal]=\"orientation() === 'horizontal'\">\n @if (steps().length > 0) {\n @if (orientation() === 'horizontal') {\n <p-stepper [value]=\"activeStep()\" [linear]=\"linear()\" (valueChange)=\"onStepChange($event !== undefined ? +$event : activeStep())\">\n <p-step-list class=\"tk-step-list-horizontal\">\n @for (step of steps(); track $index) {\n <p-step [value]=\"$index\" [disabled]=\"isStepDisabled($index)\">\n <div class=\"tk-step-header-content\">\n <span class=\"tk-step-number\">{{ $index + 1 }}</span>\n <span class=\"tk-step-title\">{{ step.label }}</span>\n </div>\n </p-step>\n }\n </p-step-list>\n\n <p-step-panels class=\"tk-step-panels-horizontal\">\n @for (step of steps(); track $index) {\n <p-step-panel [value]=\"$index\">\n <ng-template pTemplate=\"content\">\n <div class=\"tk-step-panel-content\">\n <ng-container [ngTemplateOutlet]=\"step.content\"></ng-container>\n </div>\n \n @if (showFooter() && (step.actionsPrimary?.length || step.actionsSecondary?.length)) {\n <div class=\"tk-step-actions-footer\">\n <div class=\"tk-step-actions-secondary\">\n @for (action of step.actionsSecondary; track $index) {\n <tk-button\n [label]=\"action.label\"\n [icon]=\"action.icon\"\n [severity]=\"action.severity || 'secondary'\"\n [variant]=\"action.variant\"\n [disabled]=\"evalDisabled(action.disabled)\"\n (clicked)=\"action.action()\">\n </tk-button>\n }\n </div>\n <div class=\"tk-step-actions-primary\">\n @for (action of step.actionsPrimary; track $index) {\n <tk-button\n [label]=\"action.label\"\n [icon]=\"action.icon\"\n [severity]=\"action.severity || 'primary'\"\n [variant]=\"action.variant\"\n [disabled]=\"evalDisabled(action.disabled)\"\n (clicked)=\"action.action()\">\n </tk-button>\n }\n </div>\n </div>\n }\n </ng-template>\n </p-step-panel>\n }\n </p-step-panels>\n </p-stepper>\n } @else {\n <p-stepper [value]=\"activeStep()\" [linear]=\"linear()\" (valueChange)=\"onStepChange($event !== undefined ? +$event : activeStep())\">\n @for (step of steps(); track $index) {\n <p-step-item [value]=\"$index\">\n <p-step [value]=\"$index\" [disabled]=\"isStepDisabled($index)\">\n <div class=\"tk-step-header-content\">\n <span class=\"tk-step-number\">{{ $index + 1 }}</span>\n <span class=\"tk-step-title\">{{ step.label }}</span>\n </div>\n </p-step>\n <p-step-panel [value]=\"$index\">\n <ng-template pTemplate=\"content\">\n <div class=\"tk-step-panel-content\">\n <ng-container [ngTemplateOutlet]=\"step.content\"></ng-container>\n </div>\n\n @if (showFooter() && (step.actionsPrimary?.length || step.actionsSecondary?.length)) {\n <div class=\"tk-step-actions-footer vertical\">\n @for (action of step.actionsSecondary; track $index) {\n <tk-button\n [label]=\"action.label\"\n [icon]=\"action.icon\"\n [severity]=\"action.severity || 'secondary'\"\n [variant]=\"action.variant\"\n [disabled]=\"evalDisabled(action.disabled)\"\n (clicked)=\"action.action()\">\n </tk-button>\n }\n @for (action of step.actionsPrimary; track $index) {\n <tk-button\n [label]=\"action.label\"\n [icon]=\"action.icon\"\n [severity]=\"action.severity || 'primary'\"\n [variant]=\"action.variant\"\n [disabled]=\"evalDisabled(action.disabled)\"\n (clicked)=\"action.action()\">\n </tk-button>\n }\n </div>\n }\n </ng-template>\n </p-step-panel>\n </p-step-item>\n }\n </p-stepper>\n }\n }\n</div>\n", styles: [":host{display:block;width:100%}.tk-stepper-container{display:block;width:100%;box-sizing:border-box}.tk-stepper-container.tk-stepper-vertical{padding-right:1rem;padding-bottom:.5rem}:host ::ng-deep .p-stepper{display:flex;flex-direction:column;width:100%;background:transparent}:host ::ng-deep .p-steplist{display:flex;align-items:center;width:100%;background:transparent;padding:0;margin-bottom:var(--tk-spacing-base-150, 1.5rem)}:host ::ng-deep .p-step{padding:0;background:transparent;border:none;outline:none!important;box-shadow:none!important;cursor:pointer;display:flex}:host ::ng-deep .p-step:focus,:host ::ng-deep .p-step:focus-visible,:host ::ng-deep .p-step:focus-within{outline:none!important;box-shadow:none!important}:host ::ng-deep .p-step{align-items:center;gap:var(--tk-spacing-base-50, .5rem)}:host ::ng-deep .p-step .p-step-header{outline:none!important;box-shadow:none!important;border:none!important;background:transparent!important}:host ::ng-deep .p-step .p-step-header:focus,:host ::ng-deep .p-step .p-step-header:focus-visible,:host ::ng-deep .p-step .p-step-header:focus-within{outline:none!important;box-shadow:none!important}:host ::ng-deep .p-step .p-step-number{display:none!important}:host ::ng-deep .p-step .tk-step-header-content{display:flex;align-items:center;gap:var(--tk-spacing-base-50, .5rem)}:host ::ng-deep .p-step .tk-step-number{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;border:1px solid var(--tk-color-border-default, #cecdcd);border-radius:var(--tk-borderRadius-full, 50%);color:var(--tk-color-text-muted, #8a8a8b);font-size:var(--tk-font-size-paragraph-s, .875rem);font-weight:var(--tk-font-weight-600, 600);background-color:var(--tk-color-background-default, #ffffff);transition:all .2s ease-in-out}:host ::ng-deep .p-step .tk-step-title{color:var(--tk-color-text-muted, #8a8a8b);font-size:var(--tk-font-size-paragraph-m, 1rem);font-weight:var(--tk-font-weight-400, 400);transition:all .2s ease-in-out}:host ::ng-deep .p-step.p-step-active .tk-step-number,:host ::ng-deep .p-step[data-p-active=true] .tk-step-number{border-color:var(--tk-color-border-default, #cecdcd);color:var(--tk-color-primary-default, #16006f);background-color:var(--tk-color-background-default, #ffffff)}:host ::ng-deep .p-step.p-step-active .tk-step-title,:host ::ng-deep .p-step[data-p-active=true] .tk-step-title{color:var(--tk-color-primary-default, #16006f);font-weight:var(--tk-font-weight-600, 600)}:host ::ng-deep .p-step.p-disabled,:host ::ng-deep .p-step[disabled],:host ::ng-deep .p-step[data-p-disabled=true]{opacity:.6;cursor:not-allowed}:host ::ng-deep .p-stepper-separator{flex:1 1 0;height:1px!important;background-color:var(--tk-color-primary-default, #16006f)!important;margin:0 var(--tk-spacing-base-100, 1rem)!important;border:none!important;transition:background-color .2s ease-in-out}:host ::ng-deep .p-steppanels{width:100%;background:transparent;padding:0}:host ::ng-deep .p-steppanel{width:100%;outline:none}:host ::ng-deep .tk-stepper-vertical .p-stepper{flex-direction:column;gap:0}:host ::ng-deep .tk-stepper-vertical .p-stepitem{display:flex;flex-direction:column;width:calc(100% - .95rem);margin-left:.95rem;padding-left:var(--tk-spacing-base-100, 1rem);padding-bottom:var(--tk-spacing-base-150, 1.5rem);position:relative;box-sizing:border-box}:host ::ng-deep .tk-stepper-vertical .p-stepitem:before{content:\"\";position:absolute;left:0;top:2.6rem;bottom:1rem;width:1px;background-color:transparent;transition:background-color .2s ease-in-out}:host ::ng-deep .tk-stepper-vertical .p-stepitem[data-p-active=true]:before{background-color:var(--tk-color-primary-default, #16006f)}:host ::ng-deep .tk-stepper-vertical .p-stepitem:last-child{padding-bottom:0}:host ::ng-deep .tk-stepper-vertical .p-stepitem:last-child:before{display:none!important}:host ::ng-deep .tk-stepper-vertical .p-stepitem .p-step{margin-left:-2rem;background:transparent;position:relative;z-index:2;margin-bottom:var(--tk-spacing-base-75, .75rem)}:host ::ng-deep .tk-stepper-vertical .p-stepitem .p-steppanel{padding:0;width:100%}:host ::ng-deep .tk-stepper-vertical .p-stepitem .p-steppanel .p-steppanel-content-wrapper,:host ::ng-deep .tk-stepper-vertical .p-stepitem .p-steppanel .p-steppanel-content{margin:0!important;padding:0!important;margin-inline-start:0!important}.tk-step-panel-content{width:100%;min-height:100px}.tk-step-actions-footer{display:flex;justify-content:space-between;align-items:center;margin-top:var(--tk-spacing-base-150, 1.5rem);width:100%}.tk-step-actions-footer .tk-step-actions-secondary{display:flex;gap:var(--tk-spacing-base-50, .5rem)}.tk-step-actions-footer .tk-step-actions-primary{display:flex;gap:var(--tk-spacing-base-50, .5rem);margin-left:auto}.tk-step-actions-footer.vertical{justify-content:flex-start;gap:var(--tk-spacing-base-50, .5rem);margin-top:var(--tk-spacing-base-100, 1rem)}\n"] }]
108
+ }], propDecorators: { steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: false }] }], activeStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeStep", required: false }] }, { type: i0.Output, args: ["activeStepChange"] }], linear: [{ type: i0.Input, args: [{ isSignal: true, alias: "linear", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], showFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFooter", required: false }] }], stepChange: [{ type: i0.Output, args: ["stepChange"] }] } });
109
+
110
+ /**
111
+ * Generated bundle index. Do not edit.
112
+ */
113
+
114
+ export { StepperComponent };
115
+ //# sourceMappingURL=tekus-design-system-components-stepper.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tekus-design-system-components-stepper.mjs","sources":["../../../projects/design-system/components/stepper/src/stepper.component.ts","../../../projects/design-system/components/stepper/src/stepper.component.html","../../../projects/design-system/components/stepper/tekus-design-system-components-stepper.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input, model, output } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { StepperModule } from 'primeng/stepper';\nimport { SharedModule } from 'primeng/api';\nimport { ButtonComponent } from '@tekus/design-system/components/button';\nimport { StepData } from './stepper.types';\n\n/**\n * @component StepperComponent\n * @description\n * Reusable stepper component that acts as a wrapper around PrimeNG's Stepper.\n * Supports horizontal and vertical orientations, linear step completion rules,\n * and automated footer action buttons.\n *\n * @usage\n * ```html\n * <tk-stepper\n * [steps]=\"steps\"\n * [(activeStep)]=\"currentStep\"\n * [linear]=\"true\"\n * orientation=\"horizontal\">\n * </tk-stepper>\n * ```\n */\n@Component({\n selector: 'tk-stepper',\n imports: [StepperModule, NgTemplateOutlet, ButtonComponent, SharedModule],\n templateUrl: './stepper.component.html',\n styleUrl: './stepper.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class StepperComponent {\n /**\n * @property {InputSignal<StepData[]>} steps\n * @description Array of step configurations to display.\n */\n steps = input<StepData[]>([]);\n\n /**\n * @property {ModelSignal<number>} activeStep\n * @description The 0-based index of the currently active step. Supports two-way binding.\n * @default 0\n */\n activeStep = model<number>(0);\n\n /**\n * @property {InputSignal<boolean>} linear\n * @description If true, blocks navigation to steps ahead of the active step.\n * @default true\n */\n linear = input<boolean>(true);\n\n /**\n * @property {InputSignal<'horizontal' | 'vertical'>} orientation\n * @description Defines the layout orientation of the stepper.\n * @default 'horizontal'\n */\n orientation = input<'horizontal' | 'vertical'>('horizontal');\n\n /**\n * @property {InputSignal<boolean>} showFooter\n * @description Whether to render the default footer action buttons for each step.\n * @default true\n */\n showFooter = input<boolean>(true);\n\n /**\n * @event stepChange\n * @description Emitted when the active step changes.\n */\n stepChange = output<{\n index: number;\n step: StepData;\n }>();\n\n /**\n * Checks if a step header should be disabled.\n * Steps ahead of the active index are disabled in linear mode.\n */\n isStepDisabled(index: number): boolean {\n const step = this.steps()[index];\n if (!step) return true;\n if (step.disabled) return true;\n if (this.linear() && index > this.activeStep()) return true;\n return false;\n }\n\n /**\n * Helper to evaluate button disabled states dynamically.\n */\n evalDisabled(disabled: boolean | (() => boolean) | undefined): boolean {\n if (disabled === undefined) return false;\n if (typeof disabled === 'function') return disabled();\n return disabled;\n }\n\n /**\n * Handles step transition events.\n */\n onStepChange(index: number) {\n if (this.activeStep() === index) return;\n this.activeStep.set(index);\n if (this.steps()[index]) {\n this.stepChange.emit({\n index,\n step: this.steps()[index],\n });\n }\n }\n}\n\n","<div class=\"tk-stepper-container\" [class.tk-stepper-vertical]=\"orientation() === 'vertical'\" [class.tk-stepper-horizontal]=\"orientation() === 'horizontal'\">\n @if (steps().length > 0) {\n @if (orientation() === 'horizontal') {\n <p-stepper [value]=\"activeStep()\" [linear]=\"linear()\" (valueChange)=\"onStepChange($event !== undefined ? +$event : activeStep())\">\n <p-step-list class=\"tk-step-list-horizontal\">\n @for (step of steps(); track $index) {\n <p-step [value]=\"$index\" [disabled]=\"isStepDisabled($index)\">\n <div class=\"tk-step-header-content\">\n <span class=\"tk-step-number\">{{ $index + 1 }}</span>\n <span class=\"tk-step-title\">{{ step.label }}</span>\n </div>\n </p-step>\n }\n </p-step-list>\n\n <p-step-panels class=\"tk-step-panels-horizontal\">\n @for (step of steps(); track $index) {\n <p-step-panel [value]=\"$index\">\n <ng-template pTemplate=\"content\">\n <div class=\"tk-step-panel-content\">\n <ng-container [ngTemplateOutlet]=\"step.content\"></ng-container>\n </div>\n \n @if (showFooter() && (step.actionsPrimary?.length || step.actionsSecondary?.length)) {\n <div class=\"tk-step-actions-footer\">\n <div class=\"tk-step-actions-secondary\">\n @for (action of step.actionsSecondary; track $index) {\n <tk-button\n [label]=\"action.label\"\n [icon]=\"action.icon\"\n [severity]=\"action.severity || 'secondary'\"\n [variant]=\"action.variant\"\n [disabled]=\"evalDisabled(action.disabled)\"\n (clicked)=\"action.action()\">\n </tk-button>\n }\n </div>\n <div class=\"tk-step-actions-primary\">\n @for (action of step.actionsPrimary; track $index) {\n <tk-button\n [label]=\"action.label\"\n [icon]=\"action.icon\"\n [severity]=\"action.severity || 'primary'\"\n [variant]=\"action.variant\"\n [disabled]=\"evalDisabled(action.disabled)\"\n (clicked)=\"action.action()\">\n </tk-button>\n }\n </div>\n </div>\n }\n </ng-template>\n </p-step-panel>\n }\n </p-step-panels>\n </p-stepper>\n } @else {\n <p-stepper [value]=\"activeStep()\" [linear]=\"linear()\" (valueChange)=\"onStepChange($event !== undefined ? +$event : activeStep())\">\n @for (step of steps(); track $index) {\n <p-step-item [value]=\"$index\">\n <p-step [value]=\"$index\" [disabled]=\"isStepDisabled($index)\">\n <div class=\"tk-step-header-content\">\n <span class=\"tk-step-number\">{{ $index + 1 }}</span>\n <span class=\"tk-step-title\">{{ step.label }}</span>\n </div>\n </p-step>\n <p-step-panel [value]=\"$index\">\n <ng-template pTemplate=\"content\">\n <div class=\"tk-step-panel-content\">\n <ng-container [ngTemplateOutlet]=\"step.content\"></ng-container>\n </div>\n\n @if (showFooter() && (step.actionsPrimary?.length || step.actionsSecondary?.length)) {\n <div class=\"tk-step-actions-footer vertical\">\n @for (action of step.actionsSecondary; track $index) {\n <tk-button\n [label]=\"action.label\"\n [icon]=\"action.icon\"\n [severity]=\"action.severity || 'secondary'\"\n [variant]=\"action.variant\"\n [disabled]=\"evalDisabled(action.disabled)\"\n (clicked)=\"action.action()\">\n </tk-button>\n }\n @for (action of step.actionsPrimary; track $index) {\n <tk-button\n [label]=\"action.label\"\n [icon]=\"action.icon\"\n [severity]=\"action.severity || 'primary'\"\n [variant]=\"action.variant\"\n [disabled]=\"evalDisabled(action.disabled)\"\n (clicked)=\"action.action()\">\n </tk-button>\n }\n </div>\n }\n </ng-template>\n </p-step-panel>\n </p-step-item>\n }\n </p-stepper>\n }\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@ import { ButtonComponent } from '@tekus/design-system/components/button';
9
9
  import { CheckboxComponent } from '@tekus/design-system/components/checkbox';
10
10
  import { ActionGroupComponent } from '@tekus/design-system/components/action-group';
11
11
  import { IconComponent } from '@tekus/design-system/components/icon';
12
+ import { TimeAgoComponent } from '@tekus/design-system/components/time-ago';
12
13
  import * as i2 from 'primeng/api';
13
14
 
14
15
  /**
@@ -88,7 +89,10 @@ class TableComponent {
88
89
  /** Stores the selected filter value per column field (null = no filter) */
89
90
  this.columnFilters = signal({}, ...(ngDevMode ? [{ debugName: "columnFilters" }] : /* istanbul ignore next */ []));
90
91
  /** Position of the filter overlay (fixed, relative to viewport) */
91
- this.filterOverlayPosition = signal({ top: 0, left: 0 }, ...(ngDevMode ? [{ debugName: "filterOverlayPosition" }] : /* istanbul ignore next */ []));
92
+ this.filterOverlayPosition = signal({
93
+ top: 0,
94
+ left: 0,
95
+ }, ...(ngDevMode ? [{ debugName: "filterOverlayPosition" }] : /* istanbul ignore next */ []));
92
96
  /**
93
97
  * @computed isAllSelected
94
98
  * @description
@@ -160,7 +164,7 @@ class TableComponent {
160
164
  rowCache.set(row, actions.map(a => ({
161
165
  icon: a.icon,
162
166
  label: a.label,
163
- action: () => a.action(row)
167
+ action: () => a.action(row),
164
168
  })));
165
169
  }
166
170
  return rowCache.get(row);
@@ -257,7 +261,7 @@ class TableComponent {
257
261
  continue;
258
262
  data = data.filter(row => {
259
263
  const cellValue = row[filterField];
260
- return cellValue != null && this.cellToString(cellValue) === selectedValue;
264
+ return (cellValue != null && this.cellToString(cellValue) === selectedValue);
261
265
  });
262
266
  }
263
267
  const values = data
@@ -330,7 +334,7 @@ class TableComponent {
330
334
  continue;
331
335
  filtered = filtered.filter(row => {
332
336
  const cellValue = row[field];
333
- return cellValue != null && this.cellToString(cellValue) === selectedValue;
337
+ return (cellValue != null && this.cellToString(cellValue) === selectedValue);
334
338
  });
335
339
  }
336
340
  return filtered;
@@ -348,8 +352,37 @@ class TableComponent {
348
352
  return `${value}`;
349
353
  return JSON.stringify(value);
350
354
  }
355
+ /**
356
+ * @method handleImageClick
357
+ * @description
358
+ * Handles click events on image-type cells.
359
+ * Stops row selection propagation and invokes the column's imageAction callback when defined.
360
+ * No-op when imageAction is not set, preserving default row-click behavior.
361
+ * @param event {Event} - The native click event.
362
+ * @param col {TableColumn<T>} - The column definition that may carry an imageAction.
363
+ * @param row {T} - The data row associated with the clicked image.
364
+ */
365
+ handleImageClick(event, col, row) {
366
+ if (col.imageAction) {
367
+ event.stopPropagation();
368
+ col.imageAction(row);
369
+ }
370
+ }
371
+ /**
372
+ * @method onImageError
373
+ * @description
374
+ * Handles image load errors by replacing the broken src with a fallback URL.
375
+ * Called from the template's (error) binding on image-type columns.
376
+ * @param event {Event} - The native error event from the <img> element.
377
+ * @param fallback {string | undefined} - Optional URL to use as replacement src.
378
+ */
379
+ onImageError(event, fallback) {
380
+ if (fallback) {
381
+ event.target.src = fallback;
382
+ }
383
+ }
351
384
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
352
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: TableComponent, isStandalone: true, selector: "tk-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection: "selectionChange" }, viewQueries: [{ propertyName: "tableRef", first: true, predicate: ["tableRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<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 [actions]=\"getActionGroup(col.actionGroup!, row)\" [maxVisible]=\"col.actionGroupMaxVisible ?? 2\" (click)=\"$event.stopPropagation()\" (keypress)=\"$event.stopPropagation()\"></tk-action-group>\n </div>\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", styles: [":host ::ng-deep .p-datatable-column-sorted{background-color:var(--tk-primary-100, #b7b0d2)!important;color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-column-sorted svg{color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-sortable-column{font-size:var(--tk-font-size-sm, .875rem);color:var(--tk-surface-950, #191a1b);padding:.625rem}:host ::ng-deep .p-datatable-sortable-column svg{color:var(--tk-surface-500, #424243)}:host ::ng-deep .p-button-secondary{background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-0, #ffffff)}:host ::ng-deep .p-datatable-tbody td{color:var(--tk-surface-950, #191a1b);font-size:var(--tk-font-size-sm, .875rem);padding:.625rem}.tk-table__actions{display:flex;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__header-content{display:flex;align-items:center;gap:.25rem;width:100%}.tk-table__header-label{white-space:nowrap}.tk-table__header--active{background-color:var(--tk-primary-100, #b7b0d2)!important}.tk-table__filter-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border:none;background:transparent;border-radius:var(--tk-border-radius-xs, 4px);cursor:pointer;color:var(--tk-surface-500, #8a8a8b);transition:background-color .2s,color .2s;padding:0;margin-left:auto}.tk-table__filter-trigger:hover{background-color:var(--tk-surface-200, #e4e4e4);color:var(--tk-surface-700, #424243)}.tk-table__filter-trigger--active{color:var(--tk-primary-700, #10004f);background-color:var(--tk-primary-50, #e8e6f1)}.tk-table__filter-trigger--active:hover{background-color:var(--tk-primary-100, #b7b0d2);color:var(--tk-primary-700, #10004f)}.tk-table__filter-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999;background:transparent}.tk-table__filter-overlay{position:fixed;z-index:1000;min-width:10rem;max-height:15rem;background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-200, #e4e4e4);border-radius:var(--tk-border-radius-s, 8px);box-shadow:0 4px 16px #0000001f;overflow:hidden;display:flex;flex-direction:column;animation:tk-filter-fade-in .15s ease-out}.tk-table__filter-list{margin:0;padding:.25rem 0;overflow-y:auto;max-height:12rem;display:flex;flex-direction:column}.tk-table__filter-option{display:block;width:100%;padding:.5rem .75rem;font-size:.875rem;color:var(--tk-surface-950, #191a1b);cursor:pointer;transition:background-color .15s;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border:none;background:transparent;text-align:left}.tk-table__filter-option:hover{background-color:var(--tk-surface-100, #f2f1f1)}.tk-table__filter-option--selected{background-color:var(--tk-primary-50, #e8e6f1);color:var(--tk-primary-700, #10004f);font-weight:600}.tk-table__filter-option--selected:hover{background-color:var(--tk-primary-100, #b7b0d2)}.tk-table__filter-clear{border-top:1px solid var(--tk-surface-200, #e4e4e4);padding:.375rem .75rem;display:flex;justify-content:center}.tk-table__filter-clear-btn{background:transparent;border:none;color:var(--tk-primary-500, #16006f);font-size:.8125rem;font-weight:600;cursor:pointer;padding:.25rem .5rem;border-radius:var(--tk-border-radius-xs, 4px);transition:background-color .15s}.tk-table__filter-clear-btn:hover{background-color:var(--tk-primary-50, #e8e6f1)}:host ::ng-deep .p-datatable-thead>tr>th{position:relative}@keyframes tk-filter-fade-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: TableModule }, { kind: "component", type: i1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i1.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i1.SelectableRow, selector: "[pSelectableRow]", inputs: ["pSelectableRow", "pSelectableRowIndex", "pSelectableRowDisabled"] }, { kind: "component", type: i1.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "ngmodule", type: TagModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: TagComponent, selector: "tk-tag", inputs: ["value", "severity", "truncationLimit"] }, { kind: "component", type: ButtonComponent, selector: "tk-button", inputs: ["label", "disabled", "type", "severity", "variant", "link", "icon", "iconPosition", "tooltipText", "size"], outputs: ["clicked"] }, { kind: "component", type: CheckboxComponent, selector: "tk-checkbox", inputs: ["model", "value", "label", "name", "inputId", "binary", "control", "errorMessage", "indeterminate", "disabled"], outputs: ["modelChange", "indeterminateChange", "disabledChange"] }, { kind: "component", type: ActionGroupComponent, selector: "tk-action-group", inputs: ["actions", "maxVisible"] }, { kind: "component", type: IconComponent, selector: "tk-icon", inputs: ["icon", "styleIcon", "color", "size", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
385
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.3", type: TableComponent, isStandalone: true, selector: "tk-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection: "selectionChange" }, viewQueries: [{ propertyName: "tableRef", first: true, predicate: ["tableRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<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 [actions]=\"getActionGroup(col.actionGroup!, row)\" [maxVisible]=\"col.actionGroupMaxVisible ?? 2\" (click)=\"$event.stopPropagation()\" (keypress)=\"$event.stopPropagation()\"></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", styles: [":host ::ng-deep .p-datatable-column-sorted{background-color:var(--tk-primary-100, #b7b0d2)!important;color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-column-sorted svg{color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-sortable-column{font-size:var(--tk-font-size-sm, .875rem);color:var(--tk-surface-950, #191a1b);padding:.625rem}:host ::ng-deep .p-datatable-sortable-column svg{color:var(--tk-surface-500, #424243)}:host ::ng-deep .p-button-secondary{background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-0, #ffffff)}:host ::ng-deep .p-datatable-tbody td{color:var(--tk-surface-950, #191a1b);font-size:var(--tk-font-size-sm, .875rem);padding:.625rem}.tk-table__cell-img{display:block;object-fit:cover}.tk-table__cell-img--clickable{cursor:pointer}.tk-table__actions{display:flex;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__header-content{display:flex;align-items:center;gap:.25rem;width:100%}.tk-table__header-label{white-space:nowrap}.tk-table__header--active{background-color:var(--tk-primary-100, #b7b0d2)!important}.tk-table__filter-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border:none;background:transparent;border-radius:var(--tk-border-radius-xs, 4px);cursor:pointer;color:var(--tk-surface-500, #8a8a8b);transition:background-color .2s,color .2s;padding:0;margin-left:auto}.tk-table__filter-trigger:hover{background-color:var(--tk-surface-200, #e4e4e4);color:var(--tk-surface-700, #424243)}.tk-table__filter-trigger--active{color:var(--tk-primary-700, #10004f);background-color:var(--tk-primary-50, #e8e6f1)}.tk-table__filter-trigger--active:hover{background-color:var(--tk-primary-100, #b7b0d2);color:var(--tk-primary-700, #10004f)}.tk-table__filter-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999;background:transparent}.tk-table__filter-overlay{position:fixed;z-index:1000;min-width:10rem;max-height:15rem;background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-200, #e4e4e4);border-radius:var(--tk-border-radius-s, 8px);box-shadow:0 4px 16px #0000001f;overflow:hidden;display:flex;flex-direction:column;animation:tk-filter-fade-in .15s ease-out}.tk-table__filter-list{margin:0;padding:.25rem 0;overflow-y:auto;max-height:12rem;display:flex;flex-direction:column}.tk-table__filter-option{display:block;width:100%;padding:.5rem .75rem;font-size:.875rem;color:var(--tk-surface-950, #191a1b);cursor:pointer;transition:background-color .15s;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border:none;background:transparent;text-align:left}.tk-table__filter-option:hover{background-color:var(--tk-surface-100, #f2f1f1)}.tk-table__filter-option--selected{background-color:var(--tk-primary-50, #e8e6f1);color:var(--tk-primary-700, #10004f);font-weight:600}.tk-table__filter-option--selected:hover{background-color:var(--tk-primary-100, #b7b0d2)}.tk-table__filter-clear{border-top:1px solid var(--tk-surface-200, #e4e4e4);padding:.375rem .75rem;display:flex;justify-content:center}.tk-table__filter-clear-btn{background:transparent;border:none;color:var(--tk-primary-500, #16006f);font-size:.8125rem;font-weight:600;cursor:pointer;padding:.25rem .5rem;border-radius:var(--tk-border-radius-xs, 4px);transition:background-color .15s}.tk-table__filter-clear-btn:hover{background-color:var(--tk-primary-50, #e8e6f1)}:host ::ng-deep .p-datatable-thead>tr>th{position:relative}@keyframes tk-filter-fade-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: TableModule }, { kind: "component", type: i1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i1.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i1.SelectableRow, selector: "[pSelectableRow]", inputs: ["pSelectableRow", "pSelectableRowIndex", "pSelectableRowDisabled"] }, { kind: "component", type: i1.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "ngmodule", type: TagModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: TagComponent, selector: "tk-tag", inputs: ["value", "severity", "truncationLimit"] }, { kind: "component", type: ButtonComponent, selector: "tk-button", inputs: ["label", "disabled", "type", "severity", "variant", "link", "icon", "iconPosition", "tooltipText", "size"], outputs: ["clicked"] }, { kind: "component", type: CheckboxComponent, selector: "tk-checkbox", inputs: ["model", "value", "label", "name", "inputId", "binary", "control", "errorMessage", "indeterminate", "disabled"], outputs: ["modelChange", "indeterminateChange", "disabledChange"] }, { kind: "component", type: ActionGroupComponent, selector: "tk-action-group", inputs: ["actions", "maxVisible"] }, { kind: "component", type: IconComponent, selector: "tk-icon", inputs: ["icon", "styleIcon", "color", "size", "disabled"] }, { kind: "component", type: TimeAgoComponent, selector: "tk-time-ago", inputs: ["dateTime", "severity", "tooltipText", "tooltipFormat"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
353
386
  }
354
387
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImport: i0, type: TableComponent, decorators: [{
355
388
  type: Component,
@@ -362,7 +395,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.3", ngImpor
362
395
  CheckboxComponent,
363
396
  ActionGroupComponent,
364
397
  IconComponent,
365
- ], template: "<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 [actions]=\"getActionGroup(col.actionGroup!, row)\" [maxVisible]=\"col.actionGroupMaxVisible ?? 2\" (click)=\"$event.stopPropagation()\" (keypress)=\"$event.stopPropagation()\"></tk-action-group>\n </div>\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", styles: [":host ::ng-deep .p-datatable-column-sorted{background-color:var(--tk-primary-100, #b7b0d2)!important;color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-column-sorted svg{color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-sortable-column{font-size:var(--tk-font-size-sm, .875rem);color:var(--tk-surface-950, #191a1b);padding:.625rem}:host ::ng-deep .p-datatable-sortable-column svg{color:var(--tk-surface-500, #424243)}:host ::ng-deep .p-button-secondary{background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-0, #ffffff)}:host ::ng-deep .p-datatable-tbody td{color:var(--tk-surface-950, #191a1b);font-size:var(--tk-font-size-sm, .875rem);padding:.625rem}.tk-table__actions{display:flex;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__header-content{display:flex;align-items:center;gap:.25rem;width:100%}.tk-table__header-label{white-space:nowrap}.tk-table__header--active{background-color:var(--tk-primary-100, #b7b0d2)!important}.tk-table__filter-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border:none;background:transparent;border-radius:var(--tk-border-radius-xs, 4px);cursor:pointer;color:var(--tk-surface-500, #8a8a8b);transition:background-color .2s,color .2s;padding:0;margin-left:auto}.tk-table__filter-trigger:hover{background-color:var(--tk-surface-200, #e4e4e4);color:var(--tk-surface-700, #424243)}.tk-table__filter-trigger--active{color:var(--tk-primary-700, #10004f);background-color:var(--tk-primary-50, #e8e6f1)}.tk-table__filter-trigger--active:hover{background-color:var(--tk-primary-100, #b7b0d2);color:var(--tk-primary-700, #10004f)}.tk-table__filter-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999;background:transparent}.tk-table__filter-overlay{position:fixed;z-index:1000;min-width:10rem;max-height:15rem;background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-200, #e4e4e4);border-radius:var(--tk-border-radius-s, 8px);box-shadow:0 4px 16px #0000001f;overflow:hidden;display:flex;flex-direction:column;animation:tk-filter-fade-in .15s ease-out}.tk-table__filter-list{margin:0;padding:.25rem 0;overflow-y:auto;max-height:12rem;display:flex;flex-direction:column}.tk-table__filter-option{display:block;width:100%;padding:.5rem .75rem;font-size:.875rem;color:var(--tk-surface-950, #191a1b);cursor:pointer;transition:background-color .15s;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border:none;background:transparent;text-align:left}.tk-table__filter-option:hover{background-color:var(--tk-surface-100, #f2f1f1)}.tk-table__filter-option--selected{background-color:var(--tk-primary-50, #e8e6f1);color:var(--tk-primary-700, #10004f);font-weight:600}.tk-table__filter-option--selected:hover{background-color:var(--tk-primary-100, #b7b0d2)}.tk-table__filter-clear{border-top:1px solid var(--tk-surface-200, #e4e4e4);padding:.375rem .75rem;display:flex;justify-content:center}.tk-table__filter-clear-btn{background:transparent;border:none;color:var(--tk-primary-500, #16006f);font-size:.8125rem;font-weight:600;cursor:pointer;padding:.25rem .5rem;border-radius:var(--tk-border-radius-xs, 4px);transition:background-color .15s}.tk-table__filter-clear-btn:hover{background-color:var(--tk-primary-50, #e8e6f1)}:host ::ng-deep .p-datatable-thead>tr>th{position:relative}@keyframes tk-filter-fade-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"] }]
398
+ TimeAgoComponent,
399
+ ], template: "<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 [actions]=\"getActionGroup(col.actionGroup!, row)\" [maxVisible]=\"col.actionGroupMaxVisible ?? 2\" (click)=\"$event.stopPropagation()\" (keypress)=\"$event.stopPropagation()\"></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", styles: [":host ::ng-deep .p-datatable-column-sorted{background-color:var(--tk-primary-100, #b7b0d2)!important;color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-column-sorted svg{color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-sortable-column{font-size:var(--tk-font-size-sm, .875rem);color:var(--tk-surface-950, #191a1b);padding:.625rem}:host ::ng-deep .p-datatable-sortable-column svg{color:var(--tk-surface-500, #424243)}:host ::ng-deep .p-button-secondary{background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-0, #ffffff)}:host ::ng-deep .p-datatable-tbody td{color:var(--tk-surface-950, #191a1b);font-size:var(--tk-font-size-sm, .875rem);padding:.625rem}.tk-table__cell-img{display:block;object-fit:cover}.tk-table__cell-img--clickable{cursor:pointer}.tk-table__actions{display:flex;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__header-content{display:flex;align-items:center;gap:.25rem;width:100%}.tk-table__header-label{white-space:nowrap}.tk-table__header--active{background-color:var(--tk-primary-100, #b7b0d2)!important}.tk-table__filter-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border:none;background:transparent;border-radius:var(--tk-border-radius-xs, 4px);cursor:pointer;color:var(--tk-surface-500, #8a8a8b);transition:background-color .2s,color .2s;padding:0;margin-left:auto}.tk-table__filter-trigger:hover{background-color:var(--tk-surface-200, #e4e4e4);color:var(--tk-surface-700, #424243)}.tk-table__filter-trigger--active{color:var(--tk-primary-700, #10004f);background-color:var(--tk-primary-50, #e8e6f1)}.tk-table__filter-trigger--active:hover{background-color:var(--tk-primary-100, #b7b0d2);color:var(--tk-primary-700, #10004f)}.tk-table__filter-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999;background:transparent}.tk-table__filter-overlay{position:fixed;z-index:1000;min-width:10rem;max-height:15rem;background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-200, #e4e4e4);border-radius:var(--tk-border-radius-s, 8px);box-shadow:0 4px 16px #0000001f;overflow:hidden;display:flex;flex-direction:column;animation:tk-filter-fade-in .15s ease-out}.tk-table__filter-list{margin:0;padding:.25rem 0;overflow-y:auto;max-height:12rem;display:flex;flex-direction:column}.tk-table__filter-option{display:block;width:100%;padding:.5rem .75rem;font-size:.875rem;color:var(--tk-surface-950, #191a1b);cursor:pointer;transition:background-color .15s;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border:none;background:transparent;text-align:left}.tk-table__filter-option:hover{background-color:var(--tk-surface-100, #f2f1f1)}.tk-table__filter-option--selected{background-color:var(--tk-primary-50, #e8e6f1);color:var(--tk-primary-700, #10004f);font-weight:600}.tk-table__filter-option--selected:hover{background-color:var(--tk-primary-100, #b7b0d2)}.tk-table__filter-clear{border-top:1px solid var(--tk-surface-200, #e4e4e4);padding:.375rem .75rem;display:flex;justify-content:center}.tk-table__filter-clear-btn{background:transparent;border:none;color:var(--tk-primary-500, #16006f);font-size:.8125rem;font-weight:600;cursor:pointer;padding:.25rem .5rem;border-radius:var(--tk-border-radius-xs, 4px);transition:background-color .15s}.tk-table__filter-clear-btn:hover{background-color:var(--tk-primary-50, #e8e6f1)}:host ::ng-deep .p-datatable-thead>tr>th{position:relative}@keyframes tk-filter-fade-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"] }]
366
400
  }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], tableRef: [{ type: i0.ViewChild, args: ['tableRef', { isSignal: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }, { type: i0.Output, args: ["selectionChange"] }], dataKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataKey", required: false }] }] } });
367
401
 
368
402
  /**