@sonny-ui/core 0.1.0-alpha.13 → 0.1.0-alpha.14
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.
- package/fesm2022/sonny-ui-core.mjs +1184 -379
- package/fesm2022/sonny-ui-core.mjs.map +1 -1
- package/package.json +1 -1
- package/src/lib/data-table/data-table.component.spec.ts +443 -0
- package/src/lib/data-table/data-table.component.ts +603 -0
- package/src/lib/data-table/data-table.directives.ts +35 -0
- package/src/lib/data-table/data-table.types.ts +20 -0
- package/src/lib/data-table/index.ts +13 -0
- package/types/sonny-ui-core.d.ts +109 -3
|
@@ -3,8 +3,8 @@ import { twMerge } from 'tailwind-merge';
|
|
|
3
3
|
import { cva } from 'class-variance-authority';
|
|
4
4
|
export { cva } from 'class-variance-authority';
|
|
5
5
|
import * as i0 from '@angular/core';
|
|
6
|
-
import { inject, PLATFORM_ID, signal, computed, Injectable, InjectionToken, makeEnvironmentProviders, provideEnvironmentInitializer, input, Directive, ChangeDetectionStrategy, Component, ElementRef, model, viewChild, forwardRef, HostListener,
|
|
7
|
-
import { DOCUMENT, isPlatformBrowser } from '@angular/common';
|
|
6
|
+
import { inject, PLATFORM_ID, signal, computed, Injectable, InjectionToken, makeEnvironmentProviders, provideEnvironmentInitializer, input, Directive, ChangeDetectionStrategy, Component, ElementRef, model, viewChild, forwardRef, HostListener, TemplateRef, output, contentChildren, contentChild, effect, untracked, Injector, afterNextRender, Renderer2 } from '@angular/core';
|
|
7
|
+
import { DOCUMENT, isPlatformBrowser, NgTemplateOutlet } from '@angular/common';
|
|
8
8
|
import { Dialog, DialogRef } from '@angular/cdk/dialog';
|
|
9
9
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
10
10
|
import { createGlobalPositionStrategy } from '@angular/cdk/overlay';
|
|
@@ -2417,6 +2417,1146 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
|
|
|
2417
2417
|
}]
|
|
2418
2418
|
}], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
2419
2419
|
|
|
2420
|
+
const paginationItemVariants = cva('inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50', {
|
|
2421
|
+
variants: {
|
|
2422
|
+
variant: {
|
|
2423
|
+
default: 'bg-background hover:bg-accent hover:text-accent-foreground',
|
|
2424
|
+
outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
|
|
2425
|
+
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
|
2426
|
+
},
|
|
2427
|
+
size: {
|
|
2428
|
+
sm: 'h-8 w-8 text-xs',
|
|
2429
|
+
md: 'h-9 w-9',
|
|
2430
|
+
lg: 'h-10 w-10',
|
|
2431
|
+
},
|
|
2432
|
+
active: {
|
|
2433
|
+
true: 'bg-primary text-primary-foreground hover:bg-primary/90 hover:text-primary-foreground',
|
|
2434
|
+
false: '',
|
|
2435
|
+
},
|
|
2436
|
+
},
|
|
2437
|
+
defaultVariants: {
|
|
2438
|
+
variant: 'default',
|
|
2439
|
+
size: 'md',
|
|
2440
|
+
active: false,
|
|
2441
|
+
},
|
|
2442
|
+
});
|
|
2443
|
+
|
|
2444
|
+
function computePageRange(totalPages, currentPage, siblingCount, boundaryCount) {
|
|
2445
|
+
const range = (start, end) => Array.from({ length: end - start + 1 }, (_, i) => start + i);
|
|
2446
|
+
const startPages = range(1, Math.min(boundaryCount, totalPages));
|
|
2447
|
+
const endPages = range(Math.max(totalPages - boundaryCount + 1, boundaryCount + 1), totalPages);
|
|
2448
|
+
const siblingsStart = Math.max(Math.min(currentPage - siblingCount, totalPages - boundaryCount - siblingCount * 2 - 1), boundaryCount + 2);
|
|
2449
|
+
const siblingsEnd = Math.min(Math.max(currentPage + siblingCount, boundaryCount + siblingCount * 2 + 2), endPages.length > 0 ? endPages[0] - 2 : totalPages - 1);
|
|
2450
|
+
const result = [...startPages];
|
|
2451
|
+
if (siblingsStart > boundaryCount + 2) {
|
|
2452
|
+
result.push('ellipsis');
|
|
2453
|
+
}
|
|
2454
|
+
else if (boundaryCount + 1 < totalPages - boundaryCount) {
|
|
2455
|
+
result.push(boundaryCount + 1);
|
|
2456
|
+
}
|
|
2457
|
+
result.push(...range(siblingsStart, siblingsEnd));
|
|
2458
|
+
if (siblingsEnd < totalPages - boundaryCount - 1) {
|
|
2459
|
+
result.push('ellipsis');
|
|
2460
|
+
}
|
|
2461
|
+
else if (totalPages - boundaryCount > boundaryCount) {
|
|
2462
|
+
result.push(totalPages - boundaryCount);
|
|
2463
|
+
}
|
|
2464
|
+
result.push(...endPages);
|
|
2465
|
+
return [...new Set(result)].sort((a, b) => {
|
|
2466
|
+
if (a === 'ellipsis')
|
|
2467
|
+
return 0;
|
|
2468
|
+
if (b === 'ellipsis')
|
|
2469
|
+
return 0;
|
|
2470
|
+
return a - b;
|
|
2471
|
+
});
|
|
2472
|
+
}
|
|
2473
|
+
class SnyPaginationComponent {
|
|
2474
|
+
currentPage = model(1, ...(ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []));
|
|
2475
|
+
totalPages = input.required(...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
|
|
2476
|
+
siblingCount = input(1, ...(ngDevMode ? [{ debugName: "siblingCount" }] : /* istanbul ignore next */ []));
|
|
2477
|
+
boundaryCount = input(1, ...(ngDevMode ? [{ debugName: "boundaryCount" }] : /* istanbul ignore next */ []));
|
|
2478
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
2479
|
+
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
2480
|
+
class = input('', ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
|
|
2481
|
+
pages = computed(() => computePageRange(this.totalPages(), this.currentPage(), this.siblingCount(), this.boundaryCount()), ...(ngDevMode ? [{ debugName: "pages" }] : /* istanbul ignore next */ []));
|
|
2482
|
+
hasPrev = computed(() => this.currentPage() > 1, ...(ngDevMode ? [{ debugName: "hasPrev" }] : /* istanbul ignore next */ []));
|
|
2483
|
+
hasNext = computed(() => this.currentPage() < this.totalPages(), ...(ngDevMode ? [{ debugName: "hasNext" }] : /* istanbul ignore next */ []));
|
|
2484
|
+
goToPage(page) {
|
|
2485
|
+
if (page === 'ellipsis')
|
|
2486
|
+
return;
|
|
2487
|
+
this.currentPage.set(page);
|
|
2488
|
+
}
|
|
2489
|
+
prev() {
|
|
2490
|
+
if (this.hasPrev())
|
|
2491
|
+
this.currentPage.update((p) => p - 1);
|
|
2492
|
+
}
|
|
2493
|
+
next() {
|
|
2494
|
+
if (this.hasNext())
|
|
2495
|
+
this.currentPage.update((p) => p + 1);
|
|
2496
|
+
}
|
|
2497
|
+
pageClass(page) {
|
|
2498
|
+
return cn(paginationItemVariants({
|
|
2499
|
+
variant: this.variant(),
|
|
2500
|
+
size: this.size(),
|
|
2501
|
+
active: page === this.currentPage(),
|
|
2502
|
+
}));
|
|
2503
|
+
}
|
|
2504
|
+
navBtnClass() {
|
|
2505
|
+
return cn(paginationItemVariants({ variant: this.variant(), size: this.size(), active: false }));
|
|
2506
|
+
}
|
|
2507
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyPaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2508
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: SnyPaginationComponent, isStandalone: true, selector: "sny-pagination", inputs: { currentPage: { classPropertyName: "currentPage", publicName: "currentPage", isSignal: true, isRequired: false, transformFunction: null }, totalPages: { classPropertyName: "totalPages", publicName: "totalPages", isSignal: true, isRequired: true, transformFunction: null }, siblingCount: { classPropertyName: "siblingCount", publicName: "siblingCount", isSignal: true, isRequired: false, transformFunction: null }, boundaryCount: { classPropertyName: "boundaryCount", publicName: "boundaryCount", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { currentPage: "currentPageChange" }, host: { attributes: { "role": "navigation", "aria-label": "Pagination" } }, ngImport: i0, template: `
|
|
2509
|
+
<div class="flex items-center gap-1">
|
|
2510
|
+
<button
|
|
2511
|
+
[class]="navBtnClass()"
|
|
2512
|
+
[disabled]="!hasPrev()"
|
|
2513
|
+
[attr.aria-label]="'Go to previous page'"
|
|
2514
|
+
(click)="prev()"
|
|
2515
|
+
>
|
|
2516
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m15 18-6-6 6-6"/></svg>
|
|
2517
|
+
</button>
|
|
2518
|
+
|
|
2519
|
+
@for (page of pages(); track $index) {
|
|
2520
|
+
@if (page === 'ellipsis') {
|
|
2521
|
+
<span class="flex h-9 w-9 items-center justify-center" aria-hidden="true">...</span>
|
|
2522
|
+
} @else {
|
|
2523
|
+
<button
|
|
2524
|
+
[class]="pageClass(page)"
|
|
2525
|
+
[attr.aria-label]="'Page ' + page"
|
|
2526
|
+
[attr.aria-current]="page === currentPage() ? 'page' : null"
|
|
2527
|
+
(click)="goToPage(page)"
|
|
2528
|
+
>
|
|
2529
|
+
{{ page }}
|
|
2530
|
+
</button>
|
|
2531
|
+
}
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
<button
|
|
2535
|
+
[class]="navBtnClass()"
|
|
2536
|
+
[disabled]="!hasNext()"
|
|
2537
|
+
[attr.aria-label]="'Go to next page'"
|
|
2538
|
+
(click)="next()"
|
|
2539
|
+
>
|
|
2540
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>
|
|
2541
|
+
</button>
|
|
2542
|
+
</div>
|
|
2543
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2544
|
+
}
|
|
2545
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyPaginationComponent, decorators: [{
|
|
2546
|
+
type: Component,
|
|
2547
|
+
args: [{
|
|
2548
|
+
selector: 'sny-pagination',
|
|
2549
|
+
standalone: true,
|
|
2550
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2551
|
+
host: {
|
|
2552
|
+
'role': 'navigation',
|
|
2553
|
+
'aria-label': 'Pagination',
|
|
2554
|
+
},
|
|
2555
|
+
template: `
|
|
2556
|
+
<div class="flex items-center gap-1">
|
|
2557
|
+
<button
|
|
2558
|
+
[class]="navBtnClass()"
|
|
2559
|
+
[disabled]="!hasPrev()"
|
|
2560
|
+
[attr.aria-label]="'Go to previous page'"
|
|
2561
|
+
(click)="prev()"
|
|
2562
|
+
>
|
|
2563
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m15 18-6-6 6-6"/></svg>
|
|
2564
|
+
</button>
|
|
2565
|
+
|
|
2566
|
+
@for (page of pages(); track $index) {
|
|
2567
|
+
@if (page === 'ellipsis') {
|
|
2568
|
+
<span class="flex h-9 w-9 items-center justify-center" aria-hidden="true">...</span>
|
|
2569
|
+
} @else {
|
|
2570
|
+
<button
|
|
2571
|
+
[class]="pageClass(page)"
|
|
2572
|
+
[attr.aria-label]="'Page ' + page"
|
|
2573
|
+
[attr.aria-current]="page === currentPage() ? 'page' : null"
|
|
2574
|
+
(click)="goToPage(page)"
|
|
2575
|
+
>
|
|
2576
|
+
{{ page }}
|
|
2577
|
+
</button>
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
|
|
2581
|
+
<button
|
|
2582
|
+
[class]="navBtnClass()"
|
|
2583
|
+
[disabled]="!hasNext()"
|
|
2584
|
+
[attr.aria-label]="'Go to next page'"
|
|
2585
|
+
(click)="next()"
|
|
2586
|
+
>
|
|
2587
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>
|
|
2588
|
+
</button>
|
|
2589
|
+
</div>
|
|
2590
|
+
`,
|
|
2591
|
+
}]
|
|
2592
|
+
}], propDecorators: { currentPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentPage", required: false }] }, { type: i0.Output, args: ["currentPageChange"] }], totalPages: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalPages", required: true }] }], siblingCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "siblingCount", required: false }] }], boundaryCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "boundaryCount", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
2593
|
+
|
|
2594
|
+
const dropdownContentVariants = cva('z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md', {
|
|
2595
|
+
variants: {},
|
|
2596
|
+
defaultVariants: {},
|
|
2597
|
+
});
|
|
2598
|
+
const dropdownItemVariants = cva('relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[active]:bg-accent data-[active]:text-accent-foreground', {
|
|
2599
|
+
variants: {
|
|
2600
|
+
variant: {
|
|
2601
|
+
default: '',
|
|
2602
|
+
destructive: 'text-destructive data-[active]:bg-destructive/10 data-[active]:text-destructive',
|
|
2603
|
+
},
|
|
2604
|
+
},
|
|
2605
|
+
defaultVariants: {
|
|
2606
|
+
variant: 'default',
|
|
2607
|
+
},
|
|
2608
|
+
});
|
|
2609
|
+
|
|
2610
|
+
const SNY_DROPDOWN = new InjectionToken('SnyDropdown');
|
|
2611
|
+
class SnyDropdownDirective {
|
|
2612
|
+
elementRef = inject(ElementRef);
|
|
2613
|
+
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
2614
|
+
toggle() { this.isOpen.update((v) => !v); }
|
|
2615
|
+
open() { this.isOpen.set(true); }
|
|
2616
|
+
close() { this.isOpen.set(false); }
|
|
2617
|
+
onDocumentClick(event) {
|
|
2618
|
+
if (!this.elementRef.nativeElement.contains(event.target)) {
|
|
2619
|
+
this.close();
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2622
|
+
onEscape() {
|
|
2623
|
+
this.close();
|
|
2624
|
+
}
|
|
2625
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyDropdownDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2626
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: SnyDropdownDirective, isStandalone: true, selector: "[snyDropdown]", host: { listeners: { "document:click": "onDocumentClick($event)", "keydown.escape": "onEscape()" }, properties: { "class": "\"relative inline-block\"" } }, providers: [{ provide: SNY_DROPDOWN, useExisting: SnyDropdownDirective }], exportAs: ["snyDropdown"], ngImport: i0 });
|
|
2627
|
+
}
|
|
2628
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyDropdownDirective, decorators: [{
|
|
2629
|
+
type: Directive,
|
|
2630
|
+
args: [{
|
|
2631
|
+
selector: '[snyDropdown]',
|
|
2632
|
+
standalone: true,
|
|
2633
|
+
exportAs: 'snyDropdown',
|
|
2634
|
+
providers: [{ provide: SNY_DROPDOWN, useExisting: SnyDropdownDirective }],
|
|
2635
|
+
host: {
|
|
2636
|
+
'[class]': '"relative inline-block"',
|
|
2637
|
+
},
|
|
2638
|
+
}]
|
|
2639
|
+
}], propDecorators: { onDocumentClick: [{
|
|
2640
|
+
type: HostListener,
|
|
2641
|
+
args: ['document:click', ['$event']]
|
|
2642
|
+
}], onEscape: [{
|
|
2643
|
+
type: HostListener,
|
|
2644
|
+
args: ['keydown.escape']
|
|
2645
|
+
}] } });
|
|
2646
|
+
class SnyDropdownTriggerDirective {
|
|
2647
|
+
dropdown = inject(SNY_DROPDOWN);
|
|
2648
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyDropdownTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2649
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: SnyDropdownTriggerDirective, isStandalone: true, selector: "[snyDropdownTrigger]", host: { listeners: { "click": "dropdown.toggle()" }, properties: { "attr.aria-expanded": "dropdown.isOpen()", "attr.aria-haspopup": "\"menu\"" } }, ngImport: i0 });
|
|
2650
|
+
}
|
|
2651
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyDropdownTriggerDirective, decorators: [{
|
|
2652
|
+
type: Directive,
|
|
2653
|
+
args: [{
|
|
2654
|
+
selector: '[snyDropdownTrigger]',
|
|
2655
|
+
standalone: true,
|
|
2656
|
+
host: {
|
|
2657
|
+
'(click)': 'dropdown.toggle()',
|
|
2658
|
+
'[attr.aria-expanded]': 'dropdown.isOpen()',
|
|
2659
|
+
'[attr.aria-haspopup]': '"menu"',
|
|
2660
|
+
},
|
|
2661
|
+
}]
|
|
2662
|
+
}] });
|
|
2663
|
+
class SnyDropdownContentDirective {
|
|
2664
|
+
dropdown = inject(SNY_DROPDOWN);
|
|
2665
|
+
class = input('', ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
|
|
2666
|
+
computedClass = computed(() => cn(dropdownContentVariants(), 'absolute mt-1 left-0 animate-in fade-in-0 zoom-in-95', this.class()), ...(ngDevMode ? [{ debugName: "computedClass" }] : /* istanbul ignore next */ []));
|
|
2667
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyDropdownContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2668
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: SnyDropdownContentDirective, isStandalone: true, selector: "[snyDropdownContent]", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "menu" }, properties: { "class": "computedClass()", "style.display": "dropdown.isOpen() ? \"\" : \"none\"" } }, ngImport: i0 });
|
|
2669
|
+
}
|
|
2670
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyDropdownContentDirective, decorators: [{
|
|
2671
|
+
type: Directive,
|
|
2672
|
+
args: [{
|
|
2673
|
+
selector: '[snyDropdownContent]',
|
|
2674
|
+
standalone: true,
|
|
2675
|
+
host: {
|
|
2676
|
+
'role': 'menu',
|
|
2677
|
+
'[class]': 'computedClass()',
|
|
2678
|
+
'[style.display]': 'dropdown.isOpen() ? "" : "none"',
|
|
2679
|
+
},
|
|
2680
|
+
}]
|
|
2681
|
+
}], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
2682
|
+
class SnyMenuContentDirective {
|
|
2683
|
+
class = input('', ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
|
|
2684
|
+
computedClass = computed(() => cn(dropdownContentVariants(), this.class()), ...(ngDevMode ? [{ debugName: "computedClass" }] : /* istanbul ignore next */ []));
|
|
2685
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyMenuContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2686
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: SnyMenuContentDirective, isStandalone: true, selector: "[snyMenuContent]", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "computedClass()" } }, ngImport: i0 });
|
|
2687
|
+
}
|
|
2688
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyMenuContentDirective, decorators: [{
|
|
2689
|
+
type: Directive,
|
|
2690
|
+
args: [{
|
|
2691
|
+
selector: '[snyMenuContent]',
|
|
2692
|
+
standalone: true,
|
|
2693
|
+
host: {
|
|
2694
|
+
'[class]': 'computedClass()',
|
|
2695
|
+
},
|
|
2696
|
+
}]
|
|
2697
|
+
}], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
2698
|
+
class SnyMenuItemDirective {
|
|
2699
|
+
dropdown = inject(SNY_DROPDOWN, { optional: true });
|
|
2700
|
+
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
2701
|
+
class = input('', ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
|
|
2702
|
+
computedClass = computed(() => cn(dropdownItemVariants({ variant: this.variant() }), 'cursor-pointer hover:bg-accent hover:text-accent-foreground', this.class()), ...(ngDevMode ? [{ debugName: "computedClass" }] : /* istanbul ignore next */ []));
|
|
2703
|
+
onClick() {
|
|
2704
|
+
this.dropdown?.close();
|
|
2705
|
+
}
|
|
2706
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyMenuItemDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2707
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: SnyMenuItemDirective, isStandalone: true, selector: "[snyMenuItem]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "menuitem" }, listeners: { "click": "onClick()" }, properties: { "class": "computedClass()" } }, ngImport: i0 });
|
|
2708
|
+
}
|
|
2709
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyMenuItemDirective, decorators: [{
|
|
2710
|
+
type: Directive,
|
|
2711
|
+
args: [{
|
|
2712
|
+
selector: '[snyMenuItem]',
|
|
2713
|
+
standalone: true,
|
|
2714
|
+
host: {
|
|
2715
|
+
'role': 'menuitem',
|
|
2716
|
+
'[class]': 'computedClass()',
|
|
2717
|
+
'(click)': 'onClick()',
|
|
2718
|
+
},
|
|
2719
|
+
}]
|
|
2720
|
+
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
2721
|
+
class SnyMenuSeparatorDirective {
|
|
2722
|
+
class = input('', ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
|
|
2723
|
+
computedClass = computed(() => cn('-mx-1 my-1 h-px bg-muted', this.class()), ...(ngDevMode ? [{ debugName: "computedClass" }] : /* istanbul ignore next */ []));
|
|
2724
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyMenuSeparatorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2725
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: SnyMenuSeparatorDirective, isStandalone: true, selector: "[snyMenuSeparator]", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "separator" }, properties: { "class": "computedClass()" } }, ngImport: i0 });
|
|
2726
|
+
}
|
|
2727
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyMenuSeparatorDirective, decorators: [{
|
|
2728
|
+
type: Directive,
|
|
2729
|
+
args: [{
|
|
2730
|
+
selector: '[snyMenuSeparator]',
|
|
2731
|
+
standalone: true,
|
|
2732
|
+
host: {
|
|
2733
|
+
'role': 'separator',
|
|
2734
|
+
'[class]': 'computedClass()',
|
|
2735
|
+
},
|
|
2736
|
+
}]
|
|
2737
|
+
}], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
2738
|
+
class SnyMenuLabelDirective {
|
|
2739
|
+
class = input('', ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
|
|
2740
|
+
computedClass = computed(() => cn('px-2 py-1.5 text-sm font-semibold', this.class()), ...(ngDevMode ? [{ debugName: "computedClass" }] : /* istanbul ignore next */ []));
|
|
2741
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyMenuLabelDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2742
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: SnyMenuLabelDirective, isStandalone: true, selector: "[snyMenuLabel]", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "computedClass()" } }, ngImport: i0 });
|
|
2743
|
+
}
|
|
2744
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyMenuLabelDirective, decorators: [{
|
|
2745
|
+
type: Directive,
|
|
2746
|
+
args: [{
|
|
2747
|
+
selector: '[snyMenuLabel]',
|
|
2748
|
+
standalone: true,
|
|
2749
|
+
host: {
|
|
2750
|
+
'[class]': 'computedClass()',
|
|
2751
|
+
},
|
|
2752
|
+
}]
|
|
2753
|
+
}], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
2754
|
+
|
|
2755
|
+
class SnyCellDefDirective {
|
|
2756
|
+
snyCell = input.required(...(ngDevMode ? [{ debugName: "snyCell" }] : /* istanbul ignore next */ []));
|
|
2757
|
+
template = inject(TemplateRef);
|
|
2758
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyCellDefDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2759
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: SnyCellDefDirective, isStandalone: true, selector: "[snyCell]", inputs: { snyCell: { classPropertyName: "snyCell", publicName: "snyCell", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
|
|
2760
|
+
}
|
|
2761
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyCellDefDirective, decorators: [{
|
|
2762
|
+
type: Directive,
|
|
2763
|
+
args: [{
|
|
2764
|
+
selector: '[snyCell]',
|
|
2765
|
+
standalone: true,
|
|
2766
|
+
}]
|
|
2767
|
+
}], propDecorators: { snyCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "snyCell", required: true }] }] } });
|
|
2768
|
+
class SnyHeaderCellDefDirective {
|
|
2769
|
+
snyHeaderCell = input.required(...(ngDevMode ? [{ debugName: "snyHeaderCell" }] : /* istanbul ignore next */ []));
|
|
2770
|
+
template = inject(TemplateRef);
|
|
2771
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyHeaderCellDefDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2772
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: SnyHeaderCellDefDirective, isStandalone: true, selector: "[snyHeaderCell]", inputs: { snyHeaderCell: { classPropertyName: "snyHeaderCell", publicName: "snyHeaderCell", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
|
|
2773
|
+
}
|
|
2774
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyHeaderCellDefDirective, decorators: [{
|
|
2775
|
+
type: Directive,
|
|
2776
|
+
args: [{
|
|
2777
|
+
selector: '[snyHeaderCell]',
|
|
2778
|
+
standalone: true,
|
|
2779
|
+
}]
|
|
2780
|
+
}], propDecorators: { snyHeaderCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "snyHeaderCell", required: true }] }] } });
|
|
2781
|
+
class SnyBulkActionsDefDirective {
|
|
2782
|
+
template = inject(TemplateRef);
|
|
2783
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyBulkActionsDefDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2784
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: SnyBulkActionsDefDirective, isStandalone: true, selector: "[snyBulkActions]", ngImport: i0 });
|
|
2785
|
+
}
|
|
2786
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyBulkActionsDefDirective, decorators: [{
|
|
2787
|
+
type: Directive,
|
|
2788
|
+
args: [{
|
|
2789
|
+
selector: '[snyBulkActions]',
|
|
2790
|
+
standalone: true,
|
|
2791
|
+
}]
|
|
2792
|
+
}] });
|
|
2793
|
+
class SnyRowExpandDefDirective {
|
|
2794
|
+
template = inject(TemplateRef);
|
|
2795
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyRowExpandDefDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2796
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: SnyRowExpandDefDirective, isStandalone: true, selector: "[snyRowExpand]", ngImport: i0 });
|
|
2797
|
+
}
|
|
2798
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyRowExpandDefDirective, decorators: [{
|
|
2799
|
+
type: Directive,
|
|
2800
|
+
args: [{
|
|
2801
|
+
selector: '[snyRowExpand]',
|
|
2802
|
+
standalone: true,
|
|
2803
|
+
}]
|
|
2804
|
+
}] });
|
|
2805
|
+
|
|
2806
|
+
const DEFAULT_PAGINATION = {
|
|
2807
|
+
pageSize: 10,
|
|
2808
|
+
pageSizeOptions: [5, 10, 25, 50],
|
|
2809
|
+
};
|
|
2810
|
+
class SnyDataTableComponent {
|
|
2811
|
+
// Inputs
|
|
2812
|
+
columns = input.required(...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
2813
|
+
data = input.required(...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
2814
|
+
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
2815
|
+
density = input('normal', ...(ngDevMode ? [{ debugName: "density" }] : /* istanbul ignore next */ []));
|
|
2816
|
+
hoverable = input(true, ...(ngDevMode ? [{ debugName: "hoverable" }] : /* istanbul ignore next */ []));
|
|
2817
|
+
stickyHeader = input(false, ...(ngDevMode ? [{ debugName: "stickyHeader" }] : /* istanbul ignore next */ []));
|
|
2818
|
+
selectable = input(false, ...(ngDevMode ? [{ debugName: "selectable" }] : /* istanbul ignore next */ []));
|
|
2819
|
+
paginated = input(true, ...(ngDevMode ? [{ debugName: "paginated" }] : /* istanbul ignore next */ []));
|
|
2820
|
+
filterable = input(true, ...(ngDevMode ? [{ debugName: "filterable" }] : /* istanbul ignore next */ []));
|
|
2821
|
+
showExport = input(false, ...(ngDevMode ? [{ debugName: "showExport" }] : /* istanbul ignore next */ []));
|
|
2822
|
+
showColumnToggle = input(false, ...(ngDevMode ? [{ debugName: "showColumnToggle" }] : /* istanbul ignore next */ []));
|
|
2823
|
+
expandable = input(false, ...(ngDevMode ? [{ debugName: "expandable" }] : /* istanbul ignore next */ []));
|
|
2824
|
+
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
2825
|
+
loadingRows = input(5, ...(ngDevMode ? [{ debugName: "loadingRows" }] : /* istanbul ignore next */ []));
|
|
2826
|
+
paginationConfig = input(DEFAULT_PAGINATION, ...(ngDevMode ? [{ debugName: "paginationConfig" }] : /* istanbul ignore next */ []));
|
|
2827
|
+
trackBy = input('', ...(ngDevMode ? [{ debugName: "trackBy" }] : /* istanbul ignore next */ []));
|
|
2828
|
+
noDataText = input('No data available', ...(ngDevMode ? [{ debugName: "noDataText" }] : /* istanbul ignore next */ []));
|
|
2829
|
+
// Model
|
|
2830
|
+
selectedRows = model([], ...(ngDevMode ? [{ debugName: "selectedRows" }] : /* istanbul ignore next */ []));
|
|
2831
|
+
// Outputs
|
|
2832
|
+
sortChanged = output();
|
|
2833
|
+
rowClicked = output();
|
|
2834
|
+
dataExported = output();
|
|
2835
|
+
// Content queries
|
|
2836
|
+
cellDefs = contentChildren(SnyCellDefDirective, ...(ngDevMode ? [{ debugName: "cellDefs" }] : /* istanbul ignore next */ []));
|
|
2837
|
+
headerCellDefs = contentChildren(SnyHeaderCellDefDirective, ...(ngDevMode ? [{ debugName: "headerCellDefs" }] : /* istanbul ignore next */ []));
|
|
2838
|
+
bulkActionsDef = contentChild(SnyBulkActionsDefDirective, ...(ngDevMode ? [{ debugName: "bulkActionsDef" }] : /* istanbul ignore next */ []));
|
|
2839
|
+
rowExpandDef = contentChild(SnyRowExpandDefDirective, ...(ngDevMode ? [{ debugName: "rowExpandDef" }] : /* istanbul ignore next */ []));
|
|
2840
|
+
// Internal state
|
|
2841
|
+
sortState = signal({ key: '', direction: null }, ...(ngDevMode ? [{ debugName: "sortState" }] : /* istanbul ignore next */ []));
|
|
2842
|
+
filterText = signal('', ...(ngDevMode ? [{ debugName: "filterText" }] : /* istanbul ignore next */ []));
|
|
2843
|
+
currentPage = signal(1, ...(ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []));
|
|
2844
|
+
pageSize = signal(10, ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
|
|
2845
|
+
hiddenColumns = signal(new Set(), ...(ngDevMode ? [{ debugName: "hiddenColumns" }] : /* istanbul ignore next */ []));
|
|
2846
|
+
expandedRows = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedRows" }] : /* istanbul ignore next */ []));
|
|
2847
|
+
// Template def maps
|
|
2848
|
+
cellDefMap = computed(() => {
|
|
2849
|
+
const map = new Map();
|
|
2850
|
+
for (const def of this.cellDefs()) {
|
|
2851
|
+
map.set(def.snyCell(), def.template);
|
|
2852
|
+
}
|
|
2853
|
+
return map;
|
|
2854
|
+
}, ...(ngDevMode ? [{ debugName: "cellDefMap" }] : /* istanbul ignore next */ []));
|
|
2855
|
+
headerCellDefMap = computed(() => {
|
|
2856
|
+
const map = new Map();
|
|
2857
|
+
for (const def of this.headerCellDefs()) {
|
|
2858
|
+
map.set(def.snyHeaderCell(), def.template);
|
|
2859
|
+
}
|
|
2860
|
+
return map;
|
|
2861
|
+
}, ...(ngDevMode ? [{ debugName: "headerCellDefMap" }] : /* istanbul ignore next */ []));
|
|
2862
|
+
// Visible columns
|
|
2863
|
+
visibleColumns = computed(() => this.columns().filter((col) => col.visible !== false && !this.hiddenColumns().has(col.key)), ...(ngDevMode ? [{ debugName: "visibleColumns" }] : /* istanbul ignore next */ []));
|
|
2864
|
+
// Page size options
|
|
2865
|
+
pageSizeOptions = computed(() => this.paginationConfig().pageSizeOptions.map((n) => ({
|
|
2866
|
+
value: String(n),
|
|
2867
|
+
label: String(n),
|
|
2868
|
+
})), ...(ngDevMode ? [{ debugName: "pageSizeOptions" }] : /* istanbul ignore next */ []));
|
|
2869
|
+
pageSizeValue = computed(() => String(this.pageSize()), ...(ngDevMode ? [{ debugName: "pageSizeValue" }] : /* istanbul ignore next */ []));
|
|
2870
|
+
// Skeleton rows
|
|
2871
|
+
skeletonRows = computed(() => Array.from({ length: this.loadingRows() }, (_, i) => i), ...(ngDevMode ? [{ debugName: "skeletonRows" }] : /* istanbul ignore next */ []));
|
|
2872
|
+
// Bulk actions visibility
|
|
2873
|
+
showBulkActions = computed(() => this.selectable() &&
|
|
2874
|
+
this.selectedRows().length > 0 &&
|
|
2875
|
+
this.bulkActionsDef() != null, ...(ngDevMode ? [{ debugName: "showBulkActions" }] : /* istanbul ignore next */ []));
|
|
2876
|
+
// Data pipeline (filter uses all columns, not just visible)
|
|
2877
|
+
filteredData = computed(() => {
|
|
2878
|
+
const text = this.filterText().toLowerCase().trim();
|
|
2879
|
+
const rows = this.data();
|
|
2880
|
+
if (!text)
|
|
2881
|
+
return rows;
|
|
2882
|
+
const cols = this.columns().filter((c) => c.filterable !== false);
|
|
2883
|
+
return rows.filter((row) => cols.some((col) => String(row[col.key] ?? '').toLowerCase().includes(text)));
|
|
2884
|
+
}, ...(ngDevMode ? [{ debugName: "filteredData" }] : /* istanbul ignore next */ []));
|
|
2885
|
+
sortedData = computed(() => {
|
|
2886
|
+
const { key, direction } = this.sortState();
|
|
2887
|
+
const rows = this.filteredData();
|
|
2888
|
+
if (!key || !direction)
|
|
2889
|
+
return rows;
|
|
2890
|
+
return [...rows].sort((a, b) => {
|
|
2891
|
+
const aVal = a[key];
|
|
2892
|
+
const bVal = b[key];
|
|
2893
|
+
if (aVal == null && bVal == null)
|
|
2894
|
+
return 0;
|
|
2895
|
+
if (aVal == null)
|
|
2896
|
+
return direction === 'asc' ? -1 : 1;
|
|
2897
|
+
if (bVal == null)
|
|
2898
|
+
return direction === 'asc' ? 1 : -1;
|
|
2899
|
+
if (typeof aVal === 'number' && typeof bVal === 'number') {
|
|
2900
|
+
return direction === 'asc' ? aVal - bVal : bVal - aVal;
|
|
2901
|
+
}
|
|
2902
|
+
const cmp = String(aVal).localeCompare(String(bVal));
|
|
2903
|
+
return direction === 'asc' ? cmp : -cmp;
|
|
2904
|
+
});
|
|
2905
|
+
}, ...(ngDevMode ? [{ debugName: "sortedData" }] : /* istanbul ignore next */ []));
|
|
2906
|
+
totalPages = computed(() => Math.max(1, Math.ceil(this.filteredData().length / this.pageSize())), ...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
|
|
2907
|
+
paginatedData = computed(() => {
|
|
2908
|
+
if (!this.paginated())
|
|
2909
|
+
return this.sortedData();
|
|
2910
|
+
const start = (this.currentPage() - 1) * this.pageSize();
|
|
2911
|
+
return this.sortedData().slice(start, start + this.pageSize());
|
|
2912
|
+
}, ...(ngDevMode ? [{ debugName: "paginatedData" }] : /* istanbul ignore next */ []));
|
|
2913
|
+
totalColSpan = computed(() => this.visibleColumns().length +
|
|
2914
|
+
(this.selectable() ? 1 : 0) +
|
|
2915
|
+
(this.expandable() ? 1 : 0), ...(ngDevMode ? [{ debugName: "totalColSpan" }] : /* istanbul ignore next */ []));
|
|
2916
|
+
// Selection computed
|
|
2917
|
+
allSelected = computed(() => {
|
|
2918
|
+
const page = this.paginatedData();
|
|
2919
|
+
if (page.length === 0)
|
|
2920
|
+
return false;
|
|
2921
|
+
const selected = this.selectedRows();
|
|
2922
|
+
return page.every((row) => this.isRowInList(row, selected));
|
|
2923
|
+
}, ...(ngDevMode ? [{ debugName: "allSelected" }] : /* istanbul ignore next */ []));
|
|
2924
|
+
someSelected = computed(() => {
|
|
2925
|
+
const page = this.paginatedData();
|
|
2926
|
+
const selected = this.selectedRows();
|
|
2927
|
+
return page.some((row) => this.isRowInList(row, selected));
|
|
2928
|
+
}, ...(ngDevMode ? [{ debugName: "someSelected" }] : /* istanbul ignore next */ []));
|
|
2929
|
+
constructor() {
|
|
2930
|
+
effect(() => {
|
|
2931
|
+
const config = this.paginationConfig();
|
|
2932
|
+
untracked(() => this.pageSize.set(config.pageSize));
|
|
2933
|
+
});
|
|
2934
|
+
effect(() => {
|
|
2935
|
+
this.filterText();
|
|
2936
|
+
this.pageSize();
|
|
2937
|
+
this.data();
|
|
2938
|
+
untracked(() => this.currentPage.set(1));
|
|
2939
|
+
});
|
|
2940
|
+
}
|
|
2941
|
+
// Sort
|
|
2942
|
+
toggleSort(key) {
|
|
2943
|
+
const current = this.sortState();
|
|
2944
|
+
let direction;
|
|
2945
|
+
if (current.key !== key) {
|
|
2946
|
+
direction = 'asc';
|
|
2947
|
+
}
|
|
2948
|
+
else if (current.direction === 'asc') {
|
|
2949
|
+
direction = 'desc';
|
|
2950
|
+
}
|
|
2951
|
+
else if (current.direction === 'desc') {
|
|
2952
|
+
direction = null;
|
|
2953
|
+
}
|
|
2954
|
+
else {
|
|
2955
|
+
direction = 'asc';
|
|
2956
|
+
}
|
|
2957
|
+
const next = { key: direction ? key : '', direction };
|
|
2958
|
+
this.sortState.set(next);
|
|
2959
|
+
this.sortChanged.emit(next);
|
|
2960
|
+
}
|
|
2961
|
+
// Filter
|
|
2962
|
+
onFilterInput(event) {
|
|
2963
|
+
this.filterText.set(event.target.value);
|
|
2964
|
+
}
|
|
2965
|
+
// Page size
|
|
2966
|
+
onPageSizeChange(value) {
|
|
2967
|
+
this.pageSize.set(Number(value));
|
|
2968
|
+
}
|
|
2969
|
+
// Selection
|
|
2970
|
+
toggleSelectAll() {
|
|
2971
|
+
if (this.allSelected()) {
|
|
2972
|
+
const page = this.paginatedData();
|
|
2973
|
+
this.selectedRows.update((sel) => sel.filter((r) => !page.some((p) => this.rowsEqual(r, p))));
|
|
2974
|
+
}
|
|
2975
|
+
else {
|
|
2976
|
+
const page = this.paginatedData();
|
|
2977
|
+
this.selectedRows.update((sel) => {
|
|
2978
|
+
const newSel = [...sel];
|
|
2979
|
+
for (const row of page) {
|
|
2980
|
+
if (!this.isRowInList(row, newSel))
|
|
2981
|
+
newSel.push(row);
|
|
2982
|
+
}
|
|
2983
|
+
return newSel;
|
|
2984
|
+
});
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
toggleRowSelection(row) {
|
|
2988
|
+
this.selectedRows.update((sel) => this.isRowInList(row, sel)
|
|
2989
|
+
? sel.filter((r) => !this.rowsEqual(r, row))
|
|
2990
|
+
: [...sel, row]);
|
|
2991
|
+
}
|
|
2992
|
+
// Row click
|
|
2993
|
+
onRowClick(row) {
|
|
2994
|
+
this.rowClicked.emit(row);
|
|
2995
|
+
}
|
|
2996
|
+
// Export
|
|
2997
|
+
onExport() {
|
|
2998
|
+
this.dataExported.emit(this.filteredData());
|
|
2999
|
+
}
|
|
3000
|
+
// Column visibility
|
|
3001
|
+
toggleColumnVisibility(key) {
|
|
3002
|
+
this.hiddenColumns.update((set) => {
|
|
3003
|
+
const next = new Set(set);
|
|
3004
|
+
if (next.has(key))
|
|
3005
|
+
next.delete(key);
|
|
3006
|
+
else
|
|
3007
|
+
next.add(key);
|
|
3008
|
+
return next;
|
|
3009
|
+
});
|
|
3010
|
+
}
|
|
3011
|
+
// Expansion
|
|
3012
|
+
toggleRowExpansion(row) {
|
|
3013
|
+
const key = this.trackBy() ? row[this.trackBy()] : row;
|
|
3014
|
+
this.expandedRows.update((set) => {
|
|
3015
|
+
const next = new Set(set);
|
|
3016
|
+
if (next.has(key))
|
|
3017
|
+
next.delete(key);
|
|
3018
|
+
else
|
|
3019
|
+
next.add(key);
|
|
3020
|
+
return next;
|
|
3021
|
+
});
|
|
3022
|
+
}
|
|
3023
|
+
isExpanded(row) {
|
|
3024
|
+
const key = this.trackBy() ? row[this.trackBy()] : row;
|
|
3025
|
+
return this.expandedRows().has(key);
|
|
3026
|
+
}
|
|
3027
|
+
// Helpers
|
|
3028
|
+
isSelected(row) {
|
|
3029
|
+
return this.isRowInList(row, this.selectedRows());
|
|
3030
|
+
}
|
|
3031
|
+
trackByFn(row, index) {
|
|
3032
|
+
const key = this.trackBy();
|
|
3033
|
+
return key ? row[key] : index;
|
|
3034
|
+
}
|
|
3035
|
+
isRowInList(row, list) {
|
|
3036
|
+
return list.some((r) => this.rowsEqual(r, row));
|
|
3037
|
+
}
|
|
3038
|
+
rowsEqual(a, b) {
|
|
3039
|
+
const key = this.trackBy();
|
|
3040
|
+
if (key)
|
|
3041
|
+
return a[key] === b[key];
|
|
3042
|
+
return a === b;
|
|
3043
|
+
}
|
|
3044
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyDataTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3045
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: SnyDataTableComponent, isStandalone: true, selector: "sny-data-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, hoverable: { classPropertyName: "hoverable", publicName: "hoverable", isSignal: true, isRequired: false, transformFunction: null }, stickyHeader: { classPropertyName: "stickyHeader", publicName: "stickyHeader", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, paginated: { classPropertyName: "paginated", publicName: "paginated", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, showExport: { classPropertyName: "showExport", publicName: "showExport", isSignal: true, isRequired: false, transformFunction: null }, showColumnToggle: { classPropertyName: "showColumnToggle", publicName: "showColumnToggle", isSignal: true, isRequired: false, transformFunction: null }, expandable: { classPropertyName: "expandable", publicName: "expandable", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingRows: { classPropertyName: "loadingRows", publicName: "loadingRows", isSignal: true, isRequired: false, transformFunction: null }, paginationConfig: { classPropertyName: "paginationConfig", publicName: "paginationConfig", isSignal: true, isRequired: false, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null }, noDataText: { classPropertyName: "noDataText", publicName: "noDataText", isSignal: true, isRequired: false, transformFunction: null }, selectedRows: { classPropertyName: "selectedRows", publicName: "selectedRows", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedRows: "selectedRowsChange", sortChanged: "sortChanged", rowClicked: "rowClicked", dataExported: "dataExported" }, queries: [{ propertyName: "cellDefs", predicate: SnyCellDefDirective, isSignal: true }, { propertyName: "headerCellDefs", predicate: SnyHeaderCellDefDirective, isSignal: true }, { propertyName: "bulkActionsDef", first: true, predicate: SnyBulkActionsDefDirective, descendants: true, isSignal: true }, { propertyName: "rowExpandDef", first: true, predicate: SnyRowExpandDefDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
3046
|
+
<!-- Toolbar -->
|
|
3047
|
+
@if (filterable() || showExport() || showColumnToggle()) {
|
|
3048
|
+
<div class="flex items-center justify-between gap-4 mb-4 flex-wrap">
|
|
3049
|
+
@if (filterable()) {
|
|
3050
|
+
<input
|
|
3051
|
+
snyInput
|
|
3052
|
+
[value]="filterText()"
|
|
3053
|
+
(input)="onFilterInput($event)"
|
|
3054
|
+
placeholder="Filter..."
|
|
3055
|
+
class="w-full sm:max-w-sm"
|
|
3056
|
+
/>
|
|
3057
|
+
}
|
|
3058
|
+
<div class="flex items-center gap-2">
|
|
3059
|
+
@if (showExport()) {
|
|
3060
|
+
<button snyBtn variant="outline" size="sm" (click)="onExport()">
|
|
3061
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="sm:mr-2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z"/><path d="M14 2v6h6"/><path d="M12 18v-6"/><path d="m9 15 3-3 3 3"/></svg>
|
|
3062
|
+
<span class="hidden sm:inline">Export</span>
|
|
3063
|
+
</button>
|
|
3064
|
+
}
|
|
3065
|
+
@if (showColumnToggle()) {
|
|
3066
|
+
<div snyDropdown class="relative">
|
|
3067
|
+
<button snyBtn variant="outline" size="sm" snyDropdownTrigger>
|
|
3068
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="sm:mr-2"><path d="M12 3v18"/><rect width="18" height="18" x="3" y="3" rx="2"/><path d="M3 9h18"/><path d="M3 15h18"/></svg>
|
|
3069
|
+
<span class="hidden sm:inline">Columns</span>
|
|
3070
|
+
</button>
|
|
3071
|
+
<div snyDropdownContent class="w-48 right-0 left-auto">
|
|
3072
|
+
@for (col of columns(); track col.key) {
|
|
3073
|
+
<label snyMenuItem class="flex items-center gap-2 cursor-pointer">
|
|
3074
|
+
<input
|
|
3075
|
+
type="checkbox"
|
|
3076
|
+
snyCheckbox
|
|
3077
|
+
[checked]="!hiddenColumns().has(col.key)"
|
|
3078
|
+
(change)="toggleColumnVisibility(col.key)"
|
|
3079
|
+
(click)="$event.stopPropagation()"
|
|
3080
|
+
/>
|
|
3081
|
+
{{ col.label }}
|
|
3082
|
+
</label>
|
|
3083
|
+
}
|
|
3084
|
+
</div>
|
|
3085
|
+
</div>
|
|
3086
|
+
}
|
|
3087
|
+
</div>
|
|
3088
|
+
</div>
|
|
3089
|
+
}
|
|
3090
|
+
|
|
3091
|
+
<!-- Bulk Actions Bar -->
|
|
3092
|
+
@if (showBulkActions()) {
|
|
3093
|
+
@let selected = selectedRows();
|
|
3094
|
+
<div class="flex items-center gap-2 mb-4 p-3 bg-muted/50 rounded-sm border border-border flex-wrap">
|
|
3095
|
+
<span class="text-sm font-medium text-muted-foreground mr-2">
|
|
3096
|
+
{{ selected.length }} selected
|
|
3097
|
+
</span>
|
|
3098
|
+
<ng-container
|
|
3099
|
+
[ngTemplateOutlet]="bulkActionsDef()!.template"
|
|
3100
|
+
[ngTemplateOutletContext]="{ $implicit: selected }"
|
|
3101
|
+
/>
|
|
3102
|
+
<button
|
|
3103
|
+
snyBtn variant="ghost" size="sm" class="ml-auto"
|
|
3104
|
+
(click)="selectedRows.set([])"
|
|
3105
|
+
>
|
|
3106
|
+
Clear
|
|
3107
|
+
</button>
|
|
3108
|
+
</div>
|
|
3109
|
+
}
|
|
3110
|
+
|
|
3111
|
+
<!-- Table -->
|
|
3112
|
+
<div class="overflow-auto border border-border rounded-sm">
|
|
3113
|
+
<table
|
|
3114
|
+
snyTable
|
|
3115
|
+
[variant]="variant()"
|
|
3116
|
+
[density]="density()"
|
|
3117
|
+
[hoverable]="hoverable()"
|
|
3118
|
+
[stickyHeader]="stickyHeader()"
|
|
3119
|
+
>
|
|
3120
|
+
<thead snyTableHeader>
|
|
3121
|
+
<tr snyTableRow>
|
|
3122
|
+
@if (selectable()) {
|
|
3123
|
+
<th snyTableHead class="w-12">
|
|
3124
|
+
<input
|
|
3125
|
+
type="checkbox"
|
|
3126
|
+
snyCheckbox
|
|
3127
|
+
[checked]="allSelected()"
|
|
3128
|
+
[indeterminate]="someSelected() && !allSelected()"
|
|
3129
|
+
(change)="toggleSelectAll()"
|
|
3130
|
+
/>
|
|
3131
|
+
</th>
|
|
3132
|
+
}
|
|
3133
|
+
@if (expandable()) {
|
|
3134
|
+
<th snyTableHead class="w-10"></th>
|
|
3135
|
+
}
|
|
3136
|
+
@let sort = sortState();
|
|
3137
|
+
@let headerDefs = headerCellDefMap();
|
|
3138
|
+
@for (col of visibleColumns(); track col.key) {
|
|
3139
|
+
<th
|
|
3140
|
+
snyTableHead
|
|
3141
|
+
[style.width]="col.width ?? null"
|
|
3142
|
+
[class]="col.sortable ? 'cursor-pointer select-none' : ''"
|
|
3143
|
+
(click)="col.sortable ? toggleSort(col.key) : null"
|
|
3144
|
+
>
|
|
3145
|
+
@if (headerDefs.has(col.key)) {
|
|
3146
|
+
<ng-container
|
|
3147
|
+
[ngTemplateOutlet]="headerDefs.get(col.key)!"
|
|
3148
|
+
[ngTemplateOutletContext]="{ $implicit: col }"
|
|
3149
|
+
/>
|
|
3150
|
+
} @else {
|
|
3151
|
+
<div class="flex items-center gap-1">
|
|
3152
|
+
<span>{{ col.label }}</span>
|
|
3153
|
+
@if (col.sortable) {
|
|
3154
|
+
@let isActive = sort.key === col.key;
|
|
3155
|
+
@if (isActive && sort.direction === 'asc') {
|
|
3156
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m5 12 7-7 7 7"/></svg>
|
|
3157
|
+
} @else if (isActive && sort.direction === 'desc') {
|
|
3158
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m19 12-7 7-7-7"/></svg>
|
|
3159
|
+
} @else {
|
|
3160
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="opacity-30"><path d="m7 15 5 5 5-5"/><path d="m7 9 5-5 5 5"/></svg>
|
|
3161
|
+
}
|
|
3162
|
+
}
|
|
3163
|
+
</div>
|
|
3164
|
+
}
|
|
3165
|
+
</th>
|
|
3166
|
+
}
|
|
3167
|
+
</tr>
|
|
3168
|
+
</thead>
|
|
3169
|
+
<tbody snyTableBody>
|
|
3170
|
+
@if (loading()) {
|
|
3171
|
+
@for (i of skeletonRows(); track i) {
|
|
3172
|
+
<tr snyTableRow>
|
|
3173
|
+
@if (selectable()) {
|
|
3174
|
+
<td snyTableCell class="w-12"><div snySkeleton class="w-4 h-4 rounded"></div></td>
|
|
3175
|
+
}
|
|
3176
|
+
@if (expandable()) {
|
|
3177
|
+
<td snyTableCell class="w-10"><div snySkeleton class="w-4 h-4 rounded"></div></td>
|
|
3178
|
+
}
|
|
3179
|
+
@for (col of visibleColumns(); track col.key) {
|
|
3180
|
+
<td snyTableCell [style.width]="col.width ?? null">
|
|
3181
|
+
<div snySkeleton class="w-full h-4 rounded"></div>
|
|
3182
|
+
</td>
|
|
3183
|
+
}
|
|
3184
|
+
</tr>
|
|
3185
|
+
}
|
|
3186
|
+
} @else if (paginatedData().length === 0) {
|
|
3187
|
+
<tr snyTableRow>
|
|
3188
|
+
<td
|
|
3189
|
+
snyTableCell
|
|
3190
|
+
[attr.colspan]="totalColSpan()"
|
|
3191
|
+
class="text-center text-muted-foreground py-8"
|
|
3192
|
+
>
|
|
3193
|
+
{{ noDataText() }}
|
|
3194
|
+
</td>
|
|
3195
|
+
</tr>
|
|
3196
|
+
} @else {
|
|
3197
|
+
@let cellDefs = cellDefMap();
|
|
3198
|
+
@let cols = visibleColumns();
|
|
3199
|
+
@let expandTpl = rowExpandDef();
|
|
3200
|
+
@for (row of paginatedData(); track trackByFn(row, $index)) {
|
|
3201
|
+
<tr
|
|
3202
|
+
snyTableRow
|
|
3203
|
+
[attr.data-state]="isSelected(row) ? 'selected' : null"
|
|
3204
|
+
(click)="onRowClick(row)"
|
|
3205
|
+
class="cursor-pointer"
|
|
3206
|
+
>
|
|
3207
|
+
@if (selectable()) {
|
|
3208
|
+
<td snyTableCell class="w-12">
|
|
3209
|
+
<input
|
|
3210
|
+
type="checkbox"
|
|
3211
|
+
snyCheckbox
|
|
3212
|
+
[checked]="isSelected(row)"
|
|
3213
|
+
(change)="toggleRowSelection(row)"
|
|
3214
|
+
(click)="$event.stopPropagation()"
|
|
3215
|
+
/>
|
|
3216
|
+
</td>
|
|
3217
|
+
}
|
|
3218
|
+
@if (expandable()) {
|
|
3219
|
+
<td snyTableCell class="w-10">
|
|
3220
|
+
<button
|
|
3221
|
+
class="p-0.5 rounded hover:bg-accent transition-transform duration-150"
|
|
3222
|
+
[class.rotate-90]="isExpanded(row)"
|
|
3223
|
+
(click)="toggleRowExpansion(row); $event.stopPropagation()"
|
|
3224
|
+
>
|
|
3225
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>
|
|
3226
|
+
</button>
|
|
3227
|
+
</td>
|
|
3228
|
+
}
|
|
3229
|
+
@for (col of cols; track col.key) {
|
|
3230
|
+
<td snyTableCell [style.width]="col.width ?? null">
|
|
3231
|
+
@if (cellDefs.has(col.key)) {
|
|
3232
|
+
<ng-container
|
|
3233
|
+
[ngTemplateOutlet]="cellDefs.get(col.key)!"
|
|
3234
|
+
[ngTemplateOutletContext]="{ $implicit: row[col.key], row: row }"
|
|
3235
|
+
/>
|
|
3236
|
+
} @else {
|
|
3237
|
+
{{ row[col.key] }}
|
|
3238
|
+
}
|
|
3239
|
+
</td>
|
|
3240
|
+
}
|
|
3241
|
+
</tr>
|
|
3242
|
+
@if (expandable() && isExpanded(row) && expandTpl) {
|
|
3243
|
+
<tr snyTableRow>
|
|
3244
|
+
<td snyTableCell [attr.colspan]="totalColSpan()" class="bg-muted/30">
|
|
3245
|
+
<ng-container
|
|
3246
|
+
[ngTemplateOutlet]="expandTpl.template"
|
|
3247
|
+
[ngTemplateOutletContext]="{ $implicit: row }"
|
|
3248
|
+
/>
|
|
3249
|
+
</td>
|
|
3250
|
+
</tr>
|
|
3251
|
+
}
|
|
3252
|
+
}
|
|
3253
|
+
}
|
|
3254
|
+
</tbody>
|
|
3255
|
+
</table>
|
|
3256
|
+
</div>
|
|
3257
|
+
|
|
3258
|
+
<!-- Footer -->
|
|
3259
|
+
@if (paginated()) {
|
|
3260
|
+
<div class="flex flex-col sm:flex-row items-start sm:items-center justify-between mt-4 gap-3 sm:gap-4">
|
|
3261
|
+
<span class="text-sm text-muted-foreground">
|
|
3262
|
+
@if (selectable()) {
|
|
3263
|
+
{{ selectedRows().length }} of {{ filteredData().length }} row(s) selected
|
|
3264
|
+
} @else {
|
|
3265
|
+
{{ filteredData().length }} row(s)
|
|
3266
|
+
}
|
|
3267
|
+
</span>
|
|
3268
|
+
<div class="flex items-center gap-3 sm:gap-4 flex-wrap">
|
|
3269
|
+
<div class="flex items-center gap-2">
|
|
3270
|
+
<span class="hidden sm:inline text-sm text-muted-foreground whitespace-nowrap">Rows per page</span>
|
|
3271
|
+
<sny-select
|
|
3272
|
+
[options]="pageSizeOptions()"
|
|
3273
|
+
[value]="pageSizeValue()"
|
|
3274
|
+
(valueChange)="onPageSizeChange($event)"
|
|
3275
|
+
size="sm"
|
|
3276
|
+
class="w-20"
|
|
3277
|
+
/>
|
|
3278
|
+
</div>
|
|
3279
|
+
<sny-pagination
|
|
3280
|
+
[currentPage]="currentPage()"
|
|
3281
|
+
(currentPageChange)="currentPage.set($event)"
|
|
3282
|
+
[totalPages]="totalPages()"
|
|
3283
|
+
/>
|
|
3284
|
+
</div>
|
|
3285
|
+
</div>
|
|
3286
|
+
}
|
|
3287
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: SnyTableDirective, selector: "table[snyTable]", inputs: ["variant", "density", "hoverable", "stickyHeader", "class"] }, { kind: "directive", type: SnyTableHeaderDirective, selector: "thead[snyTableHeader]", inputs: ["class"] }, { kind: "directive", type: SnyTableBodyDirective, selector: "tbody[snyTableBody]", inputs: ["class"] }, { kind: "directive", type: SnyTableRowDirective, selector: "tr[snyTableRow]", inputs: ["class"] }, { kind: "directive", type: SnyTableHeadDirective, selector: "th[snyTableHead]", inputs: ["class"] }, { kind: "directive", type: SnyTableCellDirective, selector: "td[snyTableCell]", inputs: ["class"] }, { kind: "component", type: SnyPaginationComponent, selector: "sny-pagination", inputs: ["currentPage", "totalPages", "siblingCount", "boundaryCount", "size", "variant", "class"], outputs: ["currentPageChange"] }, { kind: "directive", type: SnyCheckboxDirective, selector: "input[type=\"checkbox\"][snyCheckbox]", inputs: ["size", "class"] }, { kind: "directive", type: SnyInputDirective, selector: "input[snyInput], textarea[snyInput]", inputs: ["variant", "inputSize", "class", "ariaDescribedBy"] }, { kind: "directive", type: SnyButtonDirective, selector: "button[snyBtn], a[snyBtn]", inputs: ["variant", "size", "disabled", "loading", "class"] }, { kind: "component", type: SnySelectComponent, selector: "sny-select", inputs: ["options", "placeholder", "size", "disabled", "class", "value"], outputs: ["valueChange"] }, { kind: "directive", type: SnySkeletonDirective, selector: "[snySkeleton]", inputs: ["variant", "size", "class"] }, { kind: "directive", type: SnyDropdownDirective, selector: "[snyDropdown]", exportAs: ["snyDropdown"] }, { kind: "directive", type: SnyDropdownTriggerDirective, selector: "[snyDropdownTrigger]" }, { kind: "directive", type: SnyDropdownContentDirective, selector: "[snyDropdownContent]", inputs: ["class"] }, { kind: "directive", type: SnyMenuItemDirective, selector: "[snyMenuItem]", inputs: ["variant", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3288
|
+
}
|
|
3289
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyDataTableComponent, decorators: [{
|
|
3290
|
+
type: Component,
|
|
3291
|
+
args: [{
|
|
3292
|
+
selector: 'sny-data-table',
|
|
3293
|
+
standalone: true,
|
|
3294
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3295
|
+
imports: [
|
|
3296
|
+
NgTemplateOutlet,
|
|
3297
|
+
SnyTableDirective,
|
|
3298
|
+
SnyTableHeaderDirective,
|
|
3299
|
+
SnyTableBodyDirective,
|
|
3300
|
+
SnyTableRowDirective,
|
|
3301
|
+
SnyTableHeadDirective,
|
|
3302
|
+
SnyTableCellDirective,
|
|
3303
|
+
SnyPaginationComponent,
|
|
3304
|
+
SnyCheckboxDirective,
|
|
3305
|
+
SnyInputDirective,
|
|
3306
|
+
SnyButtonDirective,
|
|
3307
|
+
SnySelectComponent,
|
|
3308
|
+
SnySkeletonDirective,
|
|
3309
|
+
SnyDropdownDirective,
|
|
3310
|
+
SnyDropdownTriggerDirective,
|
|
3311
|
+
SnyDropdownContentDirective,
|
|
3312
|
+
SnyMenuItemDirective,
|
|
3313
|
+
],
|
|
3314
|
+
template: `
|
|
3315
|
+
<!-- Toolbar -->
|
|
3316
|
+
@if (filterable() || showExport() || showColumnToggle()) {
|
|
3317
|
+
<div class="flex items-center justify-between gap-4 mb-4 flex-wrap">
|
|
3318
|
+
@if (filterable()) {
|
|
3319
|
+
<input
|
|
3320
|
+
snyInput
|
|
3321
|
+
[value]="filterText()"
|
|
3322
|
+
(input)="onFilterInput($event)"
|
|
3323
|
+
placeholder="Filter..."
|
|
3324
|
+
class="w-full sm:max-w-sm"
|
|
3325
|
+
/>
|
|
3326
|
+
}
|
|
3327
|
+
<div class="flex items-center gap-2">
|
|
3328
|
+
@if (showExport()) {
|
|
3329
|
+
<button snyBtn variant="outline" size="sm" (click)="onExport()">
|
|
3330
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="sm:mr-2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z"/><path d="M14 2v6h6"/><path d="M12 18v-6"/><path d="m9 15 3-3 3 3"/></svg>
|
|
3331
|
+
<span class="hidden sm:inline">Export</span>
|
|
3332
|
+
</button>
|
|
3333
|
+
}
|
|
3334
|
+
@if (showColumnToggle()) {
|
|
3335
|
+
<div snyDropdown class="relative">
|
|
3336
|
+
<button snyBtn variant="outline" size="sm" snyDropdownTrigger>
|
|
3337
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="sm:mr-2"><path d="M12 3v18"/><rect width="18" height="18" x="3" y="3" rx="2"/><path d="M3 9h18"/><path d="M3 15h18"/></svg>
|
|
3338
|
+
<span class="hidden sm:inline">Columns</span>
|
|
3339
|
+
</button>
|
|
3340
|
+
<div snyDropdownContent class="w-48 right-0 left-auto">
|
|
3341
|
+
@for (col of columns(); track col.key) {
|
|
3342
|
+
<label snyMenuItem class="flex items-center gap-2 cursor-pointer">
|
|
3343
|
+
<input
|
|
3344
|
+
type="checkbox"
|
|
3345
|
+
snyCheckbox
|
|
3346
|
+
[checked]="!hiddenColumns().has(col.key)"
|
|
3347
|
+
(change)="toggleColumnVisibility(col.key)"
|
|
3348
|
+
(click)="$event.stopPropagation()"
|
|
3349
|
+
/>
|
|
3350
|
+
{{ col.label }}
|
|
3351
|
+
</label>
|
|
3352
|
+
}
|
|
3353
|
+
</div>
|
|
3354
|
+
</div>
|
|
3355
|
+
}
|
|
3356
|
+
</div>
|
|
3357
|
+
</div>
|
|
3358
|
+
}
|
|
3359
|
+
|
|
3360
|
+
<!-- Bulk Actions Bar -->
|
|
3361
|
+
@if (showBulkActions()) {
|
|
3362
|
+
@let selected = selectedRows();
|
|
3363
|
+
<div class="flex items-center gap-2 mb-4 p-3 bg-muted/50 rounded-sm border border-border flex-wrap">
|
|
3364
|
+
<span class="text-sm font-medium text-muted-foreground mr-2">
|
|
3365
|
+
{{ selected.length }} selected
|
|
3366
|
+
</span>
|
|
3367
|
+
<ng-container
|
|
3368
|
+
[ngTemplateOutlet]="bulkActionsDef()!.template"
|
|
3369
|
+
[ngTemplateOutletContext]="{ $implicit: selected }"
|
|
3370
|
+
/>
|
|
3371
|
+
<button
|
|
3372
|
+
snyBtn variant="ghost" size="sm" class="ml-auto"
|
|
3373
|
+
(click)="selectedRows.set([])"
|
|
3374
|
+
>
|
|
3375
|
+
Clear
|
|
3376
|
+
</button>
|
|
3377
|
+
</div>
|
|
3378
|
+
}
|
|
3379
|
+
|
|
3380
|
+
<!-- Table -->
|
|
3381
|
+
<div class="overflow-auto border border-border rounded-sm">
|
|
3382
|
+
<table
|
|
3383
|
+
snyTable
|
|
3384
|
+
[variant]="variant()"
|
|
3385
|
+
[density]="density()"
|
|
3386
|
+
[hoverable]="hoverable()"
|
|
3387
|
+
[stickyHeader]="stickyHeader()"
|
|
3388
|
+
>
|
|
3389
|
+
<thead snyTableHeader>
|
|
3390
|
+
<tr snyTableRow>
|
|
3391
|
+
@if (selectable()) {
|
|
3392
|
+
<th snyTableHead class="w-12">
|
|
3393
|
+
<input
|
|
3394
|
+
type="checkbox"
|
|
3395
|
+
snyCheckbox
|
|
3396
|
+
[checked]="allSelected()"
|
|
3397
|
+
[indeterminate]="someSelected() && !allSelected()"
|
|
3398
|
+
(change)="toggleSelectAll()"
|
|
3399
|
+
/>
|
|
3400
|
+
</th>
|
|
3401
|
+
}
|
|
3402
|
+
@if (expandable()) {
|
|
3403
|
+
<th snyTableHead class="w-10"></th>
|
|
3404
|
+
}
|
|
3405
|
+
@let sort = sortState();
|
|
3406
|
+
@let headerDefs = headerCellDefMap();
|
|
3407
|
+
@for (col of visibleColumns(); track col.key) {
|
|
3408
|
+
<th
|
|
3409
|
+
snyTableHead
|
|
3410
|
+
[style.width]="col.width ?? null"
|
|
3411
|
+
[class]="col.sortable ? 'cursor-pointer select-none' : ''"
|
|
3412
|
+
(click)="col.sortable ? toggleSort(col.key) : null"
|
|
3413
|
+
>
|
|
3414
|
+
@if (headerDefs.has(col.key)) {
|
|
3415
|
+
<ng-container
|
|
3416
|
+
[ngTemplateOutlet]="headerDefs.get(col.key)!"
|
|
3417
|
+
[ngTemplateOutletContext]="{ $implicit: col }"
|
|
3418
|
+
/>
|
|
3419
|
+
} @else {
|
|
3420
|
+
<div class="flex items-center gap-1">
|
|
3421
|
+
<span>{{ col.label }}</span>
|
|
3422
|
+
@if (col.sortable) {
|
|
3423
|
+
@let isActive = sort.key === col.key;
|
|
3424
|
+
@if (isActive && sort.direction === 'asc') {
|
|
3425
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m5 12 7-7 7 7"/></svg>
|
|
3426
|
+
} @else if (isActive && sort.direction === 'desc') {
|
|
3427
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m19 12-7 7-7-7"/></svg>
|
|
3428
|
+
} @else {
|
|
3429
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="opacity-30"><path d="m7 15 5 5 5-5"/><path d="m7 9 5-5 5 5"/></svg>
|
|
3430
|
+
}
|
|
3431
|
+
}
|
|
3432
|
+
</div>
|
|
3433
|
+
}
|
|
3434
|
+
</th>
|
|
3435
|
+
}
|
|
3436
|
+
</tr>
|
|
3437
|
+
</thead>
|
|
3438
|
+
<tbody snyTableBody>
|
|
3439
|
+
@if (loading()) {
|
|
3440
|
+
@for (i of skeletonRows(); track i) {
|
|
3441
|
+
<tr snyTableRow>
|
|
3442
|
+
@if (selectable()) {
|
|
3443
|
+
<td snyTableCell class="w-12"><div snySkeleton class="w-4 h-4 rounded"></div></td>
|
|
3444
|
+
}
|
|
3445
|
+
@if (expandable()) {
|
|
3446
|
+
<td snyTableCell class="w-10"><div snySkeleton class="w-4 h-4 rounded"></div></td>
|
|
3447
|
+
}
|
|
3448
|
+
@for (col of visibleColumns(); track col.key) {
|
|
3449
|
+
<td snyTableCell [style.width]="col.width ?? null">
|
|
3450
|
+
<div snySkeleton class="w-full h-4 rounded"></div>
|
|
3451
|
+
</td>
|
|
3452
|
+
}
|
|
3453
|
+
</tr>
|
|
3454
|
+
}
|
|
3455
|
+
} @else if (paginatedData().length === 0) {
|
|
3456
|
+
<tr snyTableRow>
|
|
3457
|
+
<td
|
|
3458
|
+
snyTableCell
|
|
3459
|
+
[attr.colspan]="totalColSpan()"
|
|
3460
|
+
class="text-center text-muted-foreground py-8"
|
|
3461
|
+
>
|
|
3462
|
+
{{ noDataText() }}
|
|
3463
|
+
</td>
|
|
3464
|
+
</tr>
|
|
3465
|
+
} @else {
|
|
3466
|
+
@let cellDefs = cellDefMap();
|
|
3467
|
+
@let cols = visibleColumns();
|
|
3468
|
+
@let expandTpl = rowExpandDef();
|
|
3469
|
+
@for (row of paginatedData(); track trackByFn(row, $index)) {
|
|
3470
|
+
<tr
|
|
3471
|
+
snyTableRow
|
|
3472
|
+
[attr.data-state]="isSelected(row) ? 'selected' : null"
|
|
3473
|
+
(click)="onRowClick(row)"
|
|
3474
|
+
class="cursor-pointer"
|
|
3475
|
+
>
|
|
3476
|
+
@if (selectable()) {
|
|
3477
|
+
<td snyTableCell class="w-12">
|
|
3478
|
+
<input
|
|
3479
|
+
type="checkbox"
|
|
3480
|
+
snyCheckbox
|
|
3481
|
+
[checked]="isSelected(row)"
|
|
3482
|
+
(change)="toggleRowSelection(row)"
|
|
3483
|
+
(click)="$event.stopPropagation()"
|
|
3484
|
+
/>
|
|
3485
|
+
</td>
|
|
3486
|
+
}
|
|
3487
|
+
@if (expandable()) {
|
|
3488
|
+
<td snyTableCell class="w-10">
|
|
3489
|
+
<button
|
|
3490
|
+
class="p-0.5 rounded hover:bg-accent transition-transform duration-150"
|
|
3491
|
+
[class.rotate-90]="isExpanded(row)"
|
|
3492
|
+
(click)="toggleRowExpansion(row); $event.stopPropagation()"
|
|
3493
|
+
>
|
|
3494
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>
|
|
3495
|
+
</button>
|
|
3496
|
+
</td>
|
|
3497
|
+
}
|
|
3498
|
+
@for (col of cols; track col.key) {
|
|
3499
|
+
<td snyTableCell [style.width]="col.width ?? null">
|
|
3500
|
+
@if (cellDefs.has(col.key)) {
|
|
3501
|
+
<ng-container
|
|
3502
|
+
[ngTemplateOutlet]="cellDefs.get(col.key)!"
|
|
3503
|
+
[ngTemplateOutletContext]="{ $implicit: row[col.key], row: row }"
|
|
3504
|
+
/>
|
|
3505
|
+
} @else {
|
|
3506
|
+
{{ row[col.key] }}
|
|
3507
|
+
}
|
|
3508
|
+
</td>
|
|
3509
|
+
}
|
|
3510
|
+
</tr>
|
|
3511
|
+
@if (expandable() && isExpanded(row) && expandTpl) {
|
|
3512
|
+
<tr snyTableRow>
|
|
3513
|
+
<td snyTableCell [attr.colspan]="totalColSpan()" class="bg-muted/30">
|
|
3514
|
+
<ng-container
|
|
3515
|
+
[ngTemplateOutlet]="expandTpl.template"
|
|
3516
|
+
[ngTemplateOutletContext]="{ $implicit: row }"
|
|
3517
|
+
/>
|
|
3518
|
+
</td>
|
|
3519
|
+
</tr>
|
|
3520
|
+
}
|
|
3521
|
+
}
|
|
3522
|
+
}
|
|
3523
|
+
</tbody>
|
|
3524
|
+
</table>
|
|
3525
|
+
</div>
|
|
3526
|
+
|
|
3527
|
+
<!-- Footer -->
|
|
3528
|
+
@if (paginated()) {
|
|
3529
|
+
<div class="flex flex-col sm:flex-row items-start sm:items-center justify-between mt-4 gap-3 sm:gap-4">
|
|
3530
|
+
<span class="text-sm text-muted-foreground">
|
|
3531
|
+
@if (selectable()) {
|
|
3532
|
+
{{ selectedRows().length }} of {{ filteredData().length }} row(s) selected
|
|
3533
|
+
} @else {
|
|
3534
|
+
{{ filteredData().length }} row(s)
|
|
3535
|
+
}
|
|
3536
|
+
</span>
|
|
3537
|
+
<div class="flex items-center gap-3 sm:gap-4 flex-wrap">
|
|
3538
|
+
<div class="flex items-center gap-2">
|
|
3539
|
+
<span class="hidden sm:inline text-sm text-muted-foreground whitespace-nowrap">Rows per page</span>
|
|
3540
|
+
<sny-select
|
|
3541
|
+
[options]="pageSizeOptions()"
|
|
3542
|
+
[value]="pageSizeValue()"
|
|
3543
|
+
(valueChange)="onPageSizeChange($event)"
|
|
3544
|
+
size="sm"
|
|
3545
|
+
class="w-20"
|
|
3546
|
+
/>
|
|
3547
|
+
</div>
|
|
3548
|
+
<sny-pagination
|
|
3549
|
+
[currentPage]="currentPage()"
|
|
3550
|
+
(currentPageChange)="currentPage.set($event)"
|
|
3551
|
+
[totalPages]="totalPages()"
|
|
3552
|
+
/>
|
|
3553
|
+
</div>
|
|
3554
|
+
</div>
|
|
3555
|
+
}
|
|
3556
|
+
`,
|
|
3557
|
+
}]
|
|
3558
|
+
}], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], hoverable: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverable", required: false }] }], stickyHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "stickyHeader", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], paginated: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginated", required: false }] }], filterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterable", required: false }] }], showExport: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExport", required: false }] }], showColumnToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showColumnToggle", required: false }] }], expandable: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandable", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadingRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingRows", required: false }] }], paginationConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginationConfig", required: false }] }], trackBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackBy", required: false }] }], noDataText: [{ type: i0.Input, args: [{ isSignal: true, alias: "noDataText", required: false }] }], selectedRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedRows", required: false }] }, { type: i0.Output, args: ["selectedRowsChange"] }], sortChanged: [{ type: i0.Output, args: ["sortChanged"] }], rowClicked: [{ type: i0.Output, args: ["rowClicked"] }], dataExported: [{ type: i0.Output, args: ["dataExported"] }], cellDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SnyCellDefDirective), { isSignal: true }] }], headerCellDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SnyHeaderCellDefDirective), { isSignal: true }] }], bulkActionsDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SnyBulkActionsDefDirective), { isSignal: true }] }], rowExpandDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SnyRowExpandDefDirective), { isSignal: true }] }] } });
|
|
3559
|
+
|
|
2420
3560
|
class SnySheetRef {
|
|
2421
3561
|
cdkRef;
|
|
2422
3562
|
constructor(cdkRef) {
|
|
@@ -2906,216 +4046,55 @@ class SnyTooltipDirective {
|
|
|
2906
4046
|
const hostRect = this.el.nativeElement.getBoundingClientRect();
|
|
2907
4047
|
const tooltipRect = this.tooltipEl.getBoundingClientRect();
|
|
2908
4048
|
const position = this.tooltipPosition();
|
|
2909
|
-
const gap = 8;
|
|
2910
|
-
let top = 0;
|
|
2911
|
-
let left = 0;
|
|
2912
|
-
switch (position) {
|
|
2913
|
-
case 'top':
|
|
2914
|
-
top = hostRect.top - tooltipRect.height - gap;
|
|
2915
|
-
left = hostRect.left + (hostRect.width - tooltipRect.width) / 2;
|
|
2916
|
-
break;
|
|
2917
|
-
case 'bottom':
|
|
2918
|
-
top = hostRect.bottom + gap;
|
|
2919
|
-
left = hostRect.left + (hostRect.width - tooltipRect.width) / 2;
|
|
2920
|
-
break;
|
|
2921
|
-
case 'left':
|
|
2922
|
-
top = hostRect.top + (hostRect.height - tooltipRect.height) / 2;
|
|
2923
|
-
left = hostRect.left - tooltipRect.width - gap;
|
|
2924
|
-
break;
|
|
2925
|
-
case 'right':
|
|
2926
|
-
top = hostRect.top + (hostRect.height - tooltipRect.height) / 2;
|
|
2927
|
-
left = hostRect.right + gap;
|
|
2928
|
-
break;
|
|
2929
|
-
}
|
|
2930
|
-
this.tooltipEl.style.top = `${top}px`;
|
|
2931
|
-
this.tooltipEl.style.left = `${left}px`;
|
|
2932
|
-
}
|
|
2933
|
-
destroyTooltip() {
|
|
2934
|
-
if (this.tooltipEl) {
|
|
2935
|
-
this.tooltipEl.remove();
|
|
2936
|
-
this.tooltipEl = null;
|
|
2937
|
-
}
|
|
2938
|
-
}
|
|
2939
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyTooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2940
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: SnyTooltipDirective, isStandalone: true, selector: "[snyTooltip]", inputs: { snyTooltip: { classPropertyName: "snyTooltip", publicName: "snyTooltip", isSignal: true, isRequired: true, transformFunction: null }, tooltipPosition: { classPropertyName: "tooltipPosition", publicName: "tooltipPosition", isSignal: true, isRequired: false, transformFunction: null }, tooltipDelay: { classPropertyName: "tooltipDelay", publicName: "tooltipDelay", isSignal: true, isRequired: false, transformFunction: null }, tooltipDisabled: { classPropertyName: "tooltipDisabled", publicName: "tooltipDisabled", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "show()", "mouseleave": "hide()", "focus": "show()", "blur": "hide()", "keydown.escape": "hide()" }, properties: { "attr.aria-describedby": "isOpen() ? tooltipId : null" } }, exportAs: ["snyTooltip"], ngImport: i0 });
|
|
2941
|
-
}
|
|
2942
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyTooltipDirective, decorators: [{
|
|
2943
|
-
type: Directive,
|
|
2944
|
-
args: [{
|
|
2945
|
-
selector: '[snyTooltip]',
|
|
2946
|
-
standalone: true,
|
|
2947
|
-
exportAs: 'snyTooltip',
|
|
2948
|
-
host: {
|
|
2949
|
-
'(mouseenter)': 'show()',
|
|
2950
|
-
'(mouseleave)': 'hide()',
|
|
2951
|
-
'(focus)': 'show()',
|
|
2952
|
-
'(blur)': 'hide()',
|
|
2953
|
-
'(keydown.escape)': 'hide()',
|
|
2954
|
-
'[attr.aria-describedby]': 'isOpen() ? tooltipId : null',
|
|
2955
|
-
},
|
|
2956
|
-
}]
|
|
2957
|
-
}], ctorParameters: () => [], propDecorators: { snyTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "snyTooltip", required: true }] }], tooltipPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipPosition", required: false }] }], tooltipDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipDelay", required: false }] }], tooltipDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipDisabled", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
2958
|
-
|
|
2959
|
-
const dropdownContentVariants = cva('z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md', {
|
|
2960
|
-
variants: {},
|
|
2961
|
-
defaultVariants: {},
|
|
2962
|
-
});
|
|
2963
|
-
const dropdownItemVariants = cva('relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[active]:bg-accent data-[active]:text-accent-foreground', {
|
|
2964
|
-
variants: {
|
|
2965
|
-
variant: {
|
|
2966
|
-
default: '',
|
|
2967
|
-
destructive: 'text-destructive data-[active]:bg-destructive/10 data-[active]:text-destructive',
|
|
2968
|
-
},
|
|
2969
|
-
},
|
|
2970
|
-
defaultVariants: {
|
|
2971
|
-
variant: 'default',
|
|
2972
|
-
},
|
|
2973
|
-
});
|
|
2974
|
-
|
|
2975
|
-
const SNY_DROPDOWN = new InjectionToken('SnyDropdown');
|
|
2976
|
-
class SnyDropdownDirective {
|
|
2977
|
-
elementRef = inject(ElementRef);
|
|
2978
|
-
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
2979
|
-
toggle() { this.isOpen.update((v) => !v); }
|
|
2980
|
-
open() { this.isOpen.set(true); }
|
|
2981
|
-
close() { this.isOpen.set(false); }
|
|
2982
|
-
onDocumentClick(event) {
|
|
2983
|
-
if (!this.elementRef.nativeElement.contains(event.target)) {
|
|
2984
|
-
this.close();
|
|
2985
|
-
}
|
|
2986
|
-
}
|
|
2987
|
-
onEscape() {
|
|
2988
|
-
this.close();
|
|
2989
|
-
}
|
|
2990
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyDropdownDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2991
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: SnyDropdownDirective, isStandalone: true, selector: "[snyDropdown]", host: { listeners: { "document:click": "onDocumentClick($event)", "keydown.escape": "onEscape()" }, properties: { "class": "\"relative inline-block\"" } }, providers: [{ provide: SNY_DROPDOWN, useExisting: SnyDropdownDirective }], exportAs: ["snyDropdown"], ngImport: i0 });
|
|
2992
|
-
}
|
|
2993
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyDropdownDirective, decorators: [{
|
|
2994
|
-
type: Directive,
|
|
2995
|
-
args: [{
|
|
2996
|
-
selector: '[snyDropdown]',
|
|
2997
|
-
standalone: true,
|
|
2998
|
-
exportAs: 'snyDropdown',
|
|
2999
|
-
providers: [{ provide: SNY_DROPDOWN, useExisting: SnyDropdownDirective }],
|
|
3000
|
-
host: {
|
|
3001
|
-
'[class]': '"relative inline-block"',
|
|
3002
|
-
},
|
|
3003
|
-
}]
|
|
3004
|
-
}], propDecorators: { onDocumentClick: [{
|
|
3005
|
-
type: HostListener,
|
|
3006
|
-
args: ['document:click', ['$event']]
|
|
3007
|
-
}], onEscape: [{
|
|
3008
|
-
type: HostListener,
|
|
3009
|
-
args: ['keydown.escape']
|
|
3010
|
-
}] } });
|
|
3011
|
-
class SnyDropdownTriggerDirective {
|
|
3012
|
-
dropdown = inject(SNY_DROPDOWN);
|
|
3013
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyDropdownTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3014
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: SnyDropdownTriggerDirective, isStandalone: true, selector: "[snyDropdownTrigger]", host: { listeners: { "click": "dropdown.toggle()" }, properties: { "attr.aria-expanded": "dropdown.isOpen()", "attr.aria-haspopup": "\"menu\"" } }, ngImport: i0 });
|
|
3015
|
-
}
|
|
3016
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyDropdownTriggerDirective, decorators: [{
|
|
3017
|
-
type: Directive,
|
|
3018
|
-
args: [{
|
|
3019
|
-
selector: '[snyDropdownTrigger]',
|
|
3020
|
-
standalone: true,
|
|
3021
|
-
host: {
|
|
3022
|
-
'(click)': 'dropdown.toggle()',
|
|
3023
|
-
'[attr.aria-expanded]': 'dropdown.isOpen()',
|
|
3024
|
-
'[attr.aria-haspopup]': '"menu"',
|
|
3025
|
-
},
|
|
3026
|
-
}]
|
|
3027
|
-
}] });
|
|
3028
|
-
class SnyDropdownContentDirective {
|
|
3029
|
-
dropdown = inject(SNY_DROPDOWN);
|
|
3030
|
-
class = input('', ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
|
|
3031
|
-
computedClass = computed(() => cn(dropdownContentVariants(), 'absolute mt-1 left-0 animate-in fade-in-0 zoom-in-95', this.class()), ...(ngDevMode ? [{ debugName: "computedClass" }] : /* istanbul ignore next */ []));
|
|
3032
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyDropdownContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3033
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: SnyDropdownContentDirective, isStandalone: true, selector: "[snyDropdownContent]", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "menu" }, properties: { "class": "computedClass()", "style.display": "dropdown.isOpen() ? \"\" : \"none\"" } }, ngImport: i0 });
|
|
3034
|
-
}
|
|
3035
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyDropdownContentDirective, decorators: [{
|
|
3036
|
-
type: Directive,
|
|
3037
|
-
args: [{
|
|
3038
|
-
selector: '[snyDropdownContent]',
|
|
3039
|
-
standalone: true,
|
|
3040
|
-
host: {
|
|
3041
|
-
'role': 'menu',
|
|
3042
|
-
'[class]': 'computedClass()',
|
|
3043
|
-
'[style.display]': 'dropdown.isOpen() ? "" : "none"',
|
|
3044
|
-
},
|
|
3045
|
-
}]
|
|
3046
|
-
}], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
3047
|
-
class SnyMenuContentDirective {
|
|
3048
|
-
class = input('', ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
|
|
3049
|
-
computedClass = computed(() => cn(dropdownContentVariants(), this.class()), ...(ngDevMode ? [{ debugName: "computedClass" }] : /* istanbul ignore next */ []));
|
|
3050
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyMenuContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3051
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: SnyMenuContentDirective, isStandalone: true, selector: "[snyMenuContent]", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "computedClass()" } }, ngImport: i0 });
|
|
3052
|
-
}
|
|
3053
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyMenuContentDirective, decorators: [{
|
|
3054
|
-
type: Directive,
|
|
3055
|
-
args: [{
|
|
3056
|
-
selector: '[snyMenuContent]',
|
|
3057
|
-
standalone: true,
|
|
3058
|
-
host: {
|
|
3059
|
-
'[class]': 'computedClass()',
|
|
3060
|
-
},
|
|
3061
|
-
}]
|
|
3062
|
-
}], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
3063
|
-
class SnyMenuItemDirective {
|
|
3064
|
-
dropdown = inject(SNY_DROPDOWN, { optional: true });
|
|
3065
|
-
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
3066
|
-
class = input('', ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
|
|
3067
|
-
computedClass = computed(() => cn(dropdownItemVariants({ variant: this.variant() }), 'cursor-pointer hover:bg-accent hover:text-accent-foreground', this.class()), ...(ngDevMode ? [{ debugName: "computedClass" }] : /* istanbul ignore next */ []));
|
|
3068
|
-
onClick() {
|
|
3069
|
-
this.dropdown?.close();
|
|
4049
|
+
const gap = 8;
|
|
4050
|
+
let top = 0;
|
|
4051
|
+
let left = 0;
|
|
4052
|
+
switch (position) {
|
|
4053
|
+
case 'top':
|
|
4054
|
+
top = hostRect.top - tooltipRect.height - gap;
|
|
4055
|
+
left = hostRect.left + (hostRect.width - tooltipRect.width) / 2;
|
|
4056
|
+
break;
|
|
4057
|
+
case 'bottom':
|
|
4058
|
+
top = hostRect.bottom + gap;
|
|
4059
|
+
left = hostRect.left + (hostRect.width - tooltipRect.width) / 2;
|
|
4060
|
+
break;
|
|
4061
|
+
case 'left':
|
|
4062
|
+
top = hostRect.top + (hostRect.height - tooltipRect.height) / 2;
|
|
4063
|
+
left = hostRect.left - tooltipRect.width - gap;
|
|
4064
|
+
break;
|
|
4065
|
+
case 'right':
|
|
4066
|
+
top = hostRect.top + (hostRect.height - tooltipRect.height) / 2;
|
|
4067
|
+
left = hostRect.right + gap;
|
|
4068
|
+
break;
|
|
4069
|
+
}
|
|
4070
|
+
this.tooltipEl.style.top = `${top}px`;
|
|
4071
|
+
this.tooltipEl.style.left = `${left}px`;
|
|
3070
4072
|
}
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
host: {
|
|
3080
|
-
'role': 'menuitem',
|
|
3081
|
-
'[class]': 'computedClass()',
|
|
3082
|
-
'(click)': 'onClick()',
|
|
3083
|
-
},
|
|
3084
|
-
}]
|
|
3085
|
-
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
3086
|
-
class SnyMenuSeparatorDirective {
|
|
3087
|
-
class = input('', ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
|
|
3088
|
-
computedClass = computed(() => cn('-mx-1 my-1 h-px bg-muted', this.class()), ...(ngDevMode ? [{ debugName: "computedClass" }] : /* istanbul ignore next */ []));
|
|
3089
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyMenuSeparatorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3090
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: SnyMenuSeparatorDirective, isStandalone: true, selector: "[snyMenuSeparator]", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "separator" }, properties: { "class": "computedClass()" } }, ngImport: i0 });
|
|
3091
|
-
}
|
|
3092
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyMenuSeparatorDirective, decorators: [{
|
|
3093
|
-
type: Directive,
|
|
3094
|
-
args: [{
|
|
3095
|
-
selector: '[snyMenuSeparator]',
|
|
3096
|
-
standalone: true,
|
|
3097
|
-
host: {
|
|
3098
|
-
'role': 'separator',
|
|
3099
|
-
'[class]': 'computedClass()',
|
|
3100
|
-
},
|
|
3101
|
-
}]
|
|
3102
|
-
}], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
3103
|
-
class SnyMenuLabelDirective {
|
|
3104
|
-
class = input('', ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
|
|
3105
|
-
computedClass = computed(() => cn('px-2 py-1.5 text-sm font-semibold', this.class()), ...(ngDevMode ? [{ debugName: "computedClass" }] : /* istanbul ignore next */ []));
|
|
3106
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyMenuLabelDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3107
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: SnyMenuLabelDirective, isStandalone: true, selector: "[snyMenuLabel]", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "computedClass()" } }, ngImport: i0 });
|
|
4073
|
+
destroyTooltip() {
|
|
4074
|
+
if (this.tooltipEl) {
|
|
4075
|
+
this.tooltipEl.remove();
|
|
4076
|
+
this.tooltipEl = null;
|
|
4077
|
+
}
|
|
4078
|
+
}
|
|
4079
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyTooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
4080
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: SnyTooltipDirective, isStandalone: true, selector: "[snyTooltip]", inputs: { snyTooltip: { classPropertyName: "snyTooltip", publicName: "snyTooltip", isSignal: true, isRequired: true, transformFunction: null }, tooltipPosition: { classPropertyName: "tooltipPosition", publicName: "tooltipPosition", isSignal: true, isRequired: false, transformFunction: null }, tooltipDelay: { classPropertyName: "tooltipDelay", publicName: "tooltipDelay", isSignal: true, isRequired: false, transformFunction: null }, tooltipDisabled: { classPropertyName: "tooltipDisabled", publicName: "tooltipDisabled", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "show()", "mouseleave": "hide()", "focus": "show()", "blur": "hide()", "keydown.escape": "hide()" }, properties: { "attr.aria-describedby": "isOpen() ? tooltipId : null" } }, exportAs: ["snyTooltip"], ngImport: i0 });
|
|
3108
4081
|
}
|
|
3109
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type:
|
|
4082
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyTooltipDirective, decorators: [{
|
|
3110
4083
|
type: Directive,
|
|
3111
4084
|
args: [{
|
|
3112
|
-
selector: '[
|
|
4085
|
+
selector: '[snyTooltip]',
|
|
3113
4086
|
standalone: true,
|
|
4087
|
+
exportAs: 'snyTooltip',
|
|
3114
4088
|
host: {
|
|
3115
|
-
'
|
|
4089
|
+
'(mouseenter)': 'show()',
|
|
4090
|
+
'(mouseleave)': 'hide()',
|
|
4091
|
+
'(focus)': 'show()',
|
|
4092
|
+
'(blur)': 'hide()',
|
|
4093
|
+
'(keydown.escape)': 'hide()',
|
|
4094
|
+
'[attr.aria-describedby]': 'isOpen() ? tooltipId : null',
|
|
3116
4095
|
},
|
|
3117
4096
|
}]
|
|
3118
|
-
}], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
4097
|
+
}], ctorParameters: () => [], propDecorators: { snyTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "snyTooltip", required: true }] }], tooltipPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipPosition", required: false }] }], tooltipDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipDelay", required: false }] }], tooltipDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipDisabled", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
3119
4098
|
|
|
3120
4099
|
const fileInputVariants = cva('flex w-full cursor-pointer items-center gap-2 rounded-md border bg-background px-3 py-2 text-sm ring-offset-background transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', {
|
|
3121
4100
|
variants: {
|
|
@@ -3684,180 +4663,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
|
|
|
3684
4663
|
}]
|
|
3685
4664
|
}], propDecorators: { side: [{ type: i0.Input, args: [{ isSignal: true, alias: "side", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
3686
4665
|
|
|
3687
|
-
const paginationItemVariants = cva('inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50', {
|
|
3688
|
-
variants: {
|
|
3689
|
-
variant: {
|
|
3690
|
-
default: 'bg-background hover:bg-accent hover:text-accent-foreground',
|
|
3691
|
-
outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
|
|
3692
|
-
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
|
3693
|
-
},
|
|
3694
|
-
size: {
|
|
3695
|
-
sm: 'h-8 w-8 text-xs',
|
|
3696
|
-
md: 'h-9 w-9',
|
|
3697
|
-
lg: 'h-10 w-10',
|
|
3698
|
-
},
|
|
3699
|
-
active: {
|
|
3700
|
-
true: 'bg-primary text-primary-foreground hover:bg-primary/90 hover:text-primary-foreground',
|
|
3701
|
-
false: '',
|
|
3702
|
-
},
|
|
3703
|
-
},
|
|
3704
|
-
defaultVariants: {
|
|
3705
|
-
variant: 'default',
|
|
3706
|
-
size: 'md',
|
|
3707
|
-
active: false,
|
|
3708
|
-
},
|
|
3709
|
-
});
|
|
3710
|
-
|
|
3711
|
-
function computePageRange(totalPages, currentPage, siblingCount, boundaryCount) {
|
|
3712
|
-
const range = (start, end) => Array.from({ length: end - start + 1 }, (_, i) => start + i);
|
|
3713
|
-
const startPages = range(1, Math.min(boundaryCount, totalPages));
|
|
3714
|
-
const endPages = range(Math.max(totalPages - boundaryCount + 1, boundaryCount + 1), totalPages);
|
|
3715
|
-
const siblingsStart = Math.max(Math.min(currentPage - siblingCount, totalPages - boundaryCount - siblingCount * 2 - 1), boundaryCount + 2);
|
|
3716
|
-
const siblingsEnd = Math.min(Math.max(currentPage + siblingCount, boundaryCount + siblingCount * 2 + 2), endPages.length > 0 ? endPages[0] - 2 : totalPages - 1);
|
|
3717
|
-
const result = [...startPages];
|
|
3718
|
-
if (siblingsStart > boundaryCount + 2) {
|
|
3719
|
-
result.push('ellipsis');
|
|
3720
|
-
}
|
|
3721
|
-
else if (boundaryCount + 1 < totalPages - boundaryCount) {
|
|
3722
|
-
result.push(boundaryCount + 1);
|
|
3723
|
-
}
|
|
3724
|
-
result.push(...range(siblingsStart, siblingsEnd));
|
|
3725
|
-
if (siblingsEnd < totalPages - boundaryCount - 1) {
|
|
3726
|
-
result.push('ellipsis');
|
|
3727
|
-
}
|
|
3728
|
-
else if (totalPages - boundaryCount > boundaryCount) {
|
|
3729
|
-
result.push(totalPages - boundaryCount);
|
|
3730
|
-
}
|
|
3731
|
-
result.push(...endPages);
|
|
3732
|
-
return [...new Set(result)].sort((a, b) => {
|
|
3733
|
-
if (a === 'ellipsis')
|
|
3734
|
-
return 0;
|
|
3735
|
-
if (b === 'ellipsis')
|
|
3736
|
-
return 0;
|
|
3737
|
-
return a - b;
|
|
3738
|
-
});
|
|
3739
|
-
}
|
|
3740
|
-
class SnyPaginationComponent {
|
|
3741
|
-
currentPage = model(1, ...(ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []));
|
|
3742
|
-
totalPages = input.required(...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
|
|
3743
|
-
siblingCount = input(1, ...(ngDevMode ? [{ debugName: "siblingCount" }] : /* istanbul ignore next */ []));
|
|
3744
|
-
boundaryCount = input(1, ...(ngDevMode ? [{ debugName: "boundaryCount" }] : /* istanbul ignore next */ []));
|
|
3745
|
-
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
3746
|
-
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
3747
|
-
class = input('', ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
|
|
3748
|
-
pages = computed(() => computePageRange(this.totalPages(), this.currentPage(), this.siblingCount(), this.boundaryCount()), ...(ngDevMode ? [{ debugName: "pages" }] : /* istanbul ignore next */ []));
|
|
3749
|
-
hasPrev = computed(() => this.currentPage() > 1, ...(ngDevMode ? [{ debugName: "hasPrev" }] : /* istanbul ignore next */ []));
|
|
3750
|
-
hasNext = computed(() => this.currentPage() < this.totalPages(), ...(ngDevMode ? [{ debugName: "hasNext" }] : /* istanbul ignore next */ []));
|
|
3751
|
-
goToPage(page) {
|
|
3752
|
-
if (page === 'ellipsis')
|
|
3753
|
-
return;
|
|
3754
|
-
this.currentPage.set(page);
|
|
3755
|
-
}
|
|
3756
|
-
prev() {
|
|
3757
|
-
if (this.hasPrev())
|
|
3758
|
-
this.currentPage.update((p) => p - 1);
|
|
3759
|
-
}
|
|
3760
|
-
next() {
|
|
3761
|
-
if (this.hasNext())
|
|
3762
|
-
this.currentPage.update((p) => p + 1);
|
|
3763
|
-
}
|
|
3764
|
-
pageClass(page) {
|
|
3765
|
-
return cn(paginationItemVariants({
|
|
3766
|
-
variant: this.variant(),
|
|
3767
|
-
size: this.size(),
|
|
3768
|
-
active: page === this.currentPage(),
|
|
3769
|
-
}));
|
|
3770
|
-
}
|
|
3771
|
-
navBtnClass() {
|
|
3772
|
-
return cn(paginationItemVariants({ variant: this.variant(), size: this.size(), active: false }));
|
|
3773
|
-
}
|
|
3774
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyPaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3775
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: SnyPaginationComponent, isStandalone: true, selector: "sny-pagination", inputs: { currentPage: { classPropertyName: "currentPage", publicName: "currentPage", isSignal: true, isRequired: false, transformFunction: null }, totalPages: { classPropertyName: "totalPages", publicName: "totalPages", isSignal: true, isRequired: true, transformFunction: null }, siblingCount: { classPropertyName: "siblingCount", publicName: "siblingCount", isSignal: true, isRequired: false, transformFunction: null }, boundaryCount: { classPropertyName: "boundaryCount", publicName: "boundaryCount", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { currentPage: "currentPageChange" }, host: { attributes: { "role": "navigation", "aria-label": "Pagination" } }, ngImport: i0, template: `
|
|
3776
|
-
<div class="flex items-center gap-1">
|
|
3777
|
-
<button
|
|
3778
|
-
[class]="navBtnClass()"
|
|
3779
|
-
[disabled]="!hasPrev()"
|
|
3780
|
-
[attr.aria-label]="'Go to previous page'"
|
|
3781
|
-
(click)="prev()"
|
|
3782
|
-
>
|
|
3783
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m15 18-6-6 6-6"/></svg>
|
|
3784
|
-
</button>
|
|
3785
|
-
|
|
3786
|
-
@for (page of pages(); track $index) {
|
|
3787
|
-
@if (page === 'ellipsis') {
|
|
3788
|
-
<span class="flex h-9 w-9 items-center justify-center" aria-hidden="true">...</span>
|
|
3789
|
-
} @else {
|
|
3790
|
-
<button
|
|
3791
|
-
[class]="pageClass(page)"
|
|
3792
|
-
[attr.aria-label]="'Page ' + page"
|
|
3793
|
-
[attr.aria-current]="page === currentPage() ? 'page' : null"
|
|
3794
|
-
(click)="goToPage(page)"
|
|
3795
|
-
>
|
|
3796
|
-
{{ page }}
|
|
3797
|
-
</button>
|
|
3798
|
-
}
|
|
3799
|
-
}
|
|
3800
|
-
|
|
3801
|
-
<button
|
|
3802
|
-
[class]="navBtnClass()"
|
|
3803
|
-
[disabled]="!hasNext()"
|
|
3804
|
-
[attr.aria-label]="'Go to next page'"
|
|
3805
|
-
(click)="next()"
|
|
3806
|
-
>
|
|
3807
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>
|
|
3808
|
-
</button>
|
|
3809
|
-
</div>
|
|
3810
|
-
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3811
|
-
}
|
|
3812
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SnyPaginationComponent, decorators: [{
|
|
3813
|
-
type: Component,
|
|
3814
|
-
args: [{
|
|
3815
|
-
selector: 'sny-pagination',
|
|
3816
|
-
standalone: true,
|
|
3817
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3818
|
-
host: {
|
|
3819
|
-
'role': 'navigation',
|
|
3820
|
-
'aria-label': 'Pagination',
|
|
3821
|
-
},
|
|
3822
|
-
template: `
|
|
3823
|
-
<div class="flex items-center gap-1">
|
|
3824
|
-
<button
|
|
3825
|
-
[class]="navBtnClass()"
|
|
3826
|
-
[disabled]="!hasPrev()"
|
|
3827
|
-
[attr.aria-label]="'Go to previous page'"
|
|
3828
|
-
(click)="prev()"
|
|
3829
|
-
>
|
|
3830
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m15 18-6-6 6-6"/></svg>
|
|
3831
|
-
</button>
|
|
3832
|
-
|
|
3833
|
-
@for (page of pages(); track $index) {
|
|
3834
|
-
@if (page === 'ellipsis') {
|
|
3835
|
-
<span class="flex h-9 w-9 items-center justify-center" aria-hidden="true">...</span>
|
|
3836
|
-
} @else {
|
|
3837
|
-
<button
|
|
3838
|
-
[class]="pageClass(page)"
|
|
3839
|
-
[attr.aria-label]="'Page ' + page"
|
|
3840
|
-
[attr.aria-current]="page === currentPage() ? 'page' : null"
|
|
3841
|
-
(click)="goToPage(page)"
|
|
3842
|
-
>
|
|
3843
|
-
{{ page }}
|
|
3844
|
-
</button>
|
|
3845
|
-
}
|
|
3846
|
-
}
|
|
3847
|
-
|
|
3848
|
-
<button
|
|
3849
|
-
[class]="navBtnClass()"
|
|
3850
|
-
[disabled]="!hasNext()"
|
|
3851
|
-
[attr.aria-label]="'Go to next page'"
|
|
3852
|
-
(click)="next()"
|
|
3853
|
-
>
|
|
3854
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>
|
|
3855
|
-
</button>
|
|
3856
|
-
</div>
|
|
3857
|
-
`,
|
|
3858
|
-
}]
|
|
3859
|
-
}], propDecorators: { currentPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentPage", required: false }] }, { type: i0.Output, args: ["currentPageChange"] }], totalPages: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalPages", required: true }] }], siblingCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "siblingCount", required: false }] }], boundaryCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "boundaryCount", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
3860
|
-
|
|
3861
4666
|
const dividerVariants = cva('shrink-0 bg-border', {
|
|
3862
4667
|
variants: {
|
|
3863
4668
|
orientation: {
|
|
@@ -5302,5 +6107,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
|
|
|
5302
6107
|
* Generated bundle index. Do not edit.
|
|
5303
6108
|
*/
|
|
5304
6109
|
|
|
5305
|
-
export { SNY_ACCORDION, SNY_ACCORDION_ITEM, SNY_CAROUSEL, SNY_CHAT_BUBBLE, SNY_CONFIG, SNY_DIALOG_DATA, SNY_DRAWER, SNY_DROPDOWN, SNY_FAB, SNY_SHEET_DATA, SNY_STEPS, SNY_TABLE, SNY_TABS, SNY_TIMELINE, SnyAccordionContentDirective, SnyAccordionDirective, SnyAccordionItemDirective, SnyAccordionTriggerDirective, SnyAlertDescriptionDirective, SnyAlertDirective, SnyAlertTitleDirective, SnyAvatarComponent, SnyBadgeDirective, SnyBreadcrumbDirective, SnyBreadcrumbItemDirective, SnyBreadcrumbLinkDirective, SnyBreadcrumbListDirective, SnyBreadcrumbPageDirective, SnyBreadcrumbSeparatorDirective, SnyButtonDirective, SnyButtonGroupDirective, SnyCalendarComponent, SnyCardContentDirective, SnyCardDescriptionDirective, SnyCardDirective, SnyCardFooterDirective, SnyCardHeaderDirective, SnyCardTitleDirective, SnyCarouselContentDirective, SnyCarouselDirective, SnyCarouselItemDirective, SnyCarouselNextDirective, SnyCarouselPrevDirective, SnyChatBubbleAvatarDirective, SnyChatBubbleBodyDirective, SnyChatBubbleContentDirective, SnyChatBubbleDirective, SnyChatBubbleFooterDirective, SnyChatBubbleHeaderDirective, SnyCheckboxDirective, SnyComboboxComponent, SnyDialogCloseDirective, SnyDialogContentDirective, SnyDialogDescriptionDirective, SnyDialogFooterDirective, SnyDialogHeaderDirective, SnyDialogRef, SnyDialogService, SnyDialogTitleDirective, SnyDiffComponent, SnyDividerComponent, SnyDockDirective, SnyDockItemDirective, SnyDrawerContentDirective, SnyDrawerLayoutComponent, SnyDrawerLayoutDirective, SnyDrawerSideDirective, SnyDropdownContentDirective, SnyDropdownDirective, SnyDropdownTriggerDirective, SnyFabActionDirective, SnyFabDirective, SnyFabTriggerDirective, SnyFieldsetContentDirective, SnyFieldsetDirective, SnyFieldsetLegendDirective, SnyFileInputComponent, SnyIndicatorBadgeDirective, SnyIndicatorDirective, SnyInputDirective, SnyKbdDirective, SnyLabelDirective, SnyLinkDirective, SnyListDirective, SnyListItemActionDirective, SnyListItemContentDirective, SnyListItemDirective, SnyListItemIconDirective, SnyLoaderComponent, SnyMenuContentDirective, SnyMenuItemDirective, SnyMenuLabelDirective, SnyMenuSeparatorDirective, SnyNavbarBrandDirective, SnyNavbarContentDirective, SnyNavbarDirective, SnyNavbarEndDirective, SnyPaginationComponent, SnyProgressComponent, SnyRadialProgressComponent, SnyRadioDirective, SnyRatingComponent, SnySelectComponent, SnySheetCloseDirective, SnySheetContentDirective, SnySheetDescriptionDirective, SnySheetHeaderDirective, SnySheetRef, SnySheetService, SnySheetTitleDirective, SnySkeletonDirective, SnySliderComponent, SnyStatDescriptionDirective, SnyStatDirective, SnyStatFigureDirective, SnyStatTitleDirective, SnyStatValueDirective, SnyStatusDirective, SnyStepDirective, SnyStepsDirective, SnySwitchComponent, SnyTableBodyDirective, SnyTableCaptionDirective, SnyTableCellDirective, SnyTableDirective, SnyTableFooterDirective, SnyTableHeadDirective, SnyTableHeaderDirective, SnyTableRowDirective, SnyTabsContentDirective, SnyTabsDirective, SnyTabsListDirective, SnyTabsTriggerDirective, SnyTextareaDirective, SnyTimelineDirective, SnyTimelineEndDirective, SnyTimelineItemDirective, SnyTimelineMiddleDirective, SnyTimelineStartDirective, SnyToastService, SnyToasterComponent, SnyToggleDirective, SnyTooltipDirective, SnyValidatorDirective, SnyValidatorHintDirective, ThemeService, alertVariants, avatarVariants, badgeVariants, buttonGroupVariants, buttonVariants, cardVariants, checkboxVariants, cn, comboboxTriggerVariants, dividerVariants, dropdownContentVariants, dropdownItemVariants, fieldsetVariants, fileInputVariants, inputVariants, kbdVariants, labelVariants, linkVariants, loaderVariants, paginationItemVariants, progressBarVariants, progressTrackVariants, provideSonnyUI, radioVariants, ratingVariants, selectTriggerVariants, skeletonVariants, sliderTrackVariants, statusVariants, switchTrackVariants, tableCellVariants, tableVariants, tabsListVariants, tabsTriggerVariants, textareaVariants, toastVariants, toggleVariants, tooltipVariants };
|
|
6110
|
+
export { SNY_ACCORDION, SNY_ACCORDION_ITEM, SNY_CAROUSEL, SNY_CHAT_BUBBLE, SNY_CONFIG, SNY_DIALOG_DATA, SNY_DRAWER, SNY_DROPDOWN, SNY_FAB, SNY_SHEET_DATA, SNY_STEPS, SNY_TABLE, SNY_TABS, SNY_TIMELINE, SnyAccordionContentDirective, SnyAccordionDirective, SnyAccordionItemDirective, SnyAccordionTriggerDirective, SnyAlertDescriptionDirective, SnyAlertDirective, SnyAlertTitleDirective, SnyAvatarComponent, SnyBadgeDirective, SnyBreadcrumbDirective, SnyBreadcrumbItemDirective, SnyBreadcrumbLinkDirective, SnyBreadcrumbListDirective, SnyBreadcrumbPageDirective, SnyBreadcrumbSeparatorDirective, SnyBulkActionsDefDirective, SnyButtonDirective, SnyButtonGroupDirective, SnyCalendarComponent, SnyCardContentDirective, SnyCardDescriptionDirective, SnyCardDirective, SnyCardFooterDirective, SnyCardHeaderDirective, SnyCardTitleDirective, SnyCarouselContentDirective, SnyCarouselDirective, SnyCarouselItemDirective, SnyCarouselNextDirective, SnyCarouselPrevDirective, SnyCellDefDirective, SnyChatBubbleAvatarDirective, SnyChatBubbleBodyDirective, SnyChatBubbleContentDirective, SnyChatBubbleDirective, SnyChatBubbleFooterDirective, SnyChatBubbleHeaderDirective, SnyCheckboxDirective, SnyComboboxComponent, SnyDataTableComponent, SnyDialogCloseDirective, SnyDialogContentDirective, SnyDialogDescriptionDirective, SnyDialogFooterDirective, SnyDialogHeaderDirective, SnyDialogRef, SnyDialogService, SnyDialogTitleDirective, SnyDiffComponent, SnyDividerComponent, SnyDockDirective, SnyDockItemDirective, SnyDrawerContentDirective, SnyDrawerLayoutComponent, SnyDrawerLayoutDirective, SnyDrawerSideDirective, SnyDropdownContentDirective, SnyDropdownDirective, SnyDropdownTriggerDirective, SnyFabActionDirective, SnyFabDirective, SnyFabTriggerDirective, SnyFieldsetContentDirective, SnyFieldsetDirective, SnyFieldsetLegendDirective, SnyFileInputComponent, SnyHeaderCellDefDirective, SnyIndicatorBadgeDirective, SnyIndicatorDirective, SnyInputDirective, SnyKbdDirective, SnyLabelDirective, SnyLinkDirective, SnyListDirective, SnyListItemActionDirective, SnyListItemContentDirective, SnyListItemDirective, SnyListItemIconDirective, SnyLoaderComponent, SnyMenuContentDirective, SnyMenuItemDirective, SnyMenuLabelDirective, SnyMenuSeparatorDirective, SnyNavbarBrandDirective, SnyNavbarContentDirective, SnyNavbarDirective, SnyNavbarEndDirective, SnyPaginationComponent, SnyProgressComponent, SnyRadialProgressComponent, SnyRadioDirective, SnyRatingComponent, SnyRowExpandDefDirective, SnySelectComponent, SnySheetCloseDirective, SnySheetContentDirective, SnySheetDescriptionDirective, SnySheetHeaderDirective, SnySheetRef, SnySheetService, SnySheetTitleDirective, SnySkeletonDirective, SnySliderComponent, SnyStatDescriptionDirective, SnyStatDirective, SnyStatFigureDirective, SnyStatTitleDirective, SnyStatValueDirective, SnyStatusDirective, SnyStepDirective, SnyStepsDirective, SnySwitchComponent, SnyTableBodyDirective, SnyTableCaptionDirective, SnyTableCellDirective, SnyTableDirective, SnyTableFooterDirective, SnyTableHeadDirective, SnyTableHeaderDirective, SnyTableRowDirective, SnyTabsContentDirective, SnyTabsDirective, SnyTabsListDirective, SnyTabsTriggerDirective, SnyTextareaDirective, SnyTimelineDirective, SnyTimelineEndDirective, SnyTimelineItemDirective, SnyTimelineMiddleDirective, SnyTimelineStartDirective, SnyToastService, SnyToasterComponent, SnyToggleDirective, SnyTooltipDirective, SnyValidatorDirective, SnyValidatorHintDirective, ThemeService, alertVariants, avatarVariants, badgeVariants, buttonGroupVariants, buttonVariants, cardVariants, checkboxVariants, cn, comboboxTriggerVariants, dividerVariants, dropdownContentVariants, dropdownItemVariants, fieldsetVariants, fileInputVariants, inputVariants, kbdVariants, labelVariants, linkVariants, loaderVariants, paginationItemVariants, progressBarVariants, progressTrackVariants, provideSonnyUI, radioVariants, ratingVariants, selectTriggerVariants, skeletonVariants, sliderTrackVariants, statusVariants, switchTrackVariants, tableCellVariants, tableVariants, tabsListVariants, tabsTriggerVariants, textareaVariants, toastVariants, toggleVariants, tooltipVariants };
|
|
5306
6111
|
//# sourceMappingURL=sonny-ui-core.mjs.map
|