@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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
5479
|
-
const
|
|
5480
|
-
|
|
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
|
|
5521
|
-
|
|
5522
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
5639
|
-
|
|
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
|
-
|
|
5650
|
-
|
|
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
|
-
|
|
5669
|
-
const newItems = currentPageData.filter((row) => !
|
|
5670
|
-
|
|
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 =
|
|
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
|
|
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: [{
|