@tolle_/tolle-ui 18.2.24 → 18.2.25
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/esm2022/lib/accordion-item.component.mjs +17 -5
- package/esm2022/lib/alert-dialog-dynamic.component.mjs +1 -1
- package/esm2022/lib/alert-dialog.component.mjs +48 -10
- package/esm2022/lib/alert-dialog.service.mjs +13 -2
- package/esm2022/lib/alert.component.mjs +5 -5
- package/esm2022/lib/avatar.component.mjs +30 -9
- package/esm2022/lib/badge.component.mjs +41 -15
- package/esm2022/lib/breadcrumb-link.component.mjs +5 -5
- package/esm2022/lib/button.component.mjs +14 -3
- package/esm2022/lib/calendar.component.mjs +99 -17
- package/esm2022/lib/card.component.mjs +29 -9
- package/esm2022/lib/carousel/carousel.component.mjs +19 -3
- package/esm2022/lib/checkbox.component.mjs +44 -21
- package/esm2022/lib/collapsible.component.mjs +12 -4
- package/esm2022/lib/country-selector.component.mjs +140 -20
- package/esm2022/lib/data-table.component.mjs +27 -16
- package/esm2022/lib/date-picker.component.mjs +24 -4
- package/esm2022/lib/date-range-picker.component.mjs +37 -9
- package/esm2022/lib/dropdown-item.component.mjs +19 -5
- package/esm2022/lib/dropdown-label.component.mjs +3 -3
- package/esm2022/lib/dropdown-menu.component.mjs +3 -3
- package/esm2022/lib/dropdown-separator.component.mjs +3 -3
- package/esm2022/lib/dropdown-trigger.directive.mjs +7 -3
- package/esm2022/lib/empty-state.component.mjs +3 -3
- package/esm2022/lib/hover-card.component.mjs +4 -2
- package/esm2022/lib/input.component.mjs +7 -5
- package/esm2022/lib/label.component.mjs +2 -2
- package/esm2022/lib/masked-input.component.mjs +3 -3
- package/esm2022/lib/modal.component.mjs +58 -22
- package/esm2022/lib/modal.service.mjs +13 -1
- package/esm2022/lib/multi-select.component.mjs +228 -20
- package/esm2022/lib/otp.component.mjs +6 -3
- package/esm2022/lib/pagination.component.mjs +19 -9
- package/esm2022/lib/progress.component.mjs +8 -5
- package/esm2022/lib/radio-group.component.mjs +51 -3
- package/esm2022/lib/radio-item.component.mjs +46 -8
- package/esm2022/lib/radio-service.mjs +60 -1
- package/esm2022/lib/range-calendar.component.mjs +317 -98
- package/esm2022/lib/resizable-panel.component.mjs +5 -4
- package/esm2022/lib/scroll-area.component.mjs +5 -5
- package/esm2022/lib/segment.component.mjs +73 -7
- package/esm2022/lib/select-item.component.mjs +20 -2
- package/esm2022/lib/select-separator.component.mjs +3 -3
- package/esm2022/lib/select.component.mjs +221 -14
- package/esm2022/lib/separator.component.mjs +12 -6
- package/esm2022/lib/sheet-ref.mjs +8 -1
- package/esm2022/lib/sheet-wrapper.component.mjs +27 -11
- package/esm2022/lib/sheet.component.mjs +57 -16
- package/esm2022/lib/sheet.service.mjs +5 -1
- package/esm2022/lib/sidebar.component.mjs +73 -15
- package/esm2022/lib/skeleton.component.mjs +19 -5
- package/esm2022/lib/switch.component.mjs +59 -53
- package/esm2022/lib/tabs.component.mjs +75 -13
- package/esm2022/lib/tag-input.component.mjs +6 -3
- package/esm2022/lib/textarea.component.mjs +9 -7
- package/esm2022/lib/theme.service.mjs +114 -138
- package/esm2022/lib/toaster.component.mjs +19 -9
- package/esm2022/lib/toggle-group.component.mjs +76 -4
- package/esm2022/lib/tolle-config.mjs +1 -1
- package/esm2022/lib/tooltip.directive.mjs +41 -17
- package/esm2022/lib/utils/color.mjs +324 -0
- package/esm2022/public-api.mjs +2 -1
- package/fesm2022/tolle-ui.mjs +2645 -637
- package/fesm2022/tolle-ui.mjs.map +1 -1
- package/lib/alert-dialog.component.d.ts +10 -1
- package/lib/avatar.component.d.ts +16 -3
- package/lib/badge.component.d.ts +17 -5
- package/lib/button.component.d.ts +10 -3
- package/lib/calendar.component.d.ts +21 -3
- package/lib/card.component.d.ts +6 -0
- package/lib/carousel/carousel.component.d.ts +1 -0
- package/lib/checkbox.component.d.ts +12 -4
- package/lib/country-selector.component.d.ts +11 -2
- package/lib/date-picker.component.d.ts +1 -0
- package/lib/date-range-picker.component.d.ts +4 -1
- package/lib/dropdown-item.component.d.ts +4 -2
- package/lib/dropdown-trigger.directive.d.ts +1 -1
- package/lib/modal.component.d.ts +6 -0
- package/lib/multi-select.component.d.ts +20 -0
- package/lib/otp.component.d.ts +1 -0
- package/lib/progress.component.d.ts +1 -0
- package/lib/radio-group.component.d.ts +8 -0
- package/lib/radio-item.component.d.ts +10 -4
- package/lib/radio-service.d.ts +29 -0
- package/lib/range-calendar.component.d.ts +33 -4
- package/lib/segment.component.d.ts +13 -0
- package/lib/select-item.component.d.ts +4 -1
- package/lib/select.component.d.ts +20 -0
- package/lib/separator.component.d.ts +2 -0
- package/lib/sheet-wrapper.component.d.ts +4 -0
- package/lib/sheet.component.d.ts +10 -1
- package/lib/sidebar.component.d.ts +2 -0
- package/lib/skeleton.component.d.ts +9 -3
- package/lib/switch.component.d.ts +13 -20
- package/lib/tabs.component.d.ts +11 -1
- package/lib/theme.service.d.ts +21 -6
- package/lib/toaster.component.d.ts +2 -2
- package/lib/toggle-group.component.d.ts +20 -2
- package/lib/toggle.component.d.ts +1 -1
- package/lib/tolle-config.d.ts +8 -0
- package/lib/tooltip.directive.d.ts +3 -0
- package/lib/utils/color.d.ts +87 -0
- package/package.json +4 -1
- package/preset.js +28 -0
- package/public-api.d.ts +1 -0
- package/registry/docs-content.json +4214 -0
- package/registry/llms-full.txt +1599 -0
- package/registry/llms.txt +83 -0
- package/registry/manifest.json +4925 -0
- package/registry/r/accordion-item.json +21 -0
- package/registry/r/accordion.json +23 -0
- package/registry/r/alert-dialog-dynamic.json +31 -0
- package/registry/r/alert-dialog.json +26 -0
- package/registry/r/alert.json +23 -0
- package/registry/r/aspect-ratio.json +21 -0
- package/registry/r/avatar-fallback.json +16 -0
- package/registry/r/avatar.json +23 -0
- package/registry/r/badge.json +23 -0
- package/registry/r/breadcrumb-item.json +16 -0
- package/registry/r/breadcrumb-link.json +16 -0
- package/registry/r/breadcrumb-separator.json +16 -0
- package/registry/r/breadcrumb.json +21 -0
- package/registry/r/button-group.json +21 -0
- package/registry/r/button.json +23 -0
- package/registry/r/calendar.json +23 -0
- package/registry/r/card.json +21 -0
- package/registry/r/carousel.json +18 -0
- package/registry/r/checkbox.json +23 -0
- package/registry/r/collapsible.json +21 -0
- package/registry/r/context-menu-trigger.json +23 -0
- package/registry/r/context-menu.json +28 -0
- package/registry/r/country-selector.json +31 -0
- package/registry/r/data-table.json +38 -0
- package/registry/r/date-picker.json +27 -0
- package/registry/r/date-range-picker.json +32 -0
- package/registry/r/dropdown-item.json +21 -0
- package/registry/r/dropdown-label.json +16 -0
- package/registry/r/dropdown-menu.json +16 -0
- package/registry/r/dropdown-separator.json +16 -0
- package/registry/r/dropdown-trigger.json +20 -0
- package/registry/r/empty-state.json +23 -0
- package/registry/r/hover-card.json +23 -0
- package/registry/r/input.json +21 -0
- package/registry/r/label.json +21 -0
- package/registry/r/masked-input.json +21 -0
- package/registry/r/modal.json +36 -0
- package/registry/r/multi-select.json +33 -0
- package/registry/r/otp-group.json +16 -0
- package/registry/r/otp-slot.json +21 -0
- package/registry/r/otp.json +21 -0
- package/registry/r/pagination.json +32 -0
- package/registry/r/phone-number-input.json +34 -0
- package/registry/r/popover-content.json +21 -0
- package/registry/r/popover.json +18 -0
- package/registry/r/progress.json +21 -0
- package/registry/r/radio-group.json +26 -0
- package/registry/r/radio-item.json +26 -0
- package/registry/r/range-calendar.json +28 -0
- package/registry/r/resizable-panel-item.json +23 -0
- package/registry/r/resizable-panel.json +23 -0
- package/registry/r/resizable.json +21 -0
- package/registry/r/scroll-area.json +21 -0
- package/registry/r/segment.json +21 -0
- package/registry/r/select-group.json +21 -0
- package/registry/r/select-item.json +26 -0
- package/registry/r/select-separator.json +21 -0
- package/registry/r/select.json +31 -0
- package/registry/r/separator.json +21 -0
- package/registry/r/sheet-wrapper.json +31 -0
- package/registry/r/sheet.json +21 -0
- package/registry/r/sidebar.json +21 -0
- package/registry/r/skeleton.json +23 -0
- package/registry/r/slider.json +21 -0
- package/registry/r/switch.json +23 -0
- package/registry/r/tabs.json +23 -0
- package/registry/r/tag-input.json +25 -0
- package/registry/r/textarea.json +21 -0
- package/registry/r/toaster.json +26 -0
- package/registry/r/toggle-group.json +25 -0
- package/registry/r/toggle.json +23 -0
- package/registry/r/tolle-cell.json +16 -0
- package/registry/r/tooltip.json +23 -0
- package/registry/registry.json +1540 -0
- package/theme.css +56 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "otp-slot",
|
|
3
|
+
"type": "registry:ui",
|
|
4
|
+
"title": "Otp Slot",
|
|
5
|
+
"description": "Otp Slot component.",
|
|
6
|
+
"category": "forms",
|
|
7
|
+
"registryDependencies": [],
|
|
8
|
+
"dependencies": [],
|
|
9
|
+
"files": [
|
|
10
|
+
{
|
|
11
|
+
"path": "otp-slot.component.ts",
|
|
12
|
+
"target": "ui/otp-slot.component.ts",
|
|
13
|
+
"content": "import { Component, Input } from '@angular/core';\nimport { cn } from \"./utils/cn\";\nimport { NgIf } from '@angular/common';\n\n@Component({\n selector: 'tolle-otp-slot',\n standalone: true,\n imports: [NgIf],\n template: `\n <div [class]=\"computedClass\">\n <span class=\"text-lg font-medium\">{{ char || '' }}</span>\n <div *ngIf=\"isActive && !char\" class=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n <div class=\"h-6 w-0.5 animate-caret-blink bg-foreground\"></div>\n </div>\n </div>\n `\n})\nexport class OtpSlotComponent {\n @Input() char: string | undefined = '';\n @Input() isActive: boolean = false;\n @Input() isFirst: boolean = false;\n @Input() isLast: boolean = false;\n @Input() class: string = '';\n protected cn = cn;\n\n get computedClass() {\n return cn(\n // Base styles (matching input container)\n 'relative flex h-10 w-10 items-center justify-center',\n 'transition-all duration-200',\n 'text-center font-medium select-none',\n\n // Border styling - exactly like input\n 'border border-input shadow-sm bg-background',\n\n // FOCUS STYLING - EXACTLY LIKE INPUT COMPONENT\n this.isActive && [\n // Darker border on focus\n 'border-primary/80',\n // Remove shadow on focus\n 'shadow-none',\n // Focus ring with same styling as input\n 'ring-4',\n 'ring-ring/30',\n 'ring-offset-0',\n // Ensure it's above other slots\n 'z-10'\n ],\n\n // Filled state\n this.char && !this.isActive && 'border-primary/60',\n\n // Border radius\n this.isFirst && 'rounded-l-md',\n this.isLast && 'rounded-r-md',\n\n // Remove left border for all but first slot\n !this.isFirst && '-ml-px',\n\n this.class\n );\n }\n}\n"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"path": "utils/cn.ts",
|
|
17
|
+
"target": "ui/utils/cn.ts",
|
|
18
|
+
"content": "import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "otp",
|
|
3
|
+
"type": "registry:ui",
|
|
4
|
+
"title": "Otp",
|
|
5
|
+
"description": "Otp component.",
|
|
6
|
+
"category": "forms",
|
|
7
|
+
"registryDependencies": [],
|
|
8
|
+
"dependencies": [],
|
|
9
|
+
"files": [
|
|
10
|
+
{
|
|
11
|
+
"path": "otp.component.ts",
|
|
12
|
+
"target": "ui/otp.component.ts",
|
|
13
|
+
"content": "import { Component, Input, forwardRef, ChangeDetectorRef } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';\nimport { cn } from './utils/cn';\n\n@Component({\n selector: 'tolle-otp',\n standalone: true,\n imports: [CommonModule, FormsModule],\n providers: [{\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => OtpComponent),\n multi: true\n }],\n template: `\n <div class=\"relative flex items-center gap-2\">\n <input\n #hiddenInput\n type=\"text\"\n inputmode=\"numeric\"\n autocomplete=\"one-time-code\"\n aria-label=\"One-time code\"\n [maxLength]=\"length\"\n class=\"absolute inset-0 opacity-0 cursor-default z-20\"\n [(ngModel)]=\"value\"\n (input)=\"onInputChange($event)\"\n (focus)=\"isFocused = true\"\n (blur)=\"isFocused = false; onTouched()\"\n [disabled]=\"disabled\"\n />\n\n <div *ngIf=\"auto\" class=\"flex items-center gap-2 pointer-events-none\">\n <div class=\"flex items-center\">\n <div *ngFor=\"let _ of slots; let i = index\"\n [class]=\"getSlotClass(i)\"\n >\n {{ value[i] || '' }}\n <div *ngIf=\"isFocused && value.length === i\" class=\"absolute inset-0 flex items-center justify-center\">\n <div class=\"h-4 w-px animate-caret-blink bg-foreground duration-1000\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"!auto\" class=\"flex items-center gap-2 pointer-events-none\">\n <ng-content></ng-content>\n </div>\n </div>\n `\n})\nexport class OtpComponent implements ControlValueAccessor {\n @Input()\n set length(val: number) {\n const numericVal = Number(val);\n this._length = numericVal;\n this.slots = Array(numericVal).fill(0);\n }\n get length() { return this._length; }\n private _length = 6;\n\n @Input() disabled = false;\n @Input() auto = false;\n\n protected slots: number[] = Array(6).fill(0);\n\n value: string = '';\n isFocused = false;\n\n onChange: any = () => { };\n onTouched: any = () => { };\n\n constructor(private cdr: ChangeDetectorRef) { }\n\n onInputChange(event: any) {\n const val = event.target.value.replace(/\\D/g, '');\n this.value = val;\n this.onChange(val);\n this.cdr.markForCheck();\n }\n\n // Visual logic for the automated slots\n getSlotClass(index: number) {\n const isActive = this.isFocused && this.value.length === index;\n\n return cn(\n 'relative flex h-10 w-10 items-center justify-center border-y border-r border-input text-sm transition-all bg-background',\n index === 0 && 'rounded-l-md border-l',\n index === this.length - 1 && 'rounded-r-md',\n isActive && 'z-30 ring-2 ring-ring ring-offset-background'\n );\n }\n\n writeValue(value: any): void { this.value = value || ''; this.cdr.markForCheck(); }\n registerOnChange(fn: any): void { this.onChange = fn; }\n registerOnTouched(fn: any): void { this.onTouched = fn; }\n setDisabledState(isDisabled: boolean): void { this.disabled = isDisabled; this.cdr.markForCheck(); }\n}\n"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"path": "utils/cn.ts",
|
|
17
|
+
"target": "ui/utils/cn.ts",
|
|
18
|
+
"content": "import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pagination",
|
|
3
|
+
"type": "registry:ui",
|
|
4
|
+
"title": "Pagination",
|
|
5
|
+
"description": "Pagination component.",
|
|
6
|
+
"category": "navigation",
|
|
7
|
+
"registryDependencies": [
|
|
8
|
+
"input",
|
|
9
|
+
"select",
|
|
10
|
+
"select-item"
|
|
11
|
+
],
|
|
12
|
+
"dependencies": [
|
|
13
|
+
"@floating-ui/dom"
|
|
14
|
+
],
|
|
15
|
+
"files": [
|
|
16
|
+
{
|
|
17
|
+
"path": "pagination.component.ts",
|
|
18
|
+
"target": "ui/pagination.component.ts",
|
|
19
|
+
"content": "import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n EventEmitter,\n inject,\n Input,\n OnChanges,\n OnInit,\n Output,\n SimpleChanges\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { cn } from './utils/cn';\nimport {FormsModule} from '@angular/forms';\nimport {SelectComponent} from './select.component';\nimport {SelectItemComponent} from './select-item.component';\n\n@Component({\n selector: 'tolle-pagination',\n standalone: true,\n imports: [CommonModule, FormsModule, SelectComponent, SelectItemComponent],\n template: `\n <nav role=\"navigation\" aria-label=\"pagination\">\n <div [class]=\"cn('flex items-center justify-between px-2 py-4', class)\">\n\n <div *ngIf=\"showCurrentPageInfo\" class=\"text-sm text-muted-foreground\">\n <ng-container *ngIf=\"currentPageInfoTemplate; else defaultReport\">\n {{ pageReport }}\n </ng-container>\n <ng-template #defaultReport>\n Showing {{ first }} to {{ last }} of {{ totalRecords }} entries\n </ng-template>\n </div>\n\n <div class=\"flex items-center space-x-6 lg:space-x-8\">\n\n <div *ngIf=\"showPageOptions\" class=\"flex items-center space-x-2\">\n <p class=\"text-sm font-medium\">Rows per page</p>\n <tolle-select\n class=\"w-[70px]\"\n size=\"sm\"\n [ngModel]=\"currentPageSize\"\n (ngModelChange)=\"sizeChange($event)\"\n >\n <tolle-select-item *ngFor=\"let opt of pageSizeOptions\" [value]=\"opt\">\n {{ opt }}\n </tolle-select-item>\n </tolle-select>\n </div>\n\n <div class=\"flex items-center space-x-2\">\n <div *ngIf=\"!showPageLinks\" class=\"flex w-[100px] items-center justify-center text-sm font-medium\">\n Page {{ currentPage }} of {{ totalPages }}\n </div>\n\n <div *ngIf=\"showPageLinks\" class=\"flex items-center space-x-1\">\n <button\n (click)=\"previousPage()\"\n [disabled]=\"currentPage === 1\"\n aria-label=\"Go to previous page\"\n [class]=\"navBtnClass\"\n >\n <i aria-hidden=\"true\" class=\"ri-arrow-left-s-line\"></i>\n </button>\n\n <button\n *ngFor=\"let page of displayPageIndex\"\n (click)=\"selectPage(page)\"\n [attr.aria-current]=\"currentPage === page ? 'page' : null\"\n [class]=\"cn(\n 'h-8 w-8 text-sm rounded-md flex items-center justify-center transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 cursor-pointer',\n currentPage === page\n ? 'bg-primary text-primary-foreground font-medium'\n : 'hover:bg-accent hover:text-accent-foreground'\n )\"\n >\n {{ page }}\n </button>\n\n <button\n (click)=\"nextPage()\"\n [disabled]=\"currentPage === totalPages || totalPages === 0\"\n aria-label=\"Go to next page\"\n [class]=\"navBtnClass\"\n >\n <i aria-hidden=\"true\" class=\"ri-arrow-right-s-line\"></i>\n </button>\n </div>\n </div>\n </div>\n </div>\n </nav>\n `,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class PaginationComponent implements OnInit, OnChanges {\n @Input() class = '';\n @Input() showPageLinks = true;\n @Input() showPageOptions = true;\n @Input() showCurrentPageInfo = true;\n @Input() currentPageInfoTemplate?: string;\n\n @Input() totalRecords = 0;\n @Input() currentPageSize = 10;\n @Input() currentPage = 1;\n @Input() pageSizeOptions: number[] = [10, 20, 30, 50];\n\n @Output() onPageNumberChange = new EventEmitter<number>();\n @Output() onPageSizeChange = new EventEmitter<number>();\n\n totalPages = 0;\n first = 0;\n last = 0;\n displayPageIndex: number[] = [];\n pageReport = '';\n\n private initialized = false;\n private cd = inject(ChangeDetectorRef);\n protected cn = cn;\n\n navBtnClass = 'h-8 w-8 p-0 flex items-center justify-center rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 cursor-pointer';\n\n ngOnInit(): void {\n if (this.pageSizeOptions.length === 0) {\n this.pageSizeOptions = [10, 20, 30, 50];\n }\n this.initializePagination();\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n // Only re-init if meaningful data changes\n if (changes['totalRecords'] || changes['currentPage'] || changes['currentPageSize']) {\n this.initializePagination();\n }\n }\n\n private initializePagination(): void {\n this.calcPagination();\n if (!this.initialized) {\n this.initialized = true;\n }\n this.cd.detectChanges();\n }\n\n nextPage() {\n if (this.totalPages > this.currentPage) {\n this.currentPage++;\n this.emitChange();\n }\n }\n\n previousPage() {\n if (this.currentPage > 1) {\n this.currentPage--;\n this.emitChange();\n }\n }\n\n selectPage(page: number) {\n if (this.currentPage === page) return;\n this.currentPage = page;\n this.emitChange();\n }\n\n sizeChange(size: number) {\n this.currentPageSize = size;\n this.currentPage = 1; // Reset to page 1 on size change\n this.emitChange();\n }\n\n private emitChange(): void {\n this.calcPagination();\n this.onPageNumberChange.emit(this.currentPage);\n this.onPageSizeChange.emit(this.currentPageSize);\n this.cd.detectChanges();\n }\n\n private calcPagination(): void {\n this.totalPages = Math.ceil(this.totalRecords / this.currentPageSize) || 0;\n\n // Bounds check\n if (this.currentPage > this.totalPages && this.totalPages > 0) {\n this.currentPage = this.totalPages;\n }\n\n this.first = this.totalRecords === 0 ? 0 : (this.currentPage - 1) * this.currentPageSize + 1;\n this.last = Math.min(this.totalRecords, this.currentPage * this.currentPageSize);\n\n // Calculate Sliding Window for Page Numbers (Max 5 visible)\n const pages: number[] = Array.from({ length: this.totalPages }, (_, i) => i + 1);\n\n if (this.totalPages <= 5) {\n this.displayPageIndex = pages;\n } else {\n let start = Math.max(0, this.currentPage - 3);\n let end = start + 5;\n\n if (end > this.totalPages) {\n end = this.totalPages;\n start = end - 5;\n }\n this.displayPageIndex = pages.slice(start, end);\n }\n\n // Template Parsing\n if (this.currentPageInfoTemplate) {\n this.pageReport = this.currentPageInfoTemplate.replace(\n /{first}|{last}|{totalRecords}|{currentPage}|{currentPageSize}|{totalPages}/g,\n (match) => {\n switch (match) {\n case '{first}': return `${this.first}`;\n case '{last}': return `${this.last}`;\n case '{totalRecords}': return `${this.totalRecords}`;\n case '{totalPages}': return `${this.totalPages}`;\n case '{currentPage}': return `${this.currentPage}`;\n case '{currentPageSize}': return `${this.currentPageSize}`;\n default: return match;\n }\n }\n );\n }\n }\n}\n"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"path": "select.service.ts",
|
|
23
|
+
"target": "ui/select.service.ts",
|
|
24
|
+
"content": "import { Injectable } from '@angular/core';\nimport { Subject } from 'rxjs';\n\n@Injectable()\nexport class SelectService {\n // Emits the value of the clicked item\n private selectedValueSource = new Subject<any>();\n selectedValue$ = this.selectedValueSource.asObservable();\n\n // Emits the label/text of the clicked item\n private selectedLabelSource = new Subject<string>();\n selectedLabel$ = this.selectedLabelSource.asObservable();\n\n registerClick(value: any, label: string) {\n this.selectedValueSource.next(value);\n this.selectedLabelSource.next(label);\n }\n}\n"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"path": "utils/cn.ts",
|
|
28
|
+
"target": "ui/utils/cn.ts",
|
|
29
|
+
"content": "import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|