@lesterarte/sefin-ui 0.0.20-dev.14 → 0.0.20-dev.16
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.
|
@@ -1940,7 +1940,6 @@ class TypographyComponent {
|
|
|
1940
1940
|
color = 'text';
|
|
1941
1941
|
lineHeight;
|
|
1942
1942
|
class = '';
|
|
1943
|
-
text;
|
|
1944
1943
|
get typographyClasses() {
|
|
1945
1944
|
return [
|
|
1946
1945
|
'sefin-typography',
|
|
@@ -1955,11 +1954,11 @@ class TypographyComponent {
|
|
|
1955
1954
|
.join(' ');
|
|
1956
1955
|
}
|
|
1957
1956
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TypographyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1958
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: TypographyComponent, isStandalone: true, selector: "sefin-typography", inputs: { variant: "variant", size: "size", weight: "weight", color: "color", lineHeight: "lineHeight", class: "class"
|
|
1957
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: TypographyComponent, isStandalone: true, selector: "sefin-typography", inputs: { variant: "variant", size: "size", weight: "weight", color: "color", lineHeight: "lineHeight", class: "class" }, ngImport: i0, template: "<ng-container [ngSwitch]=\"variant\">\n <h1 *ngSwitchCase=\"'h1'\" [class]=\"typographyClasses\"><ng-content></ng-content></h1>\n <h2 *ngSwitchCase=\"'h2'\" [class]=\"typographyClasses\"><ng-content></ng-content></h2>\n <h3 *ngSwitchCase=\"'h3'\" [class]=\"typographyClasses\"><ng-content></ng-content></h3>\n <h4 *ngSwitchCase=\"'h4'\" [class]=\"typographyClasses\"><ng-content></ng-content></h4>\n <h5 *ngSwitchCase=\"'h5'\" [class]=\"typographyClasses\"><ng-content></ng-content></h5>\n <h6 *ngSwitchCase=\"'h6'\" [class]=\"typographyClasses\"><ng-content></ng-content></h6>\n <p *ngSwitchCase=\"'p'\" [class]=\"typographyClasses\"><ng-content></ng-content></p>\n <span *ngSwitchDefault [class]=\"typographyClasses\"><ng-content></ng-content></span>\n</ng-container>\n", styles: [".sefin-typography{font-family:var(--sefin-font-family-base);margin:0;padding:0}.sefin-typography--h1{font-size:var(--sefin-font-size-4xl);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h2{font-size:var(--sefin-font-size-3xl);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h3{font-size:var(--sefin-font-size-2xl);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h4{font-size:var(--sefin-font-size-xl);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h5{font-size:var(--sefin-font-size-lg);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h6{font-size:var(--sefin-font-size-base);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--p,.sefin-typography--span{font-size:var(--sefin-font-size-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal)}.sefin-typography--xs{font-size:var(--sefin-font-size-xs)}.sefin-typography--sm{font-size:var(--sefin-font-size-sm)}.sefin-typography--base{font-size:var(--sefin-font-size-base)}.sefin-typography--lg{font-size:var(--sefin-font-size-lg)}.sefin-typography--xl{font-size:var(--sefin-font-size-xl)}.sefin-typography--2xl{font-size:var(--sefin-font-size-2xl)}.sefin-typography--3xl{font-size:var(--sefin-font-size-3xl)}.sefin-typography--4xl{font-size:var(--sefin-font-size-4xl)}.sefin-typography--5xl{font-size:var(--sefin-font-size-5xl)}.sefin-typography--light{font-weight:var(--sefin-font-weight-light)}.sefin-typography--normal{font-weight:var(--sefin-font-weight-normal)}.sefin-typography--medium{font-weight:var(--sefin-font-weight-medium)}.sefin-typography--semibold{font-weight:var(--sefin-font-weight-semibold)}.sefin-typography--bold{font-weight:var(--sefin-font-weight-bold)}.sefin-typography--text{color:var(--sefin-color-text)}.sefin-typography--text-secondary{color:var(--sefin-color-text-secondary)}.sefin-typography--text-disabled{color:var(--sefin-color-text-disabled)}.sefin-typography--primary{color:var(--sefin-color-primary)}.sefin-typography--secondary{color:var(--sefin-color-secondary)}.sefin-typography--success{color:var(--sefin-color-success)}.sefin-typography--warning{color:var(--sefin-color-warning)}.sefin-typography--error{color:var(--sefin-color-error)}.sefin-typography--line-height-tight{line-height:var(--sefin-line-height-tight)}.sefin-typography--line-height-normal{line-height:var(--sefin-line-height-normal)}.sefin-typography--line-height-relaxed{line-height:var(--sefin-line-height-relaxed)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }], changeDetection: i0.ChangeDetectionStrategy.Default });
|
|
1959
1958
|
}
|
|
1960
1959
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TypographyComponent, decorators: [{
|
|
1961
1960
|
type: Component,
|
|
1962
|
-
args: [{ selector: 'sefin-typography', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.Default, template: "<ng-container [ngSwitch]=\"variant\">\n <h1 *ngSwitchCase=\"'h1'\" [class]=\"typographyClasses\"
|
|
1961
|
+
args: [{ selector: 'sefin-typography', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.Default, template: "<ng-container [ngSwitch]=\"variant\">\n <h1 *ngSwitchCase=\"'h1'\" [class]=\"typographyClasses\"><ng-content></ng-content></h1>\n <h2 *ngSwitchCase=\"'h2'\" [class]=\"typographyClasses\"><ng-content></ng-content></h2>\n <h3 *ngSwitchCase=\"'h3'\" [class]=\"typographyClasses\"><ng-content></ng-content></h3>\n <h4 *ngSwitchCase=\"'h4'\" [class]=\"typographyClasses\"><ng-content></ng-content></h4>\n <h5 *ngSwitchCase=\"'h5'\" [class]=\"typographyClasses\"><ng-content></ng-content></h5>\n <h6 *ngSwitchCase=\"'h6'\" [class]=\"typographyClasses\"><ng-content></ng-content></h6>\n <p *ngSwitchCase=\"'p'\" [class]=\"typographyClasses\"><ng-content></ng-content></p>\n <span *ngSwitchDefault [class]=\"typographyClasses\"><ng-content></ng-content></span>\n</ng-container>\n", styles: [".sefin-typography{font-family:var(--sefin-font-family-base);margin:0;padding:0}.sefin-typography--h1{font-size:var(--sefin-font-size-4xl);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h2{font-size:var(--sefin-font-size-3xl);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h3{font-size:var(--sefin-font-size-2xl);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h4{font-size:var(--sefin-font-size-xl);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h5{font-size:var(--sefin-font-size-lg);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--h6{font-size:var(--sefin-font-size-base);font-weight:var(--sefin-font-weight-bold);line-height:var(--sefin-line-height-tight)}.sefin-typography--p,.sefin-typography--span{font-size:var(--sefin-font-size-base);font-weight:var(--sefin-font-weight-normal);line-height:var(--sefin-line-height-normal)}.sefin-typography--xs{font-size:var(--sefin-font-size-xs)}.sefin-typography--sm{font-size:var(--sefin-font-size-sm)}.sefin-typography--base{font-size:var(--sefin-font-size-base)}.sefin-typography--lg{font-size:var(--sefin-font-size-lg)}.sefin-typography--xl{font-size:var(--sefin-font-size-xl)}.sefin-typography--2xl{font-size:var(--sefin-font-size-2xl)}.sefin-typography--3xl{font-size:var(--sefin-font-size-3xl)}.sefin-typography--4xl{font-size:var(--sefin-font-size-4xl)}.sefin-typography--5xl{font-size:var(--sefin-font-size-5xl)}.sefin-typography--light{font-weight:var(--sefin-font-weight-light)}.sefin-typography--normal{font-weight:var(--sefin-font-weight-normal)}.sefin-typography--medium{font-weight:var(--sefin-font-weight-medium)}.sefin-typography--semibold{font-weight:var(--sefin-font-weight-semibold)}.sefin-typography--bold{font-weight:var(--sefin-font-weight-bold)}.sefin-typography--text{color:var(--sefin-color-text)}.sefin-typography--text-secondary{color:var(--sefin-color-text-secondary)}.sefin-typography--text-disabled{color:var(--sefin-color-text-disabled)}.sefin-typography--primary{color:var(--sefin-color-primary)}.sefin-typography--secondary{color:var(--sefin-color-secondary)}.sefin-typography--success{color:var(--sefin-color-success)}.sefin-typography--warning{color:var(--sefin-color-warning)}.sefin-typography--error{color:var(--sefin-color-error)}.sefin-typography--line-height-tight{line-height:var(--sefin-line-height-tight)}.sefin-typography--line-height-normal{line-height:var(--sefin-line-height-normal)}.sefin-typography--line-height-relaxed{line-height:var(--sefin-line-height-relaxed)}\n"] }]
|
|
1963
1962
|
}], propDecorators: { variant: [{
|
|
1964
1963
|
type: Input
|
|
1965
1964
|
}], size: [{
|
|
@@ -1972,8 +1971,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
1972
1971
|
type: Input
|
|
1973
1972
|
}], class: [{
|
|
1974
1973
|
type: Input
|
|
1975
|
-
}], text: [{
|
|
1976
|
-
type: Input
|
|
1977
1974
|
}] } });
|
|
1978
1975
|
|
|
1979
1976
|
class DividerComponent {
|
|
@@ -5382,6 +5379,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
5382
5379
|
* Molecules index
|
|
5383
5380
|
*/
|
|
5384
5381
|
|
|
5382
|
+
/**
|
|
5383
|
+
* SVG icon paths for sort indicators
|
|
5384
|
+
*/
|
|
5385
|
+
const SORT_ICONS = {
|
|
5386
|
+
unsorted: 'M3 4.5L6 1.5L9 4.5M3 7.5L6 10.5L9 7.5',
|
|
5387
|
+
ascending: 'M3 7.5L6 4.5L9 7.5',
|
|
5388
|
+
descending: 'M3 4.5L6 7.5L9 4.5',
|
|
5389
|
+
};
|
|
5385
5390
|
/**
|
|
5386
5391
|
* Helper function to build displayed columns array including selection and actions
|
|
5387
5392
|
*/
|
|
@@ -5451,6 +5456,7 @@ class TableComponent {
|
|
|
5451
5456
|
currentPageSize = signal(this.pageSize, ...(ngDevMode ? [{ debugName: "currentPageSize" }] : []));
|
|
5452
5457
|
// Computed sorted and paginated data
|
|
5453
5458
|
sortedData = computed(() => {
|
|
5459
|
+
// Early returns for performance
|
|
5454
5460
|
if (!this.sort || !this.currentSortColumn() || this.serverSide) {
|
|
5455
5461
|
return this.data;
|
|
5456
5462
|
}
|
|
@@ -5462,22 +5468,43 @@ class TableComponent {
|
|
|
5462
5468
|
if (!direction) {
|
|
5463
5469
|
return this.data;
|
|
5464
5470
|
}
|
|
5471
|
+
// Early return if no data to sort
|
|
5472
|
+
if (!this.data || this.data.length === 0) {
|
|
5473
|
+
return this.data;
|
|
5474
|
+
}
|
|
5475
|
+
// Create a copy to avoid mutating original data
|
|
5465
5476
|
const sorted = [...this.data].sort((a, b) => {
|
|
5466
5477
|
const aValue = this.getCellValue(a, column);
|
|
5467
5478
|
const bValue = this.getCellValue(b, column);
|
|
5479
|
+
// Handle null/undefined values - place them at the end
|
|
5480
|
+
if (aValue === null || aValue === undefined) {
|
|
5481
|
+
return 1;
|
|
5482
|
+
}
|
|
5483
|
+
if (bValue === null || bValue === undefined) {
|
|
5484
|
+
return -1;
|
|
5485
|
+
}
|
|
5468
5486
|
let comparison = 0;
|
|
5469
5487
|
if (column.type === 'number') {
|
|
5470
|
-
|
|
5488
|
+
const aNum = typeof aValue === 'number' ? aValue : Number(aValue);
|
|
5489
|
+
const bNum = typeof bValue === 'number' ? bValue : Number(bValue);
|
|
5490
|
+
comparison = (isNaN(aNum) ? 0 : aNum) - (isNaN(bNum) ? 0 : bNum);
|
|
5471
5491
|
}
|
|
5472
5492
|
else if (column.type === 'date') {
|
|
5473
5493
|
const aDate = this.parseDate(aValue);
|
|
5474
5494
|
const bDate = this.parseDate(bValue);
|
|
5475
|
-
|
|
5495
|
+
// Handle invalid dates
|
|
5496
|
+
const aTime = isNaN(aDate.getTime()) ? 0 : aDate.getTime();
|
|
5497
|
+
const bTime = isNaN(bDate.getTime()) ? 0 : bDate.getTime();
|
|
5498
|
+
comparison = aTime - bTime;
|
|
5476
5499
|
}
|
|
5477
5500
|
else {
|
|
5478
|
-
|
|
5479
|
-
const
|
|
5480
|
-
|
|
5501
|
+
// Use locale-aware string comparison for better internationalization
|
|
5502
|
+
const aStr = String(aValue || '').trim();
|
|
5503
|
+
const bStr = String(bValue || '').trim();
|
|
5504
|
+
comparison = aStr.localeCompare(bStr, undefined, {
|
|
5505
|
+
sensitivity: 'base',
|
|
5506
|
+
numeric: true,
|
|
5507
|
+
});
|
|
5481
5508
|
}
|
|
5482
5509
|
return direction === 'asc' ? comparison : -comparison;
|
|
5483
5510
|
});
|
|
@@ -5492,6 +5519,7 @@ class TableComponent {
|
|
|
5492
5519
|
return this.sortedData().slice(startIndex, endIndex);
|
|
5493
5520
|
}, ...(ngDevMode ? [{ debugName: "paginatedData" }] : []));
|
|
5494
5521
|
displayedData = computed(() => {
|
|
5522
|
+
// Directly return paginated data (no need for intermediate computation)
|
|
5495
5523
|
return this.paginatedData();
|
|
5496
5524
|
}, ...(ngDevMode ? [{ debugName: "displayedData" }] : []));
|
|
5497
5525
|
totalPages = computed(() => {
|
|
@@ -5516,76 +5544,180 @@ class TableComponent {
|
|
|
5516
5544
|
return false;
|
|
5517
5545
|
}
|
|
5518
5546
|
const currentPageData = this.displayedData();
|
|
5547
|
+
if (currentPageData.length === 0) {
|
|
5548
|
+
return false;
|
|
5549
|
+
}
|
|
5519
5550
|
const currentPageIds = new Set(currentPageData.map((row) => this.getItemId(row)));
|
|
5520
|
-
const
|
|
5521
|
-
|
|
5522
|
-
|
|
5551
|
+
const selectedItems = this.selectedItems();
|
|
5552
|
+
const selectedInPage = selectedItems.filter((item) => currentPageIds.has(this.getItemId(item)));
|
|
5553
|
+
return selectedInPage.length === currentPageData.length;
|
|
5523
5554
|
}, ...(ngDevMode ? [{ debugName: "isAllSelected" }] : []));
|
|
5524
5555
|
isIndeterminate = computed(() => {
|
|
5525
5556
|
if (!this.selectable || this.selectionMode === 'single') {
|
|
5526
5557
|
return false;
|
|
5527
5558
|
}
|
|
5528
5559
|
const currentPageData = this.displayedData();
|
|
5560
|
+
if (currentPageData.length === 0) {
|
|
5561
|
+
return false;
|
|
5562
|
+
}
|
|
5529
5563
|
const currentPageIds = new Set(currentPageData.map((row) => this.getItemId(row)));
|
|
5530
|
-
const
|
|
5564
|
+
const selectedItems = this.selectedItems();
|
|
5565
|
+
const selectedInPage = selectedItems.filter((item) => currentPageIds.has(this.getItemId(item)));
|
|
5531
5566
|
return (selectedInPage.length > 0 &&
|
|
5532
5567
|
selectedInPage.length < currentPageData.length);
|
|
5533
5568
|
}, ...(ngDevMode ? [{ debugName: "isIndeterminate" }] : []));
|
|
5569
|
+
// Expose sort icons to template
|
|
5570
|
+
sortIcons = SORT_ICONS;
|
|
5534
5571
|
constructor(cdr) {
|
|
5535
5572
|
this.cdr = cdr;
|
|
5536
5573
|
}
|
|
5537
5574
|
ngOnInit() {
|
|
5538
5575
|
this.currentPageSize.set(this.pageSize);
|
|
5576
|
+
this.validateInputs();
|
|
5539
5577
|
}
|
|
5540
5578
|
ngOnChanges(changes) {
|
|
5541
5579
|
if (changes['pageSize']) {
|
|
5542
|
-
|
|
5580
|
+
const newPageSize = changes['pageSize'].currentValue;
|
|
5581
|
+
if (newPageSize && newPageSize > 0) {
|
|
5582
|
+
this.currentPageSize.set(newPageSize);
|
|
5583
|
+
}
|
|
5543
5584
|
}
|
|
5544
5585
|
if (changes['data'] && this.serverSide) {
|
|
5545
5586
|
this.cdr.markForCheck();
|
|
5546
5587
|
}
|
|
5588
|
+
if (changes['columns'] || changes['data']) {
|
|
5589
|
+
this.validateInputs();
|
|
5590
|
+
}
|
|
5591
|
+
}
|
|
5592
|
+
/**
|
|
5593
|
+
* Validates component inputs and logs warnings for invalid configurations
|
|
5594
|
+
* @private
|
|
5595
|
+
*/
|
|
5596
|
+
validateInputs() {
|
|
5597
|
+
if (this.columns && this.columns.length > 0) {
|
|
5598
|
+
// Check for duplicate column keys
|
|
5599
|
+
const keys = this.columns.map((col) => col.key);
|
|
5600
|
+
const duplicates = keys.filter((key, index) => keys.indexOf(key) !== index);
|
|
5601
|
+
if (duplicates.length > 0) {
|
|
5602
|
+
console.warn(`[sefin-table] Duplicate column keys detected: ${duplicates.join(', ')}`);
|
|
5603
|
+
}
|
|
5604
|
+
// Check for columns with sortable=true but sort=false
|
|
5605
|
+
const sortableColumns = this.columns.filter((col) => col.sortable);
|
|
5606
|
+
if (sortableColumns.length > 0 && !this.sort) {
|
|
5607
|
+
console.warn(`[sefin-table] Columns with sortable=true found but sort input is false. Sorting will be disabled.`);
|
|
5608
|
+
}
|
|
5609
|
+
}
|
|
5610
|
+
if (this.selectable && this.selectionMode === 'multiple' && !this.trackByKey) {
|
|
5611
|
+
console.warn(`[sefin-table] selectable is true but trackByKey is not set. Row selection may not work correctly.`);
|
|
5612
|
+
}
|
|
5613
|
+
if (this.pagination && this.pageSize <= 0) {
|
|
5614
|
+
console.warn(`[sefin-table] pagination is enabled but pageSize is ${this.pageSize}. Using default value of 10.`);
|
|
5615
|
+
}
|
|
5547
5616
|
}
|
|
5548
5617
|
trackByFn(index, item) {
|
|
5549
5618
|
return item[this.trackByKey] !== undefined ? item[this.trackByKey] : index;
|
|
5550
5619
|
}
|
|
5620
|
+
/**
|
|
5621
|
+
* Gets the cell value from a row, supporting nested property paths (e.g., 'user.name')
|
|
5622
|
+
* @param row - The row data object
|
|
5623
|
+
* @param column - The column definition
|
|
5624
|
+
* @returns The cell value or undefined if not found
|
|
5625
|
+
*/
|
|
5551
5626
|
getCellValue(row, column) {
|
|
5552
|
-
|
|
5627
|
+
if (!row || !column?.key) {
|
|
5628
|
+
return undefined;
|
|
5629
|
+
}
|
|
5630
|
+
// Support nested property paths (e.g., 'user.name' or 'address.street')
|
|
5631
|
+
const keys = column.key.split('.');
|
|
5632
|
+
let value = row;
|
|
5633
|
+
for (const key of keys) {
|
|
5634
|
+
if (value === null || value === undefined) {
|
|
5635
|
+
return undefined;
|
|
5636
|
+
}
|
|
5637
|
+
value = value[key];
|
|
5638
|
+
}
|
|
5639
|
+
return value;
|
|
5553
5640
|
}
|
|
5554
|
-
|
|
5641
|
+
/**
|
|
5642
|
+
* Formats a cell value based on its type
|
|
5643
|
+
* @param value - The value to format
|
|
5644
|
+
* @param type - The column type
|
|
5645
|
+
* @param column - Optional column definition for additional formatting options
|
|
5646
|
+
* @returns Formatted string representation
|
|
5647
|
+
*/
|
|
5648
|
+
formatCellValue(value, type, column) {
|
|
5555
5649
|
if (value === null || value === undefined) {
|
|
5556
5650
|
return '';
|
|
5557
5651
|
}
|
|
5558
5652
|
if (type === 'number') {
|
|
5559
|
-
|
|
5653
|
+
if (typeof value === 'number') {
|
|
5654
|
+
// Use locale-aware number formatting
|
|
5655
|
+
return value.toLocaleString(undefined, {
|
|
5656
|
+
minimumFractionDigits: 0,
|
|
5657
|
+
maximumFractionDigits: 2,
|
|
5658
|
+
});
|
|
5659
|
+
}
|
|
5660
|
+
// Try to parse string numbers
|
|
5661
|
+
const numValue = Number(value);
|
|
5662
|
+
return !isNaN(numValue) ? numValue.toLocaleString() : String(value);
|
|
5560
5663
|
}
|
|
5561
5664
|
if (type === 'date') {
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
|
|
5569
|
-
}
|
|
5665
|
+
const date = this.parseDate(value);
|
|
5666
|
+
if (!isNaN(date.getTime())) {
|
|
5667
|
+
// Use locale-aware date formatting
|
|
5668
|
+
return date.toLocaleDateString(undefined, {
|
|
5669
|
+
year: 'numeric',
|
|
5670
|
+
month: 'short',
|
|
5671
|
+
day: 'numeric',
|
|
5672
|
+
});
|
|
5570
5673
|
}
|
|
5674
|
+
// If date parsing fails, return original value as string
|
|
5675
|
+
return String(value);
|
|
5571
5676
|
}
|
|
5572
5677
|
return String(value);
|
|
5573
5678
|
}
|
|
5679
|
+
/**
|
|
5680
|
+
* Parses a value into a Date object
|
|
5681
|
+
* @param value - The value to parse (Date, string, or number timestamp)
|
|
5682
|
+
* @returns A Date object
|
|
5683
|
+
*/
|
|
5574
5684
|
parseDate(value) {
|
|
5575
5685
|
if (value instanceof Date) {
|
|
5576
5686
|
return value;
|
|
5577
5687
|
}
|
|
5578
5688
|
if (typeof value === 'string') {
|
|
5689
|
+
const date = new Date(value);
|
|
5690
|
+
// Check if it's a valid date
|
|
5691
|
+
if (!isNaN(date.getTime())) {
|
|
5692
|
+
return date;
|
|
5693
|
+
}
|
|
5694
|
+
}
|
|
5695
|
+
if (typeof value === 'number') {
|
|
5696
|
+
// Assume it's a timestamp
|
|
5579
5697
|
return new Date(value);
|
|
5580
5698
|
}
|
|
5581
|
-
|
|
5699
|
+
// Return invalid date as fallback
|
|
5700
|
+
return new Date(NaN);
|
|
5582
5701
|
}
|
|
5583
5702
|
onRowClick(row) {
|
|
5584
5703
|
if (!this.loading) {
|
|
5585
5704
|
this.rowClicked.emit(row);
|
|
5586
5705
|
}
|
|
5587
5706
|
}
|
|
5588
|
-
|
|
5707
|
+
/**
|
|
5708
|
+
* Handles column sorting when header is clicked
|
|
5709
|
+
* @param column - The column to sort by
|
|
5710
|
+
* @param event - Optional keyboard event for accessibility
|
|
5711
|
+
*/
|
|
5712
|
+
onSort(column, event) {
|
|
5713
|
+
// Handle keyboard events (Enter or Space)
|
|
5714
|
+
if (event && event.key !== 'Enter' && event.key !== ' ') {
|
|
5715
|
+
return;
|
|
5716
|
+
}
|
|
5717
|
+
if (event) {
|
|
5718
|
+
event.preventDefault();
|
|
5719
|
+
event.stopPropagation();
|
|
5720
|
+
}
|
|
5589
5721
|
if (!this.sort || !column.sortable || this.loading) {
|
|
5590
5722
|
return;
|
|
5591
5723
|
}
|
|
@@ -5630,57 +5762,91 @@ class TableComponent {
|
|
|
5630
5762
|
isSelected(row) {
|
|
5631
5763
|
return this.selectedItems().some((item) => this.getItemId(item) === this.getItemId(row));
|
|
5632
5764
|
}
|
|
5765
|
+
/**
|
|
5766
|
+
* Toggles the selection state of a row
|
|
5767
|
+
* @param checked - Whether the row should be selected
|
|
5768
|
+
* @param row - The row to toggle selection for
|
|
5769
|
+
*/
|
|
5633
5770
|
toggleRowSelection(checked, row) {
|
|
5634
5771
|
if (row === undefined) {
|
|
5635
5772
|
return;
|
|
5636
5773
|
}
|
|
5637
5774
|
if (this.selectionMode === 'single') {
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
}
|
|
5641
|
-
else {
|
|
5642
|
-
this.selectedItems.set([]);
|
|
5643
|
-
}
|
|
5775
|
+
// Single selection mode: replace selection
|
|
5776
|
+
this.selectedItems.set(checked ? [row] : []);
|
|
5644
5777
|
}
|
|
5645
5778
|
else {
|
|
5779
|
+
// Multiple selection mode: add/remove from selection
|
|
5646
5780
|
const current = this.selectedItems();
|
|
5647
5781
|
const itemId = this.getItemId(row);
|
|
5648
5782
|
if (checked) {
|
|
5649
|
-
|
|
5650
|
-
|
|
5783
|
+
// Only add if not already selected
|
|
5784
|
+
const isAlreadySelected = current.some((item) => this.getItemId(item) === itemId);
|
|
5785
|
+
if (!isAlreadySelected) {
|
|
5651
5786
|
this.selectedItems.set([...current, row]);
|
|
5652
5787
|
}
|
|
5653
5788
|
}
|
|
5654
5789
|
else {
|
|
5790
|
+
// Remove from selection
|
|
5655
5791
|
const updated = current.filter((item) => this.getItemId(item) !== itemId);
|
|
5656
5792
|
this.selectedItems.set(updated);
|
|
5657
5793
|
}
|
|
5658
5794
|
}
|
|
5795
|
+
// Emit the updated selection
|
|
5659
5796
|
this.selectionChanged.emit([...this.selectedItems()]);
|
|
5660
5797
|
this.cdr.markForCheck();
|
|
5661
5798
|
}
|
|
5799
|
+
/**
|
|
5800
|
+
* Toggles selection for all rows on the current page
|
|
5801
|
+
* @param checked - Whether all rows should be selected
|
|
5802
|
+
*/
|
|
5662
5803
|
toggleSelectAll(checked) {
|
|
5663
5804
|
if (this.selectionMode === 'single') {
|
|
5664
5805
|
return;
|
|
5665
5806
|
}
|
|
5666
5807
|
const currentPageData = this.displayedData();
|
|
5808
|
+
if (currentPageData.length === 0) {
|
|
5809
|
+
return;
|
|
5810
|
+
}
|
|
5811
|
+
const selectedItems = this.selectedItems();
|
|
5812
|
+
const selectedIds = new Set(selectedItems.map((item) => this.getItemId(item)));
|
|
5667
5813
|
if (checked) {
|
|
5668
|
-
|
|
5669
|
-
const newItems = currentPageData.filter((row) => !
|
|
5670
|
-
|
|
5814
|
+
// Add all page items that aren't already selected
|
|
5815
|
+
const newItems = currentPageData.filter((row) => !selectedIds.has(this.getItemId(row)));
|
|
5816
|
+
if (newItems.length > 0) {
|
|
5817
|
+
this.selectedItems.set([...selectedItems, ...newItems]);
|
|
5818
|
+
}
|
|
5671
5819
|
}
|
|
5672
5820
|
else {
|
|
5821
|
+
// Remove all page items from selection
|
|
5673
5822
|
const currentPageIds = new Set(currentPageData.map((row) => this.getItemId(row)));
|
|
5674
|
-
const updated =
|
|
5823
|
+
const updated = selectedItems.filter((item) => !currentPageIds.has(this.getItemId(item)));
|
|
5675
5824
|
this.selectedItems.set(updated);
|
|
5676
5825
|
}
|
|
5677
5826
|
this.selectionChanged.emit([...this.selectedItems()]);
|
|
5678
5827
|
this.cdr.markForCheck();
|
|
5679
5828
|
}
|
|
5829
|
+
/**
|
|
5830
|
+
* Gets the unique identifier for an item using the trackByKey
|
|
5831
|
+
* @param item - The item to get the ID for
|
|
5832
|
+
* @returns The item's ID or the item itself if no ID property exists
|
|
5833
|
+
* @private
|
|
5834
|
+
*/
|
|
5680
5835
|
getItemId(item) {
|
|
5836
|
+
if (!item) {
|
|
5837
|
+
return item;
|
|
5838
|
+
}
|
|
5681
5839
|
return item[this.trackByKey] !== undefined ? item[this.trackByKey] : item;
|
|
5682
5840
|
}
|
|
5841
|
+
/**
|
|
5842
|
+
* Gets CSS classes for a column cell
|
|
5843
|
+
* @param column - The column definition
|
|
5844
|
+
* @returns Space-separated string of CSS classes
|
|
5845
|
+
*/
|
|
5683
5846
|
getColumnClass(column) {
|
|
5847
|
+
if (!column) {
|
|
5848
|
+
return '';
|
|
5849
|
+
}
|
|
5684
5850
|
const classes = [];
|
|
5685
5851
|
if (column.align) {
|
|
5686
5852
|
classes.push(`sefin-table__cell--align-${column.align}`);
|
|
@@ -5693,6 +5859,10 @@ class TableComponent {
|
|
|
5693
5859
|
}
|
|
5694
5860
|
return classes.join(' ');
|
|
5695
5861
|
}
|
|
5862
|
+
/**
|
|
5863
|
+
* Gets CSS classes for the table element
|
|
5864
|
+
* @returns Space-separated string of CSS classes
|
|
5865
|
+
*/
|
|
5696
5866
|
getTableClasses() {
|
|
5697
5867
|
const classes = ['sefin-table'];
|
|
5698
5868
|
if (this.density === 'compact') {
|
|
@@ -5709,9 +5879,113 @@ class TableComponent {
|
|
|
5709
5879
|
}
|
|
5710
5880
|
return classes.join(' ');
|
|
5711
5881
|
}
|
|
5882
|
+
/**
|
|
5883
|
+
* Gets the width CSS value for a column
|
|
5884
|
+
* @param column - The column definition
|
|
5885
|
+
* @returns The width value or undefined
|
|
5886
|
+
*/
|
|
5712
5887
|
getColumnWidth(column) {
|
|
5713
|
-
return column
|
|
5888
|
+
return column?.width;
|
|
5714
5889
|
}
|
|
5890
|
+
/**
|
|
5891
|
+
* Gets the appropriate sort icon path for a column
|
|
5892
|
+
* @param column - The column to get the icon for
|
|
5893
|
+
* @returns The SVG path string for the sort icon
|
|
5894
|
+
*/
|
|
5895
|
+
getSortIconPath(column) {
|
|
5896
|
+
if (!column.sortable || !this.sort) {
|
|
5897
|
+
return '';
|
|
5898
|
+
}
|
|
5899
|
+
const currentColumn = this.currentSortColumn();
|
|
5900
|
+
const currentDirection = this.currentSortDirection();
|
|
5901
|
+
if (currentColumn === column.key) {
|
|
5902
|
+
if (currentDirection === 'asc') {
|
|
5903
|
+
return SORT_ICONS.ascending;
|
|
5904
|
+
}
|
|
5905
|
+
else if (currentDirection === 'desc') {
|
|
5906
|
+
return SORT_ICONS.descending;
|
|
5907
|
+
}
|
|
5908
|
+
}
|
|
5909
|
+
return SORT_ICONS.unsorted;
|
|
5910
|
+
}
|
|
5911
|
+
/**
|
|
5912
|
+
* Determines if a column should show the unsorted icon
|
|
5913
|
+
* @param column - The column to check
|
|
5914
|
+
* @returns True if unsorted icon should be shown
|
|
5915
|
+
*/
|
|
5916
|
+
showUnsortedIcon(column) {
|
|
5917
|
+
if (!column.sortable || !this.sort) {
|
|
5918
|
+
return false;
|
|
5919
|
+
}
|
|
5920
|
+
const currentColumn = this.currentSortColumn();
|
|
5921
|
+
const currentDirection = this.currentSortDirection();
|
|
5922
|
+
return currentColumn !== column.key || currentDirection === '';
|
|
5923
|
+
}
|
|
5924
|
+
/**
|
|
5925
|
+
* Determines if a column should show the ascending icon
|
|
5926
|
+
* @param column - The column to check
|
|
5927
|
+
* @returns True if ascending icon should be shown
|
|
5928
|
+
*/
|
|
5929
|
+
showAscendingIcon(column) {
|
|
5930
|
+
if (!column.sortable || !this.sort) {
|
|
5931
|
+
return false;
|
|
5932
|
+
}
|
|
5933
|
+
return (this.currentSortColumn() === column.key &&
|
|
5934
|
+
this.currentSortDirection() === 'asc');
|
|
5935
|
+
}
|
|
5936
|
+
/**
|
|
5937
|
+
* Determines if a column should show the descending icon
|
|
5938
|
+
* @param column - The column to check
|
|
5939
|
+
* @returns True if descending icon should be shown
|
|
5940
|
+
*/
|
|
5941
|
+
showDescendingIcon(column) {
|
|
5942
|
+
if (!column.sortable || !this.sort) {
|
|
5943
|
+
return false;
|
|
5944
|
+
}
|
|
5945
|
+
return (this.currentSortColumn() === column.key &&
|
|
5946
|
+
this.currentSortDirection() === 'desc');
|
|
5947
|
+
}
|
|
5948
|
+
/**
|
|
5949
|
+
* Gets the ARIA sort state for a column
|
|
5950
|
+
* @param column - The column to get the sort state for
|
|
5951
|
+
* @returns The ARIA sort value ('ascending', 'descending', or 'none')
|
|
5952
|
+
*/
|
|
5953
|
+
getAriaSort(column) {
|
|
5954
|
+
if (!column.sortable || !this.sort) {
|
|
5955
|
+
return 'none';
|
|
5956
|
+
}
|
|
5957
|
+
if (this.currentSortColumn() === column.key) {
|
|
5958
|
+
const direction = this.currentSortDirection();
|
|
5959
|
+
return direction === 'asc' ? 'ascending' : direction === 'desc' ? 'descending' : 'none';
|
|
5960
|
+
}
|
|
5961
|
+
return 'none';
|
|
5962
|
+
}
|
|
5963
|
+
/**
|
|
5964
|
+
* Gets the ARIA label for a sortable column header
|
|
5965
|
+
* @param column - The column to get the label for
|
|
5966
|
+
* @returns The ARIA label string or null if not sortable
|
|
5967
|
+
*/
|
|
5968
|
+
getSortAriaLabel(column) {
|
|
5969
|
+
if (!column.sortable || !this.sort) {
|
|
5970
|
+
return null;
|
|
5971
|
+
}
|
|
5972
|
+
let currentState = 'not sorted';
|
|
5973
|
+
if (this.currentSortColumn() === column.key) {
|
|
5974
|
+
const direction = this.currentSortDirection();
|
|
5975
|
+
if (direction === 'asc') {
|
|
5976
|
+
currentState = 'ascending';
|
|
5977
|
+
}
|
|
5978
|
+
else if (direction === 'desc') {
|
|
5979
|
+
currentState = 'descending';
|
|
5980
|
+
}
|
|
5981
|
+
}
|
|
5982
|
+
return `Sort by ${column.header}. Currently ${currentState}`;
|
|
5983
|
+
}
|
|
5984
|
+
/**
|
|
5985
|
+
* Generates page numbers array for pagination display
|
|
5986
|
+
* This method is currently not used in the template but kept for potential future use
|
|
5987
|
+
* @returns Array of page numbers and ellipsis strings
|
|
5988
|
+
*/
|
|
5715
5989
|
getPageNumbers() {
|
|
5716
5990
|
const current = this.currentPage();
|
|
5717
5991
|
const total = this.totalPages();
|
|
@@ -5748,14 +6022,12 @@ class TableComponent {
|
|
|
5748
6022
|
}
|
|
5749
6023
|
return pages;
|
|
5750
6024
|
}
|
|
5751
|
-
// Expose Math to template
|
|
5752
|
-
Math = Math;
|
|
5753
6025
|
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 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;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%}.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);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:#55c3d80a}.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}.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)}.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, #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%}.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 });
|
|
6026
|
+
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
6027
|
}
|
|
5756
6028
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TableComponent, decorators: [{
|
|
5757
6029
|
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 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;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%}.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);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:#55c3d80a}.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}.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)}.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, #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%}.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"] }]
|
|
6030
|
+
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
6031
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { columns: [{
|
|
5760
6032
|
type: Input
|
|
5761
6033
|
}], data: [{
|