shirkasoft-ui-components 1.2.0 → 1.3.1

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 (79) hide show
  1. package/fesm2022/shirkasoft-ui-components-breadcrumb.mjs +199 -0
  2. package/fesm2022/shirkasoft-ui-components-breadcrumb.mjs.map +1 -0
  3. package/fesm2022/shirkasoft-ui-components-button.mjs +148 -0
  4. package/fesm2022/shirkasoft-ui-components-button.mjs.map +1 -0
  5. package/fesm2022/shirkasoft-ui-components-chart.mjs +153 -0
  6. package/fesm2022/shirkasoft-ui-components-chart.mjs.map +1 -0
  7. package/fesm2022/shirkasoft-ui-components-confirm-dialog.mjs +143 -0
  8. package/fesm2022/shirkasoft-ui-components-confirm-dialog.mjs.map +1 -0
  9. package/fesm2022/shirkasoft-ui-components-date-picker.mjs +638 -0
  10. package/fesm2022/shirkasoft-ui-components-date-picker.mjs.map +1 -0
  11. package/fesm2022/shirkasoft-ui-components-fieldset.mjs +94 -0
  12. package/fesm2022/shirkasoft-ui-components-fieldset.mjs.map +1 -0
  13. package/fesm2022/shirkasoft-ui-components-file-upload.mjs +294 -0
  14. package/fesm2022/shirkasoft-ui-components-file-upload.mjs.map +1 -0
  15. package/fesm2022/shirkasoft-ui-components-knob.mjs +269 -0
  16. package/fesm2022/shirkasoft-ui-components-knob.mjs.map +1 -0
  17. package/fesm2022/shirkasoft-ui-components-loading.mjs +255 -0
  18. package/fesm2022/shirkasoft-ui-components-loading.mjs.map +1 -0
  19. package/fesm2022/shirkasoft-ui-components-modal.mjs +290 -0
  20. package/fesm2022/shirkasoft-ui-components-modal.mjs.map +1 -0
  21. package/fesm2022/shirkasoft-ui-components-notification.mjs +143 -0
  22. package/fesm2022/shirkasoft-ui-components-notification.mjs.map +1 -0
  23. package/fesm2022/shirkasoft-ui-components-price-input.mjs +243 -0
  24. package/fesm2022/shirkasoft-ui-components-price-input.mjs.map +1 -0
  25. package/fesm2022/shirkasoft-ui-components-rail-sidebar.mjs +205 -0
  26. package/fesm2022/shirkasoft-ui-components-rail-sidebar.mjs.map +1 -0
  27. package/fesm2022/shirkasoft-ui-components-select.mjs +737 -0
  28. package/fesm2022/shirkasoft-ui-components-select.mjs.map +1 -0
  29. package/fesm2022/shirkasoft-ui-components-sidebar.mjs +185 -0
  30. package/fesm2022/shirkasoft-ui-components-sidebar.mjs.map +1 -0
  31. package/fesm2022/shirkasoft-ui-components-skeleton.mjs +74 -0
  32. package/fesm2022/shirkasoft-ui-components-skeleton.mjs.map +1 -0
  33. package/fesm2022/shirkasoft-ui-components-table.mjs +689 -0
  34. package/fesm2022/shirkasoft-ui-components-table.mjs.map +1 -0
  35. package/fesm2022/shirkasoft-ui-components-tabs.mjs +249 -0
  36. package/fesm2022/shirkasoft-ui-components-tabs.mjs.map +1 -0
  37. package/fesm2022/shirkasoft-ui-components-tag.mjs +70 -0
  38. package/fesm2022/shirkasoft-ui-components-tag.mjs.map +1 -0
  39. package/fesm2022/shirkasoft-ui-components-text-field.mjs +370 -0
  40. package/fesm2022/shirkasoft-ui-components-text-field.mjs.map +1 -0
  41. package/fesm2022/shirkasoft-ui-components-timeline.mjs +222 -0
  42. package/fesm2022/shirkasoft-ui-components-timeline.mjs.map +1 -0
  43. package/fesm2022/shirkasoft-ui-components-toggle.mjs +186 -0
  44. package/fesm2022/shirkasoft-ui-components-toggle.mjs.map +1 -0
  45. package/fesm2022/shirkasoft-ui-components-tooltip.mjs +169 -0
  46. package/fesm2022/shirkasoft-ui-components-tooltip.mjs.map +1 -0
  47. package/fesm2022/shirkasoft-ui-components-utils.mjs +69 -0
  48. package/fesm2022/shirkasoft-ui-components-utils.mjs.map +1 -0
  49. package/fesm2022/shirkasoft-ui-components-wizard.mjs +167 -0
  50. package/fesm2022/shirkasoft-ui-components-wizard.mjs.map +1 -0
  51. package/fesm2022/shirkasoft-ui-components.mjs +0 -5729
  52. package/fesm2022/shirkasoft-ui-components.mjs.map +1 -1
  53. package/package.json +101 -1
  54. package/types/shirkasoft-ui-components-breadcrumb.d.ts +68 -0
  55. package/types/shirkasoft-ui-components-button.d.ts +59 -0
  56. package/types/shirkasoft-ui-components-chart.d.ts +65 -0
  57. package/types/shirkasoft-ui-components-confirm-dialog.d.ts +88 -0
  58. package/types/shirkasoft-ui-components-date-picker.d.ts +200 -0
  59. package/types/shirkasoft-ui-components-fieldset.d.ts +72 -0
  60. package/types/shirkasoft-ui-components-file-upload.d.ts +121 -0
  61. package/types/shirkasoft-ui-components-knob.d.ts +69 -0
  62. package/types/shirkasoft-ui-components-loading.d.ts +94 -0
  63. package/types/shirkasoft-ui-components-modal.d.ts +139 -0
  64. package/types/shirkasoft-ui-components-notification.d.ts +82 -0
  65. package/types/shirkasoft-ui-components-price-input.d.ts +90 -0
  66. package/types/shirkasoft-ui-components-rail-sidebar.d.ts +121 -0
  67. package/types/shirkasoft-ui-components-select.d.ts +182 -0
  68. package/types/shirkasoft-ui-components-sidebar.d.ts +106 -0
  69. package/types/shirkasoft-ui-components-skeleton.d.ts +36 -0
  70. package/types/shirkasoft-ui-components-table.d.ts +293 -0
  71. package/types/shirkasoft-ui-components-tabs.d.ts +102 -0
  72. package/types/shirkasoft-ui-components-tag.d.ts +31 -0
  73. package/types/shirkasoft-ui-components-text-field.d.ts +120 -0
  74. package/types/shirkasoft-ui-components-timeline.d.ts +178 -0
  75. package/types/shirkasoft-ui-components-toggle.d.ts +48 -0
  76. package/types/shirkasoft-ui-components-tooltip.d.ts +47 -0
  77. package/types/shirkasoft-ui-components-utils.d.ts +9 -0
  78. package/types/shirkasoft-ui-components-wizard.d.ts +101 -0
  79. package/types/shirkasoft-ui-components.d.ts +1 -2333
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shirkasoft-ui-components-table.mjs","sources":["../../../projects/ui-components/table/table.component.ts","../../../projects/ui-components/table/table.component.html","../../../projects/ui-components/table/shirkasoft-ui-components-table.ts"],"sourcesContent":["import {\n Component,\n input,\n output,\n inject,\n signal,\n computed,\n effect,\n linkedSignal,\n ChangeDetectionStrategy,\n untracked,\n ChangeDetectorRef,\n DestroyRef,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { TranslocoModule, TranslocoService } from '@jsverse/transloco';\nimport { debounceTime, Subject, Subscription } from 'rxjs';\nimport { LucideDynamicIcon, LucidePlus } from '@lucide/angular';\nimport { TagComponent, TagSeverity } from 'shirkasoft-ui-components/tag';\nimport { TooltipComponent } from 'shirkasoft-ui-components/tooltip';\nimport { getIcon as getIconFromCentral } from 'shirkasoft-ui-components/utils';\n\nexport interface Column {\n field: string;\n header: string;\n sortable?: boolean;\n filter?: boolean;\n filterPlaceholder?: string;\n width?: string;\n defaultSort?: true;\n filterType?: 'text' | 'exact' | 'select';\n filterOptions?: { label: string; value: any }[];\n template?: 'text' | 'tag';\n format?: (row: any) => string;\n tagValue?: (row: any) => string;\n tagSeverity?: (row: any) => TagSeverity | undefined;\n tagRounded?: boolean | ((row: any) => boolean);\n tagIcon?: string | ((row: any) => string);\n tagStyle?: (row: any) => Record<string, string | number> | undefined;\n}\n\nexport interface TableAction {\n label: string;\n icon: string | any;\n onClick: () => void;\n class?: string;\n isVisible?: () => boolean;\n isDisabled?: () => boolean;\n}\n\nexport interface RowAction {\n label: string | ((data: any) => string);\n icon: string | ((data: any) => any) | any;\n onClick: (rowData: any) => void;\n class?: string | ((data: any) => string);\n isVisible?: (rowData: any) => boolean;\n isDisabled?: (rowData: any) => boolean;\n}\n\nexport interface PageChangeEvent {\n first: number;\n rows: number;\n page: number;\n pageCount: number;\n}\n\nexport interface FilterChangeEvent {\n filters: { [key: string]: any };\n}\n\n/**\n * Shirkasoft UI Components.\n * Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).\n * Belongs to Shirkasoft.\n */\n\n/**\n * Data table with sorting, column filters, global search, pagination,\n * row/header actions, tag cells and optional server-side mode.\n */\n@Component({\n selector: 'shk-table',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n CommonModule,\n ReactiveFormsModule,\n TranslocoModule,\n LucideDynamicIcon,\n TagComponent,\n TooltipComponent,\n ],\n templateUrl: './table.component.html',\n styles: [\n `\n input:focus {\n outline: none;\n }\n input[type='text'] {\n font-weight: normal !important;\n }\n table th {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n table td {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n td button svg {\n width: 1.125rem !important;\n height: 1.125rem !important;\n }\n td button:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n .table-action-btn svg {\n width: 1rem !important;\n height: 1rem !important;\n min-width: 1rem !important;\n min-height: 1rem !important;\n }\n .table-action-btn {\n padding: 0.5rem !important;\n min-width: 2rem !important;\n min-height: 2rem !important;\n display: inline-flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n .table-scroll-wrapper {\n width: 100%;\n overflow-x: auto;\n overflow-y: hidden;\n border-radius: inherit;\n -webkit-overflow-scrolling: touch;\n container-type: inline-size;\n }\n .table-scroll-wrapper table {\n table-layout: fixed;\n width: 100%;\n }\n\n /*\n On wide screens the table behaves as before (auto columns stretching to\n 100% of the container, no horizontal scroll). Only when the real\n container is narrow (container query, not a viewport media query, so it\n also works inside sidebars/panels) columns get a fixed width (see\n getColumnWidth in the TS) so the table's intrinsic width exceeds the\n container and horizontal scrolling actually works, snapping column by\n column. table-layout: auto is used in compact mode because with\n table-layout: fixed the table is forced to the container width and\n cannot overflow (dead scroll).\n */\n @container (max-width: 768px) {\n .table-scroll-wrapper {\n scroll-snap-type: x mandatory;\n }\n .table-scroll-wrapper table {\n table-layout: auto;\n width: 100%;\n }\n .table-scroll-wrapper th:not([data-shk-actions]),\n .table-scroll-wrapper td:not([data-shk-actions]) {\n min-width: var(--shk-col-width, 140px);\n max-width: var(--shk-col-width, 140px);\n }\n .table-scroll-wrapper th,\n .table-scroll-wrapper td {\n scroll-snap-align: start;\n }\n }\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n `,\n ],\n})\nexport class TableComponent {\n private fb = inject(FormBuilder);\n private cdr = inject(ChangeDetectorRef);\n private transloco = inject(TranslocoService);\n private destroyRef = inject(DestroyRef);\n\n/** Maps icon names to lucide components, falling back to a plus icon. */\n protected getIcon = (name: any) => getIconFromCentral(name, LucidePlus);\n\n /**\n * Minimum width applied to each column (except `actions`, which keeps its\n * own computed width) only on narrow screens. On wide screens columns\n * stretch normally to fill the container width. Can be overridden per\n * column via `col.width`.\n */\n protected readonly DEFAULT_COLUMN_WIDTH = '140px';\n\n /** Returns the effective CSS width for a column ('actions' included). */\n getColumnWidth(col: Column): string {\n return col.width || this.DEFAULT_COLUMN_WIDTH;\n }\n\n /** Signal with the translated \"Actions\" header label. */\n private actionsHeaderLabel = toSignal(this.transloco.selectTranslate('common.actions'), {\n initialValue: 'Acciones',\n });\n\n /** Signal reacting to language changes so imperative translations are recomputed. */\n private currentLang = toSignal(this.transloco.langChanges$, {\n initialValue: this.transloco.getActiveLang(),\n });\n\n /** Reactive signal of loaded translations so pageReport is not stuck with raw keys. */\n private translations = toSignal(this.transloco.selectTranslation());\n\n /** Full dataset. In server-side mode only the current page rows. */\n data = input<any[]>([]);\n /** Column definitions (field, header, filterable, tag cell options, etc.). */\n columns = input<Column[]>([]);\n /** Number of rows displayed per page. */\n rowsPerPage = input<number>(10);\n /** Options shown in the rows-per-page selector. */\n rowsPerPageOptions = input<number[]>([10, 25, 50]);\n /** Whether the table is in loading state (shows the overlay/skeleton). */\n loading = input<boolean>(false);\n /** Whether to render the row actions column. */\n showActionRow = input<boolean>(true);\n /** Custom cell/header templates keyed by column field. */\n customTemplates = input<{ [key: string]: any }>({});\n /** Actions rendered in the table header. */\n headerActions = input<TableAction[]>([]);\n /** Actions rendered per row (icon, label, class, visibility/disabled). */\n rowActions = input<RowAction[]>([]);\n /** Whether the table container renders a drop shadow. */\n hasShadow = input<boolean>(true);\n /** Field used as the default initial sort. */\n defaultSortField = input<string>('');\n /** Order used by the default initial sort (1 asc, -1 desc). */\n defaultSortOrder = input<number>(1);\n /** Whether the global search input is shown. */\n showSearch = input<boolean>(true);\n /** Placeholder for the global search input. */\n searchPlaceholder = input<string>('');\n /** Message shown when there are no rows. */\n emptyMessage = input<string>('');\n /** Enables server-side pagination/filtering/sorting mode. */\n serverSide = input<boolean>(false);\n /** Total number of records in server-side mode (for pagination math). */\n totalRecords = input<number>(0);\n /** Optional prebuilt filter chips (label + value) shown above the table. */\n filters = input<{ label: string; value: string }[]>([]);\n /** Currently active filter chip value. */\n activeFilter = input<string>('');\n\n /** Emits when the user clicks the refresh button. */\n refresh = output<void>();\n /** Emits page changes (server-side mode) with first/rows/page info. */\n pageChange = output<PageChangeEvent>();\n /** Emits the active column filters. */\n filterChange = output<FilterChangeEvent>();\n /** Emits the debounced global search term. */\n searchChange = output<string>();\n /** Emits when a filter chip is clicked. */\n filterClick = output<string>();\n\n /** Internal copy of the input data used as the base for search/filter. */\n private originalData = signal<any[]>([]);\n /** Rows after the global search is applied. */\n searchedData = signal<any[]>([]);\n /** Rows after column filters are applied. */\n filteredData = signal<any[]>([]);\n /** Rows belonging to the current page (after slicing). */\n displayedData = signal<any[]>([]);\n /** Local total records after filtering (client mode). */\n localTotalRecords = signal<number>(0);\n /** Index of the first row of the current page. */\n first = signal<number>(0);\n /** Visibility map for each column filter input. */\n showFilterInput = signal<{ [key: string]: boolean }>({});\n /** Current global search term. */\n searchQuery = signal<string>('');\n /** Currently sorted field. */\n sortField = signal<string>('');\n /** Current sort direction (1 asc, -1 desc). */\n sortOrder = signal<number>(1);\n /** Local rows per page, kept in sync with the `rowsPerPage` input. */\n rowsPerPageLocal = linkedSignal(() => this.rowsPerPage());\n\n /** Total number of pages based on the effective record count. */\n totalPages = computed(() =>\n Math.max(1, Math.ceil(this.effectiveTotalRecords() / this.rowsPerPageLocal())),\n );\n /** Current page number (1-based). */\n currentPage = computed(() => Math.floor(this.first() / this.rowsPerPageLocal()) + 1);\n\n /** Reactive form holding the value of each column filter. */\n columnFiltersForm!: FormGroup;\n\n /** Subjects used to debounce column filters (server mode) and search. */\n private filterSubject = new Subject<void>();\n private searchSubject = new Subject<string>();\n\n /**\n * Signature of the last built set of filterable fields (+filter type) to\n * avoid rebuilding the form (and losing user input) on reference changes.\n */\n private lastFilterFieldsSignature = '';\n private columnFilterSubscriptions: Subscription[] = [];\n\n /** Columns array with the leading `actions` column when row actions exist. */\n columnsWithActions = computed<Column[]>(() => {\n const columnsArray = this.columns();\n const showAction = this.showActionRow();\n const rowActionsArray = this.rowActions();\n const translatedHeader = this.actionsHeaderLabel();\n if (showAction && rowActionsArray.length > 0) {\n const actionsWidth =\n rowActionsArray.length <= 2 ? '110px' : rowActionsArray.length <= 3 ? '130px' : '170px';\n return [\n {\n field: 'actions',\n header: translatedHeader || 'Acciones',\n width: actionsWidth,\n defaultSort: true,\n },\n ...columnsArray,\n ];\n }\n return [...columnsArray];\n });\n\n /** Total records: server-provided in server mode, locally computed otherwise. */\n effectiveTotalRecords = computed(() => {\n return this.serverSide() ? this.totalRecords() : this.localTotalRecords();\n });\n /**\n * Rows rendered by the template: the input data in server-side mode or the\n * locally sliced/page current rows otherwise.\n */\n effectiveDisplayedData = computed(() => {\n return this.serverSide() ? this.data() : this.displayedData();\n });\n\n /**\n * Reactive \"X to Y of Z\" report. Depends on loaded translations and the\n * active language so it always reflects the translated template.\n */\n pageReport = computed(() => {\n this.translations(); // forces recomputation when translations finish loading\n this.currentLang(); // forces recomputation when the language changes\n const total = this.effectiveTotalRecords();\n if (total === 0) {\n return this.transloco.translate('table.pageReport', {\n from: 0,\n to: 0,\n total: 0,\n });\n }\n const from = this.first() + 1;\n const to = Math.min(this.first() + this.rowsPerPageLocal(), total);\n return this.transloco.translate('table.pageReport', { from, to, total });\n });\n\n constructor() {\n this.columnFiltersForm = this.fb.group({});\n\n // Debounced column-filter changes (server-side mode only).\n this.filterSubject\n .pipe(debounceTime(300), takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n if (this.serverSide()) {\n this.emitFilterChange();\n }\n });\n\n // Debounced global search changes (server-side mode only).\n this.searchSubject\n .pipe(debounceTime(300), takeUntilDestroyed(this.destroyRef))\n .subscribe((value) => {\n this.searchChange.emit(value);\n });\n\n // When input data changes, refresh the internal copy and re-apply filters\n // unless the server already handles the filtering.\n effect(() => {\n const newData = this.data();\n untracked(() => {\n this.originalData.set([...newData]);\n if (!this.serverSide()) {\n this.applyFilters();\n }\n });\n });\n\n // Rebuild the column filter form whenever the columns change.\n effect(() => {\n const cols = this.columns();\n untracked(() => {\n this.setupColumnFilters(cols);\n });\n });\n\n // Apply the default sort once when the default fields are provided.\n effect(() => {\n const field = this.defaultSortField();\n const order = this.defaultSortOrder();\n if (field) {\n untracked(() => {\n this.sortField.set(field);\n this.sortOrder.set(order);\n if (!this.serverSide()) {\n this.applySort();\n this.updateDisplayedData();\n }\n });\n }\n });\n\n // Apply the global search locally whenever the term changes.\n effect(() => {\n const query = this.searchQuery();\n untracked(() => {\n if (!this.serverSide()) {\n this.applySearch();\n }\n });\n });\n }\n\n /**\n * Builds (or keeps) the reactive form with one control per filterable\n * column. The form is only rebuilt when the set of filterable\n * fields/filter types changes, preserving the values already typed by the\n * user otherwise. Previous subscriptions are unsubscribed to avoid leaks.\n */\n private setupColumnFilters(cols: Column[]) {\n const filterableCols = cols.filter((c) => c.filter);\n const signature = filterableCols.map((c) => `${c.field}:${c.filterType ?? 'text'}`).join('|');\n\n if (signature === this.lastFilterFieldsSignature && this.columnFiltersForm) {\n return;\n }\n this.lastFilterFieldsSignature = signature;\n\n // Clean up previous subscriptions before rebuilding.\n this.columnFilterSubscriptions.forEach((sub) => sub.unsubscribe());\n this.columnFilterSubscriptions = [];\n\n const previousValues: { [key: string]: any } = {};\n if (this.columnFiltersForm) {\n Object.keys(this.columnFiltersForm.controls).forEach((field) => {\n previousValues[field] = this.columnFiltersForm.get(field)?.value;\n });\n }\n\n const filterControls: any = {};\n const filterVisibility: { [key: string]: boolean } = { ...this.showFilterInput() };\n filterableCols.forEach((col) => {\n const defaultValue = col.filterType === 'select' ? null : '';\n const preserved = previousValues.hasOwnProperty(col.field)\n ? previousValues[col.field]\n : defaultValue;\n filterControls[col.field] = [preserved];\n if (!(col.field in filterVisibility)) {\n filterVisibility[col.field] = false;\n }\n });\n\n this.columnFiltersForm = this.fb.group(filterControls);\n this.showFilterInput.set(filterVisibility);\n\n Object.keys(this.columnFiltersForm.controls).forEach((field) => {\n const sub = this.columnFiltersForm\n .get(field)\n ?.valueChanges.pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n this.first.set(0);\n if (this.serverSide()) {\n this.filterSubject.next();\n } else {\n this.applyFilters();\n }\n this.cdr.markForCheck();\n });\n if (sub) {\n this.columnFilterSubscriptions.push(sub);\n }\n });\n }\n\n /** Collects the non-empty column filter values and emits them. */\n private emitFilterChange() {\n const filters: { [key: string]: any } = {};\n Object.keys(this.columnFiltersForm.controls).forEach((field) => {\n const value = this.columnFiltersForm.get(field)?.value;\n if (value !== null && value !== undefined && value !== '') {\n filters[field] = value;\n }\n });\n this.filterChange.emit({ filters });\n }\n\n /** Applies the global search over the original data (client mode). */\n private applySearch() {\n const original = this.originalData();\n const query = this.searchQuery().toLowerCase();\n if (!query) {\n this.searchedData.set([...original]);\n } else {\n const filtered = original.filter((item) => {\n return Object.values(item).some((val) => {\n if (val === null || val === undefined) return false;\n return String(val).toLowerCase().includes(query);\n });\n });\n this.searchedData.set(filtered);\n }\n this.applyColumnFilters();\n }\n\n /** Entry point that applies search (which cascades into column filters). */\n private applyFilters() {\n this.applySearch();\n }\n\n /**\n * Applies every column filter on top of the searched data using each\n * column's `filterType` ('select', 'exact' or text contains).\n */\n private applyColumnFilters() {\n const data = this.searchedData();\n let filtered = [...data];\n this.columns().forEach((col) => {\n if (col.filter) {\n const filterValue = this.columnFiltersForm.get(col.field)?.value;\n if (filterValue !== null && filterValue !== undefined && filterValue !== '') {\n if (col.filterType === 'select') {\n filtered = filtered.filter((item) => item[col.field] == filterValue);\n } else if (col.filterType === 'exact') {\n const searchTerm = String(filterValue).toLowerCase();\n filtered = filtered.filter(\n (item) => String(item[col.field]).toLowerCase() === searchTerm,\n );\n } else {\n const searchTerm = String(filterValue).toLowerCase();\n filtered = filtered.filter((item) =>\n String(item[col.field]).toLowerCase().includes(searchTerm),\n );\n }\n }\n }\n });\n this.filteredData.set(filtered);\n this.localTotalRecords.set(filtered.length);\n this.applySort();\n this.updateDisplayedData();\n }\n\n /** Slices the filtered rows for the current page. */\n private updateDisplayedData() {\n const filtered = this.filteredData();\n const firstIndex = this.first();\n const rows = this.rowsPerPageLocal();\n const displayed = filtered.slice(firstIndex, firstIndex + rows);\n this.displayedData.set(displayed);\n }\n\n /** Emits the filter chip clicked in the template. */\n onFilterClick(value: string) {\n this.filterClick.emit(value);\n }\n\n /** Toggles the sort direction of a column (first click sorts ascending). */\n toggleSort(field: string) {\n if (this.sortField() === field) {\n this.sortOrder.set(this.sortOrder() * -1);\n } else {\n this.sortField.set(field);\n this.sortOrder.set(1);\n }\n this.first.set(0);\n if (!this.serverSide()) {\n this.applySort();\n this.updateDisplayedData();\n }\n }\n\n /**\n * Sorts the filtered rows by the current field. Rows with null/undefined\n * values are always kept at the end regardless of sort direction.\n */\n private applySort() {\n const field = this.sortField();\n const order = this.sortOrder();\n if (!field) return;\n const data = [...this.filteredData()];\n data.sort((a, b) => {\n const va = a[field];\n const vb = b[field];\n if (va == null && vb == null) return 0;\n if (va == null) return 1; // nulls always at the end\n if (vb == null) return -1;\n if (va < vb) return -1 * order;\n if (va > vb) return 1 * order;\n return 0;\n });\n this.filteredData.set(data);\n }\n\n /** Handles the global search input (updates query, resets page, debounces server mode). */\n onSearchInput(value: string) {\n this.searchQuery.set(value);\n this.first.set(0);\n if (this.serverSide()) {\n this.searchSubject.next(value);\n }\n }\n\n /** Clears a column filter value and hides its input. */\n clearFilter(field: string) {\n const column = this.columns().find((col) => col.field === field);\n const value = column?.filterType === 'select' ? null : '';\n this.columnFiltersForm.get(field)?.setValue(value);\n const visibility = this.showFilterInput();\n this.showFilterInput.set({ ...visibility, [field]: false });\n this.cdr.markForCheck();\n }\n\n /** Toggles the visibility of a column filter input. */\n toggleFilter(field: string) {\n const visibility = this.showFilterInput();\n this.showFilterInput.set({ ...visibility, [field]: !visibility[field] });\n this.cdr.markForCheck();\n }\n\n /**\n * Whether a column filter is non-empty. Avoids treating the number 0 as\n * \"no value\".\n */\n hasFilterValue(field: string): boolean {\n const value = this.columnFiltersForm.get(field)?.value;\n return value !== null && value !== undefined && value !== '';\n }\n\n /** Returns the reactive page report string (template helper). */\n getPageReport(): string {\n return this.pageReport();\n }\n\n /** Goes to the first page (emits pageChange in server-side mode). */\n goToFirst() {\n const rows = this.rowsPerPageLocal();\n this.first.set(0);\n if (this.serverSide()) {\n this.pageChange.emit({\n first: 0,\n rows,\n page: 0,\n pageCount: Math.ceil(this.totalRecords() / rows),\n });\n } else {\n this.updateDisplayedData();\n }\n }\n\n /** Goes to the last page (emits pageChange in server-side mode). */\n goToLast() {\n const total = this.serverSide() ? this.totalRecords() : this.filteredData().length;\n const rows = this.rowsPerPageLocal();\n const lastFirst = Math.max(0, Math.ceil(total / rows) * rows - rows);\n this.first.set(lastFirst);\n if (this.serverSide()) {\n const page = Math.floor(lastFirst / rows);\n this.pageChange.emit({\n first: lastFirst,\n rows,\n page,\n pageCount: Math.ceil(total / rows),\n });\n } else {\n this.updateDisplayedData();\n }\n }\n\n /** Updates rows-per-page and resets to the first page. */\n onRowsPerPageChange(rows: number) {\n rows = Number(rows);\n this.rowsPerPageLocal.set(rows);\n this.first.set(0);\n if (this.serverSide()) {\n this.pageChange.emit({\n first: 0,\n rows,\n page: 0,\n pageCount: Math.ceil(this.totalRecords() / rows),\n });\n } else {\n this.updateDisplayedData();\n }\n }\n\n /** Emits the refresh output. */\n refreshData() {\n this.refresh.emit();\n }\n\n /** Whether the current page is the first one. */\n isFirstPage(): boolean {\n return this.first() === 0;\n }\n\n /** Whether the current page is the last one. */\n isLastPage(): boolean {\n const total = this.effectiveTotalRecords();\n return this.first() + this.rowsPerPageLocal() >= total;\n }\n\n /** Moves to the next page (emits pageChange in server-side mode). */\n next() {\n const total = this.serverSide() ? this.totalRecords() : this.filteredData().length;\n const rows = this.rowsPerPageLocal();\n let first = this.first() + rows;\n if (first >= total) {\n first = total - rows;\n }\n this.first.set(first);\n if (this.serverSide()) {\n const page = Math.floor(first / rows);\n this.pageChange.emit({\n first,\n rows,\n page,\n pageCount: Math.ceil(total / rows),\n });\n } else {\n this.updateDisplayedData();\n }\n }\n\n /** Moves to the previous page (emits pageChange in server mode). */\n prev() {\n const rows = this.rowsPerPageLocal();\n let first = this.first() - rows;\n const total = this.serverSide() ? this.totalRecords() : this.filteredData().length;\n if (first < 0) {\n first = 0;\n }\n this.first.set(first);\n if (this.serverSide()) {\n const page = Math.floor(first / rows);\n this.pageChange.emit({\n first,\n rows,\n page,\n pageCount: Math.ceil(total / rows),\n });\n } else {\n this.updateDisplayedData();\n }\n }\n\n /** Resets the table to the first page. */\n reset() {\n this.goToFirst();\n }\n\n /** Resolves the row action label, static or per-row function. */\n getRowActionLabel(action: RowAction, rowData: any): string {\n return typeof action.label === 'function' ? action.label(rowData) : action.label;\n }\n\n /**\n * Resolves the row action icon: a lucide component, a function returning\n * the icon name, or a raw string resolved by the central icon map.\n */\n getRowActionIconName(action: RowAction, rowData: any): any {\n const icon = action.icon;\n if (typeof icon === 'function') {\n if (icon.prototype === undefined) {\n return icon(rowData);\n }\n return icon;\n }\n return icon;\n }\n\n /** Resolves the CSS class of a row action, static or per-row function. */\n getRowActionClass(action: RowAction, rowData: any): string {\n if (!action.class) return '';\n return typeof action.class === 'function' ? action.class(rowData) : action.class;\n }\n\n /** Whether a header action is disabled. */\n isHeaderActionDisabled(action: TableAction): boolean {\n return action.isDisabled ? action.isDisabled() : false;\n }\n\n /** Whether a header action is visible. */\n isHeaderActionVisible(action: TableAction): boolean {\n return action.isVisible ? action.isVisible() : true;\n }\n\n /** Whether a row action is disabled for the given row. */\n isRowActionDisabled(action: RowAction, rowData: any): boolean {\n return action.isDisabled ? action.isDisabled(rowData) : false;\n }\n\n /** Whether a row action is visible for the given row. */\n isRowActionVisible(action: RowAction, rowData: any): boolean {\n return action.isVisible ? action.isVisible(rowData) : true;\n }\n\n /** Truncates a value with an ellipsis past the given character limit. */\n truncate(value: any, limit: number = 30): string {\n if (value === null || value === undefined) return '';\n const str = String(value);\n return str.length > limit ? str.slice(0, limit) + '\\u2026' : str;\n }\n\n /** Resolves the value displayed inside a tag cell, static or per-row function. */\n getTagValue(col: Column, rowData: any): string {\n return col.tagValue ? col.tagValue(rowData) : String(rowData[col.field] ?? '');\n }\n\n /** Resolves and validates the tag severity, falling back to 'secondary'. */\n getTagSeverity(col: Column, rowData: any): TagSeverity {\n const raw = col.tagSeverity ? col.tagSeverity(rowData) : 'secondary';\n const allowed: TagSeverity[] = [\n 'secondary',\n 'success',\n 'info',\n 'warning',\n 'danger',\n 'contrast',\n ];\n return allowed.includes(raw as TagSeverity) ? (raw as TagSeverity) : 'secondary';\n }\n\n /** Resolves whether the tag in a cell is rounded, static or per-row function. */\n getTagRounded(col: Column, rowData: any): boolean {\n if (typeof col.tagRounded === 'function') return col.tagRounded(rowData);\n return col.tagRounded ?? false;\n }\n\n /** Resolves the icon shown inside a tag cell, static or per-row function. */\n getTagIcon(col: Column, rowData: any): string {\n if (typeof col.tagIcon === 'function') return col.tagIcon(rowData);\n return col.tagIcon ?? '';\n }\n\n /** Resolves the CSS styles of a tag cell, static or per-row function. */\n getTagStyle(col: Column, rowData: any): Record<string, string | number> {\n return col.tagStyle ? col.tagStyle(rowData) || {} : {};\n }\n\n /**\n * trackBy for row identity: prefers `id`/`_id` and falls back to the index.\n */\n trackByRow(row: any, index: number): any {\n return row?.id ?? row?._id ?? index;\n }\n\n /** Keyboard support (Enter/Space) for sorting a column header. */\n onHeaderKeydown(event: KeyboardEvent, col: Column) {\n if (col.field === 'actions' || !col.sortable) return;\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.toggleSort(col.field);\n }\n }\n\n /** Accessible aria-sort value for a given column header. */\n getAriaSort(col: Column): 'ascending' | 'descending' | 'none' {\n if (col.field === 'actions' || !col.sortable) return 'none';\n if (this.sortField() !== col.field) return 'none';\n return this.sortOrder() === 1 ? 'ascending' : 'descending';\n }\n}\n","<div class=\"space-y-2 min-[1440px]:space-y-3 mt-2 min-[1440px]:mt-3 animate-fade-in pb-8\">\n @if (showSearch() || filters().length > 0 || headerActions().length > 0) {\n <div class=\"card p-2 min-[1440px]:p-2.5 flex flex-row items-center justify-between gap-2\">\n <div class=\"flex items-center gap-2 min-[1440px]:gap-3 flex-1 min-w-0\">\n @if (showSearch()) {\n <div class=\"relative w-full md:w-52 min-[1440px]:w-56\">\n <label [for]=\"'shk-table-search'\" class=\"sr-only\">{{\n searchPlaceholder() || ('common.search_placeholder' | transloco)\n }}</label>\n <div class=\"absolute inset-y-0 left-0 pl-2.5 flex items-center pointer-events-none\">\n <svg\n [lucideIcon]=\"getIcon('search')\"\n class=\"w-3.5 h-3.5 _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\"\n ></svg>\n </div>\n <input\n id=\"shk-table-search\"\n type=\"text\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($any($event.target).value)\"\n [placeholder]=\"searchPlaceholder() || ('common.search_placeholder' | transloco)\"\n class=\"block w-full pl-8 pr-3 py-1.5 text-xs border _shk-border dark:[border-color:var(--shk-surface-200)] rounded-md leading-5 _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] placeholder:[color:var(--shk-surface-400)] dark:placeholder:[color:var(--shk-surface-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)] focus:outline-none focus:bg-white dark:focus:[background-color:var(--shk-surface-800)] focus:[border-color:var(--shk-primary-500)] focus:ring-1 focus:[--tw-ring-color:var(--shk-primary-500)]\"\n />\n </div>\n }\n @if (filters().length > 0) {\n <div\n class=\"flex _shk-bg-surface-100 dark:[background-color:var(--shk-surface-100)] p-0.5 rounded-md ml-auto\"\n role=\"group\"\n >\n @for (f of filters(); track f.value) {\n <button\n type=\"button\"\n (click)=\"onFilterClick(f.value)\"\n [attr.aria-pressed]=\"f.value === activeFilter()\"\n class=\"px-2.5 min-[1440px]:px-3 py-1 text-xs font-medium rounded _shk-text-surface-700 dark:[color:var(--shk-surface-700)] transition-all\"\n [class]=\"\n f.value === activeFilter()\n ? 'bg-white shadow-sm dark:[background-color:var(--shk-surface-700)]'\n : ''\n \"\n >\n {{ f.label }}\n </button>\n }\n </div>\n }\n </div>\n @if (headerActions().length > 0) {\n <div class=\"flex items-center gap-1.5 shrink-0\">\n @for (action of headerActions(); track $index) {\n @if (isHeaderActionVisible(action)) {\n <button\n type=\"button\"\n [class]=\"\n 'inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md _shk-bg-primary text-white hover:[background-color:var(--shk-primary-700)] transition-colors disabled:opacity-50 disabled:cursor-not-allowed ' +\n (action.class || '')\n \"\n [disabled]=\"isHeaderActionDisabled(action)\"\n [attr.aria-label]=\"action.label\"\n (click)=\"action.onClick()\"\n >\n @if (action.icon) {\n <svg [lucideIcon]=\"getIcon(action.icon)\" class=\"w-3.5 h-3.5\"></svg>\n }\n {{ action.label }}\n </button>\n }\n }\n </div>\n }\n </div>\n }\n <div class=\"card p-0 overflow-hidden\" [class.shadow-lg]=\"hasShadow()\">\n <div class=\"table-scroll-wrapper _shk-scrollbar\">\n <table>\n <thead>\n <tr>\n @for (col of columnsWithActions(); track col.field) {\n <th\n scope=\"col\"\n (click)=\"col.field !== 'actions' && col.sortable && toggleSort(col.field)\"\n (keydown)=\"onHeaderKeydown($event, col)\"\n [tabindex]=\"col.field !== 'actions' && col.sortable ? 0 : -1\"\n [attr.role]=\"col.field !== 'actions' && col.sortable ? 'button' : null\"\n [attr.aria-sort]=\"getAriaSort(col)\"\n [attr.data-shk-actions]=\"col.field === 'actions' ? '' : null\"\n [style.cursor]=\"col.field !== 'actions' && col.sortable ? 'pointer' : 'default'\"\n [style.width]=\"col.field === 'actions' ? col.width : null\"\n [style.min-width]=\"col.field === 'actions' ? col.width : null\"\n [style.--shk-col-width]=\"col.field !== 'actions' ? getColumnWidth(col) : null\"\n class=\"px-2 min-[1440px]:px-3 py-2 min-[1440px]:py-2.5 text-left text-[10px] min-[1440px]:text-xs font-bold _shk-text-surface-500 dark:[color:var(--shk-surface-400)] uppercase tracking-wider _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border-b _shk-border dark:[border-color:var(--shk-surface-200)] focus:outline-none focus-visible:ring-1 focus-visible:[--tw-ring-color:var(--shk-primary-500)]\"\n >\n @if (col.field !== 'actions') {\n <div class=\"flex items-center justify-between gap-2\">\n <span>{{ col.header }}</span>\n <div class=\"flex items-center gap-1\">\n @if (col.sortable) {\n <shk-tooltip [text]=\"'table.tooltips.sort' | transloco\">\n @if (sortField() === col.field) {\n <svg\n [lucideIcon]=\"getIcon(sortOrder() === 1 ? 'arrow-up' : 'arrow-down')\"\n class=\"w-3.5 h-3.5 _shk-text-primary\"\n ></svg>\n } @else {\n <svg\n [lucideIcon]=\"getIcon('arrow-up-down')\"\n class=\"w-3.5 h-3.5 _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\"\n ></svg>\n }\n </shk-tooltip>\n }\n @if (col.filter) {\n <shk-tooltip [text]=\"'table.tooltips.filter' | transloco\">\n <button\n type=\"button\"\n (click)=\"$event.stopPropagation(); toggleFilter(col.field)\"\n [attr.aria-label]=\"'table.tooltips.filter' | transloco\"\n [attr.aria-expanded]=\"showFilterInput()[col.field] || false\"\n class=\"_shk-text-surface-400 dark:[color:var(--shk-surface-500)] hover:[color:var(--shk-surface-600)] dark:hover:[color:var(--shk-surface-300)] transition-colors\"\n >\n <svg\n [lucideIcon]=\"getIcon('filter')\"\n class=\"w-3.5 h-3.5\"\n [class._shk-text-primary]=\"hasFilterValue(col.field)\"\n ></svg>\n </button>\n </shk-tooltip>\n }\n </div>\n </div>\n @if (col.filter && showFilterInput()[col.field]) {\n <div\n class=\"mt-2\"\n [formGroup]=\"columnFiltersForm\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"relative\">\n @if (col.filterType !== 'select') {\n <label [for]=\"'shk-filter-' + col.field\" class=\"sr-only\">{{\n col.filterPlaceholder || ('common.search_placeholder' | transloco)\n }}</label>\n <input\n [id]=\"'shk-filter-' + col.field\"\n type=\"text\"\n [formControlName]=\"col.field\"\n class=\"w-full px-3 py-1.5 text-sm rounded-md border _shk-border dark:[border-color:var(--shk-surface-200)] bg-white dark:[background-color:var(--shk-surface-100)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)] focus:[border-color:var(--shk-primary-500)] focus:ring-1 focus:[--tw-ring-color:var(--shk-primary-500)] placeholder:[color:var(--shk-surface-400)] dark:placeholder:[color:var(--shk-surface-500)]\"\n [placeholder]=\"\n col.filterPlaceholder || ('common.search_placeholder' | transloco)\n \"\n />\n }\n @if (col.filterType === 'select') {\n <label [for]=\"'shk-filter-' + col.field\" class=\"sr-only\">{{\n col.filterPlaceholder || ('common.search_placeholder' | transloco)\n }}</label>\n <select\n [id]=\"'shk-filter-' + col.field\"\n [formControlName]=\"col.field\"\n class=\"w-full px-2 py-1 text-xs rounded-md border _shk-border dark:[border-color:var(--shk-surface-200)] bg-white dark:[background-color:var(--shk-surface-100)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)] focus:[border-color:var(--shk-primary-500)] focus:ring-1 focus:[--tw-ring-color:var(--shk-primary-500)] appearance-none\"\n >\n <option [ngValue]=\"null\">{{ 'table.filterAll' | transloco }}</option>\n @for (opt of col.filterOptions || []; track opt.value) {\n <option [ngValue]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n }\n @if (hasFilterValue(col.field) && col.filterType !== 'select') {\n <button\n type=\"button\"\n class=\"absolute right-2 top-1/2 -translate-y-1/2 _shk-text-surface-400 dark:[color:var(--shk-surface-500)] hover:[color:var(--shk-surface-600)] dark:hover:[color:var(--shk-surface-300)]\"\n (click)=\"clearFilter(col.field)\"\n >\n <svg [lucideIcon]=\"getIcon('x')\" class=\"w-3.5 h-3.5\"></svg>\n </button>\n }\n </div>\n </div>\n }\n } @else {\n <div class=\"flex items-center justify-center\">\n <span>{{ col.header }}</span>\n </div>\n }\n </th>\n }\n </tr>\n </thead>\n @if (loading()) {\n <tbody class=\"border-b _shk-border dark:[border-color:var(--shk-surface-100)]\">\n <tr>\n <td [attr.colspan]=\"columnsWithActions().length\" class=\"text-center py-12\">\n <div\n class=\"flex items-center justify-center\"\n role=\"status\"\n [attr.aria-label]=\"'common.loading' | transloco\"\n >\n <svg\n [lucideIcon]=\"getIcon('loader')\"\n class=\"w-6 h-6 animate-spin _shk-text-primary\"\n ></svg>\n </div>\n </td>\n </tr>\n </tbody>\n } @else if (effectiveDisplayedData().length === 0) {\n <tbody class=\"border-b _shk-border dark:[border-color:var(--shk-surface-100)]\">\n <tr>\n <td [attr.colspan]=\"columnsWithActions().length\" class=\"text-center py-12\">\n <div class=\"flex flex-col items-center\">\n <div\n class=\"w-16 h-16 _shk-bg-surface-100 dark:[background-color:var(--shk-surface-100)] rounded-full flex items-center justify-center mb-4\"\n >\n <svg\n [lucideIcon]=\"getIcon('inbox')\"\n class=\"w-8 h-8 _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\"\n ></svg>\n </div>\n <p\n class=\"text-lg font-semibold _shk-text-surface-600 dark:[color:var(--shk-surface-300)]\"\n >\n {{ emptyMessage() || ('common.no_records' | transloco) }}\n </p>\n </div>\n </td>\n </tr>\n </tbody>\n } @else {\n <tbody>\n @for (rowData of effectiveDisplayedData(); track trackByRow(rowData, $index)) {\n <tr\n class=\"hover:[background-color:color-mix(in srgb,var(--shk-primary-50)30%,transparent)] dark:hover:[background-color:color-mix(in srgb,var(--shk-primary-900)10%,transparent)] transition-colors duration-200 border-b _shk-border dark:[border-color:var(--shk-surface-100)]\"\n >\n @for (col of columnsWithActions(); track col.field) {\n <td\n [attr.data-shk-actions]=\"col.field === 'actions' ? '' : null\"\n class=\"px-2 min-[1440px]:px-3 py-2 min-[1440px]:py-2.5 text-xs font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-700)] whitespace-nowrap\"\n [style.overflow]=\"col.field === 'actions' ? 'visible' : 'hidden'\"\n [style.text-overflow]=\"col.field === 'actions' ? 'clip' : 'ellipsis'\"\n [style.--shk-col-width]=\"col.field !== 'actions' ? getColumnWidth(col) : null\"\n >\n @if (col.field !== 'actions') {\n @if (col.template === 'tag') {\n <shk-tag\n [value]=\"getTagValue(col, rowData)\"\n [severity]=\"getTagSeverity(col, rowData)\"\n [rounded]=\"getTagRounded(col, rowData)\"\n [icon]=\"getTagIcon(col, rowData)\"\n [style]=\"getTagStyle(col, rowData)\"\n />\n } @else if (col.format) {\n <span>{{ col.format(rowData) }}</span>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"\n customTemplates()[col.field] || defaultTemplate;\n context: { $implicit: rowData, field: col.field }\n \"\n ></ng-container>\n }\n } @else {\n <div class=\"flex items-center justify-start gap-px\">\n @for (action of rowActions(); track $index) {\n @if (isRowActionVisible(action, rowData)) {\n <div class=\"relative group\">\n <shk-tooltip\n [text]=\"getRowActionLabel(action, rowData)\"\n position=\"top\"\n >\n <button\n type=\"button\"\n (click)=\"action.onClick(rowData)\"\n [class]=\"\n 'table-action-btn hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] rounded-md ' +\n getRowActionClass(action, rowData)\n \"\n [disabled]=\"isRowActionDisabled(action, rowData) || false\"\n [attr.aria-label]=\"getRowActionLabel(action, rowData)\"\n >\n <svg\n [lucideIcon]=\"getIcon(getRowActionIconName(action, rowData))\"\n class=\"w-4 h-4\"\n ></svg>\n </button>\n </shk-tooltip>\n </div>\n }\n }\n </div>\n }\n </td>\n }\n </tr>\n }\n </tbody>\n }\n </table>\n <ng-template #defaultTemplate let-rowData let-field=\"field\">\n {{ truncate(rowData[field], 30) }}\n </ng-template>\n </div>\n <div\n class=\"flex items-center justify-between gap-4 px-2 min-[1440px]:px-3 py-2 border-t _shk-border dark:[border-color:var(--shk-surface-100)]\"\n >\n <div class=\"text-xs _shk-text-surface-600 dark:[color:var(--shk-surface-400)]\">\n {{ pageReport() }}\n </div>\n <div\n class=\"flex items-center gap-0.5\"\n role=\"navigation\"\n >\n <button\n type=\"button\"\n (click)=\"goToFirst()\"\n [disabled]=\"isFirstPage()\"\n class=\"p-1 _shk-text-surface-500 hover:[color:var(--shk-surface-700)] dark:[color:var(--shk-surface-400)] dark:hover:[color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed rounded transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon('chevrons-left')\" class=\"w-4 h-4\"></svg>\n </button>\n <button\n type=\"button\"\n (click)=\"prev()\"\n [disabled]=\"isFirstPage()\"\n class=\"p-1 _shk-text-surface-500 hover:[color:var(--shk-surface-700)] dark:[color:var(--shk-surface-400)] dark:hover:[color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed rounded transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon('chevron-left')\" class=\"w-4 h-4\"></svg>\n </button>\n <span\n class=\"px-2 text-xs font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\"\n >{{ currentPage() }} / {{ totalPages() }}</span\n >\n <button\n type=\"button\"\n (click)=\"next()\"\n [disabled]=\"isLastPage()\"\n class=\"p-1 _shk-text-surface-500 hover:[color:var(--shk-surface-700)] dark:[color:var(--shk-surface-400)] dark:hover:[color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed rounded transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon('chevron-right')\" class=\"w-4 h-4\"></svg>\n </button>\n <button\n type=\"button\"\n (click)=\"goToLast()\"\n [disabled]=\"isLastPage()\"\n class=\"p-1 _shk-text-surface-500 hover:[color:var(--shk-surface-700)] dark:[color:var(--shk-surface-400)] dark:hover:[color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed rounded transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon('chevrons-right')\" class=\"w-4 h-4\"></svg>\n </button>\n </div>\n <div\n class=\"flex items-center gap-1.5 text-xs _shk-text-surface-600 dark:[color:var(--shk-surface-400)]\"\n >\n <label [for]=\"'shk-rows-per-page'\">{{ 'table.rows' | transloco }}</label>\n <select\n id=\"shk-rows-per-page\"\n [value]=\"rowsPerPageLocal()\"\n (change)=\"onRowsPerPageChange($any($event.target).value)\"\n class=\"border _shk-border dark:[border-color:var(--shk-surface-200)] rounded px-2 py-1 text-xs bg-white dark:[background-color:var(--shk-surface-100)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)] focus:outline-none focus:[border-color:var(--shk-primary-500)]\"\n >\n @for (opt of rowsPerPageOptions(); track opt) {\n <option [value]=\"opt\">{{ opt }}</option>\n }\n </select>\n </div>\n </div>\n </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["getIconFromCentral"],"mappings":"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"}
@@ -0,0 +1,249 @@
1
+ import * as i0 from '@angular/core';
2
+ import { signal, Injectable, model, input, inject, effect, ChangeDetectionStrategy, Component, computed } from '@angular/core';
3
+
4
+ /**
5
+ * Shirkasoft UI Components.
6
+ * Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).
7
+ * Belongs to Shirkasoft.
8
+ */
9
+ /** Shared state between shk-abs and its tab/tabpanel children. */
10
+ class TabsService {
11
+ constructor() {
12
+ /** Currently active tab value. */
13
+ this.active = signal(undefined, ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
14
+ }
15
+ /** Sets the active tab to the given value. */
16
+ select(value) {
17
+ this.active.set(value);
18
+ }
19
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TabsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
20
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TabsService }); }
21
+ }
22
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TabsService, decorators: [{
23
+ type: Injectable
24
+ }] });
25
+
26
+ /**
27
+ * Shirkasoft UI Components.
28
+ * Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).
29
+ * Belongs to Shirkasoft.
30
+ */
31
+ /** Container for tab panels. Renders its projected shk-tablist/shh-tab content. */
32
+ class TabsComponent {
33
+ constructor() {
34
+ /** Currently active tab value. Two-way bindable with [(value)]. */
35
+ this.value = model(undefined, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
36
+ /** Allows the tab header to scroll horizontally when it overflows. */
37
+ this.scrollable = input(false, ...(ngDevMode ? [{ debugName: "scrollable" }] : /* istanbul ignore next */ []));
38
+ /** Shared service used to sync the active tab with the children. */
39
+ this.tabsSvc = inject(TabsService);
40
+ // Push external value changes into the shared service.
41
+ effect(() => {
42
+ this.tabsSvc.active.set(this.value());
43
+ });
44
+ // Reflect child-side selections back into the two-way value.
45
+ effect(() => {
46
+ const active = this.tabsSvc.active();
47
+ if (active !== this.value()) {
48
+ this.value.set(active);
49
+ }
50
+ });
51
+ }
52
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
53
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.18", type: TabsComponent, isStandalone: true, selector: "shk-tabs", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, scrollable: { classPropertyName: "scrollable", publicName: "scrollable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, providers: [TabsService], ngImport: i0, template: `
54
+ <div class="shk-tabs">
55
+ <ng-content></ng-content>
56
+ </div>
57
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
58
+ }
59
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TabsComponent, decorators: [{
60
+ type: Component,
61
+ args: [{
62
+ selector: 'shk-tabs',
63
+ standalone: true,
64
+ changeDetection: ChangeDetectionStrategy.OnPush,
65
+ providers: [TabsService],
66
+ template: `
67
+ <div class="shk-tabs">
68
+ <ng-content></ng-content>
69
+ </div>
70
+ `,
71
+ }]
72
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], scrollable: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollable", required: false }] }] } });
73
+
74
+ /**
75
+ * Shirkasoft UI Components.
76
+ * Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).
77
+ * Belongs to Shirkasoft.
78
+ */
79
+ /** Horizontal bar that contains the shk-tab headers. */
80
+ class TablistComponent {
81
+ constructor() {
82
+ /** Allows the header to scroll horizontally when it overflows. */
83
+ this.scrollable = input(false, ...(ngDevMode ? [{ debugName: "scrollable" }] : /* istanbul ignore next */ []));
84
+ /** Extra CSS classes. */
85
+ this.styleClass = input('', ...(ngDevMode ? [{ debugName: "styleClass" }] : /* istanbul ignore next */ []));
86
+ }
87
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TablistComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
88
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.18", type: TablistComponent, isStandalone: true, selector: "shk-tablist", inputs: { scrollable: { classPropertyName: "scrollable", publicName: "scrollable", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
89
+ <div
90
+ class="shk-tablist"
91
+ [class.shk-tablist-scrollable]="scrollable()"
92
+ [class]="styleClass()"
93
+ role="tablist"
94
+ aria-orientation="horizontal"
95
+ >
96
+ <ng-content></ng-content>
97
+ </div>
98
+ `, isInline: true, styles: [".shk-tablist{display:flex;align-items:center;gap:.25rem;flex-wrap:wrap;border-bottom:1px solid var(--shk-surface-200)}.dark .shk-tablist{border-bottom-color:var(--shk-surface-200)}.shk-tablist-scrollable{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:thin}.shk-tablist-scrollable::-webkit-scrollbar{height:6px}.shk-tablist-scrollable::-webkit-scrollbar-thumb{background:var(--shk-surface-300);border-radius:9999px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
99
+ }
100
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TablistComponent, decorators: [{
101
+ type: Component,
102
+ args: [{ selector: 'shk-tablist', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
103
+ <div
104
+ class="shk-tablist"
105
+ [class.shk-tablist-scrollable]="scrollable()"
106
+ [class]="styleClass()"
107
+ role="tablist"
108
+ aria-orientation="horizontal"
109
+ >
110
+ <ng-content></ng-content>
111
+ </div>
112
+ `, styles: [".shk-tablist{display:flex;align-items:center;gap:.25rem;flex-wrap:wrap;border-bottom:1px solid var(--shk-surface-200)}.dark .shk-tablist{border-bottom-color:var(--shk-surface-200)}.shk-tablist-scrollable{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:thin}.shk-tablist-scrollable::-webkit-scrollbar{height:6px}.shk-tablist-scrollable::-webkit-scrollbar-thumb{background:var(--shk-surface-300);border-radius:9999px}\n"] }]
113
+ }], propDecorators: { scrollable: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollable", required: false }] }], styleClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "styleClass", required: false }] }] } });
114
+
115
+ /**
116
+ * Shirkasoft UI Components.
117
+ * Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).
118
+ * Belongs to Shirkasoft.
119
+ */
120
+ /** A single tab header. Clicking it activates the matching panel. */
121
+ class TabComponent {
122
+ constructor() {
123
+ /** Value that links this tab to its panel. */
124
+ this.value = input(undefined, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
125
+ /** Disables the tab. */
126
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
127
+ /** Extra CSS classes. */
128
+ this.styleClass = input('', ...(ngDevMode ? [{ debugName: "styleClass" }] : /* istanbul ignore next */ []));
129
+ /** Shared service used to read the active tab value. */
130
+ this.tabsSvc = inject(TabsService);
131
+ /** Whether this tab is the active one. */
132
+ this.active = computed(() => this.tabsSvc.active() === this.value(), ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
133
+ }
134
+ /** Activates this tab through the shared service. */
135
+ select() {
136
+ if (this.disabled())
137
+ return;
138
+ this.tabsSvc.select(this.value());
139
+ }
140
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
141
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.18", type: TabComponent, isStandalone: true, selector: "shk-tab", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
142
+ <button
143
+ type="button"
144
+ class="shk-tab"
145
+ [class]="styleClass()"
146
+ [class.shk-tab-active]="active()"
147
+ [class.shk-tab-disabled]="disabled()"
148
+ role="tab"
149
+ [attr.aria-selected]="active()"
150
+ [disabled]="disabled()"
151
+ (click)="select()"
152
+ >
153
+ <ng-content></ng-content>
154
+ </button>
155
+ `, isInline: true, styles: [".shk-tab{display:inline-flex;align-items:center;gap:.375rem;padding:.625rem 1rem;font-size:.875rem;font-weight:500;color:var(--shk-surface-500);background:transparent;border:none;border-bottom:2px solid transparent;margin-bottom:-1px;cursor:pointer;white-space:nowrap;transition:color .15s ease-in-out,border-color .15s ease-in-out,background-color .15s ease-in-out}.shk-tab:hover:not(:disabled):not(.shk-tab-active){color:var(--shk-surface-800)}.shk-tab-active{color:var(--shk-primary-600);border-bottom-color:var(--shk-primary-600);font-weight:600}.dark .shk-tab-active{color:var(--shk-primary-400);border-bottom-color:var(--shk-primary-400)}.shk-tab:disabled{opacity:.5;cursor:not-allowed}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
156
+ }
157
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TabComponent, decorators: [{
158
+ type: Component,
159
+ args: [{ selector: 'shk-tab', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
160
+ <button
161
+ type="button"
162
+ class="shk-tab"
163
+ [class]="styleClass()"
164
+ [class.shk-tab-active]="active()"
165
+ [class.shk-tab-disabled]="disabled()"
166
+ role="tab"
167
+ [attr.aria-selected]="active()"
168
+ [disabled]="disabled()"
169
+ (click)="select()"
170
+ >
171
+ <ng-content></ng-content>
172
+ </button>
173
+ `, styles: [".shk-tab{display:inline-flex;align-items:center;gap:.375rem;padding:.625rem 1rem;font-size:.875rem;font-weight:500;color:var(--shk-surface-500);background:transparent;border:none;border-bottom:2px solid transparent;margin-bottom:-1px;cursor:pointer;white-space:nowrap;transition:color .15s ease-in-out,border-color .15s ease-in-out,background-color .15s ease-in-out}.shk-tab:hover:not(:disabled):not(.shk-tab-active){color:var(--shk-surface-800)}.shk-tab-active{color:var(--shk-primary-600);border-bottom-color:var(--shk-primary-600);font-weight:600}.dark .shk-tab-active{color:var(--shk-primary-400);border-bottom-color:var(--shk-primary-400)}.shk-tab:disabled{opacity:.5;cursor:not-allowed}\n"] }]
174
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], styleClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "styleClass", required: false }] }] } });
175
+
176
+ /**
177
+ * Shirkasoft UI Components.
178
+ * Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).
179
+ * Belongs to Shirkasoft.
180
+ */
181
+ /** Container that groups the shk-tabpanel content sections. */
182
+ class TabpanelsComponent {
183
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TabpanelsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
184
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.18", type: TabpanelsComponent, isStandalone: true, selector: "shk-tabpanels", ngImport: i0, template: `
185
+ <div class="shk-tabpanels">
186
+ <ng-content></ng-content>
187
+ </div>
188
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
189
+ }
190
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TabpanelsComponent, decorators: [{
191
+ type: Component,
192
+ args: [{
193
+ selector: 'shk-tabpanels',
194
+ standalone: true,
195
+ changeDetection: ChangeDetectionStrategy.OnPush,
196
+ template: `
197
+ <div class="shk-tabpanels">
198
+ <ng-content></ng-content>
199
+ </div>
200
+ `,
201
+ }]
202
+ }] });
203
+
204
+ /**
205
+ * Shirkasoft UI Components.
206
+ * Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).
207
+ * Belongs to Shirkasoft.
208
+ */
209
+ /** Content section shown only while its value is the active tab. */
210
+ class TabPanelComponent {
211
+ constructor() {
212
+ /** Value that links this panel to its tab. */
213
+ this.value = input(undefined, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
214
+ /** Shared service used to read the active tab value. */
215
+ this.tabsSvc = inject(TabsService);
216
+ /** Whether this panel is the active one. */
217
+ this.active = computed(() => this.tabsSvc.active() === this.value(), ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
218
+ }
219
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TabPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
220
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: TabPanelComponent, isStandalone: true, selector: "shk-tabpanel", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
221
+ @if (active()) {
222
+ <div class="shk-tabpanel" role="tabpanel">
223
+ <ng-content></ng-content>
224
+ </div>
225
+ }
226
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
227
+ }
228
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TabPanelComponent, decorators: [{
229
+ type: Component,
230
+ args: [{
231
+ selector: 'shk-tabpanel',
232
+ standalone: true,
233
+ changeDetection: ChangeDetectionStrategy.OnPush,
234
+ template: `
235
+ @if (active()) {
236
+ <div class="shk-tabpanel" role="tabpanel">
237
+ <ng-content></ng-content>
238
+ </div>
239
+ }
240
+ `,
241
+ }]
242
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }] } });
243
+
244
+ /**
245
+ * Generated bundle index. Do not edit.
246
+ */
247
+
248
+ export { TabComponent, TabPanelComponent, TablistComponent, TabpanelsComponent, TabsComponent, TabsService };
249
+ //# sourceMappingURL=shirkasoft-ui-components-tabs.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shirkasoft-ui-components-tabs.mjs","sources":["../../../projects/ui-components/tabs/tabs.service.ts","../../../projects/ui-components/tabs/tabs.component.ts","../../../projects/ui-components/tabs/tablist.component.ts","../../../projects/ui-components/tabs/tab.component.ts","../../../projects/ui-components/tabs/tabpanels.component.ts","../../../projects/ui-components/tabs/tabpanel.component.ts","../../../projects/ui-components/tabs/shirkasoft-ui-components-tabs.ts"],"sourcesContent":["import { Injectable, signal } from '@angular/core';\n\n/**\n * Shirkasoft UI Components.\n * Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).\n * Belongs to Shirkasoft.\n */\n\n/** Shared state between shk-abs and its tab/tabpanel children. */\n@Injectable()\nexport class TabsService {\n /** Currently active tab value. */\n readonly active = signal<any>(undefined);\n\n /** Sets the active tab to the given value. */\n select(value: any): void {\n this.active.set(value);\n }\n}\n","import { Component, effect, inject, model, input, ChangeDetectionStrategy } from '@angular/core';\nimport { TabsService } from './tabs.service';\n\n/**\n * Shirkasoft UI Components.\n * Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).\n * Belongs to Shirkasoft.\n */\n\n/** Container for tab panels. Renders its projected shk-tablist/shh-tab content. */\n@Component({\n selector: 'shk-tabs',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [TabsService],\n template: `\n <div class=\"shk-tabs\">\n <ng-content></ng-content>\n </div>\n `,\n})\nexport class TabsComponent {\n /** Currently active tab value. Two-way bindable with [(value)]. */\n value = model<any>(undefined);\n /** Allows the tab header to scroll horizontally when it overflows. */\n scrollable = input<boolean>(false);\n\n /** Shared service used to sync the active tab with the children. */\n protected tabsSvc = inject(TabsService);\n\n constructor() {\n // Push external value changes into the shared service.\n effect(() => {\n this.tabsSvc.active.set(this.value());\n });\n // Reflect child-side selections back into the two-way value.\n effect(() => {\n const active = this.tabsSvc.active();\n if (active !== this.value()) {\n this.value.set(active);\n }\n });\n }\n}\n","import { Component, input, ChangeDetectionStrategy } from '@angular/core';\n\n/**\n * Shirkasoft UI Components.\n * Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).\n * Belongs to Shirkasoft.\n */\n\n/** Horizontal bar that contains the shk-tab headers. */\n@Component({\n selector: 'shk-tablist',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div\n class=\"shk-tablist\"\n [class.shk-tablist-scrollable]=\"scrollable()\"\n [class]=\"styleClass()\"\n role=\"tablist\"\n aria-orientation=\"horizontal\"\n >\n <ng-content></ng-content>\n </div>\n `,\n styles: [\n `\n .shk-tablist {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n flex-wrap: wrap;\n border-bottom: 1px solid var(--shk-surface-200);\n }\n .dark .shk-tablist {\n border-bottom-color: var(--shk-surface-200);\n }\n .shk-tablist-scrollable {\n flex-wrap: nowrap;\n overflow-x: auto;\n scrollbar-width: thin;\n }\n .shk-tablist-scrollable::-webkit-scrollbar {\n height: 6px;\n }\n .shk-tablist-scrollable::-webkit-scrollbar-thumb {\n background: var(--shk-surface-300);\n border-radius: 9999px;\n }\n `,\n ],\n})\nexport class TablistComponent {\n /** Allows the header to scroll horizontally when it overflows. */\n scrollable = input<boolean>(false);\n /** Extra CSS classes. */\n styleClass = input<string>('');\n}\n","import { Component, computed, inject, input, ChangeDetectionStrategy } from '@angular/core';\nimport { TabsService } from './tabs.service';\n\n/**\n * Shirkasoft UI Components.\n * Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).\n * Belongs to Shirkasoft.\n */\n\n/** A single tab header. Clicking it activates the matching panel. */\n@Component({\n selector: 'shk-tab',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <button\n type=\"button\"\n class=\"shk-tab\"\n [class]=\"styleClass()\"\n [class.shk-tab-active]=\"active()\"\n [class.shk-tab-disabled]=\"disabled()\"\n role=\"tab\"\n [attr.aria-selected]=\"active()\"\n [disabled]=\"disabled()\"\n (click)=\"select()\"\n >\n <ng-content></ng-content>\n </button>\n `,\n styles: [\n `\n .shk-tab {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.625rem 1rem;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--shk-surface-500);\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n margin-bottom: -1px;\n cursor: pointer;\n white-space: nowrap;\n transition:\n color 0.15s ease-in-out,\n border-color 0.15s ease-in-out,\n background-color 0.15s ease-in-out;\n }\n .shk-tab:hover:not(:disabled):not(.shk-tab-active) {\n color: var(--shk-surface-800);\n }\n .shk-tab-active {\n color: var(--shk-primary-600);\n border-bottom-color: var(--shk-primary-600);\n font-weight: 600;\n }\n .dark .shk-tab-active {\n color: var(--shk-primary-400);\n border-bottom-color: var(--shk-primary-400);\n }\n .shk-tab:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n `,\n ],\n})\nexport class TabComponent {\n /** Value that links this tab to its panel. */\n value = input<any>(undefined);\n /** Disables the tab. */\n disabled = input<boolean>(false);\n /** Extra CSS classes. */\n styleClass = input<string>('');\n\n /** Shared service used to read the active tab value. */\n protected tabsSvc = inject(TabsService);\n /** Whether this tab is the active one. */\n protected active = computed(() => this.tabsSvc.active() === this.value());\n\n /** Activates this tab through the shared service. */\n select(): void {\n if (this.disabled()) return;\n this.tabsSvc.select(this.value());\n }\n}\n","import { Component, ChangeDetectionStrategy } from '@angular/core';\n\n/**\n * Shirkasoft UI Components.\n * Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).\n * Belongs to Shirkasoft.\n */\n\n/** Container that groups the shk-tabpanel content sections. */\n@Component({\n selector: 'shk-tabpanels',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"shk-tabpanels\">\n <ng-content></ng-content>\n </div>\n `,\n})\nexport class TabpanelsComponent {}\n","import { Component, computed, inject, input, ChangeDetectionStrategy } from '@angular/core';\nimport { TabsService } from './tabs.service';\n\n/**\n * Shirkasoft UI Components.\n * Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).\n * Belongs to Shirkasoft.\n */\n\n/** Content section shown only while its value is the active tab. */\n@Component({\n selector: 'shk-tabpanel',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (active()) {\n <div class=\"shk-tabpanel\" role=\"tabpanel\">\n <ng-content></ng-content>\n </div>\n }\n `,\n})\nexport class TabPanelComponent {\n /** Value that links this panel to its tab. */\n value = input<any>(undefined);\n\n /** Shared service used to read the active tab value. */\n protected tabsSvc = inject(TabsService);\n /** Whether this panel is the active one. */\n protected active = computed(() => this.tabsSvc.active() === this.value());\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, computed, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { LucideDynamicIcon } from '@lucide/angular';
4
+ import { getIcon } from 'shirkasoft-ui-components/utils';
5
+
6
+ const SEVERITY_CLASS = {
7
+ secondary: '_shk-tag-secondary',
8
+ success: '_shk-tag-success',
9
+ info: '_shk-tag-info',
10
+ warning: '_shk-tag-warn',
11
+ danger: '_shk-tag-danger',
12
+ contrast: '_shk-tag-contrast',
13
+ };
14
+ /** Small label used to highlight a value, status or category. */
15
+ class TagComponent {
16
+ constructor() {
17
+ /** Text shown inside the tag. */
18
+ this.value = input('', ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
19
+ /** Color variant. Defaults to 'secondary'. */
20
+ this.severity = input('secondary', ...(ngDevMode ? [{ debugName: "severity" }] : /* istanbul ignore next */ []));
21
+ /** Renders the tag with fully rounded corners (pill). */
22
+ this.rounded = input(false, ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
23
+ /** Optional leading lucide icon name or component. */
24
+ this.icon = input('', ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
25
+ /** Inline styles applied to the tag. */
26
+ this.style = input({}, ...(ngDevMode ? [{ debugName: "style" }] : /* istanbul ignore next */ []));
27
+ /** Extra CSS classes. */
28
+ this.styleClass = input('', ...(ngDevMode ? [{ debugName: "styleClass" }] : /* istanbul ignore next */ []));
29
+ this.getIcon = getIcon;
30
+ this.tagClass = computed(() => {
31
+ const base = 'inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium';
32
+ const severity = SEVERITY_CLASS[this.severity()] ?? SEVERITY_CLASS.secondary;
33
+ const radius = this.rounded() ? 'rounded-full' : 'rounded-md';
34
+ return `${base} ${radius} ${severity} ${this.styleClass()}`.trim();
35
+ }, ...(ngDevMode ? [{ debugName: "tagClass" }] : /* istanbul ignore next */ []));
36
+ }
37
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TagComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
38
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: TagComponent, isStandalone: true, selector: "shk-tag", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, severity: { classPropertyName: "severity", publicName: "severity", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
39
+ <span [class]="tagClass()" [style]="style()">
40
+ @if (icon()) {
41
+ <svg [lucideIcon]="getIcon(icon())" class="shk-tag-icon"></svg>
42
+ }
43
+ @if (value() !== undefined && value() !== null) {
44
+ <span>{{ value() }}</span>
45
+ }
46
+ <ng-content></ng-content>
47
+ </span>
48
+ `, isInline: true, styles: [".shk-tag-icon{width:.875rem;height:.875rem;flex-shrink:0}\n"], dependencies: [{ kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
49
+ }
50
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: TagComponent, decorators: [{
51
+ type: Component,
52
+ args: [{ selector: 'shk-tag', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [LucideDynamicIcon], template: `
53
+ <span [class]="tagClass()" [style]="style()">
54
+ @if (icon()) {
55
+ <svg [lucideIcon]="getIcon(icon())" class="shk-tag-icon"></svg>
56
+ }
57
+ @if (value() !== undefined && value() !== null) {
58
+ <span>{{ value() }}</span>
59
+ }
60
+ <ng-content></ng-content>
61
+ </span>
62
+ `, styles: [".shk-tag-icon{width:.875rem;height:.875rem;flex-shrink:0}\n"] }]
63
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], severity: [{ type: i0.Input, args: [{ isSignal: true, alias: "severity", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], style: [{ type: i0.Input, args: [{ isSignal: true, alias: "style", required: false }] }], styleClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "styleClass", required: false }] }] } });
64
+
65
+ /**
66
+ * Generated bundle index. Do not edit.
67
+ */
68
+
69
+ export { TagComponent };
70
+ //# sourceMappingURL=shirkasoft-ui-components-tag.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shirkasoft-ui-components-tag.mjs","sources":["../../../projects/ui-components/tag/tag.component.ts","../../../projects/ui-components/tag/shirkasoft-ui-components-tag.ts"],"sourcesContent":["import { Component, computed, input, ChangeDetectionStrategy } from '@angular/core';\nimport { LucideDynamicIcon } from '@lucide/angular';\nimport { getIcon } from 'shirkasoft-ui-components/utils';\n\n/**\n * Shirkasoft UI Components.\n * Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).\n * Belongs to Shirkasoft.\n */\n\nexport type TagSeverity = 'secondary' | 'success' | 'info' | 'warning' | 'danger' | 'contrast';\n\nconst SEVERITY_CLASS: Record<TagSeverity, string> = {\n secondary: '_shk-tag-secondary',\n success: '_shk-tag-success',\n info: '_shk-tag-info',\n warning: '_shk-tag-warn',\n danger: '_shk-tag-danger',\n contrast: '_shk-tag-contrast',\n};\n\n/** Small label used to highlight a value, status or category. */\n@Component({\n selector: 'shk-tag',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [LucideDynamicIcon],\n template: `\n <span [class]=\"tagClass()\" [style]=\"style()\">\n @if (icon()) {\n <svg [lucideIcon]=\"getIcon(icon())\" class=\"shk-tag-icon\"></svg>\n }\n @if (value() !== undefined && value() !== null) {\n <span>{{ value() }}</span>\n }\n <ng-content></ng-content>\n </span>\n `,\n styles: [\n `\n .shk-tag-icon {\n width: 0.875rem;\n height: 0.875rem;\n flex-shrink: 0;\n }\n `,\n ],\n})\nexport class TagComponent {\n /** Text shown inside the tag. */\n value = input<string | number>('');\n /** Color variant. Defaults to 'secondary'. */\n severity = input<TagSeverity>('secondary');\n /** Renders the tag with fully rounded corners (pill). */\n rounded = input<boolean>(false);\n /** Optional leading lucide icon name or component. */\n icon = input<string | any>('');\n /** Inline styles applied to the tag. */\n style = input<Record<string, string | number>>({});\n /** Extra CSS classes. */\n styleClass = input<string>('');\n\n protected getIcon = getIcon;\n\n protected tagClass = computed(() => {\n const base = 'inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium';\n const severity = SEVERITY_CLASS[this.severity()] ?? SEVERITY_CLASS.secondary;\n const radius = this.rounded() ? 'rounded-full' : 'rounded-md';\n return `${base} ${radius} ${severity} ${this.styleClass()}`.trim();\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}