@lesterarte/sefin-ui 0.0.20-dev.13 → 0.0.20-dev.15

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.
@@ -5382,6 +5382,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
5382
5382
  * Molecules index
5383
5383
  */
5384
5384
 
5385
+ /**
5386
+ * SVG icon paths for sort indicators
5387
+ */
5388
+ const SORT_ICONS = {
5389
+ unsorted: 'M3 4.5L6 1.5L9 4.5M3 7.5L6 10.5L9 7.5',
5390
+ ascending: 'M3 7.5L6 4.5L9 7.5',
5391
+ descending: 'M3 4.5L6 7.5L9 4.5',
5392
+ };
5385
5393
  /**
5386
5394
  * Helper function to build displayed columns array including selection and actions
5387
5395
  */
@@ -5451,6 +5459,7 @@ class TableComponent {
5451
5459
  currentPageSize = signal(this.pageSize, ...(ngDevMode ? [{ debugName: "currentPageSize" }] : []));
5452
5460
  // Computed sorted and paginated data
5453
5461
  sortedData = computed(() => {
5462
+ // Early returns for performance
5454
5463
  if (!this.sort || !this.currentSortColumn() || this.serverSide) {
5455
5464
  return this.data;
5456
5465
  }
@@ -5462,22 +5471,43 @@ class TableComponent {
5462
5471
  if (!direction) {
5463
5472
  return this.data;
5464
5473
  }
5474
+ // Early return if no data to sort
5475
+ if (!this.data || this.data.length === 0) {
5476
+ return this.data;
5477
+ }
5478
+ // Create a copy to avoid mutating original data
5465
5479
  const sorted = [...this.data].sort((a, b) => {
5466
5480
  const aValue = this.getCellValue(a, column);
5467
5481
  const bValue = this.getCellValue(b, column);
5482
+ // Handle null/undefined values - place them at the end
5483
+ if (aValue === null || aValue === undefined) {
5484
+ return 1;
5485
+ }
5486
+ if (bValue === null || bValue === undefined) {
5487
+ return -1;
5488
+ }
5468
5489
  let comparison = 0;
5469
5490
  if (column.type === 'number') {
5470
- comparison = (aValue || 0) - (bValue || 0);
5491
+ const aNum = typeof aValue === 'number' ? aValue : Number(aValue);
5492
+ const bNum = typeof bValue === 'number' ? bValue : Number(bValue);
5493
+ comparison = (isNaN(aNum) ? 0 : aNum) - (isNaN(bNum) ? 0 : bNum);
5471
5494
  }
5472
5495
  else if (column.type === 'date') {
5473
5496
  const aDate = this.parseDate(aValue);
5474
5497
  const bDate = this.parseDate(bValue);
5475
- comparison = aDate.getTime() - bDate.getTime();
5498
+ // Handle invalid dates
5499
+ const aTime = isNaN(aDate.getTime()) ? 0 : aDate.getTime();
5500
+ const bTime = isNaN(bDate.getTime()) ? 0 : bDate.getTime();
5501
+ comparison = aTime - bTime;
5476
5502
  }
5477
5503
  else {
5478
- const aStr = String(aValue || '').toLowerCase();
5479
- const bStr = String(bValue || '').toLowerCase();
5480
- comparison = aStr.localeCompare(bStr);
5504
+ // Use locale-aware string comparison for better internationalization
5505
+ const aStr = String(aValue || '').trim();
5506
+ const bStr = String(bValue || '').trim();
5507
+ comparison = aStr.localeCompare(bStr, undefined, {
5508
+ sensitivity: 'base',
5509
+ numeric: true,
5510
+ });
5481
5511
  }
5482
5512
  return direction === 'asc' ? comparison : -comparison;
5483
5513
  });
@@ -5492,6 +5522,7 @@ class TableComponent {
5492
5522
  return this.sortedData().slice(startIndex, endIndex);
5493
5523
  }, ...(ngDevMode ? [{ debugName: "paginatedData" }] : []));
5494
5524
  displayedData = computed(() => {
5525
+ // Directly return paginated data (no need for intermediate computation)
5495
5526
  return this.paginatedData();
5496
5527
  }, ...(ngDevMode ? [{ debugName: "displayedData" }] : []));
5497
5528
  totalPages = computed(() => {
@@ -5516,76 +5547,180 @@ class TableComponent {
5516
5547
  return false;
5517
5548
  }
5518
5549
  const currentPageData = this.displayedData();
5550
+ if (currentPageData.length === 0) {
5551
+ return false;
5552
+ }
5519
5553
  const currentPageIds = new Set(currentPageData.map((row) => this.getItemId(row)));
5520
- const selectedInPage = this.selectedItems().filter((item) => currentPageIds.has(this.getItemId(item)));
5521
- return (currentPageData.length > 0 &&
5522
- selectedInPage.length === currentPageData.length);
5554
+ const selectedItems = this.selectedItems();
5555
+ const selectedInPage = selectedItems.filter((item) => currentPageIds.has(this.getItemId(item)));
5556
+ return selectedInPage.length === currentPageData.length;
5523
5557
  }, ...(ngDevMode ? [{ debugName: "isAllSelected" }] : []));
5524
5558
  isIndeterminate = computed(() => {
5525
5559
  if (!this.selectable || this.selectionMode === 'single') {
5526
5560
  return false;
5527
5561
  }
5528
5562
  const currentPageData = this.displayedData();
5563
+ if (currentPageData.length === 0) {
5564
+ return false;
5565
+ }
5529
5566
  const currentPageIds = new Set(currentPageData.map((row) => this.getItemId(row)));
5530
- const selectedInPage = this.selectedItems().filter((item) => currentPageIds.has(this.getItemId(item)));
5567
+ const selectedItems = this.selectedItems();
5568
+ const selectedInPage = selectedItems.filter((item) => currentPageIds.has(this.getItemId(item)));
5531
5569
  return (selectedInPage.length > 0 &&
5532
5570
  selectedInPage.length < currentPageData.length);
5533
5571
  }, ...(ngDevMode ? [{ debugName: "isIndeterminate" }] : []));
5572
+ // Expose sort icons to template
5573
+ sortIcons = SORT_ICONS;
5534
5574
  constructor(cdr) {
5535
5575
  this.cdr = cdr;
5536
5576
  }
5537
5577
  ngOnInit() {
5538
5578
  this.currentPageSize.set(this.pageSize);
5579
+ this.validateInputs();
5539
5580
  }
5540
5581
  ngOnChanges(changes) {
5541
5582
  if (changes['pageSize']) {
5542
- this.currentPageSize.set(this.pageSize);
5583
+ const newPageSize = changes['pageSize'].currentValue;
5584
+ if (newPageSize && newPageSize > 0) {
5585
+ this.currentPageSize.set(newPageSize);
5586
+ }
5543
5587
  }
5544
5588
  if (changes['data'] && this.serverSide) {
5545
5589
  this.cdr.markForCheck();
5546
5590
  }
5591
+ if (changes['columns'] || changes['data']) {
5592
+ this.validateInputs();
5593
+ }
5594
+ }
5595
+ /**
5596
+ * Validates component inputs and logs warnings for invalid configurations
5597
+ * @private
5598
+ */
5599
+ validateInputs() {
5600
+ if (this.columns && this.columns.length > 0) {
5601
+ // Check for duplicate column keys
5602
+ const keys = this.columns.map((col) => col.key);
5603
+ const duplicates = keys.filter((key, index) => keys.indexOf(key) !== index);
5604
+ if (duplicates.length > 0) {
5605
+ console.warn(`[sefin-table] Duplicate column keys detected: ${duplicates.join(', ')}`);
5606
+ }
5607
+ // Check for columns with sortable=true but sort=false
5608
+ const sortableColumns = this.columns.filter((col) => col.sortable);
5609
+ if (sortableColumns.length > 0 && !this.sort) {
5610
+ console.warn(`[sefin-table] Columns with sortable=true found but sort input is false. Sorting will be disabled.`);
5611
+ }
5612
+ }
5613
+ if (this.selectable && this.selectionMode === 'multiple' && !this.trackByKey) {
5614
+ console.warn(`[sefin-table] selectable is true but trackByKey is not set. Row selection may not work correctly.`);
5615
+ }
5616
+ if (this.pagination && this.pageSize <= 0) {
5617
+ console.warn(`[sefin-table] pagination is enabled but pageSize is ${this.pageSize}. Using default value of 10.`);
5618
+ }
5547
5619
  }
5548
5620
  trackByFn(index, item) {
5549
5621
  return item[this.trackByKey] !== undefined ? item[this.trackByKey] : index;
5550
5622
  }
5623
+ /**
5624
+ * Gets the cell value from a row, supporting nested property paths (e.g., 'user.name')
5625
+ * @param row - The row data object
5626
+ * @param column - The column definition
5627
+ * @returns The cell value or undefined if not found
5628
+ */
5551
5629
  getCellValue(row, column) {
5552
- return row[column.key];
5630
+ if (!row || !column?.key) {
5631
+ return undefined;
5632
+ }
5633
+ // Support nested property paths (e.g., 'user.name' or 'address.street')
5634
+ const keys = column.key.split('.');
5635
+ let value = row;
5636
+ for (const key of keys) {
5637
+ if (value === null || value === undefined) {
5638
+ return undefined;
5639
+ }
5640
+ value = value[key];
5641
+ }
5642
+ return value;
5553
5643
  }
5554
- formatCellValue(value, type) {
5644
+ /**
5645
+ * Formats a cell value based on its type
5646
+ * @param value - The value to format
5647
+ * @param type - The column type
5648
+ * @param column - Optional column definition for additional formatting options
5649
+ * @returns Formatted string representation
5650
+ */
5651
+ formatCellValue(value, type, column) {
5555
5652
  if (value === null || value === undefined) {
5556
5653
  return '';
5557
5654
  }
5558
5655
  if (type === 'number') {
5559
- return typeof value === 'number' ? value.toLocaleString() : String(value);
5656
+ if (typeof value === 'number') {
5657
+ // Use locale-aware number formatting
5658
+ return value.toLocaleString(undefined, {
5659
+ minimumFractionDigits: 0,
5660
+ maximumFractionDigits: 2,
5661
+ });
5662
+ }
5663
+ // Try to parse string numbers
5664
+ const numValue = Number(value);
5665
+ return !isNaN(numValue) ? numValue.toLocaleString() : String(value);
5560
5666
  }
5561
5667
  if (type === 'date') {
5562
- if (value instanceof Date) {
5563
- return value.toLocaleDateString();
5564
- }
5565
- if (typeof value === 'string') {
5566
- const date = this.parseDate(value);
5567
- if (!isNaN(date.getTime())) {
5568
- return date.toLocaleDateString();
5569
- }
5668
+ const date = this.parseDate(value);
5669
+ if (!isNaN(date.getTime())) {
5670
+ // Use locale-aware date formatting
5671
+ return date.toLocaleDateString(undefined, {
5672
+ year: 'numeric',
5673
+ month: 'short',
5674
+ day: 'numeric',
5675
+ });
5570
5676
  }
5677
+ // If date parsing fails, return original value as string
5678
+ return String(value);
5571
5679
  }
5572
5680
  return String(value);
5573
5681
  }
5682
+ /**
5683
+ * Parses a value into a Date object
5684
+ * @param value - The value to parse (Date, string, or number timestamp)
5685
+ * @returns A Date object
5686
+ */
5574
5687
  parseDate(value) {
5575
5688
  if (value instanceof Date) {
5576
5689
  return value;
5577
5690
  }
5578
5691
  if (typeof value === 'string') {
5692
+ const date = new Date(value);
5693
+ // Check if it's a valid date
5694
+ if (!isNaN(date.getTime())) {
5695
+ return date;
5696
+ }
5697
+ }
5698
+ if (typeof value === 'number') {
5699
+ // Assume it's a timestamp
5579
5700
  return new Date(value);
5580
5701
  }
5581
- return new Date();
5702
+ // Return invalid date as fallback
5703
+ return new Date(NaN);
5582
5704
  }
5583
5705
  onRowClick(row) {
5584
5706
  if (!this.loading) {
5585
5707
  this.rowClicked.emit(row);
5586
5708
  }
5587
5709
  }
5588
- onSort(column) {
5710
+ /**
5711
+ * Handles column sorting when header is clicked
5712
+ * @param column - The column to sort by
5713
+ * @param event - Optional keyboard event for accessibility
5714
+ */
5715
+ onSort(column, event) {
5716
+ // Handle keyboard events (Enter or Space)
5717
+ if (event && event.key !== 'Enter' && event.key !== ' ') {
5718
+ return;
5719
+ }
5720
+ if (event) {
5721
+ event.preventDefault();
5722
+ event.stopPropagation();
5723
+ }
5589
5724
  if (!this.sort || !column.sortable || this.loading) {
5590
5725
  return;
5591
5726
  }
@@ -5630,57 +5765,91 @@ class TableComponent {
5630
5765
  isSelected(row) {
5631
5766
  return this.selectedItems().some((item) => this.getItemId(item) === this.getItemId(row));
5632
5767
  }
5768
+ /**
5769
+ * Toggles the selection state of a row
5770
+ * @param checked - Whether the row should be selected
5771
+ * @param row - The row to toggle selection for
5772
+ */
5633
5773
  toggleRowSelection(checked, row) {
5634
5774
  if (row === undefined) {
5635
5775
  return;
5636
5776
  }
5637
5777
  if (this.selectionMode === 'single') {
5638
- if (checked) {
5639
- this.selectedItems.set([row]);
5640
- }
5641
- else {
5642
- this.selectedItems.set([]);
5643
- }
5778
+ // Single selection mode: replace selection
5779
+ this.selectedItems.set(checked ? [row] : []);
5644
5780
  }
5645
5781
  else {
5782
+ // Multiple selection mode: add/remove from selection
5646
5783
  const current = this.selectedItems();
5647
5784
  const itemId = this.getItemId(row);
5648
5785
  if (checked) {
5649
- const index = current.findIndex((item) => this.getItemId(item) === itemId);
5650
- if (index < 0) {
5786
+ // Only add if not already selected
5787
+ const isAlreadySelected = current.some((item) => this.getItemId(item) === itemId);
5788
+ if (!isAlreadySelected) {
5651
5789
  this.selectedItems.set([...current, row]);
5652
5790
  }
5653
5791
  }
5654
5792
  else {
5793
+ // Remove from selection
5655
5794
  const updated = current.filter((item) => this.getItemId(item) !== itemId);
5656
5795
  this.selectedItems.set(updated);
5657
5796
  }
5658
5797
  }
5798
+ // Emit the updated selection
5659
5799
  this.selectionChanged.emit([...this.selectedItems()]);
5660
5800
  this.cdr.markForCheck();
5661
5801
  }
5802
+ /**
5803
+ * Toggles selection for all rows on the current page
5804
+ * @param checked - Whether all rows should be selected
5805
+ */
5662
5806
  toggleSelectAll(checked) {
5663
5807
  if (this.selectionMode === 'single') {
5664
5808
  return;
5665
5809
  }
5666
5810
  const currentPageData = this.displayedData();
5811
+ if (currentPageData.length === 0) {
5812
+ return;
5813
+ }
5814
+ const selectedItems = this.selectedItems();
5815
+ const selectedIds = new Set(selectedItems.map((item) => this.getItemId(item)));
5667
5816
  if (checked) {
5668
- const currentIds = new Set(this.selectedItems().map((item) => this.getItemId(item)));
5669
- const newItems = currentPageData.filter((row) => !currentIds.has(this.getItemId(row)));
5670
- this.selectedItems.set([...this.selectedItems(), ...newItems]);
5817
+ // Add all page items that aren't already selected
5818
+ const newItems = currentPageData.filter((row) => !selectedIds.has(this.getItemId(row)));
5819
+ if (newItems.length > 0) {
5820
+ this.selectedItems.set([...selectedItems, ...newItems]);
5821
+ }
5671
5822
  }
5672
5823
  else {
5824
+ // Remove all page items from selection
5673
5825
  const currentPageIds = new Set(currentPageData.map((row) => this.getItemId(row)));
5674
- const updated = this.selectedItems().filter((item) => !currentPageIds.has(this.getItemId(item)));
5826
+ const updated = selectedItems.filter((item) => !currentPageIds.has(this.getItemId(item)));
5675
5827
  this.selectedItems.set(updated);
5676
5828
  }
5677
5829
  this.selectionChanged.emit([...this.selectedItems()]);
5678
5830
  this.cdr.markForCheck();
5679
5831
  }
5832
+ /**
5833
+ * Gets the unique identifier for an item using the trackByKey
5834
+ * @param item - The item to get the ID for
5835
+ * @returns The item's ID or the item itself if no ID property exists
5836
+ * @private
5837
+ */
5680
5838
  getItemId(item) {
5839
+ if (!item) {
5840
+ return item;
5841
+ }
5681
5842
  return item[this.trackByKey] !== undefined ? item[this.trackByKey] : item;
5682
5843
  }
5844
+ /**
5845
+ * Gets CSS classes for a column cell
5846
+ * @param column - The column definition
5847
+ * @returns Space-separated string of CSS classes
5848
+ */
5683
5849
  getColumnClass(column) {
5850
+ if (!column) {
5851
+ return '';
5852
+ }
5684
5853
  const classes = [];
5685
5854
  if (column.align) {
5686
5855
  classes.push(`sefin-table__cell--align-${column.align}`);
@@ -5693,6 +5862,10 @@ class TableComponent {
5693
5862
  }
5694
5863
  return classes.join(' ');
5695
5864
  }
5865
+ /**
5866
+ * Gets CSS classes for the table element
5867
+ * @returns Space-separated string of CSS classes
5868
+ */
5696
5869
  getTableClasses() {
5697
5870
  const classes = ['sefin-table'];
5698
5871
  if (this.density === 'compact') {
@@ -5709,9 +5882,113 @@ class TableComponent {
5709
5882
  }
5710
5883
  return classes.join(' ');
5711
5884
  }
5885
+ /**
5886
+ * Gets the width CSS value for a column
5887
+ * @param column - The column definition
5888
+ * @returns The width value or undefined
5889
+ */
5712
5890
  getColumnWidth(column) {
5713
- return column.width;
5891
+ return column?.width;
5714
5892
  }
5893
+ /**
5894
+ * Gets the appropriate sort icon path for a column
5895
+ * @param column - The column to get the icon for
5896
+ * @returns The SVG path string for the sort icon
5897
+ */
5898
+ getSortIconPath(column) {
5899
+ if (!column.sortable || !this.sort) {
5900
+ return '';
5901
+ }
5902
+ const currentColumn = this.currentSortColumn();
5903
+ const currentDirection = this.currentSortDirection();
5904
+ if (currentColumn === column.key) {
5905
+ if (currentDirection === 'asc') {
5906
+ return SORT_ICONS.ascending;
5907
+ }
5908
+ else if (currentDirection === 'desc') {
5909
+ return SORT_ICONS.descending;
5910
+ }
5911
+ }
5912
+ return SORT_ICONS.unsorted;
5913
+ }
5914
+ /**
5915
+ * Determines if a column should show the unsorted icon
5916
+ * @param column - The column to check
5917
+ * @returns True if unsorted icon should be shown
5918
+ */
5919
+ showUnsortedIcon(column) {
5920
+ if (!column.sortable || !this.sort) {
5921
+ return false;
5922
+ }
5923
+ const currentColumn = this.currentSortColumn();
5924
+ const currentDirection = this.currentSortDirection();
5925
+ return currentColumn !== column.key || currentDirection === '';
5926
+ }
5927
+ /**
5928
+ * Determines if a column should show the ascending icon
5929
+ * @param column - The column to check
5930
+ * @returns True if ascending icon should be shown
5931
+ */
5932
+ showAscendingIcon(column) {
5933
+ if (!column.sortable || !this.sort) {
5934
+ return false;
5935
+ }
5936
+ return (this.currentSortColumn() === column.key &&
5937
+ this.currentSortDirection() === 'asc');
5938
+ }
5939
+ /**
5940
+ * Determines if a column should show the descending icon
5941
+ * @param column - The column to check
5942
+ * @returns True if descending icon should be shown
5943
+ */
5944
+ showDescendingIcon(column) {
5945
+ if (!column.sortable || !this.sort) {
5946
+ return false;
5947
+ }
5948
+ return (this.currentSortColumn() === column.key &&
5949
+ this.currentSortDirection() === 'desc');
5950
+ }
5951
+ /**
5952
+ * Gets the ARIA sort state for a column
5953
+ * @param column - The column to get the sort state for
5954
+ * @returns The ARIA sort value ('ascending', 'descending', or 'none')
5955
+ */
5956
+ getAriaSort(column) {
5957
+ if (!column.sortable || !this.sort) {
5958
+ return 'none';
5959
+ }
5960
+ if (this.currentSortColumn() === column.key) {
5961
+ const direction = this.currentSortDirection();
5962
+ return direction === 'asc' ? 'ascending' : direction === 'desc' ? 'descending' : 'none';
5963
+ }
5964
+ return 'none';
5965
+ }
5966
+ /**
5967
+ * Gets the ARIA label for a sortable column header
5968
+ * @param column - The column to get the label for
5969
+ * @returns The ARIA label string or null if not sortable
5970
+ */
5971
+ getSortAriaLabel(column) {
5972
+ if (!column.sortable || !this.sort) {
5973
+ return null;
5974
+ }
5975
+ let currentState = 'not sorted';
5976
+ if (this.currentSortColumn() === column.key) {
5977
+ const direction = this.currentSortDirection();
5978
+ if (direction === 'asc') {
5979
+ currentState = 'ascending';
5980
+ }
5981
+ else if (direction === 'desc') {
5982
+ currentState = 'descending';
5983
+ }
5984
+ }
5985
+ return `Sort by ${column.header}. Currently ${currentState}`;
5986
+ }
5987
+ /**
5988
+ * Generates page numbers array for pagination display
5989
+ * This method is currently not used in the template but kept for potential future use
5990
+ * @returns Array of page numbers and ellipsis strings
5991
+ */
5715
5992
  getPageNumbers() {
5716
5993
  const current = this.currentPage();
5717
5994
  const total = this.totalPages();
@@ -5748,14 +6025,12 @@ class TableComponent {
5748
6025
  }
5749
6026
  return pages;
5750
6027
  }
5751
- // Expose Math to template
5752
- Math = Math;
5753
6028
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TableComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
5754
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: TableComponent, isStandalone: true, selector: "sefin-table", inputs: { columns: "columns", data: "data", trackByKey: "trackByKey", loading: "loading", emptyText: "emptyText", density: "density", striped: "striped", hover: "hover", selectable: "selectable", selectionMode: "selectionMode", pagination: "pagination", pageSizeOptions: "pageSizeOptions", pageSize: "pageSize", total: "total", sort: "sort", serverSide: "serverSide", stickyHeader: "stickyHeader", headerActionsTemplate: "headerActionsTemplate", emptyIconTemplate: "emptyIconTemplate" }, outputs: { rowClicked: "rowClicked", selectionChanged: "selectionChanged", pageChanged: "pageChanged", sortChanged: "sortChanged" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"sefin-table__container\">\n <!-- Header Actions Slot -->\n <div *ngIf=\"headerActionsTemplate\" class=\"sefin-table__header-actions\">\n <ng-container *ngTemplateOutlet=\"headerActionsTemplate\"></ng-container>\n </div>\n\n <!-- Loading Overlay -->\n <div *ngIf=\"loading\" class=\"sefin-table__loading\">\n <div class=\"sefin-table__loading-bar\"></div>\n <div class=\"sefin-table__loading-rows\">\n <div *ngFor=\"let i of [1, 2, 3, 4, 5]\" class=\"sefin-table__skeleton-row\">\n <div\n class=\"sefin-table__skeleton-cell\"\n *ngFor=\"let col of columns\"\n ></div>\n </div>\n </div>\n </div>\n\n <!-- Table -->\n <div\n class=\"sefin-table__wrapper\"\n [class.sefin-table__wrapper--loading]=\"loading\"\n >\n <table [class]=\"getTableClasses()\" class=\"sefin-table__native-table\">\n <!-- Table Header -->\n <thead\n class=\"sefin-table__header\"\n [class.sefin-table__header--sticky]=\"stickyHeader\"\n >\n <tr class=\"sefin-table__header-row\">\n <!-- Selection Column Header -->\n <th\n *ngIf=\"selectable\"\n class=\"sefin-table__header-cell sefin-table__header-cell--select\"\n >\n <sefin-checkbox\n *ngIf=\"selectionMode === 'multiple'\"\n [value]=\"isAllSelected()\"\n [indeterminate]=\"isIndeterminate()\"\n (checkedChange)=\"toggleSelectAll($event)\"\n [attr.aria-label]=\"'Select all rows'\"\n size=\"sm\"\n ></sefin-checkbox>\n </th>\n\n <!-- Data Column Headers -->\n <th\n *ngFor=\"let column of columns\"\n [class]=\"getColumnClass(column)\"\n [class.sefin-table__header-cell--sortable]=\"column.sortable && sort\"\n [class.sefin-table__header-cell--sorted]=\"\n currentSortColumn() === column.key\n \"\n [class.sefin-table__header-cell--sort-asc]=\"\n currentSortColumn() === column.key &&\n currentSortDirection() === 'asc'\n \"\n [class.sefin-table__header-cell--sort-desc]=\"\n currentSortColumn() === column.key &&\n currentSortDirection() === 'desc'\n \"\n [class.sefin-table__header-cell--sticky]=\"column.sticky\"\n [class.sefin-table__header-cell--sticky-end]=\"\n column.sticky && column.stickyEnd\n \"\n [style.width]=\"getColumnWidth(column)\"\n class=\"sefin-table__header-cell\"\n (click)=\"column.sortable && sort ? onSort(column) : null\"\n [attr.aria-sort]=\"\n currentSortColumn() === column.key\n ? currentSortDirection() === 'asc'\n ? 'ascending'\n : currentSortDirection() === 'desc'\n ? 'descending'\n : 'none'\n : null\n \"\n role=\"columnheader\"\n [attr.tabindex]=\"column.sortable && sort ? 0 : null\"\n >\n <span class=\"sefin-table__header-content\">\n {{ column.header }}\n <span\n *ngIf=\"column.sortable && sort\"\n class=\"sefin-table__sort-icon\"\n >\n <svg\n *ngIf=\"\n currentSortColumn() !== column.key ||\n currentSortDirection() === ''\n \"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3 4.5L6 1.5L9 4.5M3 7.5L6 10.5L9 7.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <svg\n *ngIf=\"\n currentSortColumn() === column.key &&\n currentSortDirection() === 'asc'\n \"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3 7.5L6 4.5L9 7.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <svg\n *ngIf=\"\n currentSortColumn() === column.key &&\n currentSortDirection() === 'desc'\n \"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3 4.5L6 7.5L9 4.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n </span>\n </th>\n\n <th\n *ngIf=\"hasActionsColumn()\"\n class=\"sefin-table__header-cell sefin-table__header-cell--actions\"\n ></th>\n </tr>\n </thead>\n\n <!-- Table Body -->\n <tbody class=\"sefin-table__body\">\n <!-- Data Rows -->\n <tr\n *ngFor=\"let row of displayedData(); trackBy: trackByFn\"\n class=\"sefin-table__row sefin-table__row--clickable\"\n (click)=\"onRowClick(row)\"\n >\n <!-- Selection Column Cell -->\n <td\n *ngIf=\"selectable\"\n class=\"sefin-table__cell sefin-table__cell--select\"\n >\n <sefin-checkbox\n [value]=\"isSelected(row)\"\n (checkedChange)=\"toggleRowSelection($event, row)\"\n [attr.aria-label]=\"'Select row'\"\n size=\"sm\"\n ></sefin-checkbox>\n </td>\n\n <!-- Data Column Cells -->\n <td\n *ngFor=\"let column of columns\"\n [class]=\"getColumnClass(column)\"\n [class.sefin-table__cell--sticky]=\"column.sticky\"\n [class.sefin-table__cell--sticky-end]=\"\n column.sticky && column.stickyEnd\n \"\n class=\"sefin-table__cell\"\n >\n <!-- Custom Template -->\n <ng-container *ngIf=\"column.cellTemplate\">\n <ng-container\n *ngTemplateOutlet=\"\n column.cellTemplate;\n context: {\n $implicit: row,\n column: column,\n value: getCellValue(row, column)\n }\n \"\n ></ng-container>\n </ng-container>\n\n <!-- Badge Type -->\n <ng-container\n *ngIf=\"!column.cellTemplate && column.type === 'badge'\"\n >\n <sefin-badge\n [value]=\"getCellValue(row, column)\"\n variant=\"primary\"\n size=\"sm\"\n ></sefin-badge>\n </ng-container>\n\n <!-- Actions Type -->\n <ng-container\n *ngIf=\"!column.cellTemplate && column.type === 'actions'\"\n >\n <div class=\"sefin-table__actions\">\n <ng-content select=\"[actions]\"></ng-content>\n </div>\n </ng-container>\n\n <!-- Default/Text/Number/Date Type -->\n <ng-container\n *ngIf=\"\n !column.cellTemplate &&\n column.type !== 'badge' &&\n column.type !== 'actions'\n \"\n >\n <span class=\"sefin-table__cell-content\">\n {{ formatCellValue(getCellValue(row, column), column.type) }}\n </span>\n </ng-container>\n </td>\n\n <!-- Actions Column Cell -->\n <td\n *ngIf=\"hasActionsColumn()\"\n class=\"sefin-table__cell sefin-table__cell--actions\"\n >\n <div class=\"sefin-table__actions\">\n <ng-content select=\"[actions]\"></ng-content>\n </div>\n </td>\n </tr>\n\n <!-- Empty Row -->\n <tr *ngIf=\"isEmpty()\" class=\"sefin-table__row sefin-table__row--empty\">\n <td [attr.colspan]=\"totalColspan()\" class=\"sefin-table__empty-cell\">\n <div class=\"sefin-table__empty-state\">\n <ng-container *ngIf=\"emptyIconTemplate\">\n <ng-container\n *ngTemplateOutlet=\"emptyIconTemplate\"\n ></ng-container>\n </ng-container>\n <p class=\"sefin-table__empty-text\">{{ emptyText }}</p>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n <sefin-pagination\n *ngIf=\"pagination && !isEmpty()\"\n [currentPage]=\"currentPage()\"\n [totalPages]=\"totalPages()\"\n [totalItems]=\"serverSide && total !== undefined ? total : undefined\"\n [itemsPerPage]=\"currentPageSize()\"\n (pageChange)=\"onPageChange($event)\"\n class=\"sefin-table__paginator\"\n size=\"sm\"\n ></sefin-pagination>\n</div>\n", styles: [".sefin-table{display:block;width:100%;font-family:var(--sefin-font-family-base, \"Pluto\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);background-color:var(--sefin-color-surface, #ffffff);border-radius:var(--sefin-radius-md, 8px);overflow:hidden}.sefin-table__container{display:flex;flex-direction:column;width:100%;background-color:var(--sefin-color-surface, #ffffff);border:1px solid var(--sefin-color-border, #cecece);border-radius:var(--sefin-radius-md, 8px);overflow:hidden;box-shadow:var(--sefin-shadow-sm, 0 1px 2px 0 rgba(0, 0, 0, .05));transition:box-shadow .2s ease-in-out}.sefin-table__header-actions{display:flex;justify-content:flex-end;align-items:center;padding:var(--sefin-spacing-md, 16px);border-bottom:1px solid var(--sefin-color-border, #e5e5e5);background-color:var(--sefin-color-background, #ffffff);border-radius:var(--sefin-radius-md, 8px) var(--sefin-radius-md, 8px) 0 0}.sefin-table__wrapper{position:relative;overflow-x:auto;overflow-y:visible;background-color:var(--sefin-color-surface, #ffffff)}.sefin-table__wrapper--loading{opacity:.6;pointer-events:none}.sefin-table__loading{position:absolute;inset:0;z-index:10;background-color:#fffffffa;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);display:flex;flex-direction:column;border-radius:var(--sefin-radius-md, 8px)}.sefin-table__loading-bar{height:3px;background:linear-gradient(90deg,transparent,var(--sefin-color-primary, #55C3D8),transparent);animation:loading-bar 1.5s ease-in-out infinite;width:100%;border-radius:0 var(--sefin-radius-lg, 12px) 0 0}@keyframes loading-bar{0%{transform:translate(-100%)}to{transform:translate(200%)}}.sefin-table__loading-rows{flex:1;display:flex;flex-direction:column;padding:var(--sefin-spacing-lg, 24px);gap:var(--sefin-spacing-md, 16px)}.sefin-table__skeleton-row{display:flex;gap:var(--sefin-spacing-md, 16px);padding:var(--sefin-spacing-sm, 8px) 0}.sefin-table__skeleton-cell{flex:1;height:20px;background:linear-gradient(90deg,var(--sefin-color-surface-hover, #f5f5f5) 0%,rgba(85,195,216,.15) 50%,var(--sefin-color-surface-hover, #f5f5f5) 100%);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:var(--sefin-radius-sm, 4px)}@keyframes skeleton-loading{0%{background-position:200% 0}to{background-position:-200% 0}}.sefin-table__native-table{width:100%;border-collapse:separate;border-spacing:0;background-color:var(--sefin-color-surface, #ffffff)}.sefin-table--density-compact .sefin-table__header-cell,.sefin-table--density-compact .sefin-table__cell{padding:var(--sefin-spacing-xs, 4px) var(--sefin-spacing-sm, 8px);font-size:var(--sefin-font-size-sm, .875rem);line-height:var(--sefin-line-height-normal, 1.5)}.sefin-table--density-compact .sefin-table__header-cell{padding-top:var(--sefin-spacing-sm, 8px);padding-bottom:var(--sefin-spacing-sm, 8px)}.sefin-table--density-compact .sefin-table__cell{padding-top:var(--sefin-spacing-xs, 4px);padding-bottom:var(--sefin-spacing-xs, 4px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__header-cell,.sefin-table:not(.sefin-table--density-compact) .sefin-table__cell{padding:var(--sefin-spacing-md, 16px);font-size:var(--sefin-font-size-base, 1rem);line-height:var(--sefin-line-height-normal, 1.5)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__header-cell{padding-top:var(--sefin-spacing-md, 16px);padding-bottom:var(--sefin-spacing-md, 16px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__cell{padding-top:var(--sefin-spacing-sm, 8px);padding-bottom:var(--sefin-spacing-sm, 8px)}.sefin-table__header{background-color:var(--sefin-color-background-elevated, #fafafa);border-bottom:2px solid var(--sefin-color-border, #e5e5e5)}.sefin-table__header--sticky{position:sticky;top:0;z-index:3;box-shadow:0 2px 8px #0000000f}.sefin-table__header-row{background-color:var(--sefin-color-background-elevated, #fafafa)}.sefin-table__header-cell{font-weight:var(--sefin-font-weight-semibold, 600);font-size:var(--sefin-font-size-sm, .875rem);color:var(--sefin-color-text, #383838);text-transform:uppercase;letter-spacing:.5px;text-align:left;white-space:nowrap;border-bottom:none;position:relative;background-color:var(--sefin-color-background-elevated, #fafafa);-webkit-user-select:none;user-select:none;transition:all .2s ease-in-out;z-index:1}.sefin-table__header-cell--align-left{text-align:left}.sefin-table__header-cell--align-center{text-align:center}.sefin-table__header-cell--align-right{text-align:right}.sefin-table__header-cell--select{width:56px;padding-left:var(--sefin-spacing-md, 16px);padding-right:var(--sefin-spacing-sm, 8px);text-align:center}.sefin-table__header-cell--actions{width:120px;text-align:right}.sefin-table__header-cell--sortable{cursor:pointer}.sefin-table__header-cell--sortable:hover{background-color:#55c3d814;color:var(--sefin-color-primary, #55C3D8)}.sefin-table__header-cell--sortable:hover .sefin-table__sort-icon{opacity:1;color:var(--sefin-color-primary, #55C3D8)}.sefin-table__header-cell--sortable:active{background-color:#55c3d81f}.sefin-table__header-cell--sortable:focus-visible{outline:2px solid var(--sefin-color-border-focus, #55C3D8);outline-offset:-2px;border-radius:var(--sefin-radius-sm, 4px)}.sefin-table__header-cell--sorted{color:var(--sefin-color-primary, #55C3D8);background-color:#55c3d80f}.sefin-table__header-cell--sorted .sefin-table__sort-icon{opacity:1;color:var(--sefin-color-primary, #55C3D8)}.sefin-table__header-cell--sticky{position:sticky;background-color:var(--sefin-color-background-elevated, #fafafa);z-index:2;box-shadow:2px 0 4px #0000000a}.sefin-table__header-cell--sticky:after{content:\"\";position:absolute;top:0;right:0;bottom:0;width:1px;background-color:var(--sefin-color-border, #e5e5e5);opacity:.6}.sefin-table__header-cell--sticky.sefin-table__header-cell--sticky-end{right:0;box-shadow:-2px 0 4px #0000000a}.sefin-table__header-cell--sticky.sefin-table__header-cell--sticky-end:after{left:0;right:auto}.sefin-table__header-content{display:flex;align-items:center;justify-content:flex-start;gap:var(--sefin-spacing-xs, 4px);width:100%}.sefin-table__sort-icon{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;color:var(--sefin-color-text-secondary, #9b9b9b);opacity:.4;transition:all .2s ease-in-out;flex-shrink:0;margin-left:var(--sefin-spacing-xs, 4px)}.sefin-table__sort-icon svg{display:block;width:100%;height:100%}.sefin-table__body{background-color:var(--sefin-color-surface, #ffffff)}.sefin-table__row{border-bottom:1px solid var(--sefin-color-border, #e5e5e5);transition:all .2s ease-in-out;background-color:var(--sefin-color-surface, #ffffff)}.sefin-table__row--clickable{cursor:pointer}.sefin-table__row--clickable:hover:not(.sefin-table__row--empty){background-color:#55c3d80d;box-shadow:inset 3px 0 0 var(--sefin-color-primary, #55C3D8)}.sefin-table__row--clickable:hover:not(.sefin-table__row--empty) .sefin-table__cell--sticky{background-color:#55c3d80d}.sefin-table__row--clickable:active:not(.sefin-table__row--empty){background-color:#55c3d814;box-shadow:inset 3px 0 0 var(--sefin-color-primary-dark, #3f9bb0)}.sefin-table__row--clickable:active:not(.sefin-table__row--empty) .sefin-table__cell--sticky{background-color:#55c3d814}.sefin-table__row--empty{border-bottom:none}.sefin-table__row:focus-visible{outline:2px solid var(--sefin-color-border-focus, #55C3D8);outline-offset:-2px;border-radius:var(--sefin-radius-sm, 4px)}.sefin-table__row:last-child{border-bottom:none}.sefin-table__cell{font-family:var(--sefin-font-family-base, \"Pluto\", sans-serif);font-size:var(--sefin-font-size-base, 1rem);font-weight:var(--sefin-font-weight-normal, 400);color:var(--sefin-color-text, #383838);border-bottom:none;vertical-align:middle;background-color:inherit;transition:background-color .2s ease-in-out,color .2s ease-in-out}.sefin-table__cell--align-left{text-align:left}.sefin-table__cell--align-center{text-align:center}.sefin-table__cell--align-right{text-align:right}.sefin-table__cell--select{width:56px;padding-left:var(--sefin-spacing-md, 16px);padding-right:var(--sefin-spacing-sm, 8px);text-align:center}.sefin-table__cell--actions{text-align:right;width:120px}.sefin-table__cell--sticky{position:sticky;background-color:inherit;z-index:1;box-shadow:2px 0 4px #0000000a}.sefin-table__cell--sticky:after{content:\"\";position:absolute;top:0;right:0;bottom:0;width:1px;background-color:var(--sefin-color-border, #e5e5e5);opacity:.6}.sefin-table__cell--sticky.sefin-table__cell--sticky-end{right:0;box-shadow:-2px 0 4px #0000000a}.sefin-table__cell--sticky.sefin-table__cell--sticky-end:after{left:0;right:auto}.sefin-table__cell-content{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:var(--sefin-line-height-normal, 1.5);color:var(--sefin-color-text, #383838)}.sefin-table__actions{display:flex;align-items:center;justify-content:flex-end;gap:var(--sefin-spacing-xs, 4px);flex-wrap:wrap}.sefin-table--striped .sefin-table__row:nth-child(2n){background-color:var(--sefin-color-surface, #ffffff)}.sefin-table--striped .sefin-table__row:nth-child(odd){background-color:#f8f9facc}.sefin-table--striped .sefin-table__cell--sticky:nth-child(2n){background-color:var(--sefin-color-surface, #ffffff)}.sefin-table--striped .sefin-table__cell--sticky:nth-child(odd){background-color:#f8f9facc}.sefin-table--striped .sefin-table__row--clickable:hover,.sefin-table--striped .sefin-table__row--clickable:hover .sefin-table__cell--sticky{background-color:#55c3d814!important}.sefin-table--hover .sefin-table__row:not(.sefin-table__row--empty):hover{background-color:#55c3d80d}.sefin-table--hover .sefin-table__row:not(.sefin-table__row--empty):hover .sefin-table__cell--sticky{background-color:#55c3d80d}.sefin-table--hover .sefin-table__row--clickable:not(.sefin-table__row--empty):hover{background-color:#55c3d80d}.sefin-table--hover .sefin-table__row--clickable:not(.sefin-table__row--empty):hover .sefin-table__cell--sticky{background-color:#55c3d80d}.sefin-table--sticky-header .sefin-table__header{position:sticky;top:0;z-index:3;box-shadow:0 4px 12px #00000014}.sefin-table__empty-cell{padding:var(--sefin-spacing-4xl, 96px) var(--sefin-spacing-xl, 32px);text-align:center;border-bottom:none;background-color:var(--sefin-color-surface, #ffffff)}.sefin-table__empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--sefin-spacing-lg, 24px);padding:var(--sefin-spacing-2xl, 48px);background:linear-gradient(to bottom,rgba(248,249,250,.5),transparent);border-radius:var(--sefin-radius-md, 8px);margin:var(--sefin-spacing-lg, 24px)}.sefin-table__empty-text{font-size:var(--sefin-font-size-lg, 1.125rem);font-weight:var(--sefin-font-weight-medium, 500);line-height:var(--sefin-line-height-relaxed, 1.75);color:var(--sefin-color-text-secondary, #686868);margin:0;font-family:var(--sefin-font-family-base, \"Pluto\", sans-serif);max-width:480px;letter-spacing:.2px}.sefin-table__paginator{border-top:1px solid var(--sefin-color-border, #e5e5e5);background-color:var(--sefin-color-background, #ffffff);padding:var(--sefin-spacing-md, 16px);border-radius:0 0 var(--sefin-radius-md, 8px) var(--sefin-radius-md, 8px)}.sefin-table ::ng-deep .sefin-checkbox{margin:0;transition:transform .2s ease-in-out}.sefin-table ::ng-deep .sefin-checkbox:hover{transform:scale(1.05)}.sefin-table ::ng-deep .sefin-badge{margin:0;box-shadow:0 1px 3px #0000001a;transition:transform .2s ease-in-out,box-shadow .2s ease-in-out}.sefin-table ::ng-deep .sefin-badge:hover{transform:translateY(-1px);box-shadow:0 2px 6px #00000026}.sefin-table ::ng-deep .sefin-button,.sefin-table ::ng-deep .sefin-icon-button{transition:transform .2s ease-in-out,box-shadow .2s ease-in-out}.sefin-table ::ng-deep .sefin-button:hover,.sefin-table ::ng-deep .sefin-icon-button:hover{transform:translateY(-1px)}.sefin-table ::ng-deep .sefin-button:active,.sefin-table ::ng-deep .sefin-icon-button:active{transform:translateY(0)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: PaginationComponent, selector: "sefin-pagination", inputs: ["currentPage", "totalPages", "totalItems", "itemsPerPage", "siblingCount", "showFirstLast", "showPrevNext", "size", "variant", "class"], outputs: ["pageChange"] }, { kind: "component", type: CheckboxComponent, selector: "sefin-checkbox", inputs: ["size", "disabled", "indeterminate", "class", "label", "name", "value"], outputs: ["valueChange", "checkedChange"] }, { kind: "component", type: BadgeComponent, selector: "sefin-badge", inputs: ["variant", "size", "dot", "max", "value", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
6029
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: TableComponent, isStandalone: true, selector: "sefin-table", inputs: { columns: "columns", data: "data", trackByKey: "trackByKey", loading: "loading", emptyText: "emptyText", density: "density", striped: "striped", hover: "hover", selectable: "selectable", selectionMode: "selectionMode", pagination: "pagination", pageSizeOptions: "pageSizeOptions", pageSize: "pageSize", total: "total", sort: "sort", serverSide: "serverSide", stickyHeader: "stickyHeader", headerActionsTemplate: "headerActionsTemplate", emptyIconTemplate: "emptyIconTemplate" }, outputs: { rowClicked: "rowClicked", selectionChanged: "selectionChanged", pageChanged: "pageChanged", sortChanged: "sortChanged" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"sefin-table__container\">\n <!-- Header Actions Slot -->\n <div *ngIf=\"headerActionsTemplate\" class=\"sefin-table__header-actions\">\n <ng-container *ngTemplateOutlet=\"headerActionsTemplate\"></ng-container>\n </div>\n\n <!-- Loading Overlay -->\n <div *ngIf=\"loading\" class=\"sefin-table__loading\">\n <div class=\"sefin-table__loading-bar\"></div>\n <div class=\"sefin-table__loading-rows\">\n <div *ngFor=\"let i of [1, 2, 3, 4, 5]\" class=\"sefin-table__skeleton-row\">\n <div\n class=\"sefin-table__skeleton-cell\"\n *ngFor=\"let col of columns\"\n ></div>\n </div>\n </div>\n </div>\n\n <!-- Table -->\n <div\n class=\"sefin-table__wrapper\"\n [class.sefin-table__wrapper--loading]=\"loading\"\n >\n <table\n [class]=\"getTableClasses()\"\n class=\"sefin-table__native-table\"\n role=\"table\"\n [attr.aria-label]=\"'Data table with ' + columns.length + ' columns'\"\n [attr.aria-rowcount]=\"serverSide && total !== undefined ? total : sortedData().length\"\n [attr.aria-colcount]=\"totalColspan()\"\n >\n <!-- Table Header -->\n <thead\n class=\"sefin-table__header\"\n [class.sefin-table__header--sticky]=\"stickyHeader\"\n >\n <tr class=\"sefin-table__header-row\">\n <!-- Selection Column Header -->\n <th\n *ngIf=\"selectable\"\n class=\"sefin-table__header-cell sefin-table__header-cell--select\"\n >\n <sefin-checkbox\n *ngIf=\"selectionMode === 'multiple'\"\n [value]=\"isAllSelected()\"\n [indeterminate]=\"isIndeterminate()\"\n (checkedChange)=\"toggleSelectAll($event)\"\n [attr.aria-label]=\"'Select all rows'\"\n size=\"sm\"\n ></sefin-checkbox>\n </th>\n\n <!-- Data Column Headers -->\n <th\n *ngFor=\"let column of columns\"\n [class]=\"getColumnClass(column)\"\n [class.sefin-table__header-cell--sortable]=\"column.sortable && sort\"\n [class.sefin-table__header-cell--sorted]=\"\n currentSortColumn() === column.key\n \"\n [class.sefin-table__header-cell--sort-asc]=\"\n currentSortColumn() === column.key &&\n currentSortDirection() === 'asc'\n \"\n [class.sefin-table__header-cell--sort-desc]=\"\n currentSortColumn() === column.key &&\n currentSortDirection() === 'desc'\n \"\n [class.sefin-table__header-cell--sticky]=\"column.sticky\"\n [class.sefin-table__header-cell--sticky-end]=\"\n column.sticky && column.stickyEnd\n \"\n [style.width]=\"getColumnWidth(column)\"\n class=\"sefin-table__header-cell\"\n (click)=\"column.sortable && sort ? onSort(column) : null\"\n (keydown)=\"column.sortable && sort ? onSort(column, $event) : null\"\n [attr.aria-sort]=\"getAriaSort(column)\"\n [attr.aria-label]=\"getSortAriaLabel(column)\"\n role=\"columnheader\"\n [attr.tabindex]=\"column.sortable && sort ? 0 : null\"\n >\n <span class=\"sefin-table__header-content\">\n {{ column.header }}\n <span\n *ngIf=\"column.sortable && sort\"\n class=\"sefin-table__sort-icon\"\n [attr.aria-hidden]=\"true\"\n >\n <svg\n *ngIf=\"showUnsortedIcon(column)\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n focusable=\"false\"\n >\n <path\n [attr.d]=\"sortIcons.unsorted\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <svg\n *ngIf=\"showAscendingIcon(column)\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n focusable=\"false\"\n >\n <path\n [attr.d]=\"sortIcons.ascending\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <svg\n *ngIf=\"showDescendingIcon(column)\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n focusable=\"false\"\n >\n <path\n [attr.d]=\"sortIcons.descending\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n </span>\n </th>\n\n <th\n *ngIf=\"hasActionsColumn()\"\n class=\"sefin-table__header-cell sefin-table__header-cell--actions\"\n ></th>\n </tr>\n </thead>\n\n <!-- Table Body -->\n <tbody class=\"sefin-table__body\" role=\"rowgroup\">\n <!-- Data Rows -->\n <tr\n *ngFor=\"let row of displayedData(); trackBy: trackByFn\"\n class=\"sefin-table__row sefin-table__row--clickable\"\n (click)=\"onRowClick(row)\"\n [attr.aria-selected]=\"selectable ? isSelected(row) : null\"\n [attr.aria-label]=\"'Row ' + (trackByFn(0, row) || '')\"\n role=\"row\"\n >\n <!-- Selection Column Cell -->\n <td\n *ngIf=\"selectable\"\n class=\"sefin-table__cell sefin-table__cell--select\"\n >\n <sefin-checkbox\n [value]=\"isSelected(row)\"\n (checkedChange)=\"toggleRowSelection($event, row)\"\n [attr.aria-label]=\"'Select row'\"\n size=\"sm\"\n ></sefin-checkbox>\n </td>\n\n <!-- Data Column Cells -->\n <td\n *ngFor=\"let column of columns\"\n [class]=\"getColumnClass(column)\"\n [class.sefin-table__cell--sticky]=\"column.sticky\"\n [class.sefin-table__cell--sticky-end]=\"\n column.sticky && column.stickyEnd\n \"\n class=\"sefin-table__cell\"\n >\n <!-- Custom Template -->\n <ng-container *ngIf=\"column.cellTemplate\">\n <ng-container\n *ngTemplateOutlet=\"\n column.cellTemplate;\n context: {\n $implicit: row,\n column: column,\n value: getCellValue(row, column)\n }\n \"\n ></ng-container>\n </ng-container>\n\n <!-- Badge Type -->\n <ng-container\n *ngIf=\"!column.cellTemplate && column.type === 'badge'\"\n >\n <sefin-badge\n [value]=\"getCellValue(row, column)\"\n variant=\"primary\"\n size=\"sm\"\n ></sefin-badge>\n </ng-container>\n\n <!-- Actions Type -->\n <ng-container\n *ngIf=\"!column.cellTemplate && column.type === 'actions'\"\n >\n <div class=\"sefin-table__actions\">\n <ng-content select=\"[actions]\"></ng-content>\n </div>\n </ng-container>\n\n <!-- Default/Text/Number/Date Type -->\n <ng-container\n *ngIf=\"\n !column.cellTemplate &&\n column.type !== 'badge' &&\n column.type !== 'actions'\n \"\n >\n <span class=\"sefin-table__cell-content\">\n {{ formatCellValue(getCellValue(row, column), column.type, column) }}\n </span>\n </ng-container>\n </td>\n\n <!-- Actions Column Cell -->\n <td\n *ngIf=\"hasActionsColumn()\"\n class=\"sefin-table__cell sefin-table__cell--actions\"\n >\n <div class=\"sefin-table__actions\">\n <ng-content select=\"[actions]\"></ng-content>\n </div>\n </td>\n </tr>\n\n <!-- Empty Row -->\n <tr *ngIf=\"isEmpty()\" class=\"sefin-table__row sefin-table__row--empty\">\n <td [attr.colspan]=\"totalColspan()\" class=\"sefin-table__empty-cell\">\n <div class=\"sefin-table__empty-state\">\n <ng-container *ngIf=\"emptyIconTemplate\">\n <ng-container\n *ngTemplateOutlet=\"emptyIconTemplate\"\n ></ng-container>\n </ng-container>\n <p class=\"sefin-table__empty-text\">{{ emptyText }}</p>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n <sefin-pagination\n *ngIf=\"pagination && !isEmpty()\"\n [currentPage]=\"currentPage()\"\n [totalPages]=\"totalPages()\"\n [totalItems]=\"serverSide && total !== undefined ? total : undefined\"\n [itemsPerPage]=\"currentPageSize()\"\n (pageChange)=\"onPageChange($event)\"\n class=\"sefin-table__paginator\"\n size=\"sm\"\n ></sefin-pagination>\n</div>\n", styles: [".sefin-table{display:block;width:100%;font-family:var(--sefin-font-family-base, \"Pluto\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);background-color:var(--sefin-color-surface, #ffffff);border-radius:var(--sefin-radius-md, 8px);overflow:hidden}.sefin-table__container{display:flex;flex-direction:column;width:100%;background-color:var(--sefin-color-surface, #ffffff);border:1px solid rgba(0,0,0,.06);border-radius:var(--sefin-radius-lg, 12px);overflow:hidden;box-shadow:0 2px 8px #0000000a,0 1px 2px #00000005;transition:box-shadow .3s ease-in-out,border-color .3s ease-in-out}.sefin-table__header-actions{display:flex;justify-content:flex-end;align-items:center;padding:var(--sefin-spacing-md, 16px);border-bottom:1px solid var(--sefin-color-border, #e5e5e5);background-color:var(--sefin-color-background, #ffffff);border-radius:var(--sefin-radius-md, 8px) var(--sefin-radius-md, 8px) 0 0}.sefin-table__wrapper{position:relative;overflow-x:auto;overflow-y:visible;background-color:var(--sefin-color-surface, #ffffff)}.sefin-table__wrapper--loading{opacity:.6;pointer-events:none}.sefin-table__loading{position:absolute;inset:0;z-index:10;background-color:#fffffffa;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);display:flex;flex-direction:column;border-radius:var(--sefin-radius-md, 8px)}.sefin-table__loading-bar{height:3px;background:linear-gradient(90deg,transparent,var(--sefin-color-primary, #55C3D8),transparent);animation:loading-bar 1.5s ease-in-out infinite;width:100%;border-radius:0 var(--sefin-radius-lg, 12px) 0 0}@keyframes loading-bar{0%{transform:translate(-100%)}to{transform:translate(200%)}}.sefin-table__loading-rows{flex:1;display:flex;flex-direction:column;padding:var(--sefin-spacing-lg, 24px);gap:var(--sefin-spacing-md, 16px)}.sefin-table__skeleton-row{display:flex;gap:var(--sefin-spacing-md, 16px);padding:var(--sefin-spacing-sm, 8px) 0}.sefin-table__skeleton-cell{flex:1;height:20px;background:linear-gradient(90deg,var(--sefin-color-surface-hover, #f5f5f5) 0%,rgba(85,195,216,.15) 50%,var(--sefin-color-surface-hover, #f5f5f5) 100%);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:var(--sefin-radius-sm, 4px)}@keyframes skeleton-loading{0%{background-position:200% 0}to{background-position:-200% 0}}.sefin-table__native-table{width:100%;border-collapse:separate;border-spacing:0;background-color:var(--sefin-color-surface, #ffffff);table-layout:auto;min-width:100%}.sefin-table--density-compact .sefin-table__header-cell:not(.sefin-table__header-cell--select):not(.sefin-table__header-cell--actions),.sefin-table--density-compact .sefin-table__cell:not(.sefin-table__cell--select):not(.sefin-table__cell--actions){padding:var(--sefin-spacing-xs, 4px) var(--sefin-spacing-sm, 8px);font-size:var(--sefin-font-size-sm, .875rem);line-height:var(--sefin-line-height-normal, 1.5)}.sefin-table--density-compact .sefin-table__header-cell:not(.sefin-table__header-cell--select):not(.sefin-table__header-cell--actions){padding-top:var(--sefin-spacing-sm, 8px);padding-bottom:var(--sefin-spacing-sm, 8px)}.sefin-table--density-compact .sefin-table__cell:not(.sefin-table__cell--select):not(.sefin-table__cell--actions){padding-top:var(--sefin-spacing-xs, 4px);padding-bottom:var(--sefin-spacing-xs, 4px)}.sefin-table--density-compact .sefin-table__header-cell--select,.sefin-table--density-compact .sefin-table__cell--select{padding:var(--sefin-spacing-sm, 8px) var(--sefin-spacing-sm, 8px) var(--sefin-spacing-sm, 8px) var(--sefin-spacing-md, 16px)!important}.sefin-table--density-compact .sefin-table__header-cell--actions,.sefin-table--density-compact .sefin-table__cell--actions{padding:var(--sefin-spacing-sm, 8px) var(--sefin-spacing-md, 16px)!important}.sefin-table:not(.sefin-table--density-compact) .sefin-table__header-cell:not(.sefin-table__header-cell--select):not(.sefin-table__header-cell--actions),.sefin-table:not(.sefin-table--density-compact) .sefin-table__cell:not(.sefin-table__cell--select):not(.sefin-table__cell--actions){font-size:var(--sefin-font-size-base, 1rem);line-height:var(--sefin-line-height-normal, 1.5);padding-left:var(--sefin-spacing-lg, 24px);padding-right:var(--sefin-spacing-lg, 24px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__header-cell:not(.sefin-table__header-cell--select):not(.sefin-table__header-cell--actions){padding-top:var(--sefin-spacing-lg, 24px);padding-bottom:var(--sefin-spacing-lg, 24px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__cell:not(.sefin-table__cell--select):not(.sefin-table__cell--actions){padding-top:var(--sefin-spacing-md, 16px);padding-bottom:var(--sefin-spacing-md, 16px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__header-cell--select,.sefin-table:not(.sefin-table--density-compact) .sefin-table__cell--select{font-size:var(--sefin-font-size-base, 1rem);line-height:var(--sefin-line-height-normal, 1.5);padding-left:var(--sefin-spacing-lg, 24px);padding-right:var(--sefin-spacing-sm, 8px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__header-cell--select{padding-top:var(--sefin-spacing-lg, 24px);padding-bottom:var(--sefin-spacing-lg, 24px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__cell--select{padding-top:var(--sefin-spacing-md, 16px);padding-bottom:var(--sefin-spacing-md, 16px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__header-cell--actions,.sefin-table:not(.sefin-table--density-compact) .sefin-table__cell--actions{font-size:var(--sefin-font-size-base, 1rem);line-height:var(--sefin-line-height-normal, 1.5);padding-left:var(--sefin-spacing-lg, 24px);padding-right:var(--sefin-spacing-lg, 24px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__header-cell--actions{padding-top:var(--sefin-spacing-lg, 24px);padding-bottom:var(--sefin-spacing-lg, 24px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__cell--actions{padding-top:var(--sefin-spacing-md, 16px);padding-bottom:var(--sefin-spacing-md, 16px)}.sefin-table__header{background:linear-gradient(to bottom,#fff,#fafafa);border-bottom:1px solid rgba(0,0,0,.08);position:relative}.sefin-table__header:after{content:\"\";position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(to right,transparent 0%,rgba(0,0,0,.06) 50%,transparent 100%)}.sefin-table__header--sticky{position:sticky;top:0;z-index:3;box-shadow:0 4px 12px #00000014,0 2px 4px #0000000a}.sefin-table__header-row{background:transparent}.sefin-table__header-cell{font-weight:var(--sefin-font-weight-semibold, 600);font-size:var(--sefin-font-size-xs, .75rem);color:var(--sefin-color-text-secondary, #6b7280);text-transform:uppercase;letter-spacing:.8px;text-align:left;border-bottom:none;background:transparent;-webkit-user-select:none;user-select:none;transition:background-color .25s cubic-bezier(.4,0,.2,1),color .25s cubic-bezier(.4,0,.2,1);z-index:1}.sefin-table__header-cell--align-left{text-align:left}.sefin-table__header-cell--align-center{text-align:center}.sefin-table__header-cell--align-right{text-align:right}.sefin-table__header-cell--select{width:56px;text-align:center}.sefin-table__header-cell--actions{width:120px;text-align:right}.sefin-table__header-cell--sortable{cursor:pointer}.sefin-table__header-cell--sortable:hover{background-color:#55c3d80f;color:var(--sefin-color-primary, #55C3D8)}.sefin-table__header-cell--sortable:hover .sefin-table__sort-icon{opacity:1;color:var(--sefin-color-primary, #55C3D8);transform:scale(1.1)}.sefin-table__header-cell--sortable:active{background-color:#55c3d81a}.sefin-table__header-cell--sortable:focus-visible{outline:2px solid var(--sefin-color-border-focus, #55C3D8);outline-offset:-2px;border-radius:var(--sefin-radius-sm, 4px)}.sefin-table__header-cell--sorted{color:var(--sefin-color-primary, #55C3D8);background:linear-gradient(to bottom,#55c3d814,#55c3d80a)}.sefin-table__header-cell--sorted .sefin-table__sort-icon{opacity:1;color:var(--sefin-color-primary, #55C3D8)}.sefin-table__header-cell--sticky{position:sticky;background-color:var(--sefin-color-background-elevated, #fafafa);z-index:2}.sefin-table__header-content{display:flex;align-items:center;justify-content:flex-start;gap:var(--sefin-spacing-xs, 4px);width:100%}.sefin-table__sort-icon{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;min-width:14px;color:var(--sefin-color-text-secondary, #9b9b9b);opacity:.5;transition:all .25s cubic-bezier(.4,0,.2,1);flex-shrink:0;margin-left:var(--sefin-spacing-xs, 4px)}.sefin-table__sort-icon svg{display:block;width:100%;height:100%;transition:transform .2s ease-out}.sefin-table__header-cell--sortable:hover .sefin-table__sort-icon{opacity:1;transform:scale(1.1)}.sefin-table__header-cell--sortable:hover .sefin-table__sort-icon svg{transform:scale(1.05)}.sefin-table__body{background-color:var(--sefin-color-surface, #ffffff)}.sefin-table__row{border-bottom:1px solid rgba(0,0,0,.04);transition:background-color .25s cubic-bezier(.4,0,.2,1),transform .15s ease-out;background-color:var(--sefin-color-surface, #ffffff);position:relative}.sefin-table__row--clickable{cursor:pointer}.sefin-table__row--clickable:hover:not(.sefin-table__row--empty){background-color:#55c3d80a;transform:translateY(-1px);box-shadow:0 2px 4px #00000005}.sefin-table__row--clickable:hover:not(.sefin-table__row--empty) .sefin-table__cell--sticky{background-color:#55c3d80a}.sefin-table__row--clickable:active:not(.sefin-table__row--empty){background-color:#55c3d80f;transform:translateY(0);box-shadow:none}.sefin-table__row--clickable:active:not(.sefin-table__row--empty) .sefin-table__cell--sticky{background-color:#55c3d80f}.sefin-table__row--empty{border-bottom:none}.sefin-table__row:focus-visible{outline:2px solid var(--sefin-color-border-focus, #55C3D8);outline-offset:-2px;border-radius:var(--sefin-radius-sm, 4px);z-index:1}.sefin-table__row:last-child{border-bottom:none}.sefin-table__row[data-animate]{animation:fadeInRow .3s ease-in-out}@keyframes fadeInRow{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.sefin-table__cell{font-family:var(--sefin-font-family-base, \"Pluto\", sans-serif);font-size:var(--sefin-font-size-base, 1rem);font-weight:var(--sefin-font-weight-normal, 400);color:var(--sefin-color-text, #1f2937);border-bottom:none;vertical-align:middle;background-color:inherit;transition:background-color .25s cubic-bezier(.4,0,.2,1),color .25s cubic-bezier(.4,0,.2,1)}.sefin-table__cell--align-left{text-align:left}.sefin-table__cell--align-center{text-align:center}.sefin-table__cell--align-right{text-align:right}.sefin-table__cell--select{width:56px;text-align:center}.sefin-table__cell--actions{text-align:right;width:120px}.sefin-table__cell--sticky{position:sticky;background-color:inherit;z-index:1}.sefin-table__cell-content{display:block;line-height:var(--sefin-line-height-relaxed, 1.75);color:var(--sefin-color-text, #1f2937);font-weight:var(--sefin-font-weight-normal, 400);word-wrap:break-word;word-break:break-word;max-width:100%;overflow:hidden;text-overflow:ellipsis;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.sefin-table__actions{display:flex;align-items:center;justify-content:flex-end;gap:var(--sefin-spacing-xs, 4px);flex-wrap:wrap}.sefin-table--striped .sefin-table__row:nth-child(2n){background-color:var(--sefin-color-surface, #ffffff)}.sefin-table--striped .sefin-table__row:nth-child(odd){background-color:#f9fafb99}.sefin-table--striped .sefin-table__cell--sticky:nth-child(2n){background-color:var(--sefin-color-surface, #ffffff)}.sefin-table--striped .sefin-table__cell--sticky:nth-child(odd){background-color:#f9fafb99}.sefin-table--striped .sefin-table__row--clickable:hover,.sefin-table--striped .sefin-table__row--clickable:hover .sefin-table__cell--sticky{background-color:#55c3d80f!important}.sefin-table--hover .sefin-table__row:not(.sefin-table__row--empty):hover{background-color:#55c3d80a}.sefin-table--hover .sefin-table__row:not(.sefin-table__row--empty):hover .sefin-table__cell--sticky{background-color:#55c3d80a}.sefin-table--hover .sefin-table__row--clickable:not(.sefin-table__row--empty):hover{background-color:#55c3d80a}.sefin-table--hover .sefin-table__row--clickable:not(.sefin-table__row--empty):hover .sefin-table__cell--sticky{background-color:#55c3d80a}.sefin-table--sticky-header .sefin-table__header{position:sticky;top:0;z-index:3;box-shadow:0 4px 16px #00000014,0 2px 4px #0000000a}.sefin-table__empty-cell{padding:var(--sefin-spacing-4xl, 96px) var(--sefin-spacing-xl, 32px);text-align:center;border-bottom:none;background-color:var(--sefin-color-surface, #ffffff)}.sefin-table__empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--sefin-spacing-lg, 24px);padding:var(--sefin-spacing-2xl, 48px);background:linear-gradient(to bottom,rgba(248,249,250,.5),transparent);border-radius:var(--sefin-radius-md, 8px);margin:var(--sefin-spacing-lg, 24px)}.sefin-table__empty-text{font-size:var(--sefin-font-size-lg, 1.125rem);font-weight:var(--sefin-font-weight-medium, 500);line-height:var(--sefin-line-height-relaxed, 1.75);color:var(--sefin-color-text-secondary, #686868);margin:0;font-family:var(--sefin-font-family-base, \"Pluto\", sans-serif);max-width:480px;letter-spacing:.2px}.sefin-table__paginator{background-color:var(--sefin-color-background, #ffffff);padding:var(--sefin-spacing-lg, 24px) var(--sefin-spacing-md, 16px);border-radius:0 0 var(--sefin-radius-lg, 12px) var(--sefin-radius-lg, 12px);display:flex;justify-content:flex-end;align-items:center}.sefin-table ::ng-deep .sefin-checkbox{margin:0;transition:transform .2s ease-in-out}.sefin-table ::ng-deep .sefin-checkbox:hover{transform:scale(1.05)}.sefin-table ::ng-deep .sefin-badge{margin:0;box-shadow:0 1px 3px #0000001a;transition:transform .2s ease-in-out,box-shadow .2s ease-in-out}.sefin-table ::ng-deep .sefin-badge:hover{transform:translateY(-1px);box-shadow:0 2px 6px #00000026}.sefin-table ::ng-deep .sefin-button,.sefin-table ::ng-deep .sefin-icon-button{transition:transform .2s ease-in-out,box-shadow .2s ease-in-out}.sefin-table ::ng-deep .sefin-button:hover,.sefin-table ::ng-deep .sefin-icon-button:hover{transform:translateY(-1px)}.sefin-table ::ng-deep .sefin-button:active,.sefin-table ::ng-deep .sefin-icon-button:active{transform:translateY(0)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: PaginationComponent, selector: "sefin-pagination", inputs: ["currentPage", "totalPages", "totalItems", "itemsPerPage", "siblingCount", "showFirstLast", "showPrevNext", "size", "variant", "class"], outputs: ["pageChange"] }, { kind: "component", type: CheckboxComponent, selector: "sefin-checkbox", inputs: ["size", "disabled", "indeterminate", "class", "label", "name", "value"], outputs: ["valueChange", "checkedChange"] }, { kind: "component", type: BadgeComponent, selector: "sefin-badge", inputs: ["variant", "size", "dot", "max", "value", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
5755
6030
  }
5756
6031
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TableComponent, decorators: [{
5757
6032
  type: Component,
5758
- args: [{ selector: 'sefin-table', standalone: true, imports: [CommonModule, PaginationComponent, CheckboxComponent, BadgeComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"sefin-table__container\">\n <!-- Header Actions Slot -->\n <div *ngIf=\"headerActionsTemplate\" class=\"sefin-table__header-actions\">\n <ng-container *ngTemplateOutlet=\"headerActionsTemplate\"></ng-container>\n </div>\n\n <!-- Loading Overlay -->\n <div *ngIf=\"loading\" class=\"sefin-table__loading\">\n <div class=\"sefin-table__loading-bar\"></div>\n <div class=\"sefin-table__loading-rows\">\n <div *ngFor=\"let i of [1, 2, 3, 4, 5]\" class=\"sefin-table__skeleton-row\">\n <div\n class=\"sefin-table__skeleton-cell\"\n *ngFor=\"let col of columns\"\n ></div>\n </div>\n </div>\n </div>\n\n <!-- Table -->\n <div\n class=\"sefin-table__wrapper\"\n [class.sefin-table__wrapper--loading]=\"loading\"\n >\n <table [class]=\"getTableClasses()\" class=\"sefin-table__native-table\">\n <!-- Table Header -->\n <thead\n class=\"sefin-table__header\"\n [class.sefin-table__header--sticky]=\"stickyHeader\"\n >\n <tr class=\"sefin-table__header-row\">\n <!-- Selection Column Header -->\n <th\n *ngIf=\"selectable\"\n class=\"sefin-table__header-cell sefin-table__header-cell--select\"\n >\n <sefin-checkbox\n *ngIf=\"selectionMode === 'multiple'\"\n [value]=\"isAllSelected()\"\n [indeterminate]=\"isIndeterminate()\"\n (checkedChange)=\"toggleSelectAll($event)\"\n [attr.aria-label]=\"'Select all rows'\"\n size=\"sm\"\n ></sefin-checkbox>\n </th>\n\n <!-- Data Column Headers -->\n <th\n *ngFor=\"let column of columns\"\n [class]=\"getColumnClass(column)\"\n [class.sefin-table__header-cell--sortable]=\"column.sortable && sort\"\n [class.sefin-table__header-cell--sorted]=\"\n currentSortColumn() === column.key\n \"\n [class.sefin-table__header-cell--sort-asc]=\"\n currentSortColumn() === column.key &&\n currentSortDirection() === 'asc'\n \"\n [class.sefin-table__header-cell--sort-desc]=\"\n currentSortColumn() === column.key &&\n currentSortDirection() === 'desc'\n \"\n [class.sefin-table__header-cell--sticky]=\"column.sticky\"\n [class.sefin-table__header-cell--sticky-end]=\"\n column.sticky && column.stickyEnd\n \"\n [style.width]=\"getColumnWidth(column)\"\n class=\"sefin-table__header-cell\"\n (click)=\"column.sortable && sort ? onSort(column) : null\"\n [attr.aria-sort]=\"\n currentSortColumn() === column.key\n ? currentSortDirection() === 'asc'\n ? 'ascending'\n : currentSortDirection() === 'desc'\n ? 'descending'\n : 'none'\n : null\n \"\n role=\"columnheader\"\n [attr.tabindex]=\"column.sortable && sort ? 0 : null\"\n >\n <span class=\"sefin-table__header-content\">\n {{ column.header }}\n <span\n *ngIf=\"column.sortable && sort\"\n class=\"sefin-table__sort-icon\"\n >\n <svg\n *ngIf=\"\n currentSortColumn() !== column.key ||\n currentSortDirection() === ''\n \"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3 4.5L6 1.5L9 4.5M3 7.5L6 10.5L9 7.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <svg\n *ngIf=\"\n currentSortColumn() === column.key &&\n currentSortDirection() === 'asc'\n \"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3 7.5L6 4.5L9 7.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <svg\n *ngIf=\"\n currentSortColumn() === column.key &&\n currentSortDirection() === 'desc'\n \"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3 4.5L6 7.5L9 4.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n </span>\n </th>\n\n <th\n *ngIf=\"hasActionsColumn()\"\n class=\"sefin-table__header-cell sefin-table__header-cell--actions\"\n ></th>\n </tr>\n </thead>\n\n <!-- Table Body -->\n <tbody class=\"sefin-table__body\">\n <!-- Data Rows -->\n <tr\n *ngFor=\"let row of displayedData(); trackBy: trackByFn\"\n class=\"sefin-table__row sefin-table__row--clickable\"\n (click)=\"onRowClick(row)\"\n >\n <!-- Selection Column Cell -->\n <td\n *ngIf=\"selectable\"\n class=\"sefin-table__cell sefin-table__cell--select\"\n >\n <sefin-checkbox\n [value]=\"isSelected(row)\"\n (checkedChange)=\"toggleRowSelection($event, row)\"\n [attr.aria-label]=\"'Select row'\"\n size=\"sm\"\n ></sefin-checkbox>\n </td>\n\n <!-- Data Column Cells -->\n <td\n *ngFor=\"let column of columns\"\n [class]=\"getColumnClass(column)\"\n [class.sefin-table__cell--sticky]=\"column.sticky\"\n [class.sefin-table__cell--sticky-end]=\"\n column.sticky && column.stickyEnd\n \"\n class=\"sefin-table__cell\"\n >\n <!-- Custom Template -->\n <ng-container *ngIf=\"column.cellTemplate\">\n <ng-container\n *ngTemplateOutlet=\"\n column.cellTemplate;\n context: {\n $implicit: row,\n column: column,\n value: getCellValue(row, column)\n }\n \"\n ></ng-container>\n </ng-container>\n\n <!-- Badge Type -->\n <ng-container\n *ngIf=\"!column.cellTemplate && column.type === 'badge'\"\n >\n <sefin-badge\n [value]=\"getCellValue(row, column)\"\n variant=\"primary\"\n size=\"sm\"\n ></sefin-badge>\n </ng-container>\n\n <!-- Actions Type -->\n <ng-container\n *ngIf=\"!column.cellTemplate && column.type === 'actions'\"\n >\n <div class=\"sefin-table__actions\">\n <ng-content select=\"[actions]\"></ng-content>\n </div>\n </ng-container>\n\n <!-- Default/Text/Number/Date Type -->\n <ng-container\n *ngIf=\"\n !column.cellTemplate &&\n column.type !== 'badge' &&\n column.type !== 'actions'\n \"\n >\n <span class=\"sefin-table__cell-content\">\n {{ formatCellValue(getCellValue(row, column), column.type) }}\n </span>\n </ng-container>\n </td>\n\n <!-- Actions Column Cell -->\n <td\n *ngIf=\"hasActionsColumn()\"\n class=\"sefin-table__cell sefin-table__cell--actions\"\n >\n <div class=\"sefin-table__actions\">\n <ng-content select=\"[actions]\"></ng-content>\n </div>\n </td>\n </tr>\n\n <!-- Empty Row -->\n <tr *ngIf=\"isEmpty()\" class=\"sefin-table__row sefin-table__row--empty\">\n <td [attr.colspan]=\"totalColspan()\" class=\"sefin-table__empty-cell\">\n <div class=\"sefin-table__empty-state\">\n <ng-container *ngIf=\"emptyIconTemplate\">\n <ng-container\n *ngTemplateOutlet=\"emptyIconTemplate\"\n ></ng-container>\n </ng-container>\n <p class=\"sefin-table__empty-text\">{{ emptyText }}</p>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n <sefin-pagination\n *ngIf=\"pagination && !isEmpty()\"\n [currentPage]=\"currentPage()\"\n [totalPages]=\"totalPages()\"\n [totalItems]=\"serverSide && total !== undefined ? total : undefined\"\n [itemsPerPage]=\"currentPageSize()\"\n (pageChange)=\"onPageChange($event)\"\n class=\"sefin-table__paginator\"\n size=\"sm\"\n ></sefin-pagination>\n</div>\n", styles: [".sefin-table{display:block;width:100%;font-family:var(--sefin-font-family-base, \"Pluto\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);background-color:var(--sefin-color-surface, #ffffff);border-radius:var(--sefin-radius-md, 8px);overflow:hidden}.sefin-table__container{display:flex;flex-direction:column;width:100%;background-color:var(--sefin-color-surface, #ffffff);border:1px solid var(--sefin-color-border, #cecece);border-radius:var(--sefin-radius-md, 8px);overflow:hidden;box-shadow:var(--sefin-shadow-sm, 0 1px 2px 0 rgba(0, 0, 0, .05));transition:box-shadow .2s ease-in-out}.sefin-table__header-actions{display:flex;justify-content:flex-end;align-items:center;padding:var(--sefin-spacing-md, 16px);border-bottom:1px solid var(--sefin-color-border, #e5e5e5);background-color:var(--sefin-color-background, #ffffff);border-radius:var(--sefin-radius-md, 8px) var(--sefin-radius-md, 8px) 0 0}.sefin-table__wrapper{position:relative;overflow-x:auto;overflow-y:visible;background-color:var(--sefin-color-surface, #ffffff)}.sefin-table__wrapper--loading{opacity:.6;pointer-events:none}.sefin-table__loading{position:absolute;inset:0;z-index:10;background-color:#fffffffa;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);display:flex;flex-direction:column;border-radius:var(--sefin-radius-md, 8px)}.sefin-table__loading-bar{height:3px;background:linear-gradient(90deg,transparent,var(--sefin-color-primary, #55C3D8),transparent);animation:loading-bar 1.5s ease-in-out infinite;width:100%;border-radius:0 var(--sefin-radius-lg, 12px) 0 0}@keyframes loading-bar{0%{transform:translate(-100%)}to{transform:translate(200%)}}.sefin-table__loading-rows{flex:1;display:flex;flex-direction:column;padding:var(--sefin-spacing-lg, 24px);gap:var(--sefin-spacing-md, 16px)}.sefin-table__skeleton-row{display:flex;gap:var(--sefin-spacing-md, 16px);padding:var(--sefin-spacing-sm, 8px) 0}.sefin-table__skeleton-cell{flex:1;height:20px;background:linear-gradient(90deg,var(--sefin-color-surface-hover, #f5f5f5) 0%,rgba(85,195,216,.15) 50%,var(--sefin-color-surface-hover, #f5f5f5) 100%);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:var(--sefin-radius-sm, 4px)}@keyframes skeleton-loading{0%{background-position:200% 0}to{background-position:-200% 0}}.sefin-table__native-table{width:100%;border-collapse:separate;border-spacing:0;background-color:var(--sefin-color-surface, #ffffff)}.sefin-table--density-compact .sefin-table__header-cell,.sefin-table--density-compact .sefin-table__cell{padding:var(--sefin-spacing-xs, 4px) var(--sefin-spacing-sm, 8px);font-size:var(--sefin-font-size-sm, .875rem);line-height:var(--sefin-line-height-normal, 1.5)}.sefin-table--density-compact .sefin-table__header-cell{padding-top:var(--sefin-spacing-sm, 8px);padding-bottom:var(--sefin-spacing-sm, 8px)}.sefin-table--density-compact .sefin-table__cell{padding-top:var(--sefin-spacing-xs, 4px);padding-bottom:var(--sefin-spacing-xs, 4px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__header-cell,.sefin-table:not(.sefin-table--density-compact) .sefin-table__cell{padding:var(--sefin-spacing-md, 16px);font-size:var(--sefin-font-size-base, 1rem);line-height:var(--sefin-line-height-normal, 1.5)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__header-cell{padding-top:var(--sefin-spacing-md, 16px);padding-bottom:var(--sefin-spacing-md, 16px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__cell{padding-top:var(--sefin-spacing-sm, 8px);padding-bottom:var(--sefin-spacing-sm, 8px)}.sefin-table__header{background-color:var(--sefin-color-background-elevated, #fafafa);border-bottom:2px solid var(--sefin-color-border, #e5e5e5)}.sefin-table__header--sticky{position:sticky;top:0;z-index:3;box-shadow:0 2px 8px #0000000f}.sefin-table__header-row{background-color:var(--sefin-color-background-elevated, #fafafa)}.sefin-table__header-cell{font-weight:var(--sefin-font-weight-semibold, 600);font-size:var(--sefin-font-size-sm, .875rem);color:var(--sefin-color-text, #383838);text-transform:uppercase;letter-spacing:.5px;text-align:left;white-space:nowrap;border-bottom:none;position:relative;background-color:var(--sefin-color-background-elevated, #fafafa);-webkit-user-select:none;user-select:none;transition:all .2s ease-in-out;z-index:1}.sefin-table__header-cell--align-left{text-align:left}.sefin-table__header-cell--align-center{text-align:center}.sefin-table__header-cell--align-right{text-align:right}.sefin-table__header-cell--select{width:56px;padding-left:var(--sefin-spacing-md, 16px);padding-right:var(--sefin-spacing-sm, 8px);text-align:center}.sefin-table__header-cell--actions{width:120px;text-align:right}.sefin-table__header-cell--sortable{cursor:pointer}.sefin-table__header-cell--sortable:hover{background-color:#55c3d814;color:var(--sefin-color-primary, #55C3D8)}.sefin-table__header-cell--sortable:hover .sefin-table__sort-icon{opacity:1;color:var(--sefin-color-primary, #55C3D8)}.sefin-table__header-cell--sortable:active{background-color:#55c3d81f}.sefin-table__header-cell--sortable:focus-visible{outline:2px solid var(--sefin-color-border-focus, #55C3D8);outline-offset:-2px;border-radius:var(--sefin-radius-sm, 4px)}.sefin-table__header-cell--sorted{color:var(--sefin-color-primary, #55C3D8);background-color:#55c3d80f}.sefin-table__header-cell--sorted .sefin-table__sort-icon{opacity:1;color:var(--sefin-color-primary, #55C3D8)}.sefin-table__header-cell--sticky{position:sticky;background-color:var(--sefin-color-background-elevated, #fafafa);z-index:2;box-shadow:2px 0 4px #0000000a}.sefin-table__header-cell--sticky:after{content:\"\";position:absolute;top:0;right:0;bottom:0;width:1px;background-color:var(--sefin-color-border, #e5e5e5);opacity:.6}.sefin-table__header-cell--sticky.sefin-table__header-cell--sticky-end{right:0;box-shadow:-2px 0 4px #0000000a}.sefin-table__header-cell--sticky.sefin-table__header-cell--sticky-end:after{left:0;right:auto}.sefin-table__header-content{display:flex;align-items:center;justify-content:flex-start;gap:var(--sefin-spacing-xs, 4px);width:100%}.sefin-table__sort-icon{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;color:var(--sefin-color-text-secondary, #9b9b9b);opacity:.4;transition:all .2s ease-in-out;flex-shrink:0;margin-left:var(--sefin-spacing-xs, 4px)}.sefin-table__sort-icon svg{display:block;width:100%;height:100%}.sefin-table__body{background-color:var(--sefin-color-surface, #ffffff)}.sefin-table__row{border-bottom:1px solid var(--sefin-color-border, #e5e5e5);transition:all .2s ease-in-out;background-color:var(--sefin-color-surface, #ffffff)}.sefin-table__row--clickable{cursor:pointer}.sefin-table__row--clickable:hover:not(.sefin-table__row--empty){background-color:#55c3d80d;box-shadow:inset 3px 0 0 var(--sefin-color-primary, #55C3D8)}.sefin-table__row--clickable:hover:not(.sefin-table__row--empty) .sefin-table__cell--sticky{background-color:#55c3d80d}.sefin-table__row--clickable:active:not(.sefin-table__row--empty){background-color:#55c3d814;box-shadow:inset 3px 0 0 var(--sefin-color-primary-dark, #3f9bb0)}.sefin-table__row--clickable:active:not(.sefin-table__row--empty) .sefin-table__cell--sticky{background-color:#55c3d814}.sefin-table__row--empty{border-bottom:none}.sefin-table__row:focus-visible{outline:2px solid var(--sefin-color-border-focus, #55C3D8);outline-offset:-2px;border-radius:var(--sefin-radius-sm, 4px)}.sefin-table__row:last-child{border-bottom:none}.sefin-table__cell{font-family:var(--sefin-font-family-base, \"Pluto\", sans-serif);font-size:var(--sefin-font-size-base, 1rem);font-weight:var(--sefin-font-weight-normal, 400);color:var(--sefin-color-text, #383838);border-bottom:none;vertical-align:middle;background-color:inherit;transition:background-color .2s ease-in-out,color .2s ease-in-out}.sefin-table__cell--align-left{text-align:left}.sefin-table__cell--align-center{text-align:center}.sefin-table__cell--align-right{text-align:right}.sefin-table__cell--select{width:56px;padding-left:var(--sefin-spacing-md, 16px);padding-right:var(--sefin-spacing-sm, 8px);text-align:center}.sefin-table__cell--actions{text-align:right;width:120px}.sefin-table__cell--sticky{position:sticky;background-color:inherit;z-index:1;box-shadow:2px 0 4px #0000000a}.sefin-table__cell--sticky:after{content:\"\";position:absolute;top:0;right:0;bottom:0;width:1px;background-color:var(--sefin-color-border, #e5e5e5);opacity:.6}.sefin-table__cell--sticky.sefin-table__cell--sticky-end{right:0;box-shadow:-2px 0 4px #0000000a}.sefin-table__cell--sticky.sefin-table__cell--sticky-end:after{left:0;right:auto}.sefin-table__cell-content{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:var(--sefin-line-height-normal, 1.5);color:var(--sefin-color-text, #383838)}.sefin-table__actions{display:flex;align-items:center;justify-content:flex-end;gap:var(--sefin-spacing-xs, 4px);flex-wrap:wrap}.sefin-table--striped .sefin-table__row:nth-child(2n){background-color:var(--sefin-color-surface, #ffffff)}.sefin-table--striped .sefin-table__row:nth-child(odd){background-color:#f8f9facc}.sefin-table--striped .sefin-table__cell--sticky:nth-child(2n){background-color:var(--sefin-color-surface, #ffffff)}.sefin-table--striped .sefin-table__cell--sticky:nth-child(odd){background-color:#f8f9facc}.sefin-table--striped .sefin-table__row--clickable:hover,.sefin-table--striped .sefin-table__row--clickable:hover .sefin-table__cell--sticky{background-color:#55c3d814!important}.sefin-table--hover .sefin-table__row:not(.sefin-table__row--empty):hover{background-color:#55c3d80d}.sefin-table--hover .sefin-table__row:not(.sefin-table__row--empty):hover .sefin-table__cell--sticky{background-color:#55c3d80d}.sefin-table--hover .sefin-table__row--clickable:not(.sefin-table__row--empty):hover{background-color:#55c3d80d}.sefin-table--hover .sefin-table__row--clickable:not(.sefin-table__row--empty):hover .sefin-table__cell--sticky{background-color:#55c3d80d}.sefin-table--sticky-header .sefin-table__header{position:sticky;top:0;z-index:3;box-shadow:0 4px 12px #00000014}.sefin-table__empty-cell{padding:var(--sefin-spacing-4xl, 96px) var(--sefin-spacing-xl, 32px);text-align:center;border-bottom:none;background-color:var(--sefin-color-surface, #ffffff)}.sefin-table__empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--sefin-spacing-lg, 24px);padding:var(--sefin-spacing-2xl, 48px);background:linear-gradient(to bottom,rgba(248,249,250,.5),transparent);border-radius:var(--sefin-radius-md, 8px);margin:var(--sefin-spacing-lg, 24px)}.sefin-table__empty-text{font-size:var(--sefin-font-size-lg, 1.125rem);font-weight:var(--sefin-font-weight-medium, 500);line-height:var(--sefin-line-height-relaxed, 1.75);color:var(--sefin-color-text-secondary, #686868);margin:0;font-family:var(--sefin-font-family-base, \"Pluto\", sans-serif);max-width:480px;letter-spacing:.2px}.sefin-table__paginator{border-top:1px solid var(--sefin-color-border, #e5e5e5);background-color:var(--sefin-color-background, #ffffff);padding:var(--sefin-spacing-md, 16px);border-radius:0 0 var(--sefin-radius-md, 8px) var(--sefin-radius-md, 8px)}.sefin-table ::ng-deep .sefin-checkbox{margin:0;transition:transform .2s ease-in-out}.sefin-table ::ng-deep .sefin-checkbox:hover{transform:scale(1.05)}.sefin-table ::ng-deep .sefin-badge{margin:0;box-shadow:0 1px 3px #0000001a;transition:transform .2s ease-in-out,box-shadow .2s ease-in-out}.sefin-table ::ng-deep .sefin-badge:hover{transform:translateY(-1px);box-shadow:0 2px 6px #00000026}.sefin-table ::ng-deep .sefin-button,.sefin-table ::ng-deep .sefin-icon-button{transition:transform .2s ease-in-out,box-shadow .2s ease-in-out}.sefin-table ::ng-deep .sefin-button:hover,.sefin-table ::ng-deep .sefin-icon-button:hover{transform:translateY(-1px)}.sefin-table ::ng-deep .sefin-button:active,.sefin-table ::ng-deep .sefin-icon-button:active{transform:translateY(0)}\n"] }]
6033
+ args: [{ selector: 'sefin-table', standalone: true, imports: [CommonModule, PaginationComponent, CheckboxComponent, BadgeComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"sefin-table__container\">\n <!-- Header Actions Slot -->\n <div *ngIf=\"headerActionsTemplate\" class=\"sefin-table__header-actions\">\n <ng-container *ngTemplateOutlet=\"headerActionsTemplate\"></ng-container>\n </div>\n\n <!-- Loading Overlay -->\n <div *ngIf=\"loading\" class=\"sefin-table__loading\">\n <div class=\"sefin-table__loading-bar\"></div>\n <div class=\"sefin-table__loading-rows\">\n <div *ngFor=\"let i of [1, 2, 3, 4, 5]\" class=\"sefin-table__skeleton-row\">\n <div\n class=\"sefin-table__skeleton-cell\"\n *ngFor=\"let col of columns\"\n ></div>\n </div>\n </div>\n </div>\n\n <!-- Table -->\n <div\n class=\"sefin-table__wrapper\"\n [class.sefin-table__wrapper--loading]=\"loading\"\n >\n <table\n [class]=\"getTableClasses()\"\n class=\"sefin-table__native-table\"\n role=\"table\"\n [attr.aria-label]=\"'Data table with ' + columns.length + ' columns'\"\n [attr.aria-rowcount]=\"serverSide && total !== undefined ? total : sortedData().length\"\n [attr.aria-colcount]=\"totalColspan()\"\n >\n <!-- Table Header -->\n <thead\n class=\"sefin-table__header\"\n [class.sefin-table__header--sticky]=\"stickyHeader\"\n >\n <tr class=\"sefin-table__header-row\">\n <!-- Selection Column Header -->\n <th\n *ngIf=\"selectable\"\n class=\"sefin-table__header-cell sefin-table__header-cell--select\"\n >\n <sefin-checkbox\n *ngIf=\"selectionMode === 'multiple'\"\n [value]=\"isAllSelected()\"\n [indeterminate]=\"isIndeterminate()\"\n (checkedChange)=\"toggleSelectAll($event)\"\n [attr.aria-label]=\"'Select all rows'\"\n size=\"sm\"\n ></sefin-checkbox>\n </th>\n\n <!-- Data Column Headers -->\n <th\n *ngFor=\"let column of columns\"\n [class]=\"getColumnClass(column)\"\n [class.sefin-table__header-cell--sortable]=\"column.sortable && sort\"\n [class.sefin-table__header-cell--sorted]=\"\n currentSortColumn() === column.key\n \"\n [class.sefin-table__header-cell--sort-asc]=\"\n currentSortColumn() === column.key &&\n currentSortDirection() === 'asc'\n \"\n [class.sefin-table__header-cell--sort-desc]=\"\n currentSortColumn() === column.key &&\n currentSortDirection() === 'desc'\n \"\n [class.sefin-table__header-cell--sticky]=\"column.sticky\"\n [class.sefin-table__header-cell--sticky-end]=\"\n column.sticky && column.stickyEnd\n \"\n [style.width]=\"getColumnWidth(column)\"\n class=\"sefin-table__header-cell\"\n (click)=\"column.sortable && sort ? onSort(column) : null\"\n (keydown)=\"column.sortable && sort ? onSort(column, $event) : null\"\n [attr.aria-sort]=\"getAriaSort(column)\"\n [attr.aria-label]=\"getSortAriaLabel(column)\"\n role=\"columnheader\"\n [attr.tabindex]=\"column.sortable && sort ? 0 : null\"\n >\n <span class=\"sefin-table__header-content\">\n {{ column.header }}\n <span\n *ngIf=\"column.sortable && sort\"\n class=\"sefin-table__sort-icon\"\n [attr.aria-hidden]=\"true\"\n >\n <svg\n *ngIf=\"showUnsortedIcon(column)\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n focusable=\"false\"\n >\n <path\n [attr.d]=\"sortIcons.unsorted\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <svg\n *ngIf=\"showAscendingIcon(column)\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n focusable=\"false\"\n >\n <path\n [attr.d]=\"sortIcons.ascending\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <svg\n *ngIf=\"showDescendingIcon(column)\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n focusable=\"false\"\n >\n <path\n [attr.d]=\"sortIcons.descending\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n </span>\n </th>\n\n <th\n *ngIf=\"hasActionsColumn()\"\n class=\"sefin-table__header-cell sefin-table__header-cell--actions\"\n ></th>\n </tr>\n </thead>\n\n <!-- Table Body -->\n <tbody class=\"sefin-table__body\" role=\"rowgroup\">\n <!-- Data Rows -->\n <tr\n *ngFor=\"let row of displayedData(); trackBy: trackByFn\"\n class=\"sefin-table__row sefin-table__row--clickable\"\n (click)=\"onRowClick(row)\"\n [attr.aria-selected]=\"selectable ? isSelected(row) : null\"\n [attr.aria-label]=\"'Row ' + (trackByFn(0, row) || '')\"\n role=\"row\"\n >\n <!-- Selection Column Cell -->\n <td\n *ngIf=\"selectable\"\n class=\"sefin-table__cell sefin-table__cell--select\"\n >\n <sefin-checkbox\n [value]=\"isSelected(row)\"\n (checkedChange)=\"toggleRowSelection($event, row)\"\n [attr.aria-label]=\"'Select row'\"\n size=\"sm\"\n ></sefin-checkbox>\n </td>\n\n <!-- Data Column Cells -->\n <td\n *ngFor=\"let column of columns\"\n [class]=\"getColumnClass(column)\"\n [class.sefin-table__cell--sticky]=\"column.sticky\"\n [class.sefin-table__cell--sticky-end]=\"\n column.sticky && column.stickyEnd\n \"\n class=\"sefin-table__cell\"\n >\n <!-- Custom Template -->\n <ng-container *ngIf=\"column.cellTemplate\">\n <ng-container\n *ngTemplateOutlet=\"\n column.cellTemplate;\n context: {\n $implicit: row,\n column: column,\n value: getCellValue(row, column)\n }\n \"\n ></ng-container>\n </ng-container>\n\n <!-- Badge Type -->\n <ng-container\n *ngIf=\"!column.cellTemplate && column.type === 'badge'\"\n >\n <sefin-badge\n [value]=\"getCellValue(row, column)\"\n variant=\"primary\"\n size=\"sm\"\n ></sefin-badge>\n </ng-container>\n\n <!-- Actions Type -->\n <ng-container\n *ngIf=\"!column.cellTemplate && column.type === 'actions'\"\n >\n <div class=\"sefin-table__actions\">\n <ng-content select=\"[actions]\"></ng-content>\n </div>\n </ng-container>\n\n <!-- Default/Text/Number/Date Type -->\n <ng-container\n *ngIf=\"\n !column.cellTemplate &&\n column.type !== 'badge' &&\n column.type !== 'actions'\n \"\n >\n <span class=\"sefin-table__cell-content\">\n {{ formatCellValue(getCellValue(row, column), column.type, column) }}\n </span>\n </ng-container>\n </td>\n\n <!-- Actions Column Cell -->\n <td\n *ngIf=\"hasActionsColumn()\"\n class=\"sefin-table__cell sefin-table__cell--actions\"\n >\n <div class=\"sefin-table__actions\">\n <ng-content select=\"[actions]\"></ng-content>\n </div>\n </td>\n </tr>\n\n <!-- Empty Row -->\n <tr *ngIf=\"isEmpty()\" class=\"sefin-table__row sefin-table__row--empty\">\n <td [attr.colspan]=\"totalColspan()\" class=\"sefin-table__empty-cell\">\n <div class=\"sefin-table__empty-state\">\n <ng-container *ngIf=\"emptyIconTemplate\">\n <ng-container\n *ngTemplateOutlet=\"emptyIconTemplate\"\n ></ng-container>\n </ng-container>\n <p class=\"sefin-table__empty-text\">{{ emptyText }}</p>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n <sefin-pagination\n *ngIf=\"pagination && !isEmpty()\"\n [currentPage]=\"currentPage()\"\n [totalPages]=\"totalPages()\"\n [totalItems]=\"serverSide && total !== undefined ? total : undefined\"\n [itemsPerPage]=\"currentPageSize()\"\n (pageChange)=\"onPageChange($event)\"\n class=\"sefin-table__paginator\"\n size=\"sm\"\n ></sefin-pagination>\n</div>\n", styles: [".sefin-table{display:block;width:100%;font-family:var(--sefin-font-family-base, \"Pluto\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);background-color:var(--sefin-color-surface, #ffffff);border-radius:var(--sefin-radius-md, 8px);overflow:hidden}.sefin-table__container{display:flex;flex-direction:column;width:100%;background-color:var(--sefin-color-surface, #ffffff);border:1px solid rgba(0,0,0,.06);border-radius:var(--sefin-radius-lg, 12px);overflow:hidden;box-shadow:0 2px 8px #0000000a,0 1px 2px #00000005;transition:box-shadow .3s ease-in-out,border-color .3s ease-in-out}.sefin-table__header-actions{display:flex;justify-content:flex-end;align-items:center;padding:var(--sefin-spacing-md, 16px);border-bottom:1px solid var(--sefin-color-border, #e5e5e5);background-color:var(--sefin-color-background, #ffffff);border-radius:var(--sefin-radius-md, 8px) var(--sefin-radius-md, 8px) 0 0}.sefin-table__wrapper{position:relative;overflow-x:auto;overflow-y:visible;background-color:var(--sefin-color-surface, #ffffff)}.sefin-table__wrapper--loading{opacity:.6;pointer-events:none}.sefin-table__loading{position:absolute;inset:0;z-index:10;background-color:#fffffffa;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);display:flex;flex-direction:column;border-radius:var(--sefin-radius-md, 8px)}.sefin-table__loading-bar{height:3px;background:linear-gradient(90deg,transparent,var(--sefin-color-primary, #55C3D8),transparent);animation:loading-bar 1.5s ease-in-out infinite;width:100%;border-radius:0 var(--sefin-radius-lg, 12px) 0 0}@keyframes loading-bar{0%{transform:translate(-100%)}to{transform:translate(200%)}}.sefin-table__loading-rows{flex:1;display:flex;flex-direction:column;padding:var(--sefin-spacing-lg, 24px);gap:var(--sefin-spacing-md, 16px)}.sefin-table__skeleton-row{display:flex;gap:var(--sefin-spacing-md, 16px);padding:var(--sefin-spacing-sm, 8px) 0}.sefin-table__skeleton-cell{flex:1;height:20px;background:linear-gradient(90deg,var(--sefin-color-surface-hover, #f5f5f5) 0%,rgba(85,195,216,.15) 50%,var(--sefin-color-surface-hover, #f5f5f5) 100%);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:var(--sefin-radius-sm, 4px)}@keyframes skeleton-loading{0%{background-position:200% 0}to{background-position:-200% 0}}.sefin-table__native-table{width:100%;border-collapse:separate;border-spacing:0;background-color:var(--sefin-color-surface, #ffffff);table-layout:auto;min-width:100%}.sefin-table--density-compact .sefin-table__header-cell:not(.sefin-table__header-cell--select):not(.sefin-table__header-cell--actions),.sefin-table--density-compact .sefin-table__cell:not(.sefin-table__cell--select):not(.sefin-table__cell--actions){padding:var(--sefin-spacing-xs, 4px) var(--sefin-spacing-sm, 8px);font-size:var(--sefin-font-size-sm, .875rem);line-height:var(--sefin-line-height-normal, 1.5)}.sefin-table--density-compact .sefin-table__header-cell:not(.sefin-table__header-cell--select):not(.sefin-table__header-cell--actions){padding-top:var(--sefin-spacing-sm, 8px);padding-bottom:var(--sefin-spacing-sm, 8px)}.sefin-table--density-compact .sefin-table__cell:not(.sefin-table__cell--select):not(.sefin-table__cell--actions){padding-top:var(--sefin-spacing-xs, 4px);padding-bottom:var(--sefin-spacing-xs, 4px)}.sefin-table--density-compact .sefin-table__header-cell--select,.sefin-table--density-compact .sefin-table__cell--select{padding:var(--sefin-spacing-sm, 8px) var(--sefin-spacing-sm, 8px) var(--sefin-spacing-sm, 8px) var(--sefin-spacing-md, 16px)!important}.sefin-table--density-compact .sefin-table__header-cell--actions,.sefin-table--density-compact .sefin-table__cell--actions{padding:var(--sefin-spacing-sm, 8px) var(--sefin-spacing-md, 16px)!important}.sefin-table:not(.sefin-table--density-compact) .sefin-table__header-cell:not(.sefin-table__header-cell--select):not(.sefin-table__header-cell--actions),.sefin-table:not(.sefin-table--density-compact) .sefin-table__cell:not(.sefin-table__cell--select):not(.sefin-table__cell--actions){font-size:var(--sefin-font-size-base, 1rem);line-height:var(--sefin-line-height-normal, 1.5);padding-left:var(--sefin-spacing-lg, 24px);padding-right:var(--sefin-spacing-lg, 24px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__header-cell:not(.sefin-table__header-cell--select):not(.sefin-table__header-cell--actions){padding-top:var(--sefin-spacing-lg, 24px);padding-bottom:var(--sefin-spacing-lg, 24px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__cell:not(.sefin-table__cell--select):not(.sefin-table__cell--actions){padding-top:var(--sefin-spacing-md, 16px);padding-bottom:var(--sefin-spacing-md, 16px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__header-cell--select,.sefin-table:not(.sefin-table--density-compact) .sefin-table__cell--select{font-size:var(--sefin-font-size-base, 1rem);line-height:var(--sefin-line-height-normal, 1.5);padding-left:var(--sefin-spacing-lg, 24px);padding-right:var(--sefin-spacing-sm, 8px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__header-cell--select{padding-top:var(--sefin-spacing-lg, 24px);padding-bottom:var(--sefin-spacing-lg, 24px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__cell--select{padding-top:var(--sefin-spacing-md, 16px);padding-bottom:var(--sefin-spacing-md, 16px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__header-cell--actions,.sefin-table:not(.sefin-table--density-compact) .sefin-table__cell--actions{font-size:var(--sefin-font-size-base, 1rem);line-height:var(--sefin-line-height-normal, 1.5);padding-left:var(--sefin-spacing-lg, 24px);padding-right:var(--sefin-spacing-lg, 24px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__header-cell--actions{padding-top:var(--sefin-spacing-lg, 24px);padding-bottom:var(--sefin-spacing-lg, 24px)}.sefin-table:not(.sefin-table--density-compact) .sefin-table__cell--actions{padding-top:var(--sefin-spacing-md, 16px);padding-bottom:var(--sefin-spacing-md, 16px)}.sefin-table__header{background:linear-gradient(to bottom,#fff,#fafafa);border-bottom:1px solid rgba(0,0,0,.08);position:relative}.sefin-table__header:after{content:\"\";position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(to right,transparent 0%,rgba(0,0,0,.06) 50%,transparent 100%)}.sefin-table__header--sticky{position:sticky;top:0;z-index:3;box-shadow:0 4px 12px #00000014,0 2px 4px #0000000a}.sefin-table__header-row{background:transparent}.sefin-table__header-cell{font-weight:var(--sefin-font-weight-semibold, 600);font-size:var(--sefin-font-size-xs, .75rem);color:var(--sefin-color-text-secondary, #6b7280);text-transform:uppercase;letter-spacing:.8px;text-align:left;border-bottom:none;background:transparent;-webkit-user-select:none;user-select:none;transition:background-color .25s cubic-bezier(.4,0,.2,1),color .25s cubic-bezier(.4,0,.2,1);z-index:1}.sefin-table__header-cell--align-left{text-align:left}.sefin-table__header-cell--align-center{text-align:center}.sefin-table__header-cell--align-right{text-align:right}.sefin-table__header-cell--select{width:56px;text-align:center}.sefin-table__header-cell--actions{width:120px;text-align:right}.sefin-table__header-cell--sortable{cursor:pointer}.sefin-table__header-cell--sortable:hover{background-color:#55c3d80f;color:var(--sefin-color-primary, #55C3D8)}.sefin-table__header-cell--sortable:hover .sefin-table__sort-icon{opacity:1;color:var(--sefin-color-primary, #55C3D8);transform:scale(1.1)}.sefin-table__header-cell--sortable:active{background-color:#55c3d81a}.sefin-table__header-cell--sortable:focus-visible{outline:2px solid var(--sefin-color-border-focus, #55C3D8);outline-offset:-2px;border-radius:var(--sefin-radius-sm, 4px)}.sefin-table__header-cell--sorted{color:var(--sefin-color-primary, #55C3D8);background:linear-gradient(to bottom,#55c3d814,#55c3d80a)}.sefin-table__header-cell--sorted .sefin-table__sort-icon{opacity:1;color:var(--sefin-color-primary, #55C3D8)}.sefin-table__header-cell--sticky{position:sticky;background-color:var(--sefin-color-background-elevated, #fafafa);z-index:2}.sefin-table__header-content{display:flex;align-items:center;justify-content:flex-start;gap:var(--sefin-spacing-xs, 4px);width:100%}.sefin-table__sort-icon{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;min-width:14px;color:var(--sefin-color-text-secondary, #9b9b9b);opacity:.5;transition:all .25s cubic-bezier(.4,0,.2,1);flex-shrink:0;margin-left:var(--sefin-spacing-xs, 4px)}.sefin-table__sort-icon svg{display:block;width:100%;height:100%;transition:transform .2s ease-out}.sefin-table__header-cell--sortable:hover .sefin-table__sort-icon{opacity:1;transform:scale(1.1)}.sefin-table__header-cell--sortable:hover .sefin-table__sort-icon svg{transform:scale(1.05)}.sefin-table__body{background-color:var(--sefin-color-surface, #ffffff)}.sefin-table__row{border-bottom:1px solid rgba(0,0,0,.04);transition:background-color .25s cubic-bezier(.4,0,.2,1),transform .15s ease-out;background-color:var(--sefin-color-surface, #ffffff);position:relative}.sefin-table__row--clickable{cursor:pointer}.sefin-table__row--clickable:hover:not(.sefin-table__row--empty){background-color:#55c3d80a;transform:translateY(-1px);box-shadow:0 2px 4px #00000005}.sefin-table__row--clickable:hover:not(.sefin-table__row--empty) .sefin-table__cell--sticky{background-color:#55c3d80a}.sefin-table__row--clickable:active:not(.sefin-table__row--empty){background-color:#55c3d80f;transform:translateY(0);box-shadow:none}.sefin-table__row--clickable:active:not(.sefin-table__row--empty) .sefin-table__cell--sticky{background-color:#55c3d80f}.sefin-table__row--empty{border-bottom:none}.sefin-table__row:focus-visible{outline:2px solid var(--sefin-color-border-focus, #55C3D8);outline-offset:-2px;border-radius:var(--sefin-radius-sm, 4px);z-index:1}.sefin-table__row:last-child{border-bottom:none}.sefin-table__row[data-animate]{animation:fadeInRow .3s ease-in-out}@keyframes fadeInRow{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.sefin-table__cell{font-family:var(--sefin-font-family-base, \"Pluto\", sans-serif);font-size:var(--sefin-font-size-base, 1rem);font-weight:var(--sefin-font-weight-normal, 400);color:var(--sefin-color-text, #1f2937);border-bottom:none;vertical-align:middle;background-color:inherit;transition:background-color .25s cubic-bezier(.4,0,.2,1),color .25s cubic-bezier(.4,0,.2,1)}.sefin-table__cell--align-left{text-align:left}.sefin-table__cell--align-center{text-align:center}.sefin-table__cell--align-right{text-align:right}.sefin-table__cell--select{width:56px;text-align:center}.sefin-table__cell--actions{text-align:right;width:120px}.sefin-table__cell--sticky{position:sticky;background-color:inherit;z-index:1}.sefin-table__cell-content{display:block;line-height:var(--sefin-line-height-relaxed, 1.75);color:var(--sefin-color-text, #1f2937);font-weight:var(--sefin-font-weight-normal, 400);word-wrap:break-word;word-break:break-word;max-width:100%;overflow:hidden;text-overflow:ellipsis;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.sefin-table__actions{display:flex;align-items:center;justify-content:flex-end;gap:var(--sefin-spacing-xs, 4px);flex-wrap:wrap}.sefin-table--striped .sefin-table__row:nth-child(2n){background-color:var(--sefin-color-surface, #ffffff)}.sefin-table--striped .sefin-table__row:nth-child(odd){background-color:#f9fafb99}.sefin-table--striped .sefin-table__cell--sticky:nth-child(2n){background-color:var(--sefin-color-surface, #ffffff)}.sefin-table--striped .sefin-table__cell--sticky:nth-child(odd){background-color:#f9fafb99}.sefin-table--striped .sefin-table__row--clickable:hover,.sefin-table--striped .sefin-table__row--clickable:hover .sefin-table__cell--sticky{background-color:#55c3d80f!important}.sefin-table--hover .sefin-table__row:not(.sefin-table__row--empty):hover{background-color:#55c3d80a}.sefin-table--hover .sefin-table__row:not(.sefin-table__row--empty):hover .sefin-table__cell--sticky{background-color:#55c3d80a}.sefin-table--hover .sefin-table__row--clickable:not(.sefin-table__row--empty):hover{background-color:#55c3d80a}.sefin-table--hover .sefin-table__row--clickable:not(.sefin-table__row--empty):hover .sefin-table__cell--sticky{background-color:#55c3d80a}.sefin-table--sticky-header .sefin-table__header{position:sticky;top:0;z-index:3;box-shadow:0 4px 16px #00000014,0 2px 4px #0000000a}.sefin-table__empty-cell{padding:var(--sefin-spacing-4xl, 96px) var(--sefin-spacing-xl, 32px);text-align:center;border-bottom:none;background-color:var(--sefin-color-surface, #ffffff)}.sefin-table__empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--sefin-spacing-lg, 24px);padding:var(--sefin-spacing-2xl, 48px);background:linear-gradient(to bottom,rgba(248,249,250,.5),transparent);border-radius:var(--sefin-radius-md, 8px);margin:var(--sefin-spacing-lg, 24px)}.sefin-table__empty-text{font-size:var(--sefin-font-size-lg, 1.125rem);font-weight:var(--sefin-font-weight-medium, 500);line-height:var(--sefin-line-height-relaxed, 1.75);color:var(--sefin-color-text-secondary, #686868);margin:0;font-family:var(--sefin-font-family-base, \"Pluto\", sans-serif);max-width:480px;letter-spacing:.2px}.sefin-table__paginator{background-color:var(--sefin-color-background, #ffffff);padding:var(--sefin-spacing-lg, 24px) var(--sefin-spacing-md, 16px);border-radius:0 0 var(--sefin-radius-lg, 12px) var(--sefin-radius-lg, 12px);display:flex;justify-content:flex-end;align-items:center}.sefin-table ::ng-deep .sefin-checkbox{margin:0;transition:transform .2s ease-in-out}.sefin-table ::ng-deep .sefin-checkbox:hover{transform:scale(1.05)}.sefin-table ::ng-deep .sefin-badge{margin:0;box-shadow:0 1px 3px #0000001a;transition:transform .2s ease-in-out,box-shadow .2s ease-in-out}.sefin-table ::ng-deep .sefin-badge:hover{transform:translateY(-1px);box-shadow:0 2px 6px #00000026}.sefin-table ::ng-deep .sefin-button,.sefin-table ::ng-deep .sefin-icon-button{transition:transform .2s ease-in-out,box-shadow .2s ease-in-out}.sefin-table ::ng-deep .sefin-button:hover,.sefin-table ::ng-deep .sefin-icon-button:hover{transform:translateY(-1px)}.sefin-table ::ng-deep .sefin-button:active,.sefin-table ::ng-deep .sefin-icon-button:active{transform:translateY(0)}\n"] }]
5759
6034
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { columns: [{
5760
6035
  type: Input
5761
6036
  }], data: [{