@yoozsoft/yoozsoft-ng 5.3.5 → 7.1.1
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/README.md +143 -24
- package/assets/js/UTIF.js-master/LICENSE +21 -21
- package/assets/js/UTIF.js-master/README.md +72 -72
- package/assets/js/UTIF.js-master/UTIF.js +1762 -1762
- package/assets/js/UTIF.js-master/package-lock.json +13 -13
- package/assets/js/UTIF.js-master/package.json +24 -0
- package/assets/styles/components/_ys-navbar.scss +22 -0
- package/assets/styles/components/_ys-pagination.scss +10 -0
- package/assets/styles/{ys-layout.scss → utilities/ys-layout.scss} +1 -1
- package/assets/styles/ys-styles.scss +2 -0
- package/autocomplete/package.json +4 -0
- package/date/package.json +4 -0
- package/datepicker/package.json +4 -0
- package/dropdown/package.json +4 -0
- package/fesm2022/yoozsoft-yoozsoft-ng-autocomplete.mjs +257 -197
- package/fesm2022/yoozsoft-yoozsoft-ng-autocomplete.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-date.mjs +562 -0
- package/fesm2022/yoozsoft-yoozsoft-ng-date.mjs.map +1 -0
- package/fesm2022/yoozsoft-yoozsoft-ng-datepicker.mjs +600 -837
- package/fesm2022/yoozsoft-yoozsoft-ng-datepicker.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-dropdown.mjs +161 -151
- package/fesm2022/yoozsoft-yoozsoft-ng-dropdown.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-file-upload.mjs +93 -103
- package/fesm2022/yoozsoft-yoozsoft-ng-file-upload.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-footer.mjs +16 -21
- package/fesm2022/yoozsoft-yoozsoft-ng-footer.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-loading.mjs +20 -24
- package/fesm2022/yoozsoft-yoozsoft-ng-loading.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-navbar.mjs +60 -76
- package/fesm2022/yoozsoft-yoozsoft-ng-navbar.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-overlay.mjs +11 -15
- package/fesm2022/yoozsoft-yoozsoft-ng-overlay.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-pagination.mjs +61 -55
- package/fesm2022/yoozsoft-yoozsoft-ng-pagination.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-password-strength.mjs +142 -130
- package/fesm2022/yoozsoft-yoozsoft-ng-password-strength.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-pipes.mjs +44 -0
- package/fesm2022/yoozsoft-yoozsoft-ng-pipes.mjs.map +1 -0
- package/fesm2022/yoozsoft-yoozsoft-ng-progress.mjs +51 -34
- package/fesm2022/yoozsoft-yoozsoft-ng-progress.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-rating.mjs +155 -0
- package/fesm2022/yoozsoft-yoozsoft-ng-rating.mjs.map +1 -0
- package/fesm2022/yoozsoft-yoozsoft-ng-select.mjs +78 -80
- package/fesm2022/yoozsoft-yoozsoft-ng-select.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-sidebar.mjs +99 -99
- package/fesm2022/yoozsoft-yoozsoft-ng-sidebar.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-table.mjs +316 -0
- package/fesm2022/yoozsoft-yoozsoft-ng-table.mjs.map +1 -0
- package/fesm2022/yoozsoft-yoozsoft-ng-tiff-viewer.mjs +128 -114
- package/fesm2022/yoozsoft-yoozsoft-ng-tiff-viewer.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-toast.mjs +112 -62
- package/fesm2022/yoozsoft-yoozsoft-ng-toast.mjs.map +1 -1
- package/fesm2022/yoozsoft-yoozsoft-ng-validators.mjs +37 -0
- package/fesm2022/yoozsoft-yoozsoft-ng-validators.mjs.map +1 -0
- package/fesm2022/yoozsoft-yoozsoft-ng.mjs.map +1 -1
- package/file-upload/package.json +4 -0
- package/footer/package.json +4 -0
- package/loading/package.json +4 -0
- package/navbar/package.json +4 -0
- package/overlay/package.json +4 -0
- package/package.json +61 -38
- package/pagination/package.json +4 -0
- package/password-strength/package.json +4 -0
- package/pipes/package.json +4 -0
- package/progress/package.json +4 -0
- package/rating/package.json +4 -0
- package/select/package.json +4 -0
- package/sidebar/package.json +4 -0
- package/table/package.json +4 -0
- package/tiff-viewer/package.json +4 -0
- package/toast/package.json +4 -0
- package/types/yoozsoft-yoozsoft-ng-autocomplete.d.ts +79 -0
- package/types/yoozsoft-yoozsoft-ng-date.d.ts +118 -0
- package/types/yoozsoft-yoozsoft-ng-datepicker.d.ts +120 -0
- package/types/yoozsoft-yoozsoft-ng-dropdown.d.ts +76 -0
- package/types/yoozsoft-yoozsoft-ng-file-upload.d.ts +75 -0
- package/types/yoozsoft-yoozsoft-ng-footer.d.ts +26 -0
- package/types/yoozsoft-yoozsoft-ng-loading.d.ts +14 -0
- package/types/yoozsoft-yoozsoft-ng-navbar.d.ts +60 -0
- package/types/yoozsoft-yoozsoft-ng-overlay.d.ts +10 -0
- package/types/yoozsoft-yoozsoft-ng-pagination.d.ts +31 -0
- package/types/yoozsoft-yoozsoft-ng-password-strength.d.ts +73 -0
- package/types/yoozsoft-yoozsoft-ng-pipes.d.ts +11 -0
- package/types/yoozsoft-yoozsoft-ng-progress.d.ts +31 -0
- package/types/yoozsoft-yoozsoft-ng-rating.d.ts +56 -0
- package/types/yoozsoft-yoozsoft-ng-select.d.ts +43 -0
- package/types/yoozsoft-yoozsoft-ng-sidebar.d.ts +69 -0
- package/types/yoozsoft-yoozsoft-ng-table.d.ts +137 -0
- package/types/yoozsoft-yoozsoft-ng-tiff-viewer.d.ts +53 -0
- package/types/yoozsoft-yoozsoft-ng-toast.d.ts +66 -0
- package/types/yoozsoft-yoozsoft-ng-validators.d.ts +5 -0
- package/validators/package.json +4 -0
- package/autocomplete/index.d.ts +0 -71
- package/datepicker/index.d.ts +0 -291
- package/directives/index.d.ts +0 -17
- package/dropdown/index.d.ts +0 -62
- package/fesm2022/yoozsoft-yoozsoft-ng-directives.mjs +0 -57
- package/fesm2022/yoozsoft-yoozsoft-ng-directives.mjs.map +0 -1
- package/file-upload/index.d.ts +0 -72
- package/footer/index.d.ts +0 -25
- package/loading/index.d.ts +0 -13
- package/navbar/index.d.ts +0 -56
- package/overlay/index.d.ts +0 -11
- package/pagination/index.d.ts +0 -29
- package/password-strength/index.d.ts +0 -84
- package/progress/index.d.ts +0 -28
- package/select/index.d.ts +0 -39
- package/sidebar/index.d.ts +0 -94
- package/tiff-viewer/index.d.ts +0 -52
- package/toast/index.d.ts +0 -53
- /package/assets/styles/{ys-preloader-9.scss → preloaders/ys-preloader-9.scss} +0 -0
- /package/assets/styles/{ys-preloader.scss → preloaders/ys-preloader.scss} +0 -0
- /package/{index.d.ts → types/yoozsoft-yoozsoft-ng.d.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yoozsoft-yoozsoft-ng-autocomplete.mjs","sources":["../../../../projects/yoozsoft/yoozsoft-ng/autocomplete/src/ys-autocomplete/ys-autocomplete.component.ts","../../../../projects/yoozsoft/yoozsoft-ng/autocomplete/src/ys-autocomplete/ys-autocomplete.component.html","../../../../projects/yoozsoft/yoozsoft-ng/autocomplete/public-api.ts","../../../../projects/yoozsoft/yoozsoft-ng/autocomplete/yoozsoft-yoozsoft-ng-autocomplete.ts"],"sourcesContent":["import { ScrollingModule } from '@angular/cdk/scrolling';\r\nimport { NgClass, NgTemplateOutlet } from '@angular/common';\r\nimport { Component, ContentChild, ElementRef, EventEmitter, forwardRef, HostListener, Input, Output, TemplateRef, ViewChild } from '@angular/core';\r\nimport { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';\r\nimport { catchError, debounceTime, distinctUntilChanged, Observable, of, Subject, switchMap } from 'rxjs';\r\n\r\n@Component({\r\n selector: 'ys-autocomplete',\r\n imports: [FormsModule, NgTemplateOutlet, NgClass, ScrollingModule],\r\n templateUrl: './ys-autocomplete.component.html',\r\n styleUrl: './ys-autocomplete.component.scss',\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => YsAutocompleteComponent),\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class YsAutocompleteComponent implements ControlValueAccessor {\r\n\r\n searchTerm = '';\r\n filteredOptions: any[] = [];\r\n selectedOptions: any[] = [];\r\n showDropdown = false;\r\n activeIndex = -1;\r\n error: string | null = null;\r\n\r\n /** Array or async function */\r\n @Input() options?: any[] | ((term: string) => Observable<any[]>);\r\n\r\n /** Label display field */\r\n @Input() optionLabel = 'label';\r\n\r\n /** placeholder */\r\n @Input() placeholder: string = '';\r\n\r\n /** Multiple choice mode */\r\n @Input() multiple = false;\r\n\r\n /** Button to clear selection */\r\n @Input() showClear = false;\r\n\r\n @Input() disabled: boolean = false;\r\n\r\n /** Custom template */\r\n @ContentChild(TemplateRef) itemTemplate?: TemplateRef<any>;\r\n\r\n @Input() styleClass?: string;\r\n /** Badge style class on Multiple choice mode */\r\n @Input() badgeStyleClass: string = 'text-bg-light';\r\n @Input() loading: boolean = false;\r\n @Input() loadingMessage: string = 'Loading...';\r\n /** No results found message */\r\n @Input() noResultMessage: string = 'No results found.';\r\n\r\n /** Infinite scroll feature enabled */\r\n @Input() infiniteScroll = false;\r\n\r\n @Input() virtualScroll: boolean = true;\r\n @Input() virtualScrollItemSize: number = 36;\r\n // [virtualScrollOptions]=\"options\"\r\n\r\n /** Event to request more items */\r\n @Output() loadMore = new EventEmitter<string>();\r\n\r\n /** Output selection */\r\n @Output() selected = new EventEmitter<any>();\r\n /** Output selection after removed item */\r\n @Output() removed = new EventEmitter<any>();\r\n\r\n private search$ = new Subject<string>();\r\n private _onChange: (value: any) => void = () => { };\r\n private _onTouched: () => void = () => { };\r\n\r\n @ViewChild('inputRef') inputRef!: ElementRef<HTMLInputElement>;\r\n\r\n get isArrayItems(): boolean { return Array.isArray(this.options); }\r\n get isFunctionItems(): boolean { return typeof this.options === 'function'; }\r\n\r\n constructor(private elRef: ElementRef) { }\r\n\r\n ngOnInit() {\r\n if (Array.isArray(this.options)) {\r\n this.filteredOptions = this.options;\r\n }\r\n\r\n /** Only in async function mode */\r\n if (typeof this.options === 'function') {\r\n const fetchFn = this.options as (term: string) => Observable<any[]>;\r\n this.search$\r\n .pipe(\r\n debounceTime(300),\r\n distinctUntilChanged(),\r\n switchMap((term) => {\r\n this.loading = true;\r\n this.error = null;\r\n return fetchFn(term).pipe(\r\n catchError((err) => {\r\n this.error = 'Error receiving data!';\r\n console.error(err);\r\n return of([]);\r\n })\r\n );\r\n })\r\n )\r\n .subscribe((results) => {\r\n this.filteredOptions = results;\r\n this.loading = false;\r\n this.showDropdown = true;\r\n });\r\n }\r\n\r\n }\r\n\r\n /** For the initial value of FormControl */\r\n writeValue(value: any): void {\r\n if (this.multiple) {\r\n this.selectedOptions = value ? [...value] : [];\r\n } else {\r\n this.searchTerm = value ? this.getLabel(value) : '';\r\n }\r\n }\r\n\r\n registerOnChange(fn: any): void {\r\n this._onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: any): void {\r\n this._onTouched = fn;\r\n }\r\n\r\n setDisabledState?(isDisabled: boolean): void {\r\n this.disabled = isDisabled;\r\n if (this.inputRef) {\r\n this.inputRef.nativeElement.disabled = isDisabled;\r\n }\r\n }\r\n\r\n onSearchChange() {\r\n const term = this.searchTerm.trim();\r\n\r\n if (Array.isArray(this.options)) {\r\n const lower = term.toLowerCase();\r\n this.filteredOptions = this.options.filter((item) =>\r\n this.getLabel(item).toLowerCase().includes(lower)\r\n );\r\n this.showDropdown = this.filteredOptions.length >= 0;\r\n } else if (typeof this.options === 'function') {\r\n this.search$.next(term);\r\n }\r\n\r\n if (!this.multiple && !term) {\r\n this.clearSelection();\r\n }\r\n }\r\n\r\n getLabel(item: any): string {\r\n if (!item) return '';\r\n if (typeof item === 'string') return item;\r\n if (item && this.optionLabel && item[this.optionLabel]) {\r\n return item[this.optionLabel];\r\n }\r\n return '';\r\n }\r\n\r\n onSelect(item: any) {\r\n if (this.multiple) {\r\n const exists = this.selectedOptions.some(\r\n (x) => this.getLabel(x) === this.getLabel(item)\r\n );\r\n if (!exists) {\r\n this.selectedOptions.push(item);\r\n this._onChange(this.selectedOptions);\r\n this._onTouched();\r\n this.selected.emit(this.selectedOptions);\r\n }\r\n this.searchTerm = '';\r\n this.showDropdown = true;\r\n this.onSearchChange();\r\n } else {\r\n this.searchTerm = this.getLabel(item);\r\n this._onChange(item);\r\n this._onTouched();\r\n this.selected.emit(item);\r\n this.showDropdown = false;\r\n }\r\n\r\n this.activeIndex = -1;\r\n }\r\n\r\n removeItem(item: any) {\r\n this.selectedOptions = this.selectedOptions.filter(\r\n (x) => this.getLabel(x) !== this.getLabel(item)\r\n );\r\n this._onChange(this.selectedOptions);\r\n this.removed.emit(this.selectedOptions);\r\n }\r\n\r\n onScroll(event: Event) {\r\n if (!this.infiniteScroll || this.loading) return;\r\n\r\n const target = event.target as HTMLElement;\r\n const nearBottom = target.scrollHeight - target.scrollTop <= target.clientHeight + 10;\r\n\r\n if (nearBottom) {\r\n // Request more items\r\n this.loadMore.emit(this.searchTerm);\r\n }\r\n }\r\n\r\n clearSelection() {\r\n if (this.multiple) {\r\n this.selectedOptions = [];\r\n this._onChange(this.selectedOptions);\r\n this.removed.emit(this.selectedOptions);\r\n } else {\r\n this.searchTerm = '';\r\n this._onChange(null);\r\n this.selected.emit(null);\r\n }\r\n\r\n this.showDropdown = false;\r\n }\r\n\r\n /** Keyboard control */\r\n @HostListener('keydown', ['$event'])\r\n handleKeyboard(event: KeyboardEvent) {\r\n if (!this.showDropdown || this.filteredOptions.length === 0) return;\r\n\r\n switch (event.key) {\r\n case 'ArrowDown':\r\n this.activeIndex = (this.activeIndex + 1) % this.filteredOptions.length;\r\n event.preventDefault();\r\n break;\r\n case 'ArrowUp':\r\n this.activeIndex =\r\n (this.activeIndex - 1 + this.filteredOptions.length) %\r\n this.filteredOptions.length;\r\n event.preventDefault();\r\n break;\r\n case 'Enter':\r\n if (this.activeIndex >= 0) {\r\n this.onSelect(this.filteredOptions[this.activeIndex]);\r\n event.preventDefault();\r\n }\r\n break;\r\n case 'Escape':\r\n this.showDropdown = false;\r\n break;\r\n }\r\n }\r\n\r\n /** Close by clicking outside */\r\n @HostListener('document:click', ['$event'])\r\n onClickOutside(event: MouseEvent) {\r\n const clickedInside = this.elRef.nativeElement.contains(event.target);\r\n if (!clickedInside) {\r\n this.showDropdown = false;\r\n }\r\n }\r\n\r\n}\r\n","<div class=\"ys-autocomplete position-relative\">\r\n <div class=\"input-group flex-wrap\">\r\n @if (multiple && selectedOptions.length > 0) {\r\n <div class=\"d-flex flex-wrap\">\r\n @for (item of selectedOptions; track item) {\r\n <span class=\"badge me-1 mb-1 p-2 d-flex align-items-center\" [ngClass]=\"badgeStyleClass\">\r\n {{ getLabel(item) }}\r\n <i class=\"fa fa-times ms-2 cursor-pointer\" (click)=\"removeItem(item)\"></i>\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"input-group w-100\">\r\n <input #inputRef type=\"text\" class=\"form-control\" [placeholder]=\"placeholder\" [(ngModel)]=\"searchTerm\"\r\n (input)=\"onSearchChange()\" (focus)=\"showDropdown = true\" [ngClass]=\"styleClass\" />\r\n\r\n @if (showClear) {\r\n @if ((multiple && selectedOptions.length > 0) || (!multiple && searchTerm)) {\r\n <button class=\"btn btn-outline-secondary btn-clear\" type=\"button\" id=\"btn-clear\" (click)=\"clearSelection()\"\r\n [disabled]=\"disabled\">\r\n <span class=\"fa fa-times\"></span>\r\n </button>\r\n }\r\n }\r\n <span class=\"input-group-text\" (click)=\"showDropdown = !showDropdown\">\r\n <i class=\"fa fa-search\"></i>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (showDropdown) {\r\n <div class=\"dropdown-container position-absolute w-100 shadow-sm bg-white border rounded\">\r\n @if (loading) {\r\n <div class=\"list-group-item text-center\">\r\n <i class=\"fa fa-spinner fa-spin me-2\"></i>{{ loadingMessage }}\r\n </div>\r\n }\r\n @else if (error) {\r\n <div class=\"list-group-item text-danger text-center\">{{ error }}</div>\r\n }\r\n @else if (filteredOptions.length === 0) {\r\n <div class=\"list-group-item text-muted text-center\">\r\n {{ noResultMessage }}\r\n </div>\r\n }\r\n <!-- ✅ حالت Virtual Scroll برای لیستهای بزرگ -->\r\n @else if (virtualScroll && filteredOptions.length > 100) {\r\n <cdk-virtual-scroll-viewport [itemSize]=\"virtualScrollItemSize\" class=\"list-group w-100 overflow-y-auto\">\r\n <ul class=\"list-group w-100\">\r\n @for (item of filteredOptions; track item; let i = $index) {\r\n <li class=\"list-group-item list-group-item-action\" [class.active]=\"i === activeIndex\"\r\n (click)=\"onSelect(item)\">\r\n @if (itemTemplate) {\r\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item }\"></ng-container>\r\n } @else {\r\n {{ getLabel(item) }}\r\n }\r\n </li>\r\n }\r\n </ul>\r\n </cdk-virtual-scroll-viewport>\r\n }\r\n <!-- ✅ حالت معمولی برای لیستهای کوچک -->\r\n @else {\r\n <ul class=\"list-group w-100 overflow-y-auto\" [class.scrollable]=\"infiniteScroll\" (scroll)=\"onScroll($event)\">\r\n @for (item of filteredOptions; track item; let i = $index) {\r\n <li class=\"list-group-item list-group-item-action\" [class.active]=\"i === activeIndex\"\r\n (click)=\"onSelect(item)\">\r\n @if (itemTemplate) {\r\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item }\"></ng-container>\r\n } @else {\r\n {{ getLabel(item) }}\r\n }\r\n </li>\r\n }\r\n </ul>\r\n }\r\n </div>\r\n }\r\n\r\n</div>","/*\r\n * Public API Surface of ys-autocomplete\r\n */\r\n\r\nexport * from './src/ys-autocomplete/ys-autocomplete.component';\r\n\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"yoozsoft-yoozsoft-ng-autocomplete.mjs","sources":["../../../../projects/yoozsoft/yoozsoft-ng/autocomplete/src/ys-autocomplete/ys-autocomplete.ts","../../../../projects/yoozsoft/yoozsoft-ng/autocomplete/src/ys-autocomplete/ys-autocomplete.html","../../../../projects/yoozsoft/yoozsoft-ng/autocomplete/public-api.ts","../../../../projects/yoozsoft/yoozsoft-ng/autocomplete/yoozsoft-yoozsoft-ng-autocomplete.ts"],"sourcesContent":["import { ScrollingModule } from '@angular/cdk/scrolling';\r\nimport { isPlatformBrowser, NgTemplateOutlet } from '@angular/common';\r\nimport { ChangeDetectionStrategy, Component, computed, ContentChild, DestroyRef, ElementRef, forwardRef, inject, input, output, PLATFORM_ID, signal, TemplateRef, viewChild } from '@angular/core';\r\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';\r\nimport { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';\r\nimport { catchError, debounceTime, distinctUntilChanged, finalize, fromEvent, Observable, of, switchMap } from 'rxjs';\r\n\r\n@Component({\r\n selector: 'ys-autocomplete',\r\n imports: [\r\n FormsModule,\r\n NgTemplateOutlet,\r\n ScrollingModule\r\n ],\r\n templateUrl: './ys-autocomplete.html',\r\n styleUrl: './ys-autocomplete.scss',\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => YsAutocomplete),\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class YsAutocomplete<T = any> implements ControlValueAccessor {\r\n\r\n /********************* Inputs */\r\n options = input<T[] | ((term: string) => Observable<T[]>)>([]);\r\n\r\n loading = input(false);\r\n loadingMessage = input('Loading...');\r\n noResultMessage = input('No results found.');\r\n\r\n optionLabel = input('label');\r\n placeholder = input('');\r\n\r\n multiple = input(false);\r\n showClear = input(false);\r\n disabled = input(false);\r\n\r\n styleClass = input<string>();\r\n selectionStyleClass = input('text-bg-light');\r\n clearIconClass = input('fa fa-times');\r\n searchIconClass = input('fa fa-search');\r\n loadingIconClass = input('fa fa-spinner fa-spin');\r\n multipleCheckIconClass = input('fa fa-check');\r\n\r\n infiniteScroll = input(false);\r\n virtualScroll = input(true);\r\n virtualScrollItemSize = input(36);\r\n virtualScrollThreshold = input(100);\r\n\r\n trackBy = input<(item: T) => unknown>();\r\n compareWith = input<(a: T, b: T) => boolean>();\r\n\r\n /********************* Outputs */\r\n /** Event to request more items */\r\n loadMore = output<string>();\r\n\r\n /** Return selected options */\r\n selectionChange = output<T | T[] | null>();\r\n\r\n\r\n /********************* Signals */\r\n searchTerm = signal('');\r\n filteredOptions = signal<T[]>([]);\r\n selectedOptions = signal<T[]>([]);\r\n showDropdown = signal(false);\r\n activeIndex = signal(-1);\r\n error = signal<string | null>(null);\r\n\r\n private readonly internalLoading = signal(false);\r\n readonly isLoading = computed(() => this.loading() || this.internalLoading());\r\n private disabledState = signal(false);\r\n readonly isDisabled = computed(() => this.disabled() || this.disabledState());\r\n\r\n private static nextId = 0;\r\n readonly componentId = `ys-autocomplete-${YsAutocomplete.nextId++}`;\r\n\r\n readonly activeOptionId = computed(() => {\r\n\r\n const index = this.activeIndex();\r\n\r\n return index >= 0\r\n ? `${this.componentId}-option-${index}`\r\n : null;\r\n\r\n });\r\n\r\n\r\n /********************* ViewChild */\r\n inputRef = viewChild<ElementRef<HTMLInputElement>>('inputRef');\r\n\r\n\r\n /********************* Inject */\r\n private readonly destroyRef = inject(DestroyRef);\r\n private readonly host = inject(ElementRef<HTMLElement>);\r\n private readonly platformId = inject(PLATFORM_ID);\r\n readonly isBrowser = isPlatformBrowser(this.platformId);\r\n\r\n /** Custom template */\r\n @ContentChild(TemplateRef) itemTemplate?: TemplateRef<any>;\r\n\r\n private onChange = (_: unknown) => { };\r\n private onTouched = () => { };\r\n\r\n constructor() {\r\n\r\n if (this.isBrowser) {\r\n\r\n fromEvent<MouseEvent>(\r\n document,\r\n 'click'\r\n )\r\n .pipe(\r\n takeUntilDestroyed(this.destroyRef)\r\n )\r\n .subscribe(event => {\r\n\r\n const target =\r\n event.target as Node;\r\n\r\n if (\r\n !this.host.nativeElement.contains(\r\n target\r\n )\r\n ) {\r\n this.showDropdown.set(false);\r\n }\r\n\r\n });\r\n }\r\n\r\n toObservable(this.searchTerm)\r\n .pipe(debounceTime(300), distinctUntilChanged(),\r\n\r\n switchMap(term => {\r\n\r\n const source = this.options();\r\n\r\n if (Array.isArray(source)) {\r\n\r\n const lower = term.toLowerCase();\r\n\r\n return of(\r\n source.filter(item =>\r\n this\r\n .getLabel(item)\r\n .toLowerCase()\r\n .includes(lower)\r\n )\r\n );\r\n }\r\n\r\n this.internalLoading.set(true);\r\n this.error.set(null);\r\n\r\n return source(term).pipe(\r\n catchError(error => {\r\n\r\n console.error(error);\r\n\r\n this.error.set('Error receiving data!');\r\n\r\n return of([]);\r\n\r\n }),\r\n\r\n finalize(() => {\r\n this.internalLoading.set(false);\r\n })\r\n );\r\n\r\n }),\r\n\r\n takeUntilDestroyed(this.destroyRef)\r\n )\r\n .subscribe(result => {\r\n\r\n this.filteredOptions.set(result);\r\n\r\n // this.showDropdown.set(\r\n // result.length > 0\r\n // );\r\n\r\n });\r\n\r\n }\r\n\r\n writeValue(value: T | T[]): void {\r\n\r\n if (this.multiple()) {\r\n\r\n this.selectedOptions.set(\r\n Array.isArray(value)\r\n ? [...value]\r\n : []\r\n );\r\n\r\n return;\r\n }\r\n\r\n this.searchTerm.set(\r\n value\r\n ? this.getLabel(value as T)\r\n : ''\r\n );\r\n\r\n }\r\n\r\n registerOnChange(fn: any): void {\r\n this.onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: any): void {\r\n this.onTouched = fn;\r\n }\r\n\r\n setDisabledState?(isDisabled: boolean): void {\r\n this.disabledState.set(isDisabled);\r\n }\r\n\r\n onInput(event: Event): void {\r\n const value = (event.target as HTMLInputElement).value;\r\n this.onSearchChange(value);\r\n }\r\n\r\n private onSearchChange(term: string) {\r\n this.searchTerm.set(term.trim());\r\n\r\n if (Array.isArray(this.options())) {\r\n const lower = term.toLowerCase();\r\n this.filteredOptions.set(\r\n (this.options() as T[]).filter(item =>\r\n this.getLabel(item).toLowerCase().includes(lower)\r\n )\r\n );\r\n this.showDropdown.set(true);\r\n }\r\n\r\n if (!this.multiple && !term) {\r\n this.clearSelection();\r\n }\r\n }\r\n\r\n getLabel(item: T): string {\r\n\r\n if (item === null || item === undefined) {\r\n return '';\r\n }\r\n\r\n if (typeof item === 'string' || typeof item === 'number') {\r\n return String(item);\r\n }\r\n\r\n const key = this.optionLabel();\r\n const value = (item as any)?.[key];\r\n\r\n return value != null\r\n ? String(value)\r\n : '';\r\n\r\n }\r\n\r\n private isEqual(a: T, b: T): boolean {\r\n\r\n const comparer = this.compareWith();\r\n\r\n if (comparer) {\r\n return comparer(a, b);\r\n }\r\n\r\n return this.getLabel(a) === this.getLabel(b);\r\n }\r\n\r\n onSelect(item: any) {\r\n if (this.multiple()) {\r\n this.selectedOptions.update(list =>\r\n list.some(x => this.isEqual(x, item))\r\n ? list.filter(x => !this.isEqual(x, item)) // ✅ حذف\r\n : [...list, item] // ✅ اضافه\r\n );\r\n\r\n const value = this.selectedOptions();\r\n this.onChange(value);\r\n this.onTouched();\r\n this.selectionChange.emit(value);\r\n\r\n this.searchTerm.set('');\r\n this.showDropdown.set(true);\r\n this.onSearchChange(this.searchTerm());\r\n\r\n } else {\r\n this.searchTerm.set(this.getLabel(item));\r\n this.onChange(item);\r\n this.onTouched();\r\n this.selectionChange.emit(item);\r\n this.showDropdown.set(false);\r\n }\r\n\r\n this.activeIndex.set(-1);\r\n\r\n this.inputRef()?.nativeElement.focus();\r\n }\r\n\r\n removeItem(item: any) {\r\n const prev = this.selectedOptions();\r\n\r\n this.selectedOptions.update(list =>\r\n list.filter(x => !this.isEqual(x, item))\r\n );\r\n\r\n if (prev !== this.selectedOptions()) {\r\n const value = this.selectedOptions();\r\n this.onChange(value);\r\n this.selectionChange.emit(value);\r\n }\r\n }\r\n\r\n onScroll(event: Event) {\r\n if (!this.infiniteScroll || this.isLoading()) return;\r\n\r\n const target = event.target as HTMLElement;\r\n const nearBottom = target.scrollHeight - target.scrollTop <= target.clientHeight + 10;\r\n\r\n if (nearBottom) {\r\n // Request more items\r\n this.loadMore.emit(this.searchTerm());\r\n }\r\n }\r\n\r\n clearSelection() {\r\n if (this.multiple()) {\r\n this.selectedOptions.set([]);\r\n const value = this.selectedOptions();\r\n this.onChange(value);\r\n this.selectionChange.emit(value);\r\n } else {\r\n this.searchTerm.set('');\r\n this.onChange(null);\r\n this.selectionChange.emit(null);\r\n }\r\n\r\n // this.showDropdown.set(false);\r\n }\r\n\r\n handleKeyboard(event: KeyboardEvent) {\r\n const list = this.filteredOptions();\r\n if (list.length === 0) {\r\n return;\r\n }\r\n\r\n if (!this.showDropdown()) {\r\n this.showDropdown.set(true);\r\n }\r\n\r\n switch (event.key) {\r\n case 'ArrowDown':\r\n // برو به آیتم بعدی\r\n this.activeIndex.update(i => (i + 1) % list.length);\r\n event.preventDefault();\r\n break;\r\n case 'ArrowUp':\r\n // برو به آیتم قبلی\r\n this.activeIndex.update(i => (i - 1 + list.length) % list.length);\r\n event.preventDefault();\r\n break;\r\n case 'Enter':\r\n const index = this.activeIndex();\r\n if (index >= 0 && index < list.length) {\r\n this.onSelect(list[index]);\r\n }\r\n event.preventDefault();\r\n break;\r\n case 'Escape':\r\n this.showDropdown.set(false);\r\n break;\r\n case 'Home':\r\n this.activeIndex.set(0);\r\n event.preventDefault();\r\n break;\r\n case 'End':\r\n this.activeIndex.set(list.length - 1);\r\n event.preventDefault();\r\n break;\r\n case 'Tab':\r\n this.showDropdown.set(false);\r\n break;\r\n case 'PageUp':\r\n this.activeIndex.update(i =>\r\n Math.max(0, i - 10)\r\n );\r\n event.preventDefault();\r\n break;\r\n case 'PageDown':\r\n this.activeIndex.update(i =>\r\n Math.min(list.length - 1, i + 10)\r\n );\r\n event.preventDefault();\r\n break;\r\n }\r\n }\r\n\r\n isSelected(item: T): boolean {\r\n return this.selectedOptions()\r\n .some(x => this.isEqual(x, item));\r\n }\r\n\r\n trackItem(item: T) {\r\n return this.trackBy()?.(item)\r\n ?? this.getLabel(item);\r\n }\r\n\r\n}\r\n","<div class=\"ys-autocomplete position-relative\">\n <div class=\"input-group flex-wrap\">\n @if (multiple() && selectedOptions().length > 0) {\n <div class=\"d-flex flex-wrap\">\n @for (item of selectedOptions(); track trackItem(item)) {\n <span class=\"badge me-1 mb-1 p-2 d-flex align-items-center\" [class]=\"selectionStyleClass()\">\n {{ getLabel(item) }}\n <i class=\"ms-2 cursor-pointer\" [class]=\"clearIconClass()\" (click)=\"removeItem(item)\"></i>\n </span>\n }\n </div>\n }\n\n <div class=\"input-group w-100\">\n <input #inputRef type=\"text\" class=\"form-control\" [class]=\"styleClass()\" [placeholder]=\"placeholder()\"\n [value]=\"searchTerm()\" (input)=\"onInput($event)\" (keydown)=\"handleKeyboard($event)\"\n (focus)=\"showDropdown.set(true)\" (click)=\"showDropdown.set(true)\" role=\"combobox\"\n aria-autocomplete=\"list\" [attr.aria-expanded]=\"showDropdown()\" aria-haspopup=\"listbox\"\n [attr.aria-activedescendant]=\"activeOptionId()\" [disabled]=\"isDisabled()\" />\n\n @if (showClear()) {\n @if ((multiple() && selectedOptions().length > 0) || (!multiple() && searchTerm())) {\n <button class=\"btn btn-outline-secondary btn-clear\" type=\"button\" id=\"btn-clear\" (click)=\"clearSelection()\"\n [disabled]=\"isDisabled()\">\n <span [class]=\"clearIconClass()\"></span>\n </button>\n }\n }\n <span class=\"input-group-text\" (click)=\"showDropdown.set( !showDropdown())\">\n <i [class]=\"searchIconClass()\"></i>\n </span>\n </div>\n </div>\n\n @if (showDropdown()) {\n <div class=\"dropdown-container position-absolute w-100 shadow-sm bg-white border rounded\">\n @if (isLoading()) {\n <div class=\"list-group-item text-center\">\n <i class=\"me-2\" [class]=\"loadingIconClass()\"></i>{{ loadingMessage() }}\n </div>\n }\n @else if (error()) {\n <div class=\"list-group-item text-danger text-center\">{{ error() }}</div>\n }\n @else if (filteredOptions().length === 0) {\n <div class=\"list-group-item text-muted text-center\">\n {{ noResultMessage() }}\n </div>\n }\n <!-- ✅ حالت Virtual Scroll برای لیستهای بزرگ -->\n @else if (virtualScroll() && filteredOptions().length > virtualScrollThreshold()) {\n <cdk-virtual-scroll-viewport [itemSize]=\"virtualScrollItemSize()\" class=\"list-group w-100\">\n\n <div [id]=\"componentId + '-option-' + i\" *cdkVirtualFor=\"let item of filteredOptions(); let i = index\"\n class=\"list-group-item list-group-item-action\" [class.active]=\"i === activeIndex()\"\n [class.selected]=\"isSelected(item)\" (click)=\"onSelect(item)\">\n\n @if (itemTemplate) {\n\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: {$implicit: item}\"> </ng-container>\n\n } @else {\n\n @if(multiple()){\n <i class=\"me-1 text-success\" [class]=\"multipleCheckIconClass()\" [class.invisible]=\"!isSelected(item)\">\n </i>\n }\n\n {{ getLabel(item) }}\n\n }\n\n </div>\n\n </cdk-virtual-scroll-viewport>\n\n }\n <!-- ✅ حالت معمولی برای لیستهای کوچک -->\n @else {\n <ul class=\"list-group w-100 overflow-y-auto\" [class.scrollable]=\"infiniteScroll()\" (scroll)=\"onScroll($event)\"\n role=\"listbox\">\n @for (item of filteredOptions(); track trackItem(item); let i = $index) {\n <li [id]=\"componentId + '-option-' + i\" class=\"list-group-item list-group-item-action\"\n [class.active]=\"i === activeIndex()\" [class.selected]=\"isSelected(item)\" (click)=\"onSelect(item)\"\n role=\"option\" [attr.aria-selected]=\"isSelected(item)\">\n @if (itemTemplate) {\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item }\"></ng-container>\n } @else {\n @if(multiple()){\n <i class=\"me-1 text-success\" [class]=\"multipleCheckIconClass()\" [class.invisible]=\"!isSelected(item)\">\n </i>\n }\n {{ getLabel(item) }}\n }\n </li>\n }\n </ul>\n }\n </div>\n\n }\n\n</div>","/*\r\n * Public API Surface of ys-autocomplete\r\n */\r\n\r\nexport * from './src/ys-autocomplete/ys-autocomplete';\r\n\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
const GREGORIAN_MONTHS = [
|
|
2
|
+
'January',
|
|
3
|
+
'February',
|
|
4
|
+
'March',
|
|
5
|
+
'April',
|
|
6
|
+
'May',
|
|
7
|
+
'June',
|
|
8
|
+
'July',
|
|
9
|
+
'August',
|
|
10
|
+
'September',
|
|
11
|
+
'October',
|
|
12
|
+
'November',
|
|
13
|
+
'December'
|
|
14
|
+
];
|
|
15
|
+
const GREGORIAN_WEEKDAYS = [
|
|
16
|
+
'Monday',
|
|
17
|
+
'Tuesday',
|
|
18
|
+
'Wednesday',
|
|
19
|
+
'Thursday',
|
|
20
|
+
'Friday',
|
|
21
|
+
'Saturday',
|
|
22
|
+
'Sunday',
|
|
23
|
+
];
|
|
24
|
+
const PERSIAN_MONTHS = [
|
|
25
|
+
'فروردین',
|
|
26
|
+
'اردیبهشت',
|
|
27
|
+
'خرداد',
|
|
28
|
+
'تیر',
|
|
29
|
+
'مرداد',
|
|
30
|
+
'شهریور',
|
|
31
|
+
'مهر',
|
|
32
|
+
'آبان',
|
|
33
|
+
'آذر',
|
|
34
|
+
'دی',
|
|
35
|
+
'بهمن',
|
|
36
|
+
'اسفند'
|
|
37
|
+
];
|
|
38
|
+
const PERSIAN_MONTH_SHORT = [
|
|
39
|
+
'فرو',
|
|
40
|
+
'ارد',
|
|
41
|
+
'خرد',
|
|
42
|
+
'تیر',
|
|
43
|
+
'مرد',
|
|
44
|
+
'شهر',
|
|
45
|
+
'مهر',
|
|
46
|
+
'آبا',
|
|
47
|
+
'آذر',
|
|
48
|
+
'دی',
|
|
49
|
+
'بهم',
|
|
50
|
+
'اسف'
|
|
51
|
+
];
|
|
52
|
+
const PERSIAN_WEEKDAYS = [
|
|
53
|
+
'دوشنبه',
|
|
54
|
+
'سهشنبه',
|
|
55
|
+
'چهارشنبه',
|
|
56
|
+
'پنجشنبه',
|
|
57
|
+
'جمعه',
|
|
58
|
+
'شنبه',
|
|
59
|
+
'یکشنبه'
|
|
60
|
+
];
|
|
61
|
+
const PERSIAN_WEEKDAYS_SHORT = [
|
|
62
|
+
'د',
|
|
63
|
+
'س',
|
|
64
|
+
'چ',
|
|
65
|
+
'پ',
|
|
66
|
+
'ج',
|
|
67
|
+
'ش',
|
|
68
|
+
'ی'
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
class JalaliDate {
|
|
72
|
+
static calendarDaysInMonth = {
|
|
73
|
+
g_days_in_month: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
|
|
74
|
+
j_days_in_month: [31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29],
|
|
75
|
+
};
|
|
76
|
+
// private static readonly supportedTokens = [
|
|
77
|
+
// 'yyyy',
|
|
78
|
+
// 'yy',
|
|
79
|
+
// 'MMMM',
|
|
80
|
+
// 'MM',
|
|
81
|
+
// 'M',
|
|
82
|
+
// 'dd',
|
|
83
|
+
// 'd',
|
|
84
|
+
// 'HH',
|
|
85
|
+
// 'H',
|
|
86
|
+
// 'mm',
|
|
87
|
+
// 'm',
|
|
88
|
+
// 'ss',
|
|
89
|
+
// 's',
|
|
90
|
+
// 'EEEE'
|
|
91
|
+
// ];
|
|
92
|
+
static validateJalaliDate(year, month, day) {
|
|
93
|
+
if (year < 1) {
|
|
94
|
+
throw new Error('Invalid Jalali year');
|
|
95
|
+
}
|
|
96
|
+
if (month < 1 || month > 12) {
|
|
97
|
+
throw new Error('Invalid Jalali month');
|
|
98
|
+
}
|
|
99
|
+
const maxDay = this.daysInMonth(year, month);
|
|
100
|
+
if (day < 1 || day > maxDay) {
|
|
101
|
+
throw new Error('Invalid Jalali day');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
static validateGregorianDate(year, month, day) {
|
|
105
|
+
if (year < 1) {
|
|
106
|
+
throw new Error('Invalid Gregorian year');
|
|
107
|
+
}
|
|
108
|
+
if (month < 1 || month > 12) {
|
|
109
|
+
throw new Error('Invalid Gregorian month');
|
|
110
|
+
}
|
|
111
|
+
let maxDay = this.calendarDaysInMonth.g_days_in_month[month - 1];
|
|
112
|
+
// Check leap year for February
|
|
113
|
+
if (month === 2 && ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0)) {
|
|
114
|
+
maxDay = 29;
|
|
115
|
+
}
|
|
116
|
+
if (day < 1 || day > maxDay) {
|
|
117
|
+
throw new Error('Invalid Gregorian day');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// validation
|
|
121
|
+
static isValid(year, month, day) {
|
|
122
|
+
if (year < 1)
|
|
123
|
+
return false;
|
|
124
|
+
if (month < 1 || month > 12) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
return day >= 1 &&
|
|
128
|
+
day <= this.daysInMonth(year, month);
|
|
129
|
+
}
|
|
130
|
+
static isLeapYear(year) {
|
|
131
|
+
const mod = year % 33;
|
|
132
|
+
return [
|
|
133
|
+
1, 5, 9, 13,
|
|
134
|
+
17, 22, 26, 30
|
|
135
|
+
].includes(mod);
|
|
136
|
+
}
|
|
137
|
+
// month
|
|
138
|
+
static daysInMonth(year, month) {
|
|
139
|
+
if (month <= 6) {
|
|
140
|
+
return 31;
|
|
141
|
+
}
|
|
142
|
+
if (month <= 11) {
|
|
143
|
+
return 30;
|
|
144
|
+
}
|
|
145
|
+
return this.isLeapYear(year)
|
|
146
|
+
? 30
|
|
147
|
+
: 29;
|
|
148
|
+
}
|
|
149
|
+
static monthName(month) {
|
|
150
|
+
return PERSIAN_MONTHS[month - 1] ?? '';
|
|
151
|
+
}
|
|
152
|
+
static weekdayName(day) {
|
|
153
|
+
return PERSIAN_WEEKDAYS[day] ?? '';
|
|
154
|
+
}
|
|
155
|
+
// week
|
|
156
|
+
static dayOfWeek(year, month, day) {
|
|
157
|
+
const date = this.toDate({
|
|
158
|
+
year,
|
|
159
|
+
month,
|
|
160
|
+
day
|
|
161
|
+
});
|
|
162
|
+
const jsDay = date.getDay();
|
|
163
|
+
return jsDay === 0
|
|
164
|
+
? 7
|
|
165
|
+
: jsDay;
|
|
166
|
+
}
|
|
167
|
+
static weekDayName(day) {
|
|
168
|
+
return PERSIAN_WEEKDAYS[day] ?? '';
|
|
169
|
+
}
|
|
170
|
+
// current
|
|
171
|
+
static today() {
|
|
172
|
+
return this.fromDate(new Date());
|
|
173
|
+
}
|
|
174
|
+
// compare
|
|
175
|
+
static compare(a, b) {
|
|
176
|
+
const d1 = this.toDate(a).getTime();
|
|
177
|
+
const d2 = this.toDate(b).getTime();
|
|
178
|
+
if (d1 === d2) {
|
|
179
|
+
return 0;
|
|
180
|
+
}
|
|
181
|
+
return d1 > d2 ? 1 : -1;
|
|
182
|
+
}
|
|
183
|
+
// parse
|
|
184
|
+
static parse(value) {
|
|
185
|
+
const match = value.match(/^(\d{4})[-\/](\d{1,2})[-\/](\d{1,2})$/);
|
|
186
|
+
if (!match) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
const date = {
|
|
190
|
+
year: +match[1],
|
|
191
|
+
month: +match[2],
|
|
192
|
+
day: +match[3]
|
|
193
|
+
};
|
|
194
|
+
return this.isValid(date.year, date.month, date.day)
|
|
195
|
+
? date
|
|
196
|
+
: null;
|
|
197
|
+
}
|
|
198
|
+
// arithmetic
|
|
199
|
+
static addDays(date, days) {
|
|
200
|
+
const result = this.toDate(date);
|
|
201
|
+
result.setDate(result.getDate() + days);
|
|
202
|
+
return this.fromDate(result);
|
|
203
|
+
}
|
|
204
|
+
static addMonths(date, months) {
|
|
205
|
+
const result = this.toDate(date);
|
|
206
|
+
result.setMonth(result.getMonth() + months);
|
|
207
|
+
return this.fromDate(result);
|
|
208
|
+
}
|
|
209
|
+
static addYears(date, years) {
|
|
210
|
+
const result = this.toDate(date);
|
|
211
|
+
result.setFullYear(result.getFullYear() + years);
|
|
212
|
+
return this.fromDate(result);
|
|
213
|
+
}
|
|
214
|
+
// conversion helpers
|
|
215
|
+
static fromDate(date) {
|
|
216
|
+
const jDate = this.gregorianToJalali(date.getFullYear(), date.getMonth() + 1, date.getDate());
|
|
217
|
+
return {
|
|
218
|
+
year: jDate.year,
|
|
219
|
+
month: jDate.month,
|
|
220
|
+
day: jDate.day
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
static toDate(date) {
|
|
224
|
+
const gDate = this.jalaliToGregorian(date.year, date.month, date.day);
|
|
225
|
+
return new Date(gDate.year, gDate.month - 1, gDate.day);
|
|
226
|
+
}
|
|
227
|
+
// format
|
|
228
|
+
static format(value, format = 'yyyy/MM/dd') {
|
|
229
|
+
let date;
|
|
230
|
+
if (value instanceof Date) {
|
|
231
|
+
date = value;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
date = new Date(value);
|
|
235
|
+
}
|
|
236
|
+
if (isNaN(date.getTime())) {
|
|
237
|
+
return '';
|
|
238
|
+
}
|
|
239
|
+
const j = this.gregorianToJalali(date.getFullYear(), date.getMonth() + 1, date.getDate());
|
|
240
|
+
const pad = (v) => String(v).padStart(2, '0');
|
|
241
|
+
const weekdayIndex = (date.getDay() + 1) % 7;
|
|
242
|
+
const tokens = {
|
|
243
|
+
yyyy: String(j.year),
|
|
244
|
+
yy: String(j.year).slice(-2),
|
|
245
|
+
MM: pad(j.month),
|
|
246
|
+
M: String(j.month),
|
|
247
|
+
dd: pad(j.day),
|
|
248
|
+
d: String(j.day),
|
|
249
|
+
HH: pad(date.getHours()),
|
|
250
|
+
H: String(date.getHours()),
|
|
251
|
+
mm: pad(date.getMinutes()),
|
|
252
|
+
m: String(date.getMinutes()),
|
|
253
|
+
ss: pad(date.getSeconds()),
|
|
254
|
+
s: String(date.getSeconds()),
|
|
255
|
+
MMMM: PERSIAN_MONTHS[j.month - 1],
|
|
256
|
+
EEEE: PERSIAN_WEEKDAYS[weekdayIndex]
|
|
257
|
+
};
|
|
258
|
+
return format.replace(/yyyy|yy|MMMM|MM|M|dd|d|HH|H|mm|m|ss|s|EEEE/g, token => tokens[token]);
|
|
259
|
+
}
|
|
260
|
+
// conversion
|
|
261
|
+
static gregorianToJalali(year, month, day) {
|
|
262
|
+
// Floor inputs
|
|
263
|
+
year = Math.floor(year);
|
|
264
|
+
month = Math.floor(month);
|
|
265
|
+
day = Math.floor(day);
|
|
266
|
+
// Validate inputs
|
|
267
|
+
this.validateGregorianDate(year, month, day);
|
|
268
|
+
let gy = year - 1600;
|
|
269
|
+
let gm = month - 1;
|
|
270
|
+
let gd = day - 1;
|
|
271
|
+
// Calculate number of days passed since Gregorian epoch
|
|
272
|
+
let g_day_no = 365 * gy +
|
|
273
|
+
Math.floor((gy + 3) / 4) -
|
|
274
|
+
Math.floor((gy + 99) / 100) +
|
|
275
|
+
Math.floor((gy + 399) / 400);
|
|
276
|
+
for (let i = 0; i < gm; ++i)
|
|
277
|
+
g_day_no += this.calendarDaysInMonth.g_days_in_month[i];
|
|
278
|
+
if (gm > 1 &&
|
|
279
|
+
((gy % 4 === 0 && gy % 100 !== 0) || gy % 400 === 0))
|
|
280
|
+
g_day_no++;
|
|
281
|
+
g_day_no += gd;
|
|
282
|
+
let j_day_no = g_day_no - 79;
|
|
283
|
+
let j_np = Math.floor(j_day_no / 12053);
|
|
284
|
+
j_day_no %= 12053;
|
|
285
|
+
let jy = 979 + 33 * j_np + 4 * Math.floor(j_day_no / 1461);
|
|
286
|
+
j_day_no %= 1461;
|
|
287
|
+
if (j_day_no >= 366) {
|
|
288
|
+
jy += Math.floor((j_day_no - 1) / 365);
|
|
289
|
+
j_day_no = (j_day_no - 1) % 365;
|
|
290
|
+
}
|
|
291
|
+
let jm = 0;
|
|
292
|
+
let jd = 0;
|
|
293
|
+
for (let i = 0; i < 11 && j_day_no >= this.calendarDaysInMonth.j_days_in_month[i]; ++i) {
|
|
294
|
+
j_day_no -= this.calendarDaysInMonth.j_days_in_month[i];
|
|
295
|
+
jm = i + 1;
|
|
296
|
+
}
|
|
297
|
+
jm++;
|
|
298
|
+
jd = j_day_no + 1;
|
|
299
|
+
return {
|
|
300
|
+
year: jy,
|
|
301
|
+
month: jm,
|
|
302
|
+
day: jd
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
static jalaliToGregorian(year, month, day) {
|
|
306
|
+
// Floor inputs to make sure they are integers
|
|
307
|
+
year = Math.floor(year);
|
|
308
|
+
month = Math.floor(month);
|
|
309
|
+
day = Math.floor(day);
|
|
310
|
+
// Validate inputs
|
|
311
|
+
this.validateJalaliDate(year, month, day);
|
|
312
|
+
let jy = year - 979;
|
|
313
|
+
let jm = month - 1;
|
|
314
|
+
let jd = day - 1;
|
|
315
|
+
// Calculate number of days passed since Jalali epoch
|
|
316
|
+
let j_day_no = 365 * jy + Math.floor(jy / 33) * 8 + Math.floor(((jy % 33) + 3) / 4);
|
|
317
|
+
for (let i = 0; i < jm; ++i)
|
|
318
|
+
j_day_no += this.calendarDaysInMonth.j_days_in_month[i];
|
|
319
|
+
j_day_no += jd;
|
|
320
|
+
// Convert to Gregorian day number
|
|
321
|
+
let g_day_no = j_day_no + 79;
|
|
322
|
+
// Calculate Gregorian year
|
|
323
|
+
let gy = 1600 + 400 * Math.floor(g_day_no / 146097);
|
|
324
|
+
g_day_no %= 146097;
|
|
325
|
+
let leap = true;
|
|
326
|
+
if (g_day_no >= 36525) {
|
|
327
|
+
g_day_no--;
|
|
328
|
+
gy += 100 * Math.floor(g_day_no / 36524);
|
|
329
|
+
g_day_no %= 36524;
|
|
330
|
+
if (g_day_no >= 365)
|
|
331
|
+
g_day_no++;
|
|
332
|
+
else
|
|
333
|
+
leap = false;
|
|
334
|
+
}
|
|
335
|
+
gy += 4 * Math.floor(g_day_no / 1461);
|
|
336
|
+
g_day_no %= 1461;
|
|
337
|
+
if (g_day_no >= 366) {
|
|
338
|
+
leap = false;
|
|
339
|
+
g_day_no--;
|
|
340
|
+
gy += Math.floor(g_day_no / 365);
|
|
341
|
+
g_day_no %= 365;
|
|
342
|
+
}
|
|
343
|
+
// Calculate Gregorian month and day
|
|
344
|
+
let gm = 0;
|
|
345
|
+
let gd = 0;
|
|
346
|
+
for (let i = 0; g_day_no >=
|
|
347
|
+
this.calendarDaysInMonth.g_days_in_month[i] + (i === 1 && leap ? 1 : 0); i++) {
|
|
348
|
+
g_day_no -= this.calendarDaysInMonth.g_days_in_month[i] + (i === 1 && leap ? 1 : 0);
|
|
349
|
+
gm = i + 1;
|
|
350
|
+
}
|
|
351
|
+
gm++;
|
|
352
|
+
gd = g_day_no + 1;
|
|
353
|
+
return {
|
|
354
|
+
year: gy,
|
|
355
|
+
month: gm,
|
|
356
|
+
day: gd
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
static toNgbDateStruct(date) {
|
|
360
|
+
return {
|
|
361
|
+
year: date.year,
|
|
362
|
+
month: date.month,
|
|
363
|
+
day: date.day
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
static fromNgbDateStruct(date) {
|
|
367
|
+
return {
|
|
368
|
+
year: date.year,
|
|
369
|
+
month: date.month,
|
|
370
|
+
day: date.day
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
static isBetween(value, start, end) {
|
|
374
|
+
return (this.compare(value, start) >= 0 &&
|
|
375
|
+
this.compare(value, end) <= 0);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
class GregorianCalendarAdapter {
|
|
380
|
+
today() {
|
|
381
|
+
const now = new Date();
|
|
382
|
+
return {
|
|
383
|
+
year: now.getFullYear(),
|
|
384
|
+
month: now.getMonth() + 1,
|
|
385
|
+
day: now.getDate()
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
isValid(year, month, day) {
|
|
389
|
+
const date = new Date(year, month - 1, day);
|
|
390
|
+
return (date.getFullYear() === year &&
|
|
391
|
+
date.getMonth() === month - 1 &&
|
|
392
|
+
date.getDate() === day);
|
|
393
|
+
}
|
|
394
|
+
daysInMonth(year, month) {
|
|
395
|
+
return new Date(year, month, 0).getDate();
|
|
396
|
+
}
|
|
397
|
+
dayOfWeek(year, month, day) {
|
|
398
|
+
const jsDay = new Date(year, month - 1, day).getDay();
|
|
399
|
+
return jsDay === 0
|
|
400
|
+
? 7
|
|
401
|
+
: jsDay;
|
|
402
|
+
}
|
|
403
|
+
monthName(month) {
|
|
404
|
+
return GREGORIAN_MONTHS[month - 1] ?? '';
|
|
405
|
+
}
|
|
406
|
+
weekdayName(day) {
|
|
407
|
+
return GREGORIAN_WEEKDAYS[day] ?? '';
|
|
408
|
+
}
|
|
409
|
+
compare(a, b) {
|
|
410
|
+
const t1 = this.toDate(a).getTime();
|
|
411
|
+
const t2 = this.toDate(b).getTime();
|
|
412
|
+
if (t1 === t2) {
|
|
413
|
+
return 0;
|
|
414
|
+
}
|
|
415
|
+
return t1 > t2 ? 1 : -1;
|
|
416
|
+
}
|
|
417
|
+
addDays(date, days) {
|
|
418
|
+
const d = this.toDate(date);
|
|
419
|
+
d.setDate(d.getDate() + days);
|
|
420
|
+
return this.fromDate(d);
|
|
421
|
+
}
|
|
422
|
+
addMonths(date, months) {
|
|
423
|
+
const d = this.toDate(date);
|
|
424
|
+
d.setMonth(d.getMonth() + months);
|
|
425
|
+
return this.fromDate(d);
|
|
426
|
+
}
|
|
427
|
+
addYears(date, years) {
|
|
428
|
+
const d = this.toDate(date);
|
|
429
|
+
d.setFullYear(d.getFullYear() + years);
|
|
430
|
+
return this.fromDate(d);
|
|
431
|
+
}
|
|
432
|
+
toDate(date) {
|
|
433
|
+
return new Date(date.year, date.month - 1, date.day);
|
|
434
|
+
}
|
|
435
|
+
fromDate(date) {
|
|
436
|
+
return {
|
|
437
|
+
year: date.getFullYear(),
|
|
438
|
+
month: date.getMonth() + 1,
|
|
439
|
+
day: date.getDate()
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
parse(value) {
|
|
443
|
+
const match = value.match(/^(\d{4})[-\/](\d{1,2})[-\/](\d{1,2})$/);
|
|
444
|
+
if (!match) {
|
|
445
|
+
return null;
|
|
446
|
+
}
|
|
447
|
+
const result = {
|
|
448
|
+
year: +match[1],
|
|
449
|
+
month: +match[2],
|
|
450
|
+
day: +match[3]
|
|
451
|
+
};
|
|
452
|
+
return this.isValid(result.year, result.month, result.day)
|
|
453
|
+
? result
|
|
454
|
+
: null;
|
|
455
|
+
}
|
|
456
|
+
format(value, format = 'yyyy/MM/dd') {
|
|
457
|
+
const date = value instanceof Date
|
|
458
|
+
? value
|
|
459
|
+
: new Date(value);
|
|
460
|
+
if (isNaN(date.getTime())) {
|
|
461
|
+
return '';
|
|
462
|
+
}
|
|
463
|
+
const pad = (v) => String(v).padStart(2, '0');
|
|
464
|
+
return format
|
|
465
|
+
.replace('yyyy', String(date.getFullYear()))
|
|
466
|
+
.replace('MM', pad(date.getMonth() + 1))
|
|
467
|
+
.replace('dd', pad(date.getDate()));
|
|
468
|
+
}
|
|
469
|
+
isBetween(value, start, end) {
|
|
470
|
+
return (this.compare(value, start) >= 0 &&
|
|
471
|
+
this.compare(value, end) <= 0);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
class JalaliCalendarAdapter {
|
|
476
|
+
today() {
|
|
477
|
+
return JalaliDate.toNgbDateStruct(JalaliDate.today());
|
|
478
|
+
}
|
|
479
|
+
isValid(year, month, day) {
|
|
480
|
+
return JalaliDate.isValid(year, month, day);
|
|
481
|
+
}
|
|
482
|
+
daysInMonth(year, month) {
|
|
483
|
+
return JalaliDate.daysInMonth(year, month);
|
|
484
|
+
}
|
|
485
|
+
dayOfWeek(year, month, day) {
|
|
486
|
+
return JalaliDate.dayOfWeek(year, month, day);
|
|
487
|
+
}
|
|
488
|
+
monthName(month) {
|
|
489
|
+
return JalaliDate.monthName(month);
|
|
490
|
+
}
|
|
491
|
+
weekdayName(day) {
|
|
492
|
+
return JalaliDate.weekdayName(day);
|
|
493
|
+
}
|
|
494
|
+
compare(a, b) {
|
|
495
|
+
return JalaliDate.compare(JalaliDate.fromNgbDateStruct(a), JalaliDate.fromNgbDateStruct(b));
|
|
496
|
+
}
|
|
497
|
+
addDays(date, days) {
|
|
498
|
+
return JalaliDate.toNgbDateStruct(JalaliDate.addDays(JalaliDate.fromNgbDateStruct(date), days));
|
|
499
|
+
}
|
|
500
|
+
addMonths(date, months) {
|
|
501
|
+
return JalaliDate.toNgbDateStruct(JalaliDate.addMonths(JalaliDate.fromNgbDateStruct(date), months));
|
|
502
|
+
}
|
|
503
|
+
addYears(date, years) {
|
|
504
|
+
return JalaliDate.toNgbDateStruct(JalaliDate.addYears(JalaliDate.fromNgbDateStruct(date), years));
|
|
505
|
+
}
|
|
506
|
+
toDate(date) {
|
|
507
|
+
return JalaliDate.toDate(JalaliDate.fromNgbDateStruct(date));
|
|
508
|
+
}
|
|
509
|
+
fromDate(date) {
|
|
510
|
+
return JalaliDate.toNgbDateStruct(JalaliDate.fromDate(date));
|
|
511
|
+
}
|
|
512
|
+
parse(value) {
|
|
513
|
+
const result = JalaliDate.parse(value);
|
|
514
|
+
return result
|
|
515
|
+
? JalaliDate.toNgbDateStruct(result)
|
|
516
|
+
: null;
|
|
517
|
+
}
|
|
518
|
+
format(value, format = 'yyyy/MM/dd') {
|
|
519
|
+
return JalaliDate.format(value, format);
|
|
520
|
+
}
|
|
521
|
+
isBetween(value, start, end) {
|
|
522
|
+
return JalaliDate.isBetween(JalaliDate.fromNgbDateStruct(value), JalaliDate.fromNgbDateStruct(start), JalaliDate.fromNgbDateStruct(end));
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
function createCalendarAdapter(type) {
|
|
527
|
+
return type === 'jalali'
|
|
528
|
+
? new JalaliCalendarAdapter()
|
|
529
|
+
: new GregorianCalendarAdapter();
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
function compareDates(a, b) {
|
|
533
|
+
if (a.year !== b.year) {
|
|
534
|
+
return a.year - b.year;
|
|
535
|
+
}
|
|
536
|
+
if (a.month !== b.month) {
|
|
537
|
+
return a.month - b.month;
|
|
538
|
+
}
|
|
539
|
+
return a.day - b.day;
|
|
540
|
+
}
|
|
541
|
+
function dateToStruct(date) {
|
|
542
|
+
return {
|
|
543
|
+
year: date.getFullYear(),
|
|
544
|
+
month: date.getMonth() + 1,
|
|
545
|
+
day: date.getDate()
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
function structToDate(date) {
|
|
549
|
+
return new Date(date.year, date.month - 1, date.day, 12, // noon
|
|
550
|
+
0, 0, 0);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/*
|
|
554
|
+
* Public API Surface of ys jalali date features
|
|
555
|
+
*/
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Generated bundle index. Do not edit.
|
|
559
|
+
*/
|
|
560
|
+
|
|
561
|
+
export { GREGORIAN_MONTHS, GREGORIAN_WEEKDAYS, GregorianCalendarAdapter, JalaliCalendarAdapter, JalaliDate, PERSIAN_MONTHS, PERSIAN_MONTH_SHORT, PERSIAN_WEEKDAYS, PERSIAN_WEEKDAYS_SHORT, compareDates, createCalendarAdapter, dateToStruct, structToDate };
|
|
562
|
+
//# sourceMappingURL=yoozsoft-yoozsoft-ng-date.mjs.map
|