ngx-kit 6.3.0 → 7.0.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.
Files changed (67) hide show
  1. package/README.md +3 -3
  2. package/angle-selector/README.md +34 -34
  3. package/box-shadow/README.md +33 -33
  4. package/color-picker/README.md +52 -49
  5. package/data-table/README.md +120 -113
  6. package/date-picker/README.md +74 -69
  7. package/dialog/README.md +92 -92
  8. package/drag-resize/README.md +55 -0
  9. package/dropzone/README.md +422 -422
  10. package/fesm2022/ngx-kit-angle-selector.mjs +2 -2
  11. package/fesm2022/ngx-kit-angle-selector.mjs.map +1 -1
  12. package/fesm2022/ngx-kit-box-shadow.mjs +2 -2
  13. package/fesm2022/ngx-kit-box-shadow.mjs.map +1 -1
  14. package/fesm2022/ngx-kit-color-picker.mjs +265 -73
  15. package/fesm2022/ngx-kit-color-picker.mjs.map +1 -1
  16. package/fesm2022/ngx-kit-data-table.mjs +2 -2
  17. package/fesm2022/ngx-kit-data-table.mjs.map +1 -1
  18. package/fesm2022/ngx-kit-date-picker.mjs +7 -9
  19. package/fesm2022/ngx-kit-date-picker.mjs.map +1 -1
  20. package/fesm2022/ngx-kit-dialog.mjs +3 -3
  21. package/fesm2022/ngx-kit-dialog.mjs.map +1 -1
  22. package/fesm2022/ngx-kit-drag-resize.mjs +1664 -0
  23. package/fesm2022/ngx-kit-drag-resize.mjs.map +1 -0
  24. package/fesm2022/ngx-kit-drawer-menu.mjs +389 -285
  25. package/fesm2022/ngx-kit-drawer-menu.mjs.map +1 -1
  26. package/fesm2022/ngx-kit-dropzone.mjs +2 -2
  27. package/fesm2022/ngx-kit-dropzone.mjs.map +1 -1
  28. package/fesm2022/ngx-kit-form-field.mjs +3 -5
  29. package/fesm2022/ngx-kit-form-field.mjs.map +1 -1
  30. package/fesm2022/ngx-kit-gallery.mjs +2 -2
  31. package/fesm2022/ngx-kit-gallery.mjs.map +1 -1
  32. package/fesm2022/ngx-kit-gradient-picker.mjs.map +1 -1
  33. package/fesm2022/ngx-kit-grid-layout.mjs +994 -0
  34. package/fesm2022/ngx-kit-grid-layout.mjs.map +1 -0
  35. package/fesm2022/ngx-kit-image-editor.mjs.map +1 -1
  36. package/fesm2022/ngx-kit-menu.mjs +8 -8
  37. package/fesm2022/ngx-kit-menu.mjs.map +1 -1
  38. package/fesm2022/ngx-kit-message.mjs.map +1 -1
  39. package/fesm2022/ngx-kit-notify.mjs +2 -2
  40. package/fesm2022/ngx-kit-notify.mjs.map +1 -1
  41. package/fesm2022/ngx-kit-shared.mjs +54 -3
  42. package/fesm2022/ngx-kit-shared.mjs.map +1 -1
  43. package/fesm2022/ngx-kit-time-picker.mjs +2 -2
  44. package/fesm2022/ngx-kit-time-picker.mjs.map +1 -1
  45. package/fesm2022/ngx-kit-virtual-scroll.mjs +392 -0
  46. package/fesm2022/ngx-kit-virtual-scroll.mjs.map +1 -0
  47. package/fesm2022/ngx-kit-webflow.mjs +709 -0
  48. package/fesm2022/ngx-kit-webflow.mjs.map +1 -0
  49. package/gallery/README.md +71 -71
  50. package/gradient-picker/README.md +41 -41
  51. package/grid-layout/README.md +64 -0
  52. package/image-editor/README.md +12 -12
  53. package/menu/README.md +85 -85
  54. package/message/README.md +70 -70
  55. package/notify/README.md +56 -58
  56. package/package.json +17 -1
  57. package/shared/README.md +117 -117
  58. package/time-picker/README.md +89 -95
  59. package/types/ngx-kit-color-picker.d.ts +72 -16
  60. package/types/ngx-kit-drag-resize.d.ts +368 -0
  61. package/types/ngx-kit-drawer-menu.d.ts +135 -86
  62. package/types/ngx-kit-grid-layout.d.ts +311 -0
  63. package/types/ngx-kit-image-editor.d.ts +1 -1
  64. package/types/ngx-kit-shared.d.ts +12 -1
  65. package/types/ngx-kit-virtual-scroll.d.ts +179 -0
  66. package/types/ngx-kit-webflow.d.ts +286 -0
  67. package/virtual-scroll/README.md +199 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-kit-time-picker.mjs","sources":["../../../projects/libs/time-picker/types/config.ts","../../../projects/libs/time-picker/utils/normalize.ts","../../../projects/libs/time-picker/components/time-picker/time-picker.ts","../../../projects/libs/time-picker/components/time-picker/time-picker.html","../../../projects/libs/time-picker/directives/time-picker.directive.ts","../../../projects/libs/time-picker/providers/provide-time-picker.ts","../../../projects/libs/time-picker/ngx-kit-time-picker.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\r\n\r\nexport class NgxTimePickerConfig {\r\n cancelButtonText: string = 'Cancel';\r\n confirmButtonText: string = 'Ok';\r\n amText: string = 'AM';\r\n pmText: string = 'PM';\r\n format: '12' | '24' = '12';\r\n minuteStep: number = 1;\r\n autoSwitchToMinute: boolean = true;\r\n}\r\n\r\nexport const DEFAULT_TIME_PICKER_CONFIG = new NgxTimePickerConfig();\r\nexport const NGX_TIME_PICKER_CONFIG = new InjectionToken<NgxTimePickerConfig>(\r\n 'ngx-time-picker-config',\r\n {\r\n factory: () => DEFAULT_TIME_PICKER_CONFIG,\r\n },\r\n);\r\n","export function normalizeTime(value: string): string | null {\r\n const match = value.match(/^(\\d{1,2}):(\\d{2})$/);\r\n\r\n if (!match) {\r\n return null;\r\n }\r\n\r\n const hour = Number(match[1]);\r\n const minute = Number(match[2]);\r\n\r\n if (hour < 0 || hour > 23 || minute < 0 || minute > 59) {\r\n return null;\r\n }\r\n\r\n return [hour.toString().padStart(2, '0'), minute.toString().padStart(2, '0')].join(':');\r\n}\r\n","import {\r\n Component,\r\n computed,\r\n ElementRef,\r\n EventEmitter,\r\n forwardRef,\r\n inject,\r\n input,\r\n model,\r\n OnInit,\r\n output,\r\n Output,\r\n signal,\r\n viewChild,\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { BrowserService } from 'ngx-kit/shared';\r\nimport {\r\n AbstractControl,\r\n ControlValueAccessor,\r\n NG_VALIDATORS,\r\n NG_VALUE_ACCESSOR,\r\n ValidationErrors,\r\n Validator,\r\n} from '@angular/forms';\r\nimport type { NgxTimePickerMode } from '../../types/mode';\r\nimport { NGX_TIME_PICKER_CONFIG } from '../../types/config';\r\nimport { normalizeTime } from '../../utils/normalize';\r\n\r\n@Component({\r\n selector: 'ngx-time-picker',\r\n templateUrl: './time-picker.html',\r\n styleUrls: ['./time-picker.scss'],\r\n imports: [CommonModule],\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => NgxInputTimePickerComponent),\r\n multi: true,\r\n },\r\n {\r\n provide: NG_VALIDATORS,\r\n useExisting: forwardRef(() => NgxInputTimePickerComponent),\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class NgxInputTimePickerComponent implements ControlValueAccessor, Validator, OnInit {\r\n protected readonly browserService = inject(BrowserService);\r\n\r\n readonly change = output<string | null>();\r\n readonly cancel = output<void>();\r\n\r\n protected readonly config = inject(NGX_TIME_PICKER_CONFIG);\r\n isDisabled = false;\r\n\r\n /**\r\n * Time value.\r\n *\r\n * Example:\r\n * 14:35\r\n */\r\n readonly value = model<string>('12:00');\r\n\r\n /**\r\n * 12h or 24h.\r\n */\r\n readonly format = input<'12' | '24'>(this.config.format);\r\n\r\n /**\r\n * Minute step.\r\n */\r\n readonly minuteStep = input(this.config.minuteStep);\r\n\r\n /**\r\n * Whether the clock is disabled.\r\n */\r\n readonly disabled = input(false);\r\n\r\n /**\r\n * Whether to automatically switch from hour to minute.\r\n */\r\n readonly autoSwitchToMinute = input<boolean>(this.config.autoSwitchToMinute);\r\n\r\n readonly clock = viewChild<ElementRef<SVGSVGElement>>('clock');\r\n\r\n readonly mode = signal<NgxTimePickerMode>('hour');\r\n\r\n private dragging = false;\r\n\r\n readonly parsedTime = computed(() => {\r\n const value = this.value();\r\n\r\n const [hour, minute] = value.split(':').map(Number);\r\n\r\n return {\r\n hour: Number.isFinite(hour) ? hour : 12,\r\n minute: Number.isFinite(minute) ? minute : 0,\r\n };\r\n });\r\n\r\n readonly displayHour = computed(() => {\r\n const { hour } = this.parsedTime();\r\n\r\n if (this.format() === '12') {\r\n const h = hour % 12;\r\n return h === 0 ? 12 : h;\r\n }\r\n\r\n return hour;\r\n });\r\n readonly isPm = computed(() => {\r\n const hour = Number(this.value().split(':')[0]);\r\n\r\n return hour >= 12;\r\n });\r\n readonly displayMinute = computed(() => {\r\n return this.parsedTime().minute;\r\n });\r\n\r\n readonly hourNumbers = computed(() => {\r\n if (this.format() === '24') {\r\n return Array.from({ length: 24 }, (_, i) => i);\r\n }\r\n\r\n return Array.from({ length: 12 }, (_, i) => i + 1);\r\n });\r\n\r\n readonly minuteNumbers = computed(() => {\r\n const step = Math.max(1, 5);\r\n\r\n const values: number[] = [];\r\n\r\n for (let i = 0; i < 60; i += step) {\r\n values.push(i);\r\n }\r\n\r\n return values;\r\n });\r\n\r\n readonly hourAngle = computed(() => {\r\n const { hour } = this.parsedTime();\r\n\r\n if (this.format() === '24') {\r\n /*\r\n * MUI-like 24 hour clock.\r\n *\r\n * 0 -> 0°\r\n * 6 -> 90°\r\n * 12 -> 180°\r\n * 18 -> 270°\r\n */\r\n return (hour % 12) * 30;\r\n }\r\n\r\n const h = hour % 12;\r\n\r\n return h * 30;\r\n });\r\n\r\n readonly minuteAngle = computed(() => {\r\n return this.parsedTime().minute * 6;\r\n });\r\n\r\n readonly currentAngle = computed(() => {\r\n return this.mode() === 'hour' ? this.hourAngle() : this.minuteAngle();\r\n });\r\n\r\n readonly handLength = computed(() => {\r\n if (this.mode() === 'hour' && this.format() === '24') {\r\n const hour = this.parsedTime().hour;\r\n\r\n if (hour >= 13 && hour <= 23) {\r\n return 58;\r\n }\r\n }\r\n\r\n return 86;\r\n });\r\n\r\n readonly hourRadius = computed(() => {\r\n if (this.mode() !== 'hour') {\r\n return 94;\r\n }\r\n\r\n if (this.format() !== '24') {\r\n return 94;\r\n }\r\n\r\n const hour = this.parsedTime().hour;\r\n\r\n // 00, 13..23 → inner ring\r\n if (hour === 0 || hour >= 13) {\r\n return 58;\r\n }\r\n\r\n // 01..12 → outer ring\r\n return 94;\r\n });\r\n readonly selectedPosition = computed(() => {\r\n const angle = this.currentAngle();\r\n\r\n const radians = ((angle - 90) * Math.PI) / 180;\r\n\r\n const radius = this.mode() === 'hour' ? this.hourRadius() : 94;\r\n\r\n return {\r\n x: 120 + Math.cos(radians) * radius,\r\n y: 120 + Math.sin(radians) * radius,\r\n };\r\n });\r\n readonly handEnd = computed(() => {\r\n const angle = this.currentAngle();\r\n\r\n const radians = ((angle - 90) * Math.PI) / 180;\r\n\r\n const radius = this.mode() === 'hour' ? this.hourRadius() : 94;\r\n\r\n return {\r\n x: 120 + Math.cos(radians) * radius,\r\n y: 120 + Math.sin(radians) * radius,\r\n };\r\n });\r\n\r\n protected _onChange = (value: string) => {};\r\n protected _onTouched = () => {};\r\n protected _validatorOnChange = () => {};\r\n constructor() {}\r\n\r\n ngOnInit(): void {}\r\n\r\n writeValue(value: string): void {\r\n if (!value) {\r\n this.value.set('12:00');\r\n return;\r\n }\r\n\r\n const normalized = normalizeTime(value);\r\n\r\n if (normalized === null) {\r\n // invalid value\r\n return;\r\n }\r\n\r\n this.value.set(normalized);\r\n }\r\n validate(control: AbstractControl): ValidationErrors | null {\r\n return null;\r\n }\r\n registerOnChange(fn: any): void {\r\n this._onChange = fn;\r\n }\r\n registerOnTouched(fn: any): void {\r\n this._onTouched = fn;\r\n }\r\n registerOnValidatorChange?(fn: () => void): void {\r\n this._validatorOnChange = fn;\r\n }\r\n setDisabledState(disabled: boolean): void {\r\n this.isDisabled = disabled;\r\n }\r\n\r\n startPointer(event: PointerEvent): void {\r\n if (this.disabled()) {\r\n return;\r\n }\r\n\r\n event.preventDefault();\r\n\r\n this.dragging = true;\r\n\r\n const target = event.currentTarget as HTMLElement;\r\n\r\n target.setPointerCapture?.(event.pointerId);\r\n\r\n this.updateFromPointer(event);\r\n }\r\n\r\n movePointer(event: PointerEvent): void {\r\n if (!this.dragging || this.disabled()) {\r\n return;\r\n }\r\n\r\n event.preventDefault();\r\n\r\n this.updateFromPointer(event);\r\n }\r\n\r\n endPointer(event: PointerEvent): void {\r\n if (!this.dragging) {\r\n return;\r\n }\r\n\r\n this.dragging = false;\r\n\r\n const target = event.currentTarget as HTMLElement;\r\n\r\n target.releasePointerCapture?.(event.pointerId);\r\n\r\n if (this.mode() === 'hour' && this.autoSwitchToMinute()) {\r\n this.mode.set('minute');\r\n }\r\n }\r\n\r\n selectHour(hour: number): void {\r\n if (this.disabled()) {\r\n return;\r\n }\r\n\r\n let normalizedHour = hour;\r\n\r\n if (this.format() === '12') {\r\n const currentHour = this.parsedTime().hour;\r\n\r\n const isPm = currentHour >= 12;\r\n\r\n normalizedHour = hour === 12 ? (isPm ? 12 : 0) : isPm ? hour + 12 : hour;\r\n }\r\n\r\n this.setTime(normalizedHour, this.parsedTime().minute);\r\n\r\n if (this.autoSwitchToMinute()) {\r\n this.mode.set('minute');\r\n }\r\n }\r\n\r\n selectMinute(minute: number): void {\r\n if (this.disabled()) {\r\n return;\r\n }\r\n\r\n this.setTime(this.parsedTime().hour, minute);\r\n }\r\n\r\n setMode(mode: NgxTimePickerMode): void {\r\n if (!this.disabled()) {\r\n this.mode.set(mode);\r\n }\r\n }\r\n\r\n private updateFromPointer(event: PointerEvent): void {\r\n const svg = this.clock()?.nativeElement;\r\n\r\n if (!svg) {\r\n return;\r\n }\r\n\r\n const rect = svg.getBoundingClientRect();\r\n\r\n const x = ((event.clientX - rect.left) / rect.width) * 240;\r\n\r\n const y = ((event.clientY - rect.top) / rect.height) * 240;\r\n\r\n if (this.mode() === 'hour') {\r\n this.updateHourFromPointer(x, y);\r\n return;\r\n }\r\n\r\n this.updateMinuteFromPointer(x, y);\r\n }\r\n\r\n private updateHourFromPointer(x: number, y: number): void {\r\n const dx = x - 120;\r\n const dy = y - 120;\r\n\r\n const distance = Math.sqrt(dx * dx + dy * dy);\r\n\r\n let angle = (Math.atan2(dy, dx) * 180) / Math.PI + 90;\r\n\r\n if (angle < 0) {\r\n angle += 360;\r\n }\r\n\r\n let hour = Math.round(angle / 30) % 12;\r\n\r\n if (this.format() === '12') {\r\n hour = hour === 0 ? 12 : hour;\r\n\r\n this.setTime(hour, this.parsedTime().minute);\r\n\r\n return;\r\n }\r\n\r\n /*\r\n * 24 hour mode\r\n *\r\n * Outer ring:\r\n * 1 ... 12\r\n *\r\n * Inner ring:\r\n * 13 ... 23, 00\r\n */\r\n const INNER_RING_THRESHOLD = 76;\r\n\r\n const isInnerRing = distance < INNER_RING_THRESHOLD;\r\n\r\n if (isInnerRing) {\r\n /*\r\n * Inner ring:\r\n *\r\n * 12 position -> 00\r\n * 1 position -> 13\r\n * 2 position -> 14\r\n * ...\r\n * 11 position -> 23\r\n */\r\n hour = hour === 0 ? 0 : hour + 12;\r\n } else {\r\n /*\r\n * Outer ring:\r\n *\r\n * 12 position -> 12\r\n * 1 ... 11 -> 1 ... 11\r\n */\r\n hour = hour === 0 ? 12 : hour;\r\n }\r\n\r\n this.setTime(hour, this.parsedTime().minute);\r\n }\r\n private updateMinuteFromPointer(x: number, y: number): void {\r\n const dx = x - 120;\r\n const dy = y - 120;\r\n\r\n let angle = (Math.atan2(dy, dx) * 180) / Math.PI + 90;\r\n\r\n if (angle < 0) {\r\n angle += 360;\r\n }\r\n\r\n let minute = Math.round(angle / 6);\r\n\r\n minute %= 60;\r\n\r\n const step = Math.max(1, this.minuteStep());\r\n\r\n minute = Math.round(minute / step) * step;\r\n\r\n if (minute >= 60) {\r\n minute = 0;\r\n }\r\n\r\n this.setTime(this.parsedTime().hour, minute);\r\n }\r\n\r\n private setTime(hour: number, minute: number): void {\r\n const h = String(hour).padStart(2, '0');\r\n const m = String(minute).padStart(2, '0');\r\n\r\n this.value.set(`${h}:${m}`);\r\n }\r\n\r\n formatHour(hour: number): string {\r\n if (this.format() === '24') {\r\n return String(hour).padStart(2, '0');\r\n }\r\n\r\n return String(hour);\r\n }\r\n\r\n formatMinute(minute: number): string {\r\n return String(minute).padStart(2, '0');\r\n }\r\n\r\n numberPosition(index: number, total: number, radius = 94): { x: number; y: number } {\r\n const angle = (index / total) * 360 - 90;\r\n\r\n const radians = (angle * Math.PI) / 180;\r\n\r\n return {\r\n x: 120 + Math.cos(radians) * radius,\r\n y: 120 + Math.sin(radians) * radius,\r\n };\r\n }\r\n\r\n hourPosition(hour: number, inner = false): { x: number; y: number } {\r\n const normalized = hour % 12;\r\n\r\n const angle = normalized * 30 - 90;\r\n\r\n const radians = (angle * Math.PI) / 180;\r\n\r\n const radius = inner ? 58 : 94;\r\n\r\n return {\r\n x: 120 + Math.cos(radians) * radius,\r\n y: 120 + Math.sin(radians) * radius,\r\n };\r\n }\r\n\r\n minutePosition(minute: number): {\r\n x: number;\r\n y: number;\r\n } {\r\n const angle = minute * 6 - 90;\r\n\r\n const radians = (angle * Math.PI) / 180;\r\n\r\n return {\r\n x: 120 + Math.cos(radians) * 94,\r\n y: 120 + Math.sin(radians) * 94,\r\n };\r\n }\r\n\r\n togglePmAm(val: 'AM' | 'PM'): void {\r\n const [hour, minute] = this.value().split(':').map(Number);\r\n\r\n let newHour = hour;\r\n\r\n if (val === 'AM') {\r\n // 12:xx PM → 00:xx\r\n if (hour >= 12) {\r\n newHour = hour - 12;\r\n }\r\n } else {\r\n // 00:xx AM → 12:xx PM\r\n if (hour < 12) {\r\n newHour = hour + 12;\r\n }\r\n }\r\n\r\n const value = `${String(newHour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`;\r\n\r\n this.value.set(value);\r\n }\r\n ok() {\r\n this.change.emit(this.value());\r\n this._onChange(this.value());\r\n }\r\n\r\n close() {\r\n this.cancel.emit();\r\n }\r\n}\r\n","<div class=\"ngx-time-picker\" [class.ngx-time-picker--disabled]=\"disabled()\">\r\n <!-- Header -->\r\n <div class=\"ngx-time-picker__header\">\r\n <button\r\n type=\"button\"\r\n class=\"ngx-time-picker__value\"\r\n [class.active]=\"mode() === 'hour'\"\r\n [disabled]=\"disabled()\"\r\n (click)=\"setMode('hour')\">\r\n {{ formatHour(displayHour()) }}\r\n </button>\r\n\r\n <span class=\"ngx-time-picker__separator\">:</span>\r\n\r\n <button\r\n type=\"button\"\r\n class=\"ngx-time-picker__value\"\r\n [class.active]=\"mode() === 'minute'\"\r\n [disabled]=\"disabled()\"\r\n (click)=\"setMode('minute')\">\r\n {{ formatMinute(displayMinute()) }}\r\n </button>\r\n\r\n @if (format() == '12') {\r\n <div class=\"ngx-time-picker_format\">\r\n <button [class.active]=\"!isPm()\" (click)=\"togglePmAm('AM')\">\r\n {{ config.amText }}\r\n </button>\r\n <button [class.active]=\"isPm()\" (click)=\"togglePmAm('PM')\">\r\n {{ config.pmText }}\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Clock -->\r\n <div class=\"ngx-time-picker__clock-wrapper\">\r\n <svg\r\n #clock\r\n class=\"ngx-time-picker__clock\"\r\n viewBox=\"0 0 240 240\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n (pointerdown)=\"startPointer($event)\"\r\n (pointermove)=\"movePointer($event)\"\r\n (pointerup)=\"endPointer($event)\"\r\n (pointercancel)=\"endPointer($event)\">\r\n <!-- Background -->\r\n <circle class=\"clock-background\" cx=\"120\" cy=\"120\" r=\"112\" />\r\n\r\n <!-- Selected hand line -->\r\n <line class=\"clock-hand\" x1=\"120\" y1=\"120\" [attr.x2]=\"handEnd().x\" [attr.y2]=\"handEnd().y\" />\r\n\r\n <!-- Selected circle -->\r\n <circle\r\n class=\"clock-selected\"\r\n [attr.cx]=\"selectedPosition().x\"\r\n [attr.cy]=\"selectedPosition().y\"\r\n r=\"18\" />\r\n\r\n <!-- Center -->\r\n <circle class=\"clock-center\" cx=\"120\" cy=\"120\" r=\"5\" />\r\n\r\n <!-- HOURS -->\r\n @if (mode() === 'hour') {\r\n @for (hour of hourNumbers(); track hour) {\r\n @if (format() === '24' && (hour >= 13 || hour == 0)) {\r\n <g class=\"clock-number clock-number--inner\" (click)=\"selectHour(hour)\">\r\n <circle\r\n [attr.cx]=\"hourPosition(hour - 12, true).x\"\r\n [attr.cy]=\"hourPosition(hour - 12, true).y\"\r\n r=\"16\" />\r\n\r\n <text\r\n [attr.x]=\"hourPosition(hour - 12, true).x\"\r\n [attr.y]=\"hourPosition(hour - 12, true).y\">\r\n {{ hour == 0 ? '00' : hour }}\r\n </text>\r\n </g>\r\n } @else {\r\n <g\r\n class=\"clock-number\"\r\n [class.selected]=\"displayHour() == hour\"\r\n (click)=\"selectHour(hour)\">\r\n <circle [attr.cx]=\"hourPosition(hour).x\" [attr.cy]=\"hourPosition(hour).y\" r=\"18\" />\r\n\r\n <text [attr.x]=\"hourPosition(hour).x\" [attr.y]=\"hourPosition(hour).y\">\r\n {{ hour }}\r\n </text>\r\n </g>\r\n }\r\n }\r\n }\r\n\r\n <!-- MINUTES -->\r\n @if (mode() === 'minute') {\r\n @for (minute of minuteNumbers(); track minute) {\r\n <g\r\n class=\"clock-number\"\r\n [class.selected]=\"displayMinute() == minute\"\r\n (click)=\"selectMinute(minute)\">\r\n <circle\r\n [attr.cx]=\"minutePosition(minute).x\"\r\n [attr.cy]=\"minutePosition(minute).y\"\r\n r=\"18\" />\r\n\r\n <text [attr.x]=\"minutePosition(minute).x\" [attr.y]=\"minutePosition(minute).y\">\r\n {{ formatMinute(minute) }}\r\n </text>\r\n </g>\r\n }\r\n }\r\n </svg>\r\n </div>\r\n <div class=\"ngx-time-picker--footer\">\r\n <button (click)=\"close()\">\r\n {{ config.cancelButtonText }}\r\n </button>\r\n\r\n <button (click)=\"ok()\">\r\n {{ config.confirmButtonText }}\r\n </button>\r\n </div>\r\n</div>\r\n","import {\r\n Directive,\r\n ElementRef,\r\n EventEmitter,\r\n forwardRef,\r\n HostListener,\r\n inject,\r\n input,\r\n model,\r\n output,\r\n Output,\r\n Renderer2,\r\n signal,\r\n ViewContainerRef,\r\n} from '@angular/core';\r\nimport {\r\n AbstractControl,\r\n ControlValueAccessor,\r\n NG_VALIDATORS,\r\n NG_VALUE_ACCESSOR,\r\n ValidationErrors,\r\n Validator,\r\n} from '@angular/forms';\r\nimport { OverlayRef, OverlayService } from 'ngx-kit/shared';\r\nimport { NgxInputTimePickerComponent } from '../components/time-picker/time-picker';\r\nimport { NGX_TIME_PICKER_CONFIG } from '../types/config';\r\nimport { normalizeTime } from '../utils/normalize';\r\n\r\n@Directive({\r\n selector: '[ngxInputTimePicker]',\r\n exportAs: 'ngxInputTimePicker',\r\n host: {\r\n class: 'ngx-datepicker-input',\r\n '[attr.readOnly]': 'true',\r\n },\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => NgxInputTimePicker),\r\n multi: true,\r\n },\r\n {\r\n provide: NG_VALIDATORS,\r\n useExisting: forwardRef(() => NgxInputTimePicker),\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class NgxInputTimePicker implements ControlValueAccessor, Validator {\r\n protected readonly config = inject(NGX_TIME_PICKER_CONFIG);\r\n\r\n openOnCLick = input<boolean>(true);\r\n\r\n readonly change = output<string | null>();\r\n protected readonly value = signal<string>('');\r\n\r\n readonly format = input<'12' | '24'>(this.config.format);\r\n\r\n private pickerRef?: OverlayRef<NgxInputTimePickerComponent>;\r\n\r\n protected _onChange = (value: string | null | undefined) => {};\r\n protected _onTouched = () => {};\r\n protected _validatorOnChange = () => {};\r\n\r\n private isDisabled = false;\r\n\r\n private readonly overlayService = inject(OverlayService);\r\n private readonly viewContainerRef = inject(ViewContainerRef);\r\n private readonly renderer = inject(Renderer2);\r\n constructor(private el: ElementRef<HTMLInputElement>) {}\r\n\r\n ngOnDestroy(): void {\r\n this.destroy();\r\n }\r\n\r\n @HostListener('click', ['$event'])\r\n onClick(ev: Event) {\r\n if (this.openOnCLick() && !this.isDisabled) {\r\n ev.stopPropagation();\r\n ev.preventDefault();\r\n this.toggle();\r\n }\r\n }\r\n\r\n @HostListener('input', ['$event'])\r\n onInput(event: Event) {\r\n const input = event.target as HTMLInputElement;\r\n this.value.set(input.value ?? '');\r\n this._formatValue();\r\n this._onChange(this.value());\r\n }\r\n\r\n @HostListener('blur')\r\n onBlur() {\r\n this._onTouched();\r\n }\r\n\r\n writeValue(value: string): void {\r\n this.value.set(value);\r\n this._formatValue();\r\n }\r\n\r\n registerOnChange(fn: any): void {\r\n this._onChange = fn;\r\n }\r\n registerOnTouched(fn: any): void {\r\n this._onTouched = fn;\r\n }\r\n registerOnValidatorChange?(fn: () => void): void {\r\n this._validatorOnChange = fn;\r\n }\r\n setDisabledState(disabled: boolean): void {\r\n this.isDisabled = disabled;\r\n if (disabled) {\r\n this.renderer.setProperty(this.el.nativeElement, 'disabled', disabled);\r\n } else {\r\n this.renderer.removeAttribute(this.el.nativeElement, 'disabled');\r\n }\r\n }\r\n\r\n public toggle() {\r\n if (this.pickerRef || this.isDisabled) {\r\n this.destroy();\r\n return;\r\n }\r\n\r\n this.pickerRef = this.overlayService.open({\r\n anchor: this.el.nativeElement,\r\n component: NgxInputTimePickerComponent,\r\n viewContainerRef: this.viewContainerRef,\r\n alignment: 'center',\r\n placement: 'bottom',\r\n margin: 2,\r\n configure: (instance, ref) => {\r\n instance.writeValue(this.value());\r\n\r\n instance.change.subscribe((c: string | null) => {\r\n this.value.set(c ?? '');\r\n this.emitChange();\r\n this.destroy();\r\n });\r\n\r\n instance.cancel.subscribe(() => ref.close());\r\n },\r\n onClosed: () => {\r\n this.pickerRef = undefined;\r\n },\r\n });\r\n }\r\n\r\n private destroy() {\r\n this.pickerRef?.close();\r\n this.pickerRef = undefined;\r\n }\r\n private async emitChange() {\r\n this._onChange(this.value());\r\n this._formatValue();\r\n this.change.emit(this.value());\r\n this._onTouched();\r\n }\r\n\r\n validate(control: AbstractControl): ValidationErrors | null {\r\n const raw = this.value();\r\n if (!raw) return null; // empty is handled by Validators.required, not us\r\n return normalizeTime(raw) === null ? { invalid: true } : null;\r\n }\r\n\r\n protected _formatValue() {\r\n this.renderer.setProperty(this.el.nativeElement, 'value', this.value());\r\n }\r\n}\r\n","import { Provider } from '@angular/core';\r\nimport {\r\n DEFAULT_TIME_PICKER_CONFIG,\r\n NGX_TIME_PICKER_CONFIG,\r\n type NgxTimePickerConfig,\r\n} from '../types/config';\r\n\r\nexport function provideTimePicker(config: Partial<NgxTimePickerConfig>): Provider[] {\r\n const configuration = { ...DEFAULT_TIME_PICKER_CONFIG, ...config };\r\n return [\r\n {\r\n provide: NGX_TIME_PICKER_CONFIG,\r\n useValue: configuration,\r\n },\r\n ];\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":"ngx-kit-time-picker.mjs","sources":["../../../projects/libs/time-picker/types/config.ts","../../../projects/libs/time-picker/utils/normalize.ts","../../../projects/libs/time-picker/components/time-picker/time-picker.ts","../../../projects/libs/time-picker/components/time-picker/time-picker.html","../../../projects/libs/time-picker/directives/time-picker.directive.ts","../../../projects/libs/time-picker/providers/provide-time-picker.ts","../../../projects/libs/time-picker/ngx-kit-time-picker.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\nexport class NgxTimePickerConfig {\n cancelButtonText: string = 'Cancel';\n confirmButtonText: string = 'Ok';\n amText: string = 'AM';\n pmText: string = 'PM';\n format: '12' | '24' = '12';\n minuteStep: number = 1;\n autoSwitchToMinute: boolean = true;\n}\n\nexport const DEFAULT_TIME_PICKER_CONFIG = new NgxTimePickerConfig();\nexport const NGX_TIME_PICKER_CONFIG = new InjectionToken<NgxTimePickerConfig>(\n 'ngx-time-picker-config',\n {\n factory: () => DEFAULT_TIME_PICKER_CONFIG,\n },\n);\n","export function normalizeTime(value: string): string | null {\n const match = value.match(/^(\\d{1,2}):(\\d{2})$/);\n\n if (!match) {\n return null;\n }\n\n const hour = Number(match[1]);\n const minute = Number(match[2]);\n\n if (hour < 0 || hour > 23 || minute < 0 || minute > 59) {\n return null;\n }\n\n return [hour.toString().padStart(2, '0'), minute.toString().padStart(2, '0')].join(':');\n}\n","import {\n Component,\n computed,\n ElementRef,\n EventEmitter,\n forwardRef,\n inject,\n input,\n model,\n OnInit,\n output,\n Output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { BrowserService } from 'ngx-kit/shared';\nimport {\n AbstractControl,\n ControlValueAccessor,\n NG_VALIDATORS,\n NG_VALUE_ACCESSOR,\n ValidationErrors,\n Validator,\n} from '@angular/forms';\nimport type { NgxTimePickerMode } from '../../types/mode';\nimport { NGX_TIME_PICKER_CONFIG } from '../../types/config';\nimport { normalizeTime } from '../../utils/normalize';\n\n@Component({\n selector: 'ngx-time-picker',\n templateUrl: './time-picker.html',\n styleUrls: ['./time-picker.scss'],\n imports: [CommonModule],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NgxInputTimePickerComponent),\n multi: true,\n },\n {\n provide: NG_VALIDATORS,\n useExisting: forwardRef(() => NgxInputTimePickerComponent),\n multi: true,\n },\n ],\n})\nexport class NgxInputTimePickerComponent implements ControlValueAccessor, Validator, OnInit {\n protected readonly browserService = inject(BrowserService);\n\n readonly change = output<string | null>();\n readonly cancel = output<void>();\n\n protected readonly config = inject(NGX_TIME_PICKER_CONFIG);\n isDisabled = false;\n\n /**\n * Time value.\n *\n * Example:\n * 14:35\n */\n readonly value = model<string>('12:00');\n\n /**\n * 12h or 24h.\n */\n readonly format = input<'12' | '24'>(this.config.format);\n\n /**\n * Minute step.\n */\n readonly minuteStep = input(this.config.minuteStep);\n\n /**\n * Whether the clock is disabled.\n */\n readonly disabled = input(false);\n\n /**\n * Whether to automatically switch from hour to minute.\n */\n readonly autoSwitchToMinute = input<boolean>(this.config.autoSwitchToMinute);\n\n readonly clock = viewChild<ElementRef<SVGSVGElement>>('clock');\n\n readonly mode = signal<NgxTimePickerMode>('hour');\n\n private dragging = false;\n\n readonly parsedTime = computed(() => {\n const value = this.value();\n\n const [hour, minute] = value.split(':').map(Number);\n\n return {\n hour: Number.isFinite(hour) ? hour : 12,\n minute: Number.isFinite(minute) ? minute : 0,\n };\n });\n\n readonly displayHour = computed(() => {\n const { hour } = this.parsedTime();\n\n if (this.format() === '12') {\n const h = hour % 12;\n return h === 0 ? 12 : h;\n }\n\n return hour;\n });\n readonly isPm = computed(() => {\n const hour = Number(this.value().split(':')[0]);\n\n return hour >= 12;\n });\n readonly displayMinute = computed(() => {\n return this.parsedTime().minute;\n });\n\n readonly hourNumbers = computed(() => {\n if (this.format() === '24') {\n return Array.from({ length: 24 }, (_, i) => i);\n }\n\n return Array.from({ length: 12 }, (_, i) => i + 1);\n });\n\n readonly minuteNumbers = computed(() => {\n const step = Math.max(1, 5);\n\n const values: number[] = [];\n\n for (let i = 0; i < 60; i += step) {\n values.push(i);\n }\n\n return values;\n });\n\n readonly hourAngle = computed(() => {\n const { hour } = this.parsedTime();\n\n if (this.format() === '24') {\n /*\n * MUI-like 24 hour clock.\n *\n * 0 -> 0°\n * 6 -> 90°\n * 12 -> 180°\n * 18 -> 270°\n */\n return (hour % 12) * 30;\n }\n\n const h = hour % 12;\n\n return h * 30;\n });\n\n readonly minuteAngle = computed(() => {\n return this.parsedTime().minute * 6;\n });\n\n readonly currentAngle = computed(() => {\n return this.mode() === 'hour' ? this.hourAngle() : this.minuteAngle();\n });\n\n readonly handLength = computed(() => {\n if (this.mode() === 'hour' && this.format() === '24') {\n const hour = this.parsedTime().hour;\n\n if (hour >= 13 && hour <= 23) {\n return 58;\n }\n }\n\n return 86;\n });\n\n readonly hourRadius = computed(() => {\n if (this.mode() !== 'hour') {\n return 94;\n }\n\n if (this.format() !== '24') {\n return 94;\n }\n\n const hour = this.parsedTime().hour;\n\n // 00, 13..23 → inner ring\n if (hour === 0 || hour >= 13) {\n return 58;\n }\n\n // 01..12 → outer ring\n return 94;\n });\n readonly selectedPosition = computed(() => {\n const angle = this.currentAngle();\n\n const radians = ((angle - 90) * Math.PI) / 180;\n\n const radius = this.mode() === 'hour' ? this.hourRadius() : 94;\n\n return {\n x: 120 + Math.cos(radians) * radius,\n y: 120 + Math.sin(radians) * radius,\n };\n });\n readonly handEnd = computed(() => {\n const angle = this.currentAngle();\n\n const radians = ((angle - 90) * Math.PI) / 180;\n\n const radius = this.mode() === 'hour' ? this.hourRadius() : 94;\n\n return {\n x: 120 + Math.cos(radians) * radius,\n y: 120 + Math.sin(radians) * radius,\n };\n });\n\n protected _onChange = (value: string) => {};\n protected _onTouched = () => {};\n protected _validatorOnChange = () => {};\n constructor() {}\n\n ngOnInit(): void {}\n\n writeValue(value: string): void {\n if (!value) {\n this.value.set('12:00');\n return;\n }\n\n const normalized = normalizeTime(value);\n\n if (normalized === null) {\n // invalid value\n return;\n }\n\n this.value.set(normalized);\n }\n validate(control: AbstractControl): ValidationErrors | null {\n return null;\n }\n registerOnChange(fn: any): void {\n this._onChange = fn;\n }\n registerOnTouched(fn: any): void {\n this._onTouched = fn;\n }\n registerOnValidatorChange?(fn: () => void): void {\n this._validatorOnChange = fn;\n }\n setDisabledState(disabled: boolean): void {\n this.isDisabled = disabled;\n }\n\n startPointer(event: PointerEvent): void {\n if (this.disabled()) {\n return;\n }\n\n event.preventDefault();\n\n this.dragging = true;\n\n const target = event.currentTarget as HTMLElement;\n\n target.setPointerCapture?.(event.pointerId);\n\n this.updateFromPointer(event);\n }\n\n movePointer(event: PointerEvent): void {\n if (!this.dragging || this.disabled()) {\n return;\n }\n\n event.preventDefault();\n\n this.updateFromPointer(event);\n }\n\n endPointer(event: PointerEvent): void {\n if (!this.dragging) {\n return;\n }\n\n this.dragging = false;\n\n const target = event.currentTarget as HTMLElement;\n\n target.releasePointerCapture?.(event.pointerId);\n\n if (this.mode() === 'hour' && this.autoSwitchToMinute()) {\n this.mode.set('minute');\n }\n }\n\n selectHour(hour: number): void {\n if (this.disabled()) {\n return;\n }\n\n let normalizedHour = hour;\n\n if (this.format() === '12') {\n const currentHour = this.parsedTime().hour;\n\n const isPm = currentHour >= 12;\n\n normalizedHour = hour === 12 ? (isPm ? 12 : 0) : isPm ? hour + 12 : hour;\n }\n\n this.setTime(normalizedHour, this.parsedTime().minute);\n\n if (this.autoSwitchToMinute()) {\n this.mode.set('minute');\n }\n }\n\n selectMinute(minute: number): void {\n if (this.disabled()) {\n return;\n }\n\n this.setTime(this.parsedTime().hour, minute);\n }\n\n setMode(mode: NgxTimePickerMode): void {\n if (!this.disabled()) {\n this.mode.set(mode);\n }\n }\n\n private updateFromPointer(event: PointerEvent): void {\n const svg = this.clock()?.nativeElement;\n\n if (!svg) {\n return;\n }\n\n const rect = svg.getBoundingClientRect();\n\n const x = ((event.clientX - rect.left) / rect.width) * 240;\n\n const y = ((event.clientY - rect.top) / rect.height) * 240;\n\n if (this.mode() === 'hour') {\n this.updateHourFromPointer(x, y);\n return;\n }\n\n this.updateMinuteFromPointer(x, y);\n }\n\n private updateHourFromPointer(x: number, y: number): void {\n const dx = x - 120;\n const dy = y - 120;\n\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n let angle = (Math.atan2(dy, dx) * 180) / Math.PI + 90;\n\n if (angle < 0) {\n angle += 360;\n }\n\n let hour = Math.round(angle / 30) % 12;\n\n if (this.format() === '12') {\n hour = hour === 0 ? 12 : hour;\n\n this.setTime(hour, this.parsedTime().minute);\n\n return;\n }\n\n /*\n * 24 hour mode\n *\n * Outer ring:\n * 1 ... 12\n *\n * Inner ring:\n * 13 ... 23, 00\n */\n const INNER_RING_THRESHOLD = 76;\n\n const isInnerRing = distance < INNER_RING_THRESHOLD;\n\n if (isInnerRing) {\n /*\n * Inner ring:\n *\n * 12 position -> 00\n * 1 position -> 13\n * 2 position -> 14\n * ...\n * 11 position -> 23\n */\n hour = hour === 0 ? 0 : hour + 12;\n } else {\n /*\n * Outer ring:\n *\n * 12 position -> 12\n * 1 ... 11 -> 1 ... 11\n */\n hour = hour === 0 ? 12 : hour;\n }\n\n this.setTime(hour, this.parsedTime().minute);\n }\n private updateMinuteFromPointer(x: number, y: number): void {\n const dx = x - 120;\n const dy = y - 120;\n\n let angle = (Math.atan2(dy, dx) * 180) / Math.PI + 90;\n\n if (angle < 0) {\n angle += 360;\n }\n\n let minute = Math.round(angle / 6);\n\n minute %= 60;\n\n const step = Math.max(1, this.minuteStep());\n\n minute = Math.round(minute / step) * step;\n\n if (minute >= 60) {\n minute = 0;\n }\n\n this.setTime(this.parsedTime().hour, minute);\n }\n\n private setTime(hour: number, minute: number): void {\n const h = String(hour).padStart(2, '0');\n const m = String(minute).padStart(2, '0');\n\n this.value.set(`${h}:${m}`);\n }\n\n formatHour(hour: number): string {\n if (this.format() === '24') {\n return String(hour).padStart(2, '0');\n }\n\n return String(hour);\n }\n\n formatMinute(minute: number): string {\n return String(minute).padStart(2, '0');\n }\n\n numberPosition(index: number, total: number, radius = 94): { x: number; y: number } {\n const angle = (index / total) * 360 - 90;\n\n const radians = (angle * Math.PI) / 180;\n\n return {\n x: 120 + Math.cos(radians) * radius,\n y: 120 + Math.sin(radians) * radius,\n };\n }\n\n hourPosition(hour: number, inner = false): { x: number; y: number } {\n const normalized = hour % 12;\n\n const angle = normalized * 30 - 90;\n\n const radians = (angle * Math.PI) / 180;\n\n const radius = inner ? 58 : 94;\n\n return {\n x: 120 + Math.cos(radians) * radius,\n y: 120 + Math.sin(radians) * radius,\n };\n }\n\n minutePosition(minute: number): {\n x: number;\n y: number;\n } {\n const angle = minute * 6 - 90;\n\n const radians = (angle * Math.PI) / 180;\n\n return {\n x: 120 + Math.cos(radians) * 94,\n y: 120 + Math.sin(radians) * 94,\n };\n }\n\n togglePmAm(val: 'AM' | 'PM'): void {\n const [hour, minute] = this.value().split(':').map(Number);\n\n let newHour = hour;\n\n if (val === 'AM') {\n // 12:xx PM → 00:xx\n if (hour >= 12) {\n newHour = hour - 12;\n }\n } else {\n // 00:xx AM → 12:xx PM\n if (hour < 12) {\n newHour = hour + 12;\n }\n }\n\n const value = `${String(newHour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`;\n\n this.value.set(value);\n }\n ok() {\n this.change.emit(this.value());\n this._onChange(this.value());\n }\n\n close() {\n this.cancel.emit();\n }\n}\n","<div class=\"ngx-time-picker\" [class.ngx-time-picker--disabled]=\"disabled()\">\n <!-- Header -->\n <div class=\"ngx-time-picker__header\">\n <button\n type=\"button\"\n class=\"ngx-time-picker__value\"\n [class.active]=\"mode() === 'hour'\"\n [disabled]=\"disabled()\"\n (click)=\"setMode('hour')\">\n {{ formatHour(displayHour()) }}\n </button>\n\n <span class=\"ngx-time-picker__separator\">:</span>\n\n <button\n type=\"button\"\n class=\"ngx-time-picker__value\"\n [class.active]=\"mode() === 'minute'\"\n [disabled]=\"disabled()\"\n (click)=\"setMode('minute')\">\n {{ formatMinute(displayMinute()) }}\n </button>\n\n @if (format() == '12') {\n <div class=\"ngx-time-picker_format\">\n <button [class.active]=\"!isPm()\" (click)=\"togglePmAm('AM')\">\n {{ config.amText }}\n </button>\n <button [class.active]=\"isPm()\" (click)=\"togglePmAm('PM')\">\n {{ config.pmText }}\n </button>\n </div>\n }\n </div>\n\n <!-- Clock -->\n <div class=\"ngx-time-picker__clock-wrapper\">\n <svg\n #clock\n class=\"ngx-time-picker__clock\"\n viewBox=\"0 0 240 240\"\n xmlns=\"http://www.w3.org/2000/svg\"\n (pointerdown)=\"startPointer($event)\"\n (pointermove)=\"movePointer($event)\"\n (pointerup)=\"endPointer($event)\"\n (pointercancel)=\"endPointer($event)\">\n <!-- Background -->\n <circle class=\"clock-background\" cx=\"120\" cy=\"120\" r=\"112\" />\n\n <!-- Selected hand line -->\n <line class=\"clock-hand\" x1=\"120\" y1=\"120\" [attr.x2]=\"handEnd().x\" [attr.y2]=\"handEnd().y\" />\n\n <!-- Selected circle -->\n <circle\n class=\"clock-selected\"\n [attr.cx]=\"selectedPosition().x\"\n [attr.cy]=\"selectedPosition().y\"\n r=\"18\" />\n\n <!-- Center -->\n <circle class=\"clock-center\" cx=\"120\" cy=\"120\" r=\"5\" />\n\n <!-- HOURS -->\n @if (mode() === 'hour') {\n @for (hour of hourNumbers(); track hour) {\n @if (format() === '24' && (hour >= 13 || hour == 0)) {\n <g class=\"clock-number clock-number--inner\" (click)=\"selectHour(hour)\">\n <circle\n [attr.cx]=\"hourPosition(hour - 12, true).x\"\n [attr.cy]=\"hourPosition(hour - 12, true).y\"\n r=\"16\" />\n\n <text\n [attr.x]=\"hourPosition(hour - 12, true).x\"\n [attr.y]=\"hourPosition(hour - 12, true).y\">\n {{ hour == 0 ? '00' : hour }}\n </text>\n </g>\n } @else {\n <g\n class=\"clock-number\"\n [class.selected]=\"displayHour() == hour\"\n (click)=\"selectHour(hour)\">\n <circle [attr.cx]=\"hourPosition(hour).x\" [attr.cy]=\"hourPosition(hour).y\" r=\"18\" />\n\n <text [attr.x]=\"hourPosition(hour).x\" [attr.y]=\"hourPosition(hour).y\">\n {{ hour }}\n </text>\n </g>\n }\n }\n }\n\n <!-- MINUTES -->\n @if (mode() === 'minute') {\n @for (minute of minuteNumbers(); track minute) {\n <g\n class=\"clock-number\"\n [class.selected]=\"displayMinute() == minute\"\n (click)=\"selectMinute(minute)\">\n <circle\n [attr.cx]=\"minutePosition(minute).x\"\n [attr.cy]=\"minutePosition(minute).y\"\n r=\"18\" />\n\n <text [attr.x]=\"minutePosition(minute).x\" [attr.y]=\"minutePosition(minute).y\">\n {{ formatMinute(minute) }}\n </text>\n </g>\n }\n }\n </svg>\n </div>\n <div class=\"ngx-time-picker--footer\">\n <button (click)=\"close()\">\n {{ config.cancelButtonText }}\n </button>\n\n <button (click)=\"ok()\">\n {{ config.confirmButtonText }}\n </button>\n </div>\n</div>\n","import {\n Directive,\n ElementRef,\n EventEmitter,\n forwardRef,\n HostListener,\n inject,\n input,\n model,\n output,\n Output,\n Renderer2,\n signal,\n ViewContainerRef,\n} from '@angular/core';\nimport {\n AbstractControl,\n ControlValueAccessor,\n NG_VALIDATORS,\n NG_VALUE_ACCESSOR,\n ValidationErrors,\n Validator,\n} from '@angular/forms';\nimport { OverlayRef, OverlayService } from 'ngx-kit/shared';\nimport { NgxInputTimePickerComponent } from '../components/time-picker/time-picker';\nimport { NGX_TIME_PICKER_CONFIG } from '../types/config';\nimport { normalizeTime } from '../utils/normalize';\n\n@Directive({\n selector: '[ngxInputTimePicker]',\n exportAs: 'ngxInputTimePicker',\n host: {\n class: 'ngx-datepicker-input',\n '[attr.readOnly]': 'true',\n },\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NgxInputTimePicker),\n multi: true,\n },\n {\n provide: NG_VALIDATORS,\n useExisting: forwardRef(() => NgxInputTimePicker),\n multi: true,\n },\n ],\n})\nexport class NgxInputTimePicker implements ControlValueAccessor, Validator {\n protected readonly config = inject(NGX_TIME_PICKER_CONFIG);\n\n openOnCLick = input<boolean>(true);\n\n readonly change = output<string | null>();\n protected readonly value = signal<string>('');\n\n readonly format = input<'12' | '24'>(this.config.format);\n\n private pickerRef?: OverlayRef<NgxInputTimePickerComponent>;\n\n protected _onChange = (value: string | null | undefined) => {};\n protected _onTouched = () => {};\n protected _validatorOnChange = () => {};\n\n private isDisabled = false;\n\n private readonly overlayService = inject(OverlayService);\n private readonly viewContainerRef = inject(ViewContainerRef);\n private readonly renderer = inject(Renderer2);\n constructor(private el: ElementRef<HTMLInputElement>) {}\n\n ngOnDestroy(): void {\n this.destroy();\n }\n\n @HostListener('click', ['$event'])\n onClick(ev: Event) {\n if (this.openOnCLick() && !this.isDisabled) {\n ev.stopPropagation();\n ev.preventDefault();\n this.toggle();\n }\n }\n\n @HostListener('input', ['$event'])\n onInput(event: Event) {\n const input = event.target as HTMLInputElement;\n this.value.set(input.value ?? '');\n this._formatValue();\n this._onChange(this.value());\n }\n\n @HostListener('blur')\n onBlur() {\n this._onTouched();\n }\n\n writeValue(value: string): void {\n this.value.set(value);\n this._formatValue();\n }\n\n registerOnChange(fn: any): void {\n this._onChange = fn;\n }\n registerOnTouched(fn: any): void {\n this._onTouched = fn;\n }\n registerOnValidatorChange?(fn: () => void): void {\n this._validatorOnChange = fn;\n }\n setDisabledState(disabled: boolean): void {\n this.isDisabled = disabled;\n if (disabled) {\n this.renderer.setProperty(this.el.nativeElement, 'disabled', disabled);\n } else {\n this.renderer.removeAttribute(this.el.nativeElement, 'disabled');\n }\n }\n\n public toggle() {\n if (this.pickerRef || this.isDisabled) {\n this.destroy();\n return;\n }\n\n this.pickerRef = this.overlayService.open({\n anchor: this.el.nativeElement,\n component: NgxInputTimePickerComponent,\n viewContainerRef: this.viewContainerRef,\n alignment: 'center',\n placement: 'bottom',\n margin: 2,\n configure: (instance, ref) => {\n instance.writeValue(this.value());\n\n instance.change.subscribe((c: string | null) => {\n this.value.set(c ?? '');\n this.emitChange();\n this.destroy();\n });\n\n instance.cancel.subscribe(() => ref.close());\n },\n onClosed: () => {\n this.pickerRef = undefined;\n },\n });\n }\n\n private destroy() {\n this.pickerRef?.close();\n this.pickerRef = undefined;\n }\n private async emitChange() {\n this._onChange(this.value());\n this._formatValue();\n this.change.emit(this.value());\n this._onTouched();\n }\n\n validate(control: AbstractControl): ValidationErrors | null {\n const raw = this.value();\n if (!raw) return null; // empty is handled by Validators.required, not us\n return normalizeTime(raw) === null ? { invalid: true } : null;\n }\n\n protected _formatValue() {\n this.renderer.setProperty(this.el.nativeElement, 'value', this.value());\n }\n}\n","import { Provider } from '@angular/core';\nimport {\n DEFAULT_TIME_PICKER_CONFIG,\n NGX_TIME_PICKER_CONFIG,\n type NgxTimePickerConfig,\n} from '../types/config';\n\nexport function provideTimePicker(config: Partial<NgxTimePickerConfig>): Provider[] {\n const configuration = { ...DEFAULT_TIME_PICKER_CONFIG, ...config };\n return [\n {\n provide: NGX_TIME_PICKER_CONFIG,\n useValue: configuration,\n },\n ];\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,392 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, output, viewChild, inject, DestroyRef, signal, computed, effect, afterRenderEffect, untracked, afterNextRender, ChangeDetectionStrategy, Component } from '@angular/core';
3
+
4
+ function rangesEqual(a, b) {
5
+ return a.start === b.start && a.end === b.end;
6
+ }
7
+
8
+ const TOP_TOLERANCE_PX = 0.5;
9
+ /**
10
+ * Pure, framework-agnostic layout probe.
11
+ *
12
+ * Reads the real bounding boxes of a small batch of already-rendered
13
+ * elements and infers, purely from actual layout:
14
+ * - the scroll axis (vertical vs horizontal)
15
+ * - how many items share a single line (1 for a plain list, N for a
16
+ * wrapping grid)
17
+ * - the real size of one line, INCLUDING margins/border/box-shadow,
18
+ * because it is derived from the delta between two real sibling
19
+ * positions in normal document flow rather than from a hardcoded
20
+ * itemSize input.
21
+ *
22
+ * No orientation/itemSize is ever supplied by the consumer — this is the
23
+ * single source of truth for both.
24
+ */
25
+ function measureLayout(probeElements) {
26
+ if (probeElements.length === 0) {
27
+ return null;
28
+ }
29
+ const rects = probeElements.map((el) => el.getBoundingClientRect());
30
+ if (rects.length === 1) {
31
+ // Not enough siblings to infer direction yet; assume a vertical list
32
+ // (the overwhelmingly common case) using the element's own height.
33
+ return { axis: 'vertical', crossCount: 1, lineSize: Math.max(rects[0].height, 1) };
34
+ }
35
+ const first = rects[0];
36
+ // Find the first probed item that starts a new line (its top differs
37
+ // meaningfully from the first item's top).
38
+ let wrapIndex = -1;
39
+ for (let i = 1; i < rects.length; i++) {
40
+ if (Math.abs(rects[i].top - first.top) > TOP_TOLERANCE_PX) {
41
+ wrapIndex = i;
42
+ break;
43
+ }
44
+ }
45
+ if (wrapIndex === -1) {
46
+ // Every probed item shares the same line -> a single horizontal line.
47
+ const lineSize = rects[1].left - first.left;
48
+ return { axis: 'horizontal', crossCount: 1, lineSize: Math.max(lineSize, 1) };
49
+ }
50
+ if (wrapIndex === 1) {
51
+ // The very next item is already on a new line -> a plain vertical list.
52
+ const lineSize = rects[1].top - first.top;
53
+ return { axis: 'vertical', crossCount: 1, lineSize: Math.max(lineSize, 1) };
54
+ }
55
+ // Several items share the first line before wrapping -> a wrapping grid.
56
+ const crossCount = wrapIndex;
57
+ const lineSize = rects[wrapIndex].top - first.top;
58
+ return { axis: 'vertical', crossCount, lineSize: Math.max(lineSize, 1) };
59
+ }
60
+
61
+ /** How many items are rendered "in the open" (no transform) purely to probe their real layout. */
62
+ const PROBE_COUNT = 24;
63
+ /**
64
+ * Browsers clamp any single element's CSS width/height (and therefore
65
+ * `scrollWidth`/`scrollHeight`) to a hard maximum — roughly 33,554,428px in
66
+ * Chromium and considerably less in older WebKit (historically ~8,388,608px)
67
+ * and Gecko (~17,895,697px). Once the spacer element (used purely to give
68
+ * the native scrollbar the right size) exceeds that ceiling, the browser
69
+ * silently clamps it, the scrollbar stops early, and everything past that
70
+ * point becomes unreachable — exactly the "stuck around 524k rows" symptom.
71
+ *
72
+ * To support arbitrarily large data sets we cap the spacer at this safe
73
+ * ceiling and scroll the DOM in a *compressed* coordinate space, while all
74
+ * index math still happens against the real, uncompressed pixel space (see
75
+ * `scaleFactor`). Kept conservative (well under every known browser cap) so
76
+ * it works everywhere without per-browser detection.
77
+ */
78
+ const DEFAULT_MAX_AXIS_SIZE_PX = 6_000_000;
79
+ /**
80
+ * Headless, signal-based virtual scroll viewport.
81
+ *
82
+ * There is no `itemSize` and no `orientation` input by design: both are
83
+ * derived by measuring the real, rendered bounding boxes of a small probe
84
+ * batch (see `measure-layout.ts`), so margins/border/box-shadow on your own
85
+ * item styles are always accounted for correctly, and mixed layouts
86
+ * (vertical list of wrapping rows, i.e. a card grid) are supported out of
87
+ * the box.
88
+ *
89
+ * The component does not render your items itself — it exposes reactive
90
+ * signals (`visibleItems`, `range`, `baseIndex`, `axis`, ...) that you
91
+ * consume with a native `@for` block in your own template. This keeps the
92
+ * repeat/track logic entirely under your control (custom track expressions,
93
+ * `@empty` blocks, etc.) instead of hiding it behind a structural directive.
94
+ *
95
+ * @example
96
+ * ```html
97
+ * <ngx-virtual-scroll-viewport #vs="ngxVirtualScrollViewport" [items]="rows" style="height: 480px">
98
+ * @for (row of vs.visibleItems(); track row.id; let i = $index) {
99
+ * <div class="row">{{ vs.baseIndex() + i }} - {{ row.name }}</div>
100
+ * }
101
+ * </ngx-virtual-scroll-viewport>
102
+ * ```
103
+ */
104
+ class NgxVirtualScrollViewport {
105
+ /** The full, unvirtualized data set. */
106
+ items = input([], /* @ts-ignore */
107
+ ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
108
+ /** Minimum buffer (px) left before the render range is recomputed. */
109
+ minBufferPx = input(150, /* @ts-ignore */
110
+ ...(ngDevMode ? [{ debugName: "minBufferPx" }] : /* istanbul ignore next */ []));
111
+ /** Extra buffer (px) rendered outside the visible area on each side. */
112
+ maxBufferPx = input(300, /* @ts-ignore */
113
+ ...(ngDevMode ? [{ debugName: "maxBufferPx" }] : /* istanbul ignore next */ []));
114
+ /** Advanced escape hatch: replace the built-in layout probe entirely. */
115
+ measureFn = input(undefined, /* @ts-ignore */
116
+ ...(ngDevMode ? [{ debugName: "measureFn" }] : /* istanbul ignore next */ []));
117
+ /**
118
+ * Safe ceiling (px) for the scrollable axis's real DOM size. Only relevant
119
+ * for very large data sets — see `DEFAULT_MAX_AXIS_SIZE_PX`. You should
120
+ * not need to change this; it's exposed only for advanced cases (e.g. you
121
+ * know your app never targets older WebKit and want to raise the ceiling).
122
+ */
123
+ maxAxisSizePx = input(DEFAULT_MAX_AXIS_SIZE_PX, /* @ts-ignore */
124
+ ...(ngDevMode ? [{ debugName: "maxAxisSizePx" }] : /* istanbul ignore next */ []));
125
+ /** Emits the index of the first fully-visible item as the user scrolls. */
126
+ scrolledIndexChange = output();
127
+ /** Emits whenever the rendered line range changes. */
128
+ rangeChange = output();
129
+ scrollableRef = viewChild.required('scrollable');
130
+ wrapperRef = viewChild.required('wrapper');
131
+ destroyRef = inject(DestroyRef);
132
+ measurement = signal(null, /* @ts-ignore */
133
+ ...(ngDevMode ? [{ debugName: "measurement" }] : /* istanbul ignore next */ []));
134
+ scrollOffset = signal(0, /* @ts-ignore */
135
+ ...(ngDevMode ? [{ debugName: "scrollOffset" }] : /* istanbul ignore next */ []));
136
+ viewportSize = signal(0, /* @ts-ignore */
137
+ ...(ngDevMode ? [{ debugName: "viewportSize" }] : /* istanbul ignore next */ []));
138
+ /** Whether the user is actively scrolling (used only to toggle `will-change`). */
139
+ isScrolling = signal(false, /* @ts-ignore */
140
+ ...(ngDevMode ? [{ debugName: "isScrolling" }] : /* istanbul ignore next */ []));
141
+ /** Currently rendered line range. */
142
+ range = signal({ start: 0, end: PROBE_COUNT }, /* @ts-ignore */
143
+ ...(ngDevMode ? [{ debugName: "range" }] : /* istanbul ignore next */ []));
144
+ axis = computed(() => this.measurement()?.axis ?? 'vertical', /* @ts-ignore */
145
+ ...(ngDevMode ? [{ debugName: "axis" }] : /* istanbul ignore next */ []));
146
+ crossCount = computed(() => this.measurement()?.crossCount ?? 1, /* @ts-ignore */
147
+ ...(ngDevMode ? [{ debugName: "crossCount" }] : /* istanbul ignore next */ []));
148
+ lineSize = computed(() => this.measurement()?.lineSize ?? 0, /* @ts-ignore */
149
+ ...(ngDevMode ? [{ debugName: "lineSize" }] : /* istanbul ignore next */ []));
150
+ isMeasured = computed(() => this.measurement() !== null, /* @ts-ignore */
151
+ ...(ngDevMode ? [{ debugName: "isMeasured" }] : /* istanbul ignore next */ []));
152
+ lineCount = computed(() => Math.ceil(this.items().length / this.crossCount()), /* @ts-ignore */
153
+ ...(ngDevMode ? [{ debugName: "lineCount" }] : /* istanbul ignore next */ []));
154
+ /** Real, uncompressed total size along the scroll axis — can exceed the browser's element-size cap. */
155
+ naturalTotalSize = computed(() => this.lineCount() * this.lineSize(), /* @ts-ignore */
156
+ ...(ngDevMode ? [{ debugName: "naturalTotalSize" }] : /* istanbul ignore next */ []));
157
+ /**
158
+ * Size actually applied to the spacer element, clamped to `maxAxisSizePx`.
159
+ * Equal to `naturalTotalSize()` for any data set small enough to matter in
160
+ * practice — the compression only ever engages for extreme list sizes.
161
+ */
162
+ totalSize = computed(() => Math.min(this.naturalTotalSize(), this.maxAxisSizePx()), /* @ts-ignore */
163
+ ...(ngDevMode ? [{ debugName: "totalSize" }] : /* istanbul ignore next */ []));
164
+ /**
165
+ * Ratio between the (possibly capped) DOM scroll space and the real,
166
+ * uncompressed content size. `1` unless `naturalTotalSize()` exceeds
167
+ * `maxAxisSizePx()`, in which case it's `< 1` and the DOM scrollbar
168
+ * represents the whole data set in a compressed coordinate space.
169
+ */
170
+ scaleFactor = computed(() => {
171
+ const natural = this.naturalTotalSize();
172
+ return natural > 0 ? this.totalSize() / natural : 1;
173
+ }, /* @ts-ignore */
174
+ ...(ngDevMode ? [{ debugName: "scaleFactor" }] : /* istanbul ignore next */ []));
175
+ /** Absolute index of the first item in `visibleItems()`, for display purposes. */
176
+ baseIndex = computed(() => this.range().start * this.crossCount(), /* @ts-ignore */
177
+ ...(ngDevMode ? [{ debugName: "baseIndex" }] : /* istanbul ignore next */ []));
178
+ /** Slice of `items()` that should actually be rendered right now. */
179
+ visibleItems = computed(() => {
180
+ const data = this.items();
181
+ const { start, end } = this.range();
182
+ const cross = this.crossCount();
183
+ return data.slice(start * cross, Math.min(data.length, end * cross));
184
+ }, /* @ts-ignore */
185
+ ...(ngDevMode ? [{ debugName: "visibleItems" }] : /* istanbul ignore next */ []));
186
+ // Expressed in the same compressed DOM coordinate space as `scrollOffset`/
187
+ // `totalSize`, so it always stays within the safe, capped range even for
188
+ // enormous data sets — see `scaleFactor`.
189
+ //
190
+ // The naive `start * lineSize * scaleFactor` value is only an *ideal*
191
+ // proportional position. It is clamped so the *real* (unscaled) rendered
192
+ // block — `renderedBlockSize()` — can never be pushed past the end of the
193
+ // capped spacer. Without this clamp, once `scaleFactor() < 1`, the block
194
+ // rendered near the tail (real, unscaled size) no longer fits in the tiny
195
+ // sliver of compressed space "ideally" left for it, so it gets positioned
196
+ // partly (or entirely) past the bottom of the scrollable area — reachable
197
+ // in the DOM, but never inside the visible/scrollable viewport. Clamping
198
+ // guarantees the tail of the list is always flush with, and fully inside,
199
+ // the scrollable area.
200
+ renderedBlockSize = computed(() => {
201
+ const { start, end } = this.range();
202
+ return (end - start) * this.lineSize();
203
+ }, /* @ts-ignore */
204
+ ...(ngDevMode ? [{ debugName: "renderedBlockSize" }] : /* istanbul ignore next */ []));
205
+ contentOffset = computed(() => {
206
+ const ideal = this.range().start * this.lineSize() * this.scaleFactor();
207
+ const max = Math.max(0, this.totalSize() - this.renderedBlockSize());
208
+ return Math.min(ideal, max);
209
+ }, /* @ts-ignore */
210
+ ...(ngDevMode ? [{ debugName: "contentOffset" }] : /* istanbul ignore next */ []));
211
+ wrapperTransform = computed(() => this.axis() === 'horizontal'
212
+ ? `translateX(${this.contentOffset()}px)`
213
+ : `translateY(${this.contentOffset()}px)`, /* @ts-ignore */
214
+ ...(ngDevMode ? [{ debugName: "wrapperTransform" }] : /* istanbul ignore next */ []));
215
+ spacerWidth = computed(() => this.axis() === 'horizontal' ? this.totalSize() : 1, /* @ts-ignore */
216
+ ...(ngDevMode ? [{ debugName: "spacerWidth" }] : /* istanbul ignore next */ []));
217
+ spacerHeight = computed(() => this.axis() === 'vertical' ? this.totalSize() : 1, /* @ts-ignore */
218
+ ...(ngDevMode ? [{ debugName: "spacerHeight" }] : /* istanbul ignore next */ []));
219
+ resizeObserver;
220
+ scrollingIdleTimer;
221
+ scrollRaf = 0;
222
+ constructor() {
223
+ // Seed / reset the probe range whenever the data set changes and we
224
+ // haven't measured a real layout yet.
225
+ effect(() => {
226
+ const length = this.items().length;
227
+ if (!this.measurement()) {
228
+ this.range.set({ start: 0, end: Math.min(length, PROBE_COUNT) });
229
+ }
230
+ });
231
+ // Read the real, rendered layout of the probe batch once it has
232
+ // painted. Runs in the `read` phase so it never interleaves with DOM
233
+ // writes and never forces a layout thrash.
234
+ afterRenderEffect({
235
+ read: () => {
236
+ if (this.measurement()) {
237
+ return;
238
+ }
239
+ const children = Array.from(this.wrapperRef().nativeElement.children).slice(0, PROBE_COUNT);
240
+ const measure = this.measureFn() ?? measureLayout;
241
+ const result = measure(children);
242
+ if (result) {
243
+ this.measurement.set(result);
244
+ }
245
+ },
246
+ });
247
+ // Once measured (or when the buffer inputs change), recompute the
248
+ // actual visible range from the real viewport size / scroll offset.
249
+ // `untracked` is used because `recomputeRange` itself reads scroll/size
250
+ // signals that are already kept in sync by the scroll/resize listeners
251
+ // directly — we only want *this* effect to re-run for buffer/measurement
252
+ // changes, not for every scroll frame.
253
+ effect(() => {
254
+ this.minBufferPx();
255
+ this.maxBufferPx();
256
+ const measured = this.isMeasured();
257
+ untracked(() => {
258
+ if (measured) {
259
+ // The initial viewport-size read (in setupListeners) assumed the
260
+ // default 'vertical' axis before layout was known; now that the
261
+ // real axis is known, re-read clientWidth/clientHeight against it.
262
+ this.measureViewportSize();
263
+ this.recomputeRange(true);
264
+ }
265
+ });
266
+ });
267
+ afterNextRender(() => this.setupListeners());
268
+ this.destroyRef.onDestroy(() => {
269
+ this.resizeObserver?.disconnect();
270
+ cancelAnimationFrame(this.scrollRaf);
271
+ clearTimeout(this.scrollingIdleTimer);
272
+ });
273
+ }
274
+ /** Programmatically scroll to a given item index. */
275
+ scrollToIndex(index, behavior = 'auto') {
276
+ const line = Math.floor(index / this.crossCount());
277
+ this.scrollToOffset(line * this.lineSize(), behavior);
278
+ }
279
+ /**
280
+ * Programmatically scroll to a given pixel offset along the scroll axis.
281
+ * `offset` is expressed in real, uncompressed content px (i.e. the same
282
+ * space as `index * lineSize()`) — internally converted to the
283
+ * (possibly compressed) DOM scroll coordinate via `scaleFactor()`.
284
+ */
285
+ scrollToOffset(offset, behavior = 'auto') {
286
+ const el = this.scrollableRef().nativeElement;
287
+ const domOffset = offset * this.scaleFactor();
288
+ const options = this.axis() === 'horizontal' ? { left: domOffset, behavior } : { top: domOffset, behavior };
289
+ el.scrollTo(options);
290
+ }
291
+ /** Force a re-measure, e.g. after the container was resized by external layout logic. */
292
+ checkViewportSize() {
293
+ this.measureViewportSize();
294
+ this.recomputeRange(true);
295
+ }
296
+ setupListeners() {
297
+ const el = this.scrollableRef().nativeElement;
298
+ el.addEventListener('scroll', this.onScroll, { passive: true });
299
+ this.destroyRef.onDestroy(() => el.removeEventListener('scroll', this.onScroll));
300
+ if (typeof ResizeObserver !== 'undefined') {
301
+ this.resizeObserver = new ResizeObserver(() => this.checkViewportSize());
302
+ this.resizeObserver.observe(el);
303
+ }
304
+ this.measureViewportSize();
305
+ }
306
+ onScroll = () => {
307
+ if (this.scrollRaf) {
308
+ return;
309
+ }
310
+ this.scrollRaf = requestAnimationFrame(() => {
311
+ this.scrollRaf = 0;
312
+ this.markScrolling();
313
+ const el = this.scrollableRef().nativeElement;
314
+ const offset = this.axis() === 'horizontal' ? el.scrollLeft : el.scrollTop;
315
+ this.scrollOffset.set(offset);
316
+ this.recomputeRange(false);
317
+ const size = this.lineSize();
318
+ if (size > 0) {
319
+ const realOffset = offset / this.scaleFactor();
320
+ this.scrolledIndexChange.emit(Math.floor(realOffset / size) * this.crossCount());
321
+ }
322
+ });
323
+ };
324
+ markScrolling() {
325
+ this.isScrolling.set(true);
326
+ clearTimeout(this.scrollingIdleTimer);
327
+ this.scrollingIdleTimer = setTimeout(() => this.isScrolling.set(false), 150);
328
+ }
329
+ measureViewportSize() {
330
+ const el = this.scrollableRef().nativeElement;
331
+ const size = this.axis() === 'horizontal' ? el.clientWidth : el.clientHeight;
332
+ this.viewportSize.set(size);
333
+ }
334
+ /**
335
+ * Recomputes the rendered line range. Mirrors the CDK "fixed size"
336
+ * strategy: only recompute once the scroll offset gets within
337
+ * `minBufferPx` of the current range's edge, instead of on every pixel.
338
+ *
339
+ * All math here happens in *real* (uncompressed) content px, obtained by
340
+ * dividing the raw DOM scroll offset/viewport size by `scaleFactor()`.
341
+ * This is what makes the very last items reachable even when the total
342
+ * content size has been compressed into a browser-safe DOM range: as
343
+ * `domScrollOffset` sweeps its full (capped) range, `realOffset` still
344
+ * sweeps the entire, real `naturalTotalSize()`.
345
+ */
346
+ recomputeRange(force) {
347
+ const lineSize = this.lineSize();
348
+ if (lineSize <= 0) {
349
+ return;
350
+ }
351
+ const scale = this.scaleFactor();
352
+ const realOffset = this.scrollOffset() / scale;
353
+ const realViewportSize = this.viewportSize() / scale;
354
+ const current = this.range();
355
+ const min = this.minBufferPx();
356
+ const max = this.maxBufferPx();
357
+ const distanceToStart = realOffset - current.start * lineSize;
358
+ const distanceToEnd = current.end * lineSize - (realOffset + realViewportSize);
359
+ if (!force && distanceToStart >= min && distanceToEnd >= min) {
360
+ return;
361
+ }
362
+ const bufferStart = Math.max(0, realOffset - max);
363
+ const bufferEnd = realOffset + realViewportSize + max;
364
+ const start = Math.max(0, Math.floor(bufferStart / lineSize));
365
+ const end = Math.min(this.lineCount(), Math.ceil(bufferEnd / lineSize));
366
+ const next = { start, end };
367
+ if (!rangesEqual(next, current)) {
368
+ this.range.set(next);
369
+ this.rangeChange.emit(next);
370
+ }
371
+ }
372
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxVirtualScrollViewport, deps: [], target: i0.ɵɵFactoryTarget.Component });
373
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.4", type: NgxVirtualScrollViewport, isStandalone: true, selector: "ngx-virtual-scroll-viewport, ngx-virtual-scroll", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, minBufferPx: { classPropertyName: "minBufferPx", publicName: "minBufferPx", isSignal: true, isRequired: false, transformFunction: null }, maxBufferPx: { classPropertyName: "maxBufferPx", publicName: "maxBufferPx", isSignal: true, isRequired: false, transformFunction: null }, measureFn: { classPropertyName: "measureFn", publicName: "measureFn", isSignal: true, isRequired: false, transformFunction: null }, maxAxisSizePx: { classPropertyName: "maxAxisSizePx", publicName: "maxAxisSizePx", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { scrolledIndexChange: "scrolledIndexChange", rangeChange: "rangeChange" }, host: { properties: { "class.ngx-virtual-scroll-viewport-host--scrolling": "isScrolling()" }, classAttribute: "ngx-virtual-scroll-viewport-host" }, viewQueries: [{ propertyName: "scrollableRef", first: true, predicate: ["scrollable"], descendants: true, isSignal: true }, { propertyName: "wrapperRef", first: true, predicate: ["wrapper"], descendants: true, isSignal: true }], exportAs: ["ngxVirtualScrollViewport"], ngImport: i0, template: "<div #scrollable class=\"ngx-virtual-scroll-viewport__scrollable\">\n <div\n class=\"ngx-virtual-scroll-viewport__spacer\"\n [style.width.px]=\"spacerWidth()\"\n [style.height.px]=\"spacerHeight()\"\n aria-hidden=\"true\"></div>\n <div #wrapper class=\"ngx-virtual-scroll-viewport__wrapper\" [style.transform]=\"wrapperTransform()\">\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [":host.ngx-virtual-scroll-viewport-host{display:block;position:relative;overflow:hidden;contain:strict}.ngx-virtual-scroll-viewport__scrollable{position:relative;width:100%;height:100%;overflow:auto;-webkit-overflow-scrolling:touch;contain:strict}.ngx-virtual-scroll-viewport__spacer{position:absolute;top:0;left:0;pointer-events:none;visibility:hidden}.ngx-virtual-scroll-viewport__wrapper{position:absolute;top:0;left:0;min-width:100%;contain:layout style}:host.ngx-virtual-scroll-viewport-host--scrolling .ngx-virtual-scroll-viewport__wrapper{will-change:transform}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
374
+ }
375
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxVirtualScrollViewport, decorators: [{
376
+ type: Component,
377
+ args: [{ selector: 'ngx-virtual-scroll-viewport, ngx-virtual-scroll', standalone: true, exportAs: 'ngxVirtualScrollViewport', changeDetection: ChangeDetectionStrategy.OnPush, host: {
378
+ class: 'ngx-virtual-scroll-viewport-host',
379
+ '[class.ngx-virtual-scroll-viewport-host--scrolling]': 'isScrolling()',
380
+ }, template: "<div #scrollable class=\"ngx-virtual-scroll-viewport__scrollable\">\n <div\n class=\"ngx-virtual-scroll-viewport__spacer\"\n [style.width.px]=\"spacerWidth()\"\n [style.height.px]=\"spacerHeight()\"\n aria-hidden=\"true\"></div>\n <div #wrapper class=\"ngx-virtual-scroll-viewport__wrapper\" [style.transform]=\"wrapperTransform()\">\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [":host.ngx-virtual-scroll-viewport-host{display:block;position:relative;overflow:hidden;contain:strict}.ngx-virtual-scroll-viewport__scrollable{position:relative;width:100%;height:100%;overflow:auto;-webkit-overflow-scrolling:touch;contain:strict}.ngx-virtual-scroll-viewport__spacer{position:absolute;top:0;left:0;pointer-events:none;visibility:hidden}.ngx-virtual-scroll-viewport__wrapper{position:absolute;top:0;left:0;min-width:100%;contain:layout style}:host.ngx-virtual-scroll-viewport-host--scrolling .ngx-virtual-scroll-viewport__wrapper{will-change:transform}\n"] }]
381
+ }], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], minBufferPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "minBufferPx", required: false }] }], maxBufferPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxBufferPx", required: false }] }], measureFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "measureFn", required: false }] }], maxAxisSizePx: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxAxisSizePx", required: false }] }], scrolledIndexChange: [{ type: i0.Output, args: ["scrolledIndexChange"] }], rangeChange: [{ type: i0.Output, args: ["rangeChange"] }], scrollableRef: [{ type: i0.ViewChild, args: ['scrollable', { isSignal: true }] }], wrapperRef: [{ type: i0.ViewChild, args: ['wrapper', { isSignal: true }] }] } });
382
+
383
+ /*
384
+ * Public API surface of @ngx-kit/virtual-scroll
385
+ */
386
+
387
+ /**
388
+ * Generated bundle index. Do not edit.
389
+ */
390
+
391
+ export { NgxVirtualScrollViewport, measureLayout, rangesEqual };
392
+ //# sourceMappingURL=ngx-kit-virtual-scroll.mjs.map