@lifecorner/angular-ui-kit 3.27.2 → 3.29.0

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 (25) hide show
  1. package/fesm2022/lifecorner-angular-ui-kit-app-shell.mjs +102 -24
  2. package/fesm2022/lifecorner-angular-ui-kit-app-shell.mjs.map +1 -1
  3. package/fesm2022/lifecorner-angular-ui-kit-card.mjs +23 -3
  4. package/fesm2022/lifecorner-angular-ui-kit-card.mjs.map +1 -1
  5. package/fesm2022/lifecorner-angular-ui-kit-combobox.mjs +56 -1
  6. package/fesm2022/lifecorner-angular-ui-kit-combobox.mjs.map +1 -1
  7. package/fesm2022/lifecorner-angular-ui-kit-datepicker.mjs +257 -10
  8. package/fesm2022/lifecorner-angular-ui-kit-datepicker.mjs.map +1 -1
  9. package/fesm2022/lifecorner-angular-ui-kit-internal-overlay.mjs +31 -2
  10. package/fesm2022/lifecorner-angular-ui-kit-internal-overlay.mjs.map +1 -1
  11. package/fesm2022/lifecorner-angular-ui-kit-money.mjs +90 -7
  12. package/fesm2022/lifecorner-angular-ui-kit-money.mjs.map +1 -1
  13. package/fesm2022/lifecorner-angular-ui-kit-number-input.mjs +93 -9
  14. package/fesm2022/lifecorner-angular-ui-kit-number-input.mjs.map +1 -1
  15. package/fesm2022/lifecorner-angular-ui-kit-toast.mjs +12 -2
  16. package/fesm2022/lifecorner-angular-ui-kit-toast.mjs.map +1 -1
  17. package/package.json +1 -1
  18. package/types/lifecorner-angular-ui-kit-app-shell.d.ts +64 -0
  19. package/types/lifecorner-angular-ui-kit-card.d.ts +34 -0
  20. package/types/lifecorner-angular-ui-kit-combobox.d.ts +32 -1
  21. package/types/lifecorner-angular-ui-kit-datepicker.d.ts +143 -2
  22. package/types/lifecorner-angular-ui-kit-internal-overlay.d.ts +21 -0
  23. package/types/lifecorner-angular-ui-kit-money.d.ts +81 -2
  24. package/types/lifecorner-angular-ui-kit-number-input.d.ts +61 -0
  25. package/types/lifecorner-angular-ui-kit-toast.d.ts +25 -0
@@ -1 +1 @@
1
- {"version":3,"file":"lifecorner-angular-ui-kit-datepicker.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/datepicker/datepicker.component.ts","../../../../libs/angular-ui-kit/src/lib/datepicker/datepicker.component.html"],"sourcesContent":["import {\n Component,\n input,\n output,\n signal,\n computed,\n linkedSignal,\n ChangeDetectionStrategy,\n forwardRef,\n ElementRef,\n viewChild,\n inject,\n DOCUMENT,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { OverlayModule } from '@angular/cdk/overlay';\n\nexport type DateValue = Date | string | null;\n\n/**\n * Datepicker component for date selection with calendar overlay.\n *\n * Features:\n * - Calendar popup with month and year navigation\n * - Manual date entry in the configured format\n * - Min/max date constraints\n * - Disabled specific dates and weekends\n * - Configurable date format string\n * - Variant styles (outline, filled)\n * - Size presets (xs, sm, md, lg)\n * - Disabled and readonly states\n * - ControlValueAccessor integration for reactive forms\n *\n * @example\n * ```html\n * <lc-datepicker placeholder=\"Select date\" [(ngModel)]=\"selectedDate\" />\n * ```\n */\n@Component({\n selector: 'lc-datepicker',\n standalone: true,\n imports: [OverlayModule],\n templateUrl: './datepicker.component.html',\n styleUrl: './datepicker.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => DatepickerComponent),\n multi: true,\n },\n ],\n})\nexport class DatepickerComponent implements ControlValueAccessor {\n private static nextId = 0;\n\n /** Per-instance id for the input; helper/error text ids derive from it. */\n readonly inputId = `lc-datepicker-${++DatepickerComponent.nextId}`;\n\n private readonly datepickerInput = viewChild<ElementRef<HTMLInputElement>>('datepickerInput');\n private readonly calendarPanel = viewChild<ElementRef<HTMLElement>>('calendarPanel');\n\n /**\n * Visual variant of the datepicker\n */\n readonly variant = input<'outline' | 'filled'>('outline');\n\n /**\n * Size of the datepicker\n */\n readonly size = input<'xs' | 'sm' | 'md' | 'lg'>('md');\n\n /**\n * Whether the datepicker is disabled\n */\n readonly disabled = input<boolean>(false);\n\n /**\n * Whether the datepicker is in error state\n */\n readonly error = input<boolean>(false);\n\n /**\n * Whether the datepicker is required\n */\n readonly required = input<boolean>(false);\n\n /**\n * Whether the datepicker is readonly\n */\n readonly readonly = input<boolean>(false);\n\n /**\n * Placeholder text\n */\n readonly placeholder = input<string>('Select a date');\n\n /**\n * Helper text displayed below the datepicker\n */\n readonly helperText = input<string>('');\n\n /**\n * Error message displayed when error is true\n */\n readonly errorMessage = input<string>('');\n\n /**\n * ARIA label for accessibility\n */\n readonly ariaLabel = input<string | undefined>(undefined);\n\n /**\n * Date format string (e.g., 'YYYY-MM-DD', 'MM/DD/YYYY')\n */\n readonly format = input<string>('YYYY-MM-DD');\n\n /**\n * Minimum selectable date (compared by calendar day, time of day is ignored)\n */\n readonly minDate = input<Date | undefined>(undefined);\n\n /**\n * Maximum selectable date (compared by calendar day, time of day is ignored)\n */\n readonly maxDate = input<Date | undefined>(undefined);\n\n /**\n * Array of disabled dates\n */\n readonly disabledDates = input<Date[]>([]);\n\n /**\n * Whether to disable weekends\n */\n readonly disableWeekends = input<boolean>(false);\n\n /** BCP 47 locale for month and weekday names and the day buttons' accessible names (e.g. `'de-DE'`). Empty keeps the built-in English names. */\n readonly locale = input('');\n\n /** First column of the grid: 0 Sunday (default) … 6 Saturday — 1 for Monday. */\n readonly firstDayOfWeek = input(0);\n\n /** Accessible name of the clear button. */\n readonly clearAriaLabel = input('Clear date');\n\n /** Accessible name of the calendar dialog. */\n readonly dialogAriaLabel = input('Choose date');\n\n /** Accessible name of the previous-month button. */\n readonly previousMonthAriaLabel = input('Previous month');\n\n /** Accessible name of the next-month button. */\n readonly nextMonthAriaLabel = input('Next month');\n\n /** Label of the \"go to today\" button. */\n readonly todayLabel = input('Today');\n\n /** Appended to the selected day's accessible name (`…, selected`). */\n readonly selectedAriaLabel = input('selected');\n\n /**\n * Emitted when date selection changes\n */\n readonly dateChange = output<Date | null>();\n\n /**\n * Emitted when calendar opens\n */\n readonly opened = output<void>();\n\n /**\n * Emitted when calendar closes\n */\n readonly closed = output<void>();\n\n // Internal state\n readonly selectedDate = signal<Date | null>(null);\n readonly isOpen = signal<boolean>(false);\n readonly currentMonth = signal<number>(new Date().getMonth());\n readonly currentYear = signal<number>(new Date().getFullYear());\n\n /** Disabled state pushed in by the forms API (setDisabledState). */\n private readonly formDisabled = signal<boolean>(false);\n\n /** Effective disabled state: the `disabled` input OR the form control's disabled state. */\n readonly isDisabled = computed(() => this.disabled() || this.formDisabled());\n\n // Computed values\n readonly formattedDate = computed(() => {\n const date = this.selectedDate();\n if (!date) return '';\n return this.formatDate(date, this.format());\n });\n\n /**\n * Text currently shown in the input. Follows the selected date, but the user\n * can type freely; only a complete, valid date is committed to the model.\n */\n readonly inputValue = linkedSignal(() => this.formattedDate());\n\n weekDays = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];\n\n monthNames = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n /** Month name in the header: `locale` when set, the English names otherwise. */\n readonly currentMonthName = computed(() => {\n const locale = this.locale();\n return locale\n ? new Date(this.currentYear(), this.currentMonth(), 1).toLocaleDateString(locale, { month: 'long' })\n : this.monthNames[this.currentMonth()];\n });\n\n /** Weekday headers in grid order, starting at `firstDayOfWeek`. */\n readonly weekdayLabels = computed(() => {\n const locale = this.locale();\n const first = this.gridStart();\n // 1 Jan 2023 was a Sunday, so day d of that week has getDay() === d.\n const names = locale\n ? Array.from({ length: 7 }, (_, d) =>\n new Date(2023, 0, 1 + d).toLocaleDateString(locale, { weekday: 'short' }).replace(/\\.$/, ''),\n )\n : this.weekDays;\n return Array.from({ length: 7 }, (_, i) => names[(first + i) % 7]);\n });\n\n /** `firstDayOfWeek` clamped to 0–6. */\n private readonly gridStart = computed(() => {\n const day = Math.trunc(Number(this.firstDayOfWeek()));\n return Number.isFinite(day) ? ((day % 7) + 7) % 7 : 0;\n });\n\n /** id of the helper/error text the input is described by (aria-describedby) */\n readonly describedBy = computed(() => {\n if (this.error() && this.errorMessage()) {\n return `${this.inputId}-error`;\n }\n return this.helperText() ? `${this.inputId}-helper` : null;\n });\n\n /**\n * Computed classes for the datepicker input element\n */\n readonly datepickerClasses = computed(() => {\n const classes = [\n 'lc-datepicker',\n `lc-datepicker--${this.variant()}`,\n `lc-datepicker--${this.size()}`,\n ];\n\n if (this.isDisabled()) {\n classes.push('lc-datepicker--disabled');\n }\n\n if (this.error()) {\n classes.push('lc-datepicker--error');\n }\n\n if (this.readonly()) {\n classes.push('lc-datepicker--readonly');\n }\n\n if (this.isOpen()) {\n classes.push('lc-datepicker--open');\n }\n\n return classes.join(' ');\n });\n\n // Private properties\n private readonly document = inject(DOCUMENT);\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n private onChange: (value: Date | null) => void = () => {};\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n private onTouched: () => void = () => {};\n\n // Public methods\n /**\n * Toggle calendar open/closed\n */\n toggle(): void {\n if (this.isDisabled() || this.readonly()) {\n return;\n }\n if (this.isOpen()) {\n this.close();\n } else {\n this.open();\n }\n }\n\n /**\n * Open calendar\n */\n open(): void {\n if (this.isDisabled() || this.readonly() || this.isOpen()) {\n return;\n }\n this.isOpen.set(true);\n\n // Set calendar to selected date's month/year or current\n const date = this.selectedDate();\n if (date) {\n this.showMonthOf(date);\n }\n\n this.opened.emit();\n }\n\n /**\n * Close calendar. Idempotent: the overlay's `detach` re-enters here after\n * `isOpen` flips, and that second call must not emit `closed` again.\n */\n close(): void {\n if (!this.isOpen()) {\n return;\n }\n // A day button inside the panel may hold focus; it is about to be removed,\n // so hand focus back to the input instead of letting it drop to <body>.\n this.restoreFocusFromPanel();\n this.isOpen.set(false);\n this.closed.emit();\n }\n\n /**\n * Select a date\n */\n selectDate(date: Date): void {\n if (this.isDisabled() || this.readonly() || this.isDateDisabled(date)) {\n return;\n }\n\n this.commitDate(date);\n this.close();\n }\n\n /**\n * Clear selected date\n */\n clear(): void {\n this.selectedDate.set(null);\n this.inputValue.set('');\n this.onChange(null);\n this.dateChange.emit(null);\n }\n\n /**\n * Check if a date is disabled\n */\n isDateDisabled(date: Date): boolean {\n // min/max are compared by calendar day: consumers typically pass `new Date()`\n // (which carries the current time) while calendar cells sit at midnight.\n const day = this.startOfDay(date);\n\n const min = this.minDate();\n if (min && day < this.startOfDay(min)) {\n return true;\n }\n\n const max = this.maxDate();\n if (max && day > this.startOfDay(max)) {\n return true;\n }\n\n // Check disabled dates\n if (this.disabledDates().some((d) => this.isSameDate(d, date))) {\n return true;\n }\n\n // Check weekends\n if (this.disableWeekends()) {\n const weekday = date.getDay();\n if (weekday === 0 || weekday === 6) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Check if date is today\n */\n isToday(date: Date): boolean {\n const today = new Date();\n return this.isSameDate(date, today);\n }\n\n /** Accessible name of a day button: the full date, plus `selectedAriaLabel` when selected. */\n protected dayAriaLabel(date: Date): string {\n const locale = this.locale();\n const name = locale\n ? date.toLocaleDateString(locale, { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' })\n : date.toDateString();\n return this.isSelectedDate(date) ? `${name}, ${this.selectedAriaLabel()}` : name;\n }\n\n /**\n * Check if date is selected\n */\n isSelectedDate(date: Date): boolean {\n const selected = this.selectedDate();\n return selected ? this.isSameDate(date, selected) : false;\n }\n\n /**\n * Generate calendar days for current month\n */\n generateCalendarDays(): Date[] {\n const year = this.currentYear();\n const month = this.currentMonth();\n\n const firstDay = new Date(year, month, 1);\n const lastDay = new Date(year, month + 1, 0);\n\n const days: Date[] = [];\n\n // Add previous month's days, so the first column is `firstDayOfWeek`.\n const leadingDays = (firstDay.getDay() - this.gridStart() + 7) % 7;\n for (let i = leadingDays - 1; i >= 0; i--) {\n const date = new Date(year, month, -i);\n days.push(date);\n }\n\n // Add current month's days\n for (let i = 1; i <= lastDay.getDate(); i++) {\n days.push(new Date(year, month, i));\n }\n\n // Add next month's days to complete the grid\n const remainingDays = 42 - days.length; // 6 weeks * 7 days\n for (let i = 1; i <= remainingDays; i++) {\n days.push(new Date(year, month + 1, i));\n }\n\n return days.slice(0, 42); // Ensure exactly 42 days (6 weeks)\n }\n\n /**\n * Navigate to next month\n */\n nextMonth(): void {\n if (this.currentMonth() === 11) {\n this.currentMonth.set(0);\n this.currentYear.set(this.currentYear() + 1);\n } else {\n this.currentMonth.set(this.currentMonth() + 1);\n }\n }\n\n /**\n * Navigate to previous month\n */\n previousMonth(): void {\n if (this.currentMonth() === 0) {\n this.currentMonth.set(11);\n this.currentYear.set(this.currentYear() - 1);\n } else {\n this.currentMonth.set(this.currentMonth() - 1);\n }\n }\n\n /**\n * Navigate to today\n */\n goToToday(): void {\n this.showMonthOf(new Date());\n }\n\n /**\n * Handle input change (manual date entry). Partial input is kept as text\n * only; the model changes once the text is a complete, valid, selectable date.\n */\n onInputChange(value: string): void {\n this.inputValue.set(value);\n\n if (value.trim() === '') {\n if (this.selectedDate() !== null) {\n this.clear();\n }\n return;\n }\n\n const date = this.parseDate(value, this.format());\n if (date && !this.isDateDisabled(date) && !this.isSelectedDate(date)) {\n this.commitDate(date);\n this.showMonthOf(date);\n }\n }\n\n /**\n * Handle keyboard navigation\n */\n onKeyDown(event: KeyboardEvent): void {\n if (this.isDisabled() || this.readonly()) {\n return;\n }\n\n if (\n !this.isOpen() &&\n (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ')\n ) {\n this.open();\n event.preventDefault();\n return;\n }\n\n if (!this.isOpen()) return;\n\n // While the text differs from the model the user is mid-edit: arrows must\n // move the caret, not the calendar selection.\n const editing = this.inputValue() !== this.formattedDate();\n const currentDate = this.selectedDate() || new Date();\n let newDate: Date | null = null;\n\n switch (event.key) {\n case 'Escape':\n this.close();\n event.preventDefault();\n // Only this datepicker should react; keep the key from reaching enclosing overlays.\n event.stopPropagation();\n break;\n\n case 'ArrowRight':\n if (editing) break;\n newDate = new Date(currentDate);\n newDate.setDate(currentDate.getDate() + 1);\n event.preventDefault();\n break;\n\n case 'ArrowLeft':\n if (editing) break;\n newDate = new Date(currentDate);\n newDate.setDate(currentDate.getDate() - 1);\n event.preventDefault();\n break;\n\n case 'ArrowDown':\n if (editing) break;\n newDate = new Date(currentDate);\n newDate.setDate(currentDate.getDate() + 7);\n event.preventDefault();\n break;\n\n case 'ArrowUp':\n if (editing) break;\n newDate = new Date(currentDate);\n newDate.setDate(currentDate.getDate() - 7);\n event.preventDefault();\n break;\n\n case 'Enter': {\n const selected = this.selectedDate();\n if (selected) {\n this.selectDate(selected);\n }\n event.preventDefault();\n break;\n }\n }\n\n if (newDate && !this.isDateDisabled(newDate)) {\n this.selectedDate.set(newDate);\n this.showMonthOf(newDate);\n }\n }\n\n /**\n * Handle blur event: mark touched and drop any partial text that never became a date.\n */\n onBlur(): void {\n this.onTouched();\n this.inputValue.set(this.formattedDate());\n }\n\n /**\n * Handle click outside\n */\n onClickOutside(): void {\n this.close();\n }\n\n // ControlValueAccessor implementation\n writeValue(value: DateValue): void {\n let date: Date | null = null;\n if (value instanceof Date) {\n date = isNaN(value.getTime()) ? null : value;\n } else if (typeof value === 'string') {\n date = this.parseDate(value, this.format());\n }\n this.selectedDate.set(date);\n this.inputValue.set(this.formattedDate());\n }\n\n registerOnChange(fn: (value: Date | null) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.formDisabled.set(isDisabled);\n }\n\n /**\n * Check if date is in current month\n */\n isCurrentMonth(date: Date): boolean {\n return date.getMonth() === this.currentMonth() && date.getFullYear() === this.currentYear();\n }\n\n // Private helper methods\n private commitDate(date: Date): void {\n this.selectedDate.set(date);\n this.inputValue.set(this.formatDate(date, this.format()));\n this.onChange(date);\n this.dateChange.emit(date);\n }\n\n private showMonthOf(date: Date): void {\n this.currentMonth.set(date.getMonth());\n this.currentYear.set(date.getFullYear());\n }\n\n private restoreFocusFromPanel(): void {\n const panel = this.calendarPanel()?.nativeElement;\n const active = this.document.activeElement;\n if (panel && active && panel.contains(active)) {\n this.datepickerInput()?.nativeElement.focus();\n }\n }\n\n private startOfDay(date: Date): number {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();\n }\n\n /**\n * Check if two dates are the same day\n */\n private isSameDate(date1: Date, date2: Date): boolean {\n return (\n date1.getFullYear() === date2.getFullYear() &&\n date1.getMonth() === date2.getMonth() &&\n date1.getDate() === date2.getDate()\n );\n }\n\n private formatDate(date: Date, format: string): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n\n return format.replace('YYYY', String(year)).replace('MM', month).replace('DD', day);\n }\n\n /**\n * Strict parse: the text must match the format's length, carry digits at the\n * YYYY/MM/DD positions and round-trip through formatDate (which rejects\n * things like month 13 or Feb 31 that `new Date` would silently roll over).\n * Returns null for partial or invalid input.\n */\n private parseDate(value: string, format: string): Date | null {\n if (value.length !== format.length) {\n return null;\n }\n\n const yearIndex = format.indexOf('YYYY');\n const monthIndex = format.indexOf('MM');\n const dayIndex = format.indexOf('DD');\n if (yearIndex < 0 || monthIndex < 0 || dayIndex < 0) {\n return null;\n }\n\n const yearText = value.substring(yearIndex, yearIndex + 4);\n const monthText = value.substring(monthIndex, monthIndex + 2);\n const dayText = value.substring(dayIndex, dayIndex + 2);\n if (!/^\\d{4}$/.test(yearText) || !/^\\d{2}$/.test(monthText) || !/^\\d{2}$/.test(dayText)) {\n return null;\n }\n\n const date = new Date(Number(yearText), Number(monthText) - 1, Number(dayText));\n return this.formatDate(date, format) === value ? date : null;\n }\n\n protected getInputValue(event: Event): string {\n return (event.target as HTMLInputElement).value;\n }\n}\n","<div class=\"lc-datepicker-wrapper\">\n <div class=\"lc-datepicker-input-wrapper\">\n <input\n #datepickerInput\n type=\"text\"\n [id]=\"inputId\"\n [class]=\"datepickerClasses()\"\n role=\"combobox\"\n aria-haspopup=\"dialog\"\n autocomplete=\"off\"\n [attr.aria-expanded]=\"isOpen() ? 'true' : 'false'\"\n [attr.aria-controls]=\"isOpen() ? inputId + '-calendar' : null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-required]=\"required() ? 'true' : null\"\n [attr.aria-disabled]=\"isDisabled() ? 'true' : null\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [readonly]=\"readonly()\"\n [disabled]=\"isDisabled()\"\n [placeholder]=\"placeholder()\"\n [value]=\"inputValue()\"\n (input)=\"onInputChange(getInputValue($event))\"\n (click)=\"toggle()\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"onBlur()\"\n />\n <div class=\"lc-datepicker-icons\">\n @if (selectedDate() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"lc-datepicker-clear\"\n (click)=\"clear(); $event.stopPropagation()\"\n [attr.aria-label]=\"clearAriaLabel()\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\"\n />\n </svg>\n </button>\n }\n <svg\n class=\"lc-datepicker-calendar-icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H6a.75.75 0 01-.75-.75V12zM6 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H6zM7.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H8a.75.75 0 01-.75-.75V12zM8 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H8zM9.25 10a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H10a.75.75 0 01-.75-.75V10zM10 11.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V12a.75.75 0 00-.75-.75H10zM9.25 14a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H10a.75.75 0 01-.75-.75V14zM12 9.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V10a.75.75 0 00-.75-.75H12zM11.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H12a.75.75 0 01-.75-.75V12zM12 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H12zM13.25 10a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H14a.75.75 0 01-.75-.75V10zM14 11.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V12a.75.75 0 00-.75-.75H14z\"\n />\n <path\n fill-rule=\"evenodd\"\n d=\"M5.75 2a.75.75 0 01.75.75V4h7V2.75a.75.75 0 011.5 0V4h.25A2.75 2.75 0 0118 6.75v8.5A2.75 2.75 0 0115.25 18H4.75A2.75 2.75 0 012 15.25v-8.5A2.75 2.75 0 014.75 4H5V2.75A.75.75 0 015.75 2zm-1 5.5c-.69 0-1.25.56-1.25 1.25v6.5c0 .69.56 1.25 1.25 1.25h10.5c.69 0 1.25-.56 1.25-1.25v-6.5c0-.69-.56-1.25-1.25-1.25H4.75z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </div>\n </div>\n\n <!-- Calendar Panel -->\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"datepickerInput\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n [cdkConnectedOverlayBackdropClass]=\"'cdk-overlay-transparent-backdrop'\"\n (backdropClick)=\"onClickOutside()\"\n (detach)=\"close()\"\n >\n <div\n #calendarPanel\n class=\"lc-datepicker-calendar\"\n [class.lc-datepicker-calendar--open]=\"isOpen()\"\n [id]=\"inputId + '-calendar'\"\n role=\"dialog\"\n [attr.aria-label]=\"dialogAriaLabel()\"\n >\n <!-- Calendar Header -->\n <div class=\"lc-datepicker-header\">\n <button\n type=\"button\"\n class=\"lc-datepicker-nav-button\"\n (click)=\"previousMonth()\"\n [attr.aria-label]=\"previousMonthAriaLabel()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n fill-rule=\"evenodd\"\n d=\"M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n \n <div class=\"lc-datepicker-month-year\" aria-live=\"polite\">\n {{ currentMonthName() }} {{ currentYear() }}\n </div>\n \n <button\n type=\"button\"\n class=\"lc-datepicker-nav-button\"\n (click)=\"nextMonth()\"\n [attr.aria-label]=\"nextMonthAriaLabel()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n fill-rule=\"evenodd\"\n d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n </div>\n\n <!-- Quick Actions -->\n <div class=\"lc-datepicker-quick-actions\">\n <button\n type=\"button\"\n class=\"lc-datepicker-today-button\"\n (click)=\"goToToday()\"\n >\n {{ todayLabel() }}\n </button>\n </div>\n\n <!-- Weekday Headers -->\n <div class=\"lc-datepicker-weekdays\" aria-hidden=\"true\">\n @for (day of weekdayLabels(); track $index) {\n <div class=\"lc-datepicker-weekday\">{{ day }}</div>\n }\n </div>\n\n <!-- Calendar Days -->\n <div class=\"lc-datepicker-days\">\n @for (date of generateCalendarDays(); track date.getTime()) {\n <button\n type=\"button\"\n class=\"lc-datepicker-day\"\n [class.lc-datepicker-day--other-month]=\"!isCurrentMonth(date)\"\n [class.lc-datepicker-day--today]=\"isToday(date)\"\n [class.lc-datepicker-day--selected]=\"isSelectedDate(date)\"\n [class.lc-datepicker-day--disabled]=\"isDateDisabled(date)\"\n [disabled]=\"isDateDisabled(date)\"\n [attr.aria-current]=\"isToday(date) ? 'date' : null\"\n [attr.aria-label]=\"dayAriaLabel(date)\"\n (click)=\"selectDate(date)\"\n >\n {{ date.getDate() }}\n </button>\n }\n </div>\n </div>\n </ng-template>\n\n <!-- Helper/Error Text -->\n @if (error() && errorMessage()) {\n <div class=\"lc-datepicker__error\" [id]=\"inputId + '-error'\" role=\"alert\">\n {{ errorMessage() }}\n </div>\n } @else if (helperText()) {\n <div class=\"lc-datepicker__helper\" [id]=\"inputId + '-helper'\">\n {{ helperText() }}\n </div>\n }\n</div>\n"],"mappings":"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"}
1
+ {"version":3,"file":"lifecorner-angular-ui-kit-datepicker.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/datepicker/datepicker.component.ts","../../../../libs/angular-ui-kit/src/lib/datepicker/datepicker.component.html"],"sourcesContent":["import {\n Component,\n input,\n output,\n signal,\n computed,\n linkedSignal,\n ChangeDetectionStrategy,\n forwardRef,\n ElementRef,\n viewChild,\n inject,\n DOCUMENT,\n Injector,\n afterNextRender,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { OverlayModule } from '@angular/cdk/overlay';\n\nexport type DateValue = Date | string | null;\n\n/** What `lc-datepicker` picks: a day (`'day'`) or a month (`'month'`). */\nexport type DatepickerGranularity = 'day' | 'month';\n\n/** One cell of the month grid (`granularity=\"month\"`). */\ninterface MonthCell {\n /** 0–11. */\n month: number;\n /** Visible name („Juli“). */\n name: string;\n /** Accessible name with the year („Juli 2026“). */\n label: string;\n selected: boolean;\n current: boolean;\n disabled: boolean;\n}\n\n/**\n * Datepicker component for date selection with calendar overlay.\n *\n * Features:\n * - Calendar popup with month and year navigation\n * - Month granularity (3.29): `granularity=\"month\"` picks a month in a\n * 12-month grid with year navigation and emits its first day\n * - Manual date entry in the configured format\n * - Min/max date constraints\n * - Disabled specific dates and weekends\n * - Configurable date format string\n * - Variant styles (outline, filled)\n * - Size presets (xs, sm, md, lg)\n * - Disabled and readonly states\n * - ControlValueAccessor integration for reactive forms\n *\n * @example\n * ```html\n * <lc-datepicker placeholder=\"Select date\" [(ngModel)]=\"selectedDate\" />\n * <lc-datepicker granularity=\"month\" format=\"YYYY-MM\" placeholder=\"Select a month\" [(ngModel)]=\"validFrom\" />\n * ```\n */\n@Component({\n selector: 'lc-datepicker',\n standalone: true,\n imports: [OverlayModule],\n templateUrl: './datepicker.component.html',\n styleUrl: './datepicker.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => DatepickerComponent),\n multi: true,\n },\n ],\n})\nexport class DatepickerComponent implements ControlValueAccessor {\n private static nextId = 0;\n\n /** Per-instance id for the input; helper/error text ids derive from it. */\n readonly inputId = `lc-datepicker-${++DatepickerComponent.nextId}`;\n\n private readonly datepickerInput = viewChild<ElementRef<HTMLInputElement>>('datepickerInput');\n private readonly calendarPanel = viewChild<ElementRef<HTMLElement>>('calendarPanel');\n\n /**\n * Visual variant of the datepicker\n */\n readonly variant = input<'outline' | 'filled'>('outline');\n\n /**\n * Size of the datepicker\n */\n readonly size = input<'xs' | 'sm' | 'md' | 'lg'>('md');\n\n /**\n * Whether the datepicker is disabled\n */\n readonly disabled = input<boolean>(false);\n\n /**\n * Whether the datepicker is in error state\n */\n readonly error = input<boolean>(false);\n\n /**\n * Whether the datepicker is required\n */\n readonly required = input<boolean>(false);\n\n /**\n * Whether the datepicker is readonly\n */\n readonly readonly = input<boolean>(false);\n\n /**\n * Placeholder text\n */\n readonly placeholder = input<string>('Select a date');\n\n /**\n * Helper text displayed below the datepicker\n */\n readonly helperText = input<string>('');\n\n /**\n * Error message displayed when error is true\n */\n readonly errorMessage = input<string>('');\n\n /**\n * ARIA label for accessibility\n */\n readonly ariaLabel = input<string | undefined>(undefined);\n\n /**\n * Date format string (e.g., 'YYYY-MM-DD', 'MM/DD/YYYY')\n */\n readonly format = input<string>('YYYY-MM-DD');\n\n /**\n * Minimum selectable date (compared by calendar day, time of day is ignored)\n */\n readonly minDate = input<Date | undefined>(undefined);\n\n /**\n * Maximum selectable date (compared by calendar day, time of day is ignored)\n */\n readonly maxDate = input<Date | undefined>(undefined);\n\n /**\n * Array of disabled dates\n */\n readonly disabledDates = input<Date[]>([]);\n\n /**\n * Whether to disable weekends\n */\n readonly disableWeekends = input<boolean>(false);\n\n /** BCP 47 locale for month and weekday names and the day buttons' accessible names (e.g. `'de-DE'`). Empty keeps the built-in English names. */\n readonly locale = input('');\n\n /** First column of the grid: 0 Sunday (default) … 6 Saturday — 1 for Monday. */\n readonly firstDayOfWeek = input(0);\n\n /** Accessible name of the clear button. */\n readonly clearAriaLabel = input('Clear date');\n\n /** Accessible name of the calendar dialog. */\n readonly dialogAriaLabel = input('Choose date');\n\n /** Accessible name of the previous-month button. */\n readonly previousMonthAriaLabel = input('Previous month');\n\n /** Accessible name of the next-month button. */\n readonly nextMonthAriaLabel = input('Next month');\n\n /** Label of the \"go to today\" button. */\n readonly todayLabel = input('Today');\n\n /** Appended to the selected day's accessible name (`…, selected`). */\n readonly selectedAriaLabel = input('selected');\n\n /**\n * Pick a day (`'day'`) or a month (`'month'`, 3.29, regeln row 1). Month:\n * a 12-month grid with year navigation; `dateChange` and the forms value\n * are the 1st of the month (local midnight, as day mode); `format` should\n * be a month format (`'YYYY-MM'`; a `DD` token shows `01`), and typing\n * „2026-07“ commits like a day. `minDate`/`maxDate` keep a month\n * selectable when any of its days is in range; a `disabledDates` entry\n * disables its whole month; `disableWeekends` is ignored. Set\n * `placeholder` (e.g. \"Select a month\"). Keys in the grid: arrows move by\n * month and row, PageUp/PageDown by year, Home/End to the first/last month\n * of the year, Enter/Space select, Escape closes.\n * @default 'day'\n */\n readonly granularity = input<DatepickerGranularity>('day');\n\n /**\n * Accessible name of the previous-year button (month mode).\n * @default 'Previous year'\n */\n readonly previousYearAriaLabel = input('Previous year');\n\n /**\n * Accessible name of the next-year button (month mode).\n * @default 'Next year'\n */\n readonly nextYearAriaLabel = input('Next year');\n\n /**\n * Accessible name of the month dialog (month mode; `dialogAriaLabel`\n * stays the day dialog's).\n * @default 'Choose month'\n */\n readonly monthDialogAriaLabel = input('Choose month');\n\n /**\n * Label of the quick action that shows the current year (month mode; day\n * mode keeps `todayLabel`).\n * @default 'This month'\n */\n readonly currentMonthLabel = input('This month');\n\n /**\n * Emitted when date selection changes\n */\n readonly dateChange = output<Date | null>();\n\n /**\n * Emitted when calendar opens\n */\n readonly opened = output<void>();\n\n /**\n * Emitted when calendar closes\n */\n readonly closed = output<void>();\n\n // Internal state\n readonly selectedDate = signal<Date | null>(null);\n readonly isOpen = signal<boolean>(false);\n readonly currentMonth = signal<number>(new Date().getMonth());\n readonly currentYear = signal<number>(new Date().getFullYear());\n\n /** Disabled state pushed in by the forms API (setDisabledState). */\n private readonly formDisabled = signal<boolean>(false);\n\n /** Effective disabled state: the `disabled` input OR the form control's disabled state. */\n readonly isDisabled = computed(() => this.disabled() || this.formDisabled());\n\n /** Month granularity (3.29). */\n protected readonly isMonthMode = computed(() => this.granularity() === 'month');\n\n // Computed values\n readonly formattedDate = computed(() => {\n const date = this.selectedDate();\n if (!date) return '';\n // Month mode shows the month: a `DD` token is the 1st.\n const shown = this.isMonthMode() ? new Date(date.getFullYear(), date.getMonth(), 1) : date;\n return this.formatDate(shown, this.format());\n });\n\n /**\n * Text currently shown in the input. Follows the selected date, but the user\n * can type freely; only a complete, valid date is committed to the model.\n */\n readonly inputValue = linkedSignal(() => this.formattedDate());\n\n weekDays = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];\n\n monthNames = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ];\n\n /** Month name in the header: `locale` when set, the English names otherwise. */\n readonly currentMonthName = computed(() => {\n const locale = this.locale();\n return locale\n ? new Date(this.currentYear(), this.currentMonth(), 1).toLocaleDateString(locale, { month: 'long' })\n : this.monthNames[this.currentMonth()];\n });\n\n /** Weekday headers in grid order, starting at `firstDayOfWeek`. */\n readonly weekdayLabels = computed(() => {\n const locale = this.locale();\n const first = this.gridStart();\n // 1 Jan 2023 was a Sunday, so day d of that week has getDay() === d.\n const names = locale\n ? Array.from({ length: 7 }, (_, d) =>\n new Date(2023, 0, 1 + d).toLocaleDateString(locale, { weekday: 'short' }).replace(/\\.$/, ''),\n )\n : this.weekDays;\n return Array.from({ length: 7 }, (_, i) => names[(first + i) % 7]);\n });\n\n /** Header title: „July 2026“ (day mode) or the year „2026“ (month mode). */\n protected readonly headerTitle = computed(() =>\n this.isMonthMode() ? String(this.currentYear()) : `${this.currentMonthName()} ${this.currentYear()}`,\n );\n\n /** The twelve months of the shown year (month mode). */\n protected readonly monthCells = computed<MonthCell[]>(() => {\n const year = this.currentYear();\n const locale = this.locale();\n const selected = this.selectedDate();\n const today = new Date();\n return Array.from({ length: 12 }, (_, month) => {\n const first = new Date(year, month, 1);\n return {\n month,\n name: locale ? first.toLocaleDateString(locale, { month: 'long' }) : this.monthNames[month],\n label: first.toLocaleDateString(locale || 'en-US', { month: 'long', year: 'numeric' }),\n selected: !!selected && selected.getFullYear() === year && selected.getMonth() === month,\n current: today.getFullYear() === year && today.getMonth() === month,\n disabled: this.isMonthDisabled(year, month),\n };\n });\n });\n\n /** The month grid's four rows of three. */\n protected readonly monthRows = computed(() => [0, 3, 6, 9].map((i) => this.monthCells().slice(i, i + 3)));\n\n /**\n * The month cell that is the grid's one tab stop (roving `tabindex`): the\n * selected month in the shown year, else the current month, else the first\n * enabled one; `-1` when the whole year is disabled. Keys move it.\n */\n protected readonly monthTabStop = linkedSignal(() => this.defaultMonthTabStop());\n\n /** `firstDayOfWeek` clamped to 0–6. */\n private readonly gridStart = computed(() => {\n const day = Math.trunc(Number(this.firstDayOfWeek()));\n return Number.isFinite(day) ? ((day % 7) + 7) % 7 : 0;\n });\n\n /** id of the helper/error text the input is described by (aria-describedby) */\n readonly describedBy = computed(() => {\n if (this.error() && this.errorMessage()) {\n return `${this.inputId}-error`;\n }\n return this.helperText() ? `${this.inputId}-helper` : null;\n });\n\n /**\n * Computed classes for the datepicker input element\n */\n readonly datepickerClasses = computed(() => {\n const classes = [\n 'lc-datepicker',\n `lc-datepicker--${this.variant()}`,\n `lc-datepicker--${this.size()}`,\n ];\n\n if (this.isDisabled()) {\n classes.push('lc-datepicker--disabled');\n }\n\n if (this.error()) {\n classes.push('lc-datepicker--error');\n }\n\n if (this.readonly()) {\n classes.push('lc-datepicker--readonly');\n }\n\n if (this.isOpen()) {\n classes.push('lc-datepicker--open');\n }\n\n return classes.join(' ');\n });\n\n // Private properties\n private readonly document = inject(DOCUMENT);\n private readonly injector = inject(Injector);\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n private onChange: (value: Date | null) => void = () => {};\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n private onTouched: () => void = () => {};\n\n // Public methods\n /**\n * Toggle calendar open/closed\n */\n toggle(): void {\n if (this.isDisabled() || this.readonly()) {\n return;\n }\n if (this.isOpen()) {\n this.close();\n } else {\n this.open();\n }\n }\n\n /**\n * Open calendar\n */\n open(): void {\n if (this.isDisabled() || this.readonly() || this.isOpen()) {\n return;\n }\n this.isOpen.set(true);\n\n // Set calendar to selected date's month/year or current\n const date = this.selectedDate();\n if (date) {\n this.showMonthOf(date);\n }\n // Month mode: the grid's tab stop starts on the selected (or current) month again.\n if (this.isMonthMode()) {\n this.monthTabStop.set(this.defaultMonthTabStop());\n }\n\n this.opened.emit();\n }\n\n /**\n * Close calendar. Idempotent: the overlay's `detach` re-enters here after\n * `isOpen` flips, and that second call must not emit `closed` again.\n */\n close(): void {\n if (!this.isOpen()) {\n return;\n }\n // A day button inside the panel may hold focus; it is about to be removed,\n // so hand focus back to the input instead of letting it drop to <body>.\n this.restoreFocusFromPanel();\n this.isOpen.set(false);\n this.closed.emit();\n }\n\n /**\n * Select a date\n */\n selectDate(date: Date): void {\n if (this.isDisabled() || this.readonly() || this.isDateDisabled(date)) {\n return;\n }\n\n this.commitDate(date);\n this.close();\n }\n\n /**\n * Clear selected date\n */\n clear(): void {\n this.selectedDate.set(null);\n this.inputValue.set('');\n this.onChange(null);\n this.dateChange.emit(null);\n }\n\n /**\n * Check if a date is disabled\n */\n isDateDisabled(date: Date): boolean {\n // min/max are compared by calendar day: consumers typically pass `new Date()`\n // (which carries the current time) while calendar cells sit at midnight.\n const day = this.startOfDay(date);\n\n const min = this.minDate();\n if (min && day < this.startOfDay(min)) {\n return true;\n }\n\n const max = this.maxDate();\n if (max && day > this.startOfDay(max)) {\n return true;\n }\n\n // Check disabled dates\n if (this.disabledDates().some((d) => this.isSameDate(d, date))) {\n return true;\n }\n\n // Check weekends\n if (this.disableWeekends()) {\n const weekday = date.getDay();\n if (weekday === 0 || weekday === 6) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Check if date is today\n */\n isToday(date: Date): boolean {\n const today = new Date();\n return this.isSameDate(date, today);\n }\n\n /** Accessible name of a day button: the full date, plus `selectedAriaLabel` when selected. */\n protected dayAriaLabel(date: Date): string {\n const locale = this.locale();\n const name = locale\n ? date.toLocaleDateString(locale, { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' })\n : date.toDateString();\n return this.isSelectedDate(date) ? `${name}, ${this.selectedAriaLabel()}` : name;\n }\n\n /**\n * Check if date is selected\n */\n isSelectedDate(date: Date): boolean {\n const selected = this.selectedDate();\n return selected ? this.isSameDate(date, selected) : false;\n }\n\n /**\n * Generate calendar days for current month\n */\n generateCalendarDays(): Date[] {\n const year = this.currentYear();\n const month = this.currentMonth();\n\n const firstDay = new Date(year, month, 1);\n const lastDay = new Date(year, month + 1, 0);\n\n const days: Date[] = [];\n\n // Add previous month's days, so the first column is `firstDayOfWeek`.\n const leadingDays = (firstDay.getDay() - this.gridStart() + 7) % 7;\n for (let i = leadingDays - 1; i >= 0; i--) {\n const date = new Date(year, month, -i);\n days.push(date);\n }\n\n // Add current month's days\n for (let i = 1; i <= lastDay.getDate(); i++) {\n days.push(new Date(year, month, i));\n }\n\n // Add next month's days to complete the grid\n const remainingDays = 42 - days.length; // 6 weeks * 7 days\n for (let i = 1; i <= remainingDays; i++) {\n days.push(new Date(year, month + 1, i));\n }\n\n return days.slice(0, 42); // Ensure exactly 42 days (6 weeks)\n }\n\n /**\n * Navigate to next month\n */\n nextMonth(): void {\n if (this.currentMonth() === 11) {\n this.currentMonth.set(0);\n this.currentYear.set(this.currentYear() + 1);\n } else {\n this.currentMonth.set(this.currentMonth() + 1);\n }\n }\n\n /**\n * Navigate to previous month\n */\n previousMonth(): void {\n if (this.currentMonth() === 0) {\n this.currentMonth.set(11);\n this.currentYear.set(this.currentYear() - 1);\n } else {\n this.currentMonth.set(this.currentMonth() - 1);\n }\n }\n\n /**\n * Navigate to today\n */\n goToToday(): void {\n this.showMonthOf(new Date());\n }\n\n /** Month mode: show the previous year. */\n protected previousYear(): void {\n this.currentYear.update((year) => year - 1);\n }\n\n /** Month mode: show the next year. */\n protected nextYear(): void {\n this.currentYear.update((year) => year + 1);\n }\n\n /** Month mode's quick action: show the current year. */\n protected showCurrentYear(): void {\n this.currentYear.set(new Date().getFullYear());\n }\n\n /** Month mode: select `month` of the shown year (its 1st), emit, close and focus the field. */\n protected selectMonth(month: number): void {\n const year = this.currentYear();\n if (this.isDisabled() || this.readonly() || this.isMonthDisabled(year, month)) {\n return;\n }\n this.commitDate(new Date(year, month, 1));\n this.close();\n }\n\n /**\n * Keys on a month cell (APG date grid): arrows ±1 month and ±3 (a row),\n * PageUp/PageDown ±1 year (the nearest enabled month of that year),\n * Home/End the first/last enabled month of the year; disabled months are\n * skipped, and with none left focus stays. Enter/Space select, Escape\n * closes. Arrows only move focus.\n */\n protected onMonthKeydown(event: KeyboardEvent, month: number): void {\n const year = this.currentYear();\n const at = year * 12 + month;\n let target: number | null;\n switch (event.key) {\n case 'ArrowLeft':\n target = this.nextEnabledMonth(at, -1);\n break;\n case 'ArrowRight':\n target = this.nextEnabledMonth(at, 1);\n break;\n case 'ArrowUp':\n target = this.nextEnabledMonth(at, -3);\n break;\n case 'ArrowDown':\n target = this.nextEnabledMonth(at, 3);\n break;\n case 'PageUp':\n target = this.nearestEnabledMonth(year - 1, month);\n break;\n case 'PageDown':\n target = this.nearestEnabledMonth(year + 1, month);\n break;\n case 'Home':\n target = this.edgeEnabledMonth(year, 1);\n break;\n case 'End':\n target = this.edgeEnabledMonth(year, -1);\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this.selectMonth(month);\n return;\n case 'Escape':\n event.preventDefault();\n // Only this datepicker should react; keep the key from reaching enclosing overlays.\n event.stopPropagation();\n this.close();\n return;\n default:\n return;\n }\n event.preventDefault();\n if (target !== null) {\n this.moveMonthFocus(target);\n }\n }\n\n /**\n * Handle input change (manual date entry). Partial input is kept as text\n * only; the model changes once the text is a complete, valid, selectable date.\n */\n onInputChange(value: string): void {\n this.inputValue.set(value);\n\n if (value.trim() === '') {\n if (this.selectedDate() !== null) {\n this.clear();\n }\n return;\n }\n\n const date = this.parseDate(value, this.format());\n if (date && !this.isUnavailable(date) && !this.isSameSelection(date)) {\n this.commitDate(date);\n this.showMonthOf(date);\n }\n }\n\n /**\n * Handle keyboard navigation\n */\n onKeyDown(event: KeyboardEvent): void {\n if (this.isDisabled() || this.readonly()) {\n return;\n }\n\n if (\n !this.isOpen() &&\n (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ')\n ) {\n this.open();\n event.preventDefault();\n // Month mode: the keys work in the grid, so focus moves there once it is rendered.\n if (this.isMonthMode()) {\n afterNextRender(() => this.focusMonthCell(this.monthTabStop()), { injector: this.injector });\n }\n return;\n }\n\n if (!this.isOpen()) return;\n\n if (this.isMonthMode()) {\n this.onMonthFieldKeyDown(event);\n return;\n }\n\n // While the text differs from the model the user is mid-edit: arrows must\n // move the caret, not the calendar selection.\n const editing = this.inputValue() !== this.formattedDate();\n const currentDate = this.selectedDate() || new Date();\n let newDate: Date | null = null;\n\n switch (event.key) {\n case 'Escape':\n this.close();\n event.preventDefault();\n // Only this datepicker should react; keep the key from reaching enclosing overlays.\n event.stopPropagation();\n break;\n\n case 'ArrowRight':\n if (editing) break;\n newDate = new Date(currentDate);\n newDate.setDate(currentDate.getDate() + 1);\n event.preventDefault();\n break;\n\n case 'ArrowLeft':\n if (editing) break;\n newDate = new Date(currentDate);\n newDate.setDate(currentDate.getDate() - 1);\n event.preventDefault();\n break;\n\n case 'ArrowDown':\n if (editing) break;\n newDate = new Date(currentDate);\n newDate.setDate(currentDate.getDate() + 7);\n event.preventDefault();\n break;\n\n case 'ArrowUp':\n if (editing) break;\n newDate = new Date(currentDate);\n newDate.setDate(currentDate.getDate() - 7);\n event.preventDefault();\n break;\n\n case 'Enter': {\n const selected = this.selectedDate();\n if (selected) {\n this.selectDate(selected);\n }\n event.preventDefault();\n break;\n }\n }\n\n if (newDate && !this.isDateDisabled(newDate)) {\n this.selectedDate.set(newDate);\n this.showMonthOf(newDate);\n }\n }\n\n /**\n * Handle blur event: mark touched and drop any partial text that never became a date.\n */\n onBlur(): void {\n this.onTouched();\n this.inputValue.set(this.formattedDate());\n }\n\n /**\n * Handle click outside\n */\n onClickOutside(): void {\n this.close();\n }\n\n // ControlValueAccessor implementation\n writeValue(value: DateValue): void {\n let date: Date | null = null;\n if (value instanceof Date) {\n date = isNaN(value.getTime()) ? null : value;\n } else if (typeof value === 'string') {\n date = this.parseDate(value, this.format());\n }\n this.selectedDate.set(date);\n this.inputValue.set(this.formattedDate());\n }\n\n registerOnChange(fn: (value: Date | null) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.formDisabled.set(isDisabled);\n }\n\n /**\n * Check if date is in current month\n */\n isCurrentMonth(date: Date): boolean {\n return date.getMonth() === this.currentMonth() && date.getFullYear() === this.currentYear();\n }\n\n // Private helper methods\n\n /** The selected month of the shown year, else the current month, else the first enabled one; `-1` if none. */\n private defaultMonthTabStop(): number {\n const cells = this.monthCells().filter((c) => !c.disabled);\n return (cells.find((c) => c.selected) ?? cells.find((c) => c.current) ?? cells[0])?.month ?? -1;\n }\n\n /**\n * Keys in the field while the month panel is open: ArrowDown moves focus\n * into the grid, Escape closes, Enter closes when a month is selected;\n * the other keys stay with the text (caret, typing „2026-07“).\n */\n private onMonthFieldKeyDown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n this.focusMonthCell(this.monthTabStop());\n break;\n case 'Escape':\n this.close();\n event.preventDefault();\n // Only this datepicker should react; keep the key from reaching enclosing overlays.\n event.stopPropagation();\n break;\n case 'Enter':\n event.preventDefault();\n if (this.selectedDate()) {\n this.close();\n }\n break;\n }\n }\n\n /**\n * Month mode: a month is disabled when all its days are before `minDate`\n * or after `maxDate` (compared by day), or when `disabledDates` holds one\n * of its days. `disableWeekends` does not apply.\n */\n private isMonthDisabled(year: number, month: number): boolean {\n const min = this.minDate();\n if (min && new Date(year, month + 1, 0).getTime() < this.startOfDay(min)) {\n return true;\n }\n const max = this.maxDate();\n if (max && new Date(year, month, 1).getTime() > this.startOfDay(max)) {\n return true;\n }\n return this.disabledDates().some((d) => d.getFullYear() === year && d.getMonth() === month);\n }\n\n /** A typed date that cannot be committed: its day (day mode) or its month (month mode) is disabled. */\n private isUnavailable(date: Date): boolean {\n return this.isMonthMode() ? this.isMonthDisabled(date.getFullYear(), date.getMonth()) : this.isDateDisabled(date);\n }\n\n /** Whether `date` is the current selection: the same day, or in month mode the same month. */\n private isSameSelection(date: Date): boolean {\n if (!this.isMonthMode()) return this.isSelectedDate(date);\n const selected = this.selectedDate();\n return !!selected && selected.getFullYear() === date.getFullYear() && selected.getMonth() === date.getMonth();\n }\n\n /** Year and month (0–11) of a month index `year * 12 + month`. */\n private monthAt(index: number): { year: number; month: number } {\n return { year: Math.floor(index / 12), month: ((index % 12) + 12) % 12 };\n }\n\n /** The next enabled month from `index` in steps of `step` (up to ten years), or `null`. */\n private nextEnabledMonth(index: number, step: number): number | null {\n for (let i = 1; i * Math.abs(step) <= 120; i++) {\n const { year, month } = this.monthAt(index + step * i);\n if (!this.isMonthDisabled(year, month)) return index + step * i;\n }\n return null;\n }\n\n /** `month` of `year` if enabled, else the enabled month of that year nearest to it, or `null`. */\n private nearestEnabledMonth(year: number, month: number): number | null {\n for (let d = 0; d < 12; d++) {\n for (const m of d === 0 ? [month] : [month - d, month + d]) {\n if (m >= 0 && m < 12 && !this.isMonthDisabled(year, m)) return year * 12 + m;\n }\n }\n return null;\n }\n\n /** The first (`dir` 1) or last (`dir` -1) enabled month of `year`, or `null`. */\n private edgeEnabledMonth(year: number, dir: 1 | -1): number | null {\n for (let i = 0; i < 12; i++) {\n const month = dir === 1 ? i : 11 - i;\n if (!this.isMonthDisabled(year, month)) return year * 12 + month;\n }\n return null;\n }\n\n /** Moves the grid's tab stop and focus to the month `index`; the shown year follows. */\n private moveMonthFocus(index: number): void {\n const { year, month } = this.monthAt(index);\n if (year !== this.currentYear()) {\n this.currentYear.set(year);\n }\n this.monthTabStop.set(month);\n this.focusMonthCell(month);\n }\n\n /** Focuses the month cell `month` (0–11) of the open panel; the cells are kept across years. */\n private focusMonthCell(month: number): void {\n if (month < 0) return;\n this.calendarPanel()\n ?.nativeElement.querySelectorAll<HTMLElement>('.lc-datepicker-month')\n [month]?.focus();\n }\n\n private commitDate(date: Date): void {\n this.selectedDate.set(date);\n this.inputValue.set(this.formatDate(date, this.format()));\n this.onChange(date);\n this.dateChange.emit(date);\n }\n\n private showMonthOf(date: Date): void {\n this.currentMonth.set(date.getMonth());\n this.currentYear.set(date.getFullYear());\n }\n\n private restoreFocusFromPanel(): void {\n const panel = this.calendarPanel()?.nativeElement;\n const active = this.document.activeElement;\n if (panel && active && panel.contains(active)) {\n this.datepickerInput()?.nativeElement.focus();\n }\n }\n\n private startOfDay(date: Date): number {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();\n }\n\n /**\n * Check if two dates are the same day\n */\n private isSameDate(date1: Date, date2: Date): boolean {\n return (\n date1.getFullYear() === date2.getFullYear() &&\n date1.getMonth() === date2.getMonth() &&\n date1.getDate() === date2.getDate()\n );\n }\n\n private formatDate(date: Date, format: string): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n\n return format.replace('YYYY', String(year)).replace('MM', month).replace('DD', day);\n }\n\n /**\n * Strict parse: the text must match the format's length, carry digits at the\n * YYYY/MM/DD positions and round-trip through formatDate (which rejects\n * things like month 13 or Feb 31 that `new Date` would silently roll over).\n * Returns null for partial or invalid input. Month mode also takes a format\n * without `DD` (`YYYY-MM`) and returns the 1st of the month.\n */\n private parseDate(value: string, format: string): Date | null {\n if (value.length !== format.length) {\n return null;\n }\n\n const monthMode = this.isMonthMode();\n const yearIndex = format.indexOf('YYYY');\n const monthIndex = format.indexOf('MM');\n const dayIndex = format.indexOf('DD');\n if (yearIndex < 0 || monthIndex < 0 || (dayIndex < 0 && !monthMode)) {\n return null;\n }\n\n const yearText = value.substring(yearIndex, yearIndex + 4);\n const monthText = value.substring(monthIndex, monthIndex + 2);\n const dayText = dayIndex < 0 ? '01' : value.substring(dayIndex, dayIndex + 2);\n if (!/^\\d{4}$/.test(yearText) || !/^\\d{2}$/.test(monthText) || !/^\\d{2}$/.test(dayText)) {\n return null;\n }\n\n const date = new Date(Number(yearText), Number(monthText) - 1, Number(dayText));\n if (this.formatDate(date, format) !== value) {\n return null;\n }\n return monthMode ? new Date(date.getFullYear(), date.getMonth(), 1) : date;\n }\n\n protected getInputValue(event: Event): string {\n return (event.target as HTMLInputElement).value;\n }\n}\n","<div class=\"lc-datepicker-wrapper\">\n <div class=\"lc-datepicker-input-wrapper\">\n <input\n #datepickerInput\n type=\"text\"\n [id]=\"inputId\"\n [class]=\"datepickerClasses()\"\n role=\"combobox\"\n aria-haspopup=\"dialog\"\n autocomplete=\"off\"\n [attr.aria-expanded]=\"isOpen() ? 'true' : 'false'\"\n [attr.aria-controls]=\"isOpen() ? inputId + '-calendar' : null\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-required]=\"required() ? 'true' : null\"\n [attr.aria-disabled]=\"isDisabled() ? 'true' : null\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [readonly]=\"readonly()\"\n [disabled]=\"isDisabled()\"\n [placeholder]=\"placeholder()\"\n [value]=\"inputValue()\"\n (input)=\"onInputChange(getInputValue($event))\"\n (click)=\"toggle()\"\n (keydown)=\"onKeyDown($event)\"\n (blur)=\"onBlur()\"\n />\n <div class=\"lc-datepicker-icons\">\n @if (selectedDate() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"lc-datepicker-clear\"\n (click)=\"clear(); $event.stopPropagation()\"\n [attr.aria-label]=\"clearAriaLabel()\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z\"\n />\n </svg>\n </button>\n }\n <svg\n class=\"lc-datepicker-calendar-icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M5.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H6a.75.75 0 01-.75-.75V12zM6 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H6zM7.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H8a.75.75 0 01-.75-.75V12zM8 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H8zM9.25 10a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H10a.75.75 0 01-.75-.75V10zM10 11.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V12a.75.75 0 00-.75-.75H10zM9.25 14a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H10a.75.75 0 01-.75-.75V14zM12 9.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V10a.75.75 0 00-.75-.75H12zM11.25 12a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H12a.75.75 0 01-.75-.75V12zM12 13.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V14a.75.75 0 00-.75-.75H12zM13.25 10a.75.75 0 01.75-.75h.01a.75.75 0 01.75.75v.01a.75.75 0 01-.75.75H14a.75.75 0 01-.75-.75V10zM14 11.25a.75.75 0 00-.75.75v.01c0 .414.336.75.75.75h.01a.75.75 0 00.75-.75V12a.75.75 0 00-.75-.75H14z\"\n />\n <path\n fill-rule=\"evenodd\"\n d=\"M5.75 2a.75.75 0 01.75.75V4h7V2.75a.75.75 0 011.5 0V4h.25A2.75 2.75 0 0118 6.75v8.5A2.75 2.75 0 0115.25 18H4.75A2.75 2.75 0 012 15.25v-8.5A2.75 2.75 0 014.75 4H5V2.75A.75.75 0 015.75 2zm-1 5.5c-.69 0-1.25.56-1.25 1.25v6.5c0 .69.56 1.25 1.25 1.25h10.5c.69 0 1.25-.56 1.25-1.25v-6.5c0-.69-.56-1.25-1.25-1.25H4.75z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </div>\n </div>\n\n <!-- Calendar Panel -->\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"datepickerInput\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n [cdkConnectedOverlayBackdropClass]=\"'cdk-overlay-transparent-backdrop'\"\n (backdropClick)=\"onClickOutside()\"\n (detach)=\"close()\"\n >\n <div\n #calendarPanel\n class=\"lc-datepicker-calendar\"\n [class.lc-datepicker-calendar--open]=\"isOpen()\"\n [class.lc-datepicker-calendar--month]=\"isMonthMode()\"\n [id]=\"inputId + '-calendar'\"\n role=\"dialog\"\n [attr.aria-label]=\"isMonthMode() ? monthDialogAriaLabel() : dialogAriaLabel()\"\n >\n <!-- Calendar Header (month mode, 3.29: the year and year buttons) -->\n <div class=\"lc-datepicker-header\">\n <button\n type=\"button\"\n class=\"lc-datepicker-nav-button\"\n (click)=\"isMonthMode() ? previousYear() : previousMonth()\"\n [attr.aria-label]=\"isMonthMode() ? previousYearAriaLabel() : previousMonthAriaLabel()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n fill-rule=\"evenodd\"\n d=\"M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n \n <div class=\"lc-datepicker-month-year\" aria-live=\"polite\" [attr.id]=\"isMonthMode() ? inputId + '-year' : null\">\n {{ headerTitle() }}\n </div>\n\n <button\n type=\"button\"\n class=\"lc-datepicker-nav-button\"\n (click)=\"isMonthMode() ? nextYear() : nextMonth()\"\n [attr.aria-label]=\"isMonthMode() ? nextYearAriaLabel() : nextMonthAriaLabel()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path\n fill-rule=\"evenodd\"\n d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n </div>\n\n <!-- Quick Actions -->\n <div class=\"lc-datepicker-quick-actions\">\n <button\n type=\"button\"\n class=\"lc-datepicker-today-button\"\n (click)=\"isMonthMode() ? showCurrentYear() : goToToday()\"\n >\n {{ isMonthMode() ? currentMonthLabel() : todayLabel() }}\n </button>\n </div>\n\n @if (isMonthMode()) {\n <!-- Month grid (3.29): APG grid, one roving tab stop, named by the year title -->\n <div class=\"lc-datepicker-months\" role=\"grid\" [attr.aria-labelledby]=\"inputId + '-year'\">\n @for (row of monthRows(); track $index) {\n <div class=\"lc-datepicker-month-row\" role=\"row\">\n @for (cell of row; track cell.month) {\n <div\n role=\"gridcell\"\n class=\"lc-datepicker-month\"\n [class.lc-datepicker-month--current]=\"cell.current\"\n [class.lc-datepicker-month--selected]=\"cell.selected\"\n [class.lc-datepicker-month--disabled]=\"cell.disabled\"\n [attr.tabindex]=\"cell.month === monthTabStop() ? 0 : -1\"\n [attr.aria-selected]=\"cell.selected ? 'true' : null\"\n [attr.aria-current]=\"cell.current ? 'date' : null\"\n [attr.aria-disabled]=\"cell.disabled ? 'true' : null\"\n [attr.aria-label]=\"cell.label\"\n (click)=\"selectMonth(cell.month)\"\n (keydown)=\"onMonthKeydown($event, cell.month)\"\n >{{ cell.name }}</div>\n }\n </div>\n }\n </div>\n } @else {\n <!-- Weekday Headers -->\n <div class=\"lc-datepicker-weekdays\" aria-hidden=\"true\">\n @for (day of weekdayLabels(); track $index) {\n <div class=\"lc-datepicker-weekday\">{{ day }}</div>\n }\n </div>\n\n <!-- Calendar Days -->\n <div class=\"lc-datepicker-days\">\n @for (date of generateCalendarDays(); track date.getTime()) {\n <button\n type=\"button\"\n class=\"lc-datepicker-day\"\n [class.lc-datepicker-day--other-month]=\"!isCurrentMonth(date)\"\n [class.lc-datepicker-day--today]=\"isToday(date)\"\n [class.lc-datepicker-day--selected]=\"isSelectedDate(date)\"\n [class.lc-datepicker-day--disabled]=\"isDateDisabled(date)\"\n [disabled]=\"isDateDisabled(date)\"\n [attr.aria-current]=\"isToday(date) ? 'date' : null\"\n [attr.aria-label]=\"dayAriaLabel(date)\"\n (click)=\"selectDate(date)\"\n >\n {{ date.getDate() }}\n </button>\n }\n </div>\n }\n </div>\n </ng-template>\n\n <!-- Helper/Error Text -->\n @if (error() && errorMessage()) {\n <div class=\"lc-datepicker__error\" [id]=\"inputId + '-error'\" role=\"alert\">\n {{ errorMessage() }}\n </div>\n } @else if (helperText()) {\n <div class=\"lc-datepicker__helper\" [id]=\"inputId + '-helper'\">\n {{ helperText() }}\n </div>\n }\n</div>\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import * as i0 from "@angular/core";
2
- import { Injectable } from "@angular/core";
2
+ import { Injectable, signal } from "@angular/core";
3
3
  var OverlayStackService = class OverlayStackService {
4
4
  stack = [];
5
5
  claimed = /* @__PURE__ */ new WeakSet();
@@ -45,6 +45,35 @@ i0.ɵɵngDeclareClassMetadata({
45
45
  args: [{ providedIn: "root" }]
46
46
  }]
47
47
  });
48
- export { OverlayStackService };
48
+ var OverlayInsetsService = class OverlayInsetsService {
49
+ top = signal(null, ...ngDevMode ? [{ debugName: "top" }] : /* istanbul ignore next */ []);
50
+ bottom = signal(null, ...ngDevMode ? [{ debugName: "bottom" }] : /* istanbul ignore next */ []);
51
+ static ɵfac = i0.ɵɵngDeclareFactory({
52
+ minVersion: "12.0.0",
53
+ version: "22.2.2",
54
+ ngImport: i0,
55
+ type: OverlayInsetsService,
56
+ deps: [],
57
+ target: i0.ɵɵFactoryTarget.Injectable
58
+ });
59
+ static ɵprov = i0.ɵɵngDeclareInjectable({
60
+ minVersion: "12.0.0",
61
+ version: "22.2.2",
62
+ ngImport: i0,
63
+ type: OverlayInsetsService,
64
+ providedIn: "root"
65
+ });
66
+ };
67
+ i0.ɵɵngDeclareClassMetadata({
68
+ minVersion: "12.0.0",
69
+ version: "22.2.2",
70
+ ngImport: i0,
71
+ type: OverlayInsetsService,
72
+ decorators: [{
73
+ type: Injectable,
74
+ args: [{ providedIn: "root" }]
75
+ }]
76
+ });
77
+ export { OverlayInsetsService, OverlayStackService };
49
78
 
50
79
  //# sourceMappingURL=lifecorner-angular-ui-kit-internal-overlay.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"lifecorner-angular-ui-kit-internal-overlay.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/internal/overlay/overlay-stack.service.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\n\n/**\n * Keeps the open overlays (modal, drawer, popover, menu, tooltip, …) in\n * opening order so that a dismiss gesture — Escape, click outside — reaches\n * only the top-most one instead of closing every open layer at once.\n *\n * Every overlay pushes its id when it opens and removes it when it closes or\n * is destroyed. Internal to the library; not part of the public API.\n */\n@Injectable({ providedIn: 'root' })\nexport class OverlayStackService {\n private readonly stack: string[] = [];\n\n /**\n * Events already consumed by an overlay. All overlays listen on `document`,\n * where listeners fire in registration order — not z-order — so by the time a\n * lower overlay's listener runs, the top one may already have closed and left\n * the stack, making the lower one \"top\" for the very same event.\n */\n private readonly claimed = new WeakSet<Event>();\n\n /** Register `id` as the new top-most overlay (re-pushing moves it to the top). */\n push(id: string): void {\n this.remove(id);\n this.stack.push(id);\n }\n\n remove(id: string): void {\n const index = this.stack.indexOf(id);\n if (index !== -1) this.stack.splice(index, 1);\n }\n\n isTop(id: string): boolean {\n return this.stack.length > 0 && this.stack[this.stack.length - 1] === id;\n }\n\n /**\n * Whether overlay `id` may act on this dismiss event. True only for the\n * top-most overlay and only once per event; the caller then closes and, for\n * keyboard events, stops propagation so nothing outside the stack sees it.\n */\n claim(id: string, event: Event): boolean {\n if (this.claimed.has(event) || !this.isTop(id)) return false;\n this.claimed.add(event);\n return true;\n }\n}\n"],"mappings":";;AAWA,IAAa,sBAAb,MAAa,oBAAmB;CACb,QAAkB,CAAA;CAQlB,0BAAU,IAAI,QAAO;CAGtC,KAAK,IAAU;EACb,KAAK,OAAO,EAAE;EACd,KAAK,MAAM,KAAK,EAAE;CACpB;CAEA,OAAO,IAAU;EACf,MAAM,QAAQ,KAAK,MAAM,QAAQ,EAAE;EACnC,IAAI,UAAU,IAAI,KAAK,MAAM,OAAO,OAAO,CAAC;CAC9C;CAEA,MAAM,IAAU;EACd,OAAO,KAAK,MAAM,SAAS,KAAK,KAAK,MAAM,KAAK,MAAM,SAAS,OAAO;CACxE;CAOA,MAAM,IAAY,OAAY;EAC5B,IAAI,KAAK,QAAQ,IAAI,KAAK,KAAK,CAAC,KAAK,MAAM,EAAE,GAAG,OAAO;EACvD,KAAK,QAAQ,IAAI,KAAK;EACtB,OAAO;CACT;CAnCW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAmB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAnB,OAAA,QAAA,GAAA,sBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAmB,YADN;CAAM,CAAA;;AACnB,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAmB,YAAA,CAAA;EAD/B,MAAA;EAAW,MAAA,CAAA,EAAE,YAAY,OAAM,CAAE"}
1
+ {"version":3,"file":"lifecorner-angular-ui-kit-internal-overlay.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/internal/overlay/overlay-stack.service.ts","../../../../libs/angular-ui-kit/src/lib/internal/overlay/overlay-insets.service.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\n\n/**\n * Keeps the open overlays (modal, drawer, popover, menu, tooltip, …) in\n * opening order so that a dismiss gesture — Escape, click outside — reaches\n * only the top-most one instead of closing every open layer at once.\n *\n * Every overlay pushes its id when it opens and removes it when it closes or\n * is destroyed. Internal to the library; not part of the public API.\n */\n@Injectable({ providedIn: 'root' })\nexport class OverlayStackService {\n private readonly stack: string[] = [];\n\n /**\n * Events already consumed by an overlay. All overlays listen on `document`,\n * where listeners fire in registration order — not z-order — so by the time a\n * lower overlay's listener runs, the top one may already have closed and left\n * the stack, making the lower one \"top\" for the very same event.\n */\n private readonly claimed = new WeakSet<Event>();\n\n /** Register `id` as the new top-most overlay (re-pushing moves it to the top). */\n push(id: string): void {\n this.remove(id);\n this.stack.push(id);\n }\n\n remove(id: string): void {\n const index = this.stack.indexOf(id);\n if (index !== -1) this.stack.splice(index, 1);\n }\n\n isTop(id: string): boolean {\n return this.stack.length > 0 && this.stack[this.stack.length - 1] === id;\n }\n\n /**\n * Whether overlay `id` may act on this dismiss event. True only for the\n * top-most overlay and only once per event; the caller then closes and, for\n * keyboard events, stops propagation so nothing outside the stack sees it.\n */\n claim(id: string, event: Event): boolean {\n if (this.claimed.has(event) || !this.isTop(id)) return false;\n this.claimed.add(event);\n return true;\n }\n}\n","import { Injectable, signal } from '@angular/core';\n\n/**\n * The space a fixed overlay keeps free at the top and the bottom of the\n * viewport, as CSS lengths (3.28, AS-34). `lc-app-shell` writes them in the\n * browser: `top` is its header's bottom edge, `bottom` the shown bottom bar's\n * top edge, measured from the viewport's bottom (or the safe-area insets when\n * there is no header or no bar). `lc-toast-outlet` reads them, so its stacks\n * clear the header and the bar even when the app renders the outlet outside\n * the shell (no custom property can inherit there).\n *\n * `null` means \"no shell\": on the server, before the shell has measured,\n * without ResizeObserver and after the shell is destroyed. Internal to the\n * library; not part of the public API and without a semver guarantee.\n */\n@Injectable({ providedIn: 'root' })\nexport class OverlayInsetsService {\n /** CSS length kept free above top-edge overlays, e.g. `'56px'`. */\n readonly top = signal<string | null>(null);\n\n /** CSS length kept free below bottom-edge overlays, e.g. `'102px'`. */\n readonly bottom = signal<string | null>(null);\n}\n"],"mappings":";;AAWA,IAAa,sBAAb,MAAa,oBAAmB;CACb,QAAkB,CAAA;CAQlB,0BAAU,IAAI,QAAO;CAGtC,KAAK,IAAU;EACb,KAAK,OAAO,EAAE;EACd,KAAK,MAAM,KAAK,EAAE;CACpB;CAEA,OAAO,IAAU;EACf,MAAM,QAAQ,KAAK,MAAM,QAAQ,EAAE;EACnC,IAAI,UAAU,IAAI,KAAK,MAAM,OAAO,OAAO,CAAC;CAC9C;CAEA,MAAM,IAAU;EACd,OAAO,KAAK,MAAM,SAAS,KAAK,KAAK,MAAM,KAAK,MAAM,SAAS,OAAO;CACxE;CAOA,MAAM,IAAY,OAAY;EAC5B,IAAI,KAAK,QAAQ,IAAI,KAAK,KAAK,CAAC,KAAK,MAAM,EAAE,GAAG,OAAO;EACvD,KAAK,QAAQ,IAAI,KAAK;EACtB,OAAO;CACT;CAnCW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAmB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAnB,OAAA,QAAA,GAAA,sBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAmB,YADN;CAAM,CAAA;;AACnB,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAmB,YAAA,CAAA;EAD/B,MAAA;EAAW,MAAA,CAAA,EAAE,YAAY,OAAM,CAAE;;;ACMlC,IAAa,uBAAb,MAAa,qBAAoB;CAEtB,MAAM,OAAsB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,MAAA,CAAA,+BAAA,CAAA,CAAA;CAGjC,SAAS,OAAsB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CALlC,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAoB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAApB,OAAA,QAAA,GAAA,sBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAoB,YADP;CAAM,CAAA;;AACnB,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAoB,YAAA,CAAA;EADhC,MAAA;EAAW,MAAA,CAAA,EAAE,YAAY,OAAM,CAAE"}
@@ -97,6 +97,29 @@ function formatMoney(amountMinor, currency, options = {}) {
97
97
  spoken: named.map((p) => p.type === "minusSign" ? `${minusLabel} ` : p.type === "plusSign" ? `${plusLabel} ` : p.value).join("").replace(/\s+/g, " ").trim()
98
98
  };
99
99
  }
100
+ function moneyRangeSeparator(locale) {
101
+ return locale.split(/[-_]/)[0].toLowerCase() === "de" ? "bis" : "to";
102
+ }
103
+ function moneyRangeParts(fromMinor, toMinor, currency, options = {}) {
104
+ const { separatorLabel = "", ...single } = options;
105
+ const from = formatMoney(fromMinor, currency, single);
106
+ const to = formatMoney(toMinor, currency, single);
107
+ if (!from || !to) return null;
108
+ return {
109
+ from,
110
+ to,
111
+ word: separatorLabel || moneyRangeSeparator(single.locale || "en-US")
112
+ };
113
+ }
114
+ function formatMoneyRange(fromMinor, toMinor, currency, options = {}) {
115
+ const parts = moneyRangeParts(fromMinor, toMinor, currency, options);
116
+ if (!parts) return null;
117
+ const { from, to, word } = parts;
118
+ return {
119
+ text: `${from.text} ${word} ${to.text}`,
120
+ spoken: `${from.spoken} ${word} ${to.spoken}`
121
+ };
122
+ }
100
123
  var MoneyComponent = class MoneyComponent {
101
124
  appLocale = inject(LOCALE_ID);
102
125
  amountMinor = input.required(...ngDevMode ? [{ debugName: "amountMinor" }] : /* istanbul ignore next */ []);
@@ -106,6 +129,8 @@ var MoneyComponent = class MoneyComponent {
106
129
  minusLabel = input("minus", ...ngDevMode ? [{ debugName: "minusLabel" }] : /* istanbul ignore next */ []);
107
130
  plusLabel = input("plus", ...ngDevMode ? [{ debugName: "plusLabel" }] : /* istanbul ignore next */ []);
108
131
  showCurrency = input(true, ...ngDevMode ? [{ debugName: "showCurrency" }] : /* istanbul ignore next */ []);
132
+ rangeToMinor = input(void 0, ...ngDevMode ? [{ debugName: "rangeToMinor" }] : /* istanbul ignore next */ []);
133
+ rangeSeparatorLabel = input("", ...ngDevMode ? [{ debugName: "rangeSeparatorLabel" }] : /* istanbul ignore next */ []);
109
134
  effectiveLocale = computed(() => this.locale() || this.appLocale || "en-US", ...ngDevMode ? [{ debugName: "effectiveLocale" }] : /* istanbul ignore next */ []);
110
135
  formatted = computed(() => formatMoney(this.amountMinor(), this.currency(), {
111
136
  locale: this.effectiveLocale(),
@@ -114,12 +139,34 @@ var MoneyComponent = class MoneyComponent {
114
139
  plusLabel: this.plusLabel(),
115
140
  showCurrency: this.showCurrency()
116
141
  }), ...ngDevMode ? [{ debugName: "formatted" }] : /* istanbul ignore next */ []);
142
+ range = computed(() => {
143
+ const to = this.rangeToMinor();
144
+ if (to === null || to === void 0 || !Number.isSafeInteger(to)) return null;
145
+ const parts = moneyRangeParts(this.amountMinor(), to, this.currency(), {
146
+ locale: this.effectiveLocale(),
147
+ signDisplay: this.signDisplay(),
148
+ minusLabel: this.minusLabel(),
149
+ plusLabel: this.plusLabel(),
150
+ showCurrency: this.showCurrency(),
151
+ separatorLabel: this.rangeSeparatorLabel()
152
+ });
153
+ if (!parts) return null;
154
+ const { from, to: upper, word } = parts;
155
+ return {
156
+ from,
157
+ to: upper,
158
+ joint: ` ${word} `,
159
+ spoken: `${from.spoken} ${word} ${upper.spoken}`
160
+ };
161
+ }, ...ngDevMode ? [{ debugName: "range" }] : /* istanbul ignore next */ []);
117
162
  dir = computed(() => moneyDirection(this.effectiveLocale()), ...ngDevMode ? [{ debugName: "dir" }] : /* istanbul ignore next */ []);
118
163
  constructor() {
119
164
  effect(() => {
120
165
  if (!isDevMode()) return;
121
166
  if (!Number.isSafeInteger(this.amountMinor())) console.warn("[lc-money] amountMinor must be a safe integer");
122
167
  else if (!this.formatted()) console.warn(`[lc-money] unknown currency "${this.currency()}"`);
168
+ const to = this.rangeToMinor();
169
+ if (to !== null && to !== void 0 && !Number.isSafeInteger(to)) console.warn("[lc-money] rangeToMinor must be a safe integer");
123
170
  });
124
171
  }
125
172
  static ɵfac = i0.ɵɵngDeclareFactory({
@@ -185,13 +232,30 @@ var MoneyComponent = class MoneyComponent {
185
232
  isSignal: true,
186
233
  isRequired: false,
187
234
  transformFunction: null
235
+ },
236
+ rangeToMinor: {
237
+ classPropertyName: "rangeToMinor",
238
+ publicName: "rangeToMinor",
239
+ isSignal: true,
240
+ isRequired: false,
241
+ transformFunction: null
242
+ },
243
+ rangeSeparatorLabel: {
244
+ classPropertyName: "rangeSeparatorLabel",
245
+ publicName: "rangeSeparatorLabel",
246
+ isSignal: true,
247
+ isRequired: false,
248
+ transformFunction: null
188
249
  }
189
250
  },
190
- host: { classAttribute: "lc-money" },
251
+ host: {
252
+ properties: { "class.lc-money--range": "range() !== null" },
253
+ classAttribute: "lc-money"
254
+ },
191
255
  ngImport: i0,
192
- template: "@if (formatted(); as m) {<span class=\"lc-money__amount\" aria-hidden=\"true\" [attr.dir]=\"dir()\">{{ m.text }}</span><span class=\"lc-money__spoken\">{{ m.spoken }}</span>}",
256
+ template: "@if (range(); as r) {<span class=\"lc-money__range\" aria-hidden=\"true\" [attr.dir]=\"dir()\"><span class=\"lc-money__amount\" [attr.dir]=\"dir()\">{{ r.from.text }}</span>{{ r.joint }}<span class=\"lc-money__amount\" [attr.dir]=\"dir()\">{{ r.to.text }}</span></span><span class=\"lc-money__spoken\">{{ r.spoken }}</span>} @else if (formatted(); as m) {<span class=\"lc-money__amount\" aria-hidden=\"true\" [attr.dir]=\"dir()\">{{ m.text }}</span><span class=\"lc-money__spoken\">{{ m.spoken }}</span>}",
193
257
  isInline: true,
194
- styles: [":host{position:relative;display:inline;font-variant-numeric:tabular-nums;white-space:nowrap}.lc-money__spoken{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;-webkit-user-select:none;user-select:none}\n"],
258
+ styles: [":host{position:relative;display:inline;font-variant-numeric:tabular-nums;white-space:nowrap}:host(.lc-money--range){white-space:normal}.lc-money__amount{white-space:nowrap}.lc-money__spoken{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;-webkit-user-select:none;user-select:none}\n"],
195
259
  changeDetection: i0.ChangeDetectionStrategy.OnPush
196
260
  });
197
261
  };
@@ -205,10 +269,13 @@ i0.ɵɵngDeclareClassMetadata({
205
269
  args: [{
206
270
  selector: "lc-money",
207
271
  standalone: true,
208
- template: "@if (formatted(); as m) {<span class=\"lc-money__amount\" aria-hidden=\"true\" [attr.dir]=\"dir()\">{{ m.text }}</span><span class=\"lc-money__spoken\">{{ m.spoken }}</span>}",
272
+ template: "@if (range(); as r) {<span class=\"lc-money__range\" aria-hidden=\"true\" [attr.dir]=\"dir()\"><span class=\"lc-money__amount\" [attr.dir]=\"dir()\">{{ r.from.text }}</span>{{ r.joint }}<span class=\"lc-money__amount\" [attr.dir]=\"dir()\">{{ r.to.text }}</span></span><span class=\"lc-money__spoken\">{{ r.spoken }}</span>} @else if (formatted(); as m) {<span class=\"lc-money__amount\" aria-hidden=\"true\" [attr.dir]=\"dir()\">{{ m.text }}</span><span class=\"lc-money__spoken\">{{ m.spoken }}</span>}",
209
273
  changeDetection: ChangeDetectionStrategy.OnPush,
210
- host: { class: "lc-money" },
211
- styles: [":host{position:relative;display:inline;font-variant-numeric:tabular-nums;white-space:nowrap}.lc-money__spoken{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;-webkit-user-select:none;user-select:none}\n"]
274
+ host: {
275
+ class: "lc-money",
276
+ "[class.lc-money--range]": "range() !== null"
277
+ },
278
+ styles: [":host{position:relative;display:inline;font-variant-numeric:tabular-nums;white-space:nowrap}:host(.lc-money--range){white-space:normal}.lc-money__amount{white-space:nowrap}.lc-money__spoken{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;-webkit-user-select:none;user-select:none}\n"]
212
279
  }]
213
280
  }],
214
281
  ctorParameters: () => [],
@@ -268,9 +335,25 @@ i0.ɵɵngDeclareClassMetadata({
268
335
  alias: "showCurrency",
269
336
  required: false
270
337
  }]
338
+ }],
339
+ rangeToMinor: [{
340
+ type: i0.Input,
341
+ args: [{
342
+ isSignal: true,
343
+ alias: "rangeToMinor",
344
+ required: false
345
+ }]
346
+ }],
347
+ rangeSeparatorLabel: [{
348
+ type: i0.Input,
349
+ args: [{
350
+ isSignal: true,
351
+ alias: "rangeSeparatorLabel",
352
+ required: false
353
+ }]
271
354
  }]
272
355
  }
273
356
  });
274
- export { MoneyComponent, formatMoney };
357
+ export { MoneyComponent, formatMoney, formatMoneyRange };
275
358
 
276
359
  //# sourceMappingURL=lifecorner-angular-ui-kit-money.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"lifecorner-angular-ui-kit-money.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/money/money-format.ts","../../../../libs/angular-ui-kit/src/lib/money/money.component.ts"],"sourcesContent":["/**\n * How the sign of an amount shows, as `Intl.NumberFormat`'s `signDisplay`:\n * - `auto`: negative amounts only (−42,17 €)\n * - `always`: plus and minus, also on zero (+0,00 €)\n * - `exceptZero`: plus and minus, no sign on zero\n * - `never`: no sign\n */\nexport type MoneySignDisplay = 'auto' | 'always' | 'exceptZero' | 'never';\n\n/** Options of {@link formatMoney}. */\nexport interface MoneyFormatOptions {\n /** BCP 47 locale. An invalid one falls back to `en-US`. @default 'en-US' */\n locale?: string;\n /** As `Intl.NumberFormat`'s `signDisplay`. @default 'auto' */\n signDisplay?: MoneySignDisplay;\n /** Spoken word for the minus sign. @default 'minus' */\n minusLabel?: string;\n /** Spoken word for the plus sign. @default 'plus' */\n plusLabel?: string;\n /**\n * Whether the visible `text` shows the currency symbol (or code). `false`\n * leaves out the symbol and the space that belongs to it („−42,17“), for a\n * column or title that already names the unit („Kosten in €“). Digits,\n * grouping, sign and minor units stay. The `spoken` text still names the\n * currency.\n * @default true\n */\n showCurrency?: boolean;\n}\n\n/** A formatted amount: the visible text and the words a screen reader speaks. */\nexport interface MoneyText {\n /**\n * Visible text, e.g. „−42,17 €“ (U+2212 minus, U+00A0 from `Intl`), or\n * „−42,17“ with `showCurrency: false`.\n */\n text: string;\n /** Spoken text, e.g. „minus 42,17 Euro“. */\n spoken: string;\n}\n\n/**\n * Minor-unit exponents per ISO 4217 that are not 2. Not `Intl`'s digits:\n * CLDR gives 0 for HUF, IDR, RSD and IQD, which ISO 4217 does not.\n */\nconst MINOR_UNITS: Readonly<Record<string, number>> = {\n BIF: 0, CLP: 0, DJF: 0, GNF: 0, ISK: 0, JPY: 0, KMF: 0, KRW: 0, PYG: 0,\n RWF: 0, UGX: 0, UYI: 0, VND: 0, VUV: 0, XAF: 0, XOF: 0, XPF: 0,\n BHD: 3, IQD: 3, JOD: 3, KWD: 3, LYD: 3, OMR: 3, TND: 3,\n CLF: 4, UYW: 4,\n};\n\n/** The ISO 4217 minor-unit exponent of `currency` (2 unless listed). */\nexport function moneyMinorUnits(currency: string): number {\n return MINOR_UNITS[currency.toUpperCase()] ?? 2;\n}\n\n/** Primary language subtags written right to left (a fixed list: the same on server and browser). */\nconst RTL_LANGUAGES = new Set(['ar', 'ckb', 'dv', 'fa', 'he', 'iw', 'ks', 'ps', 'sd', 'ug', 'ur', 'yi']);\n\n/** Text direction of an amount formatted for `locale`. */\nexport function moneyDirection(locale: string): 'ltr' | 'rtl' {\n return RTL_LANGUAGES.has(locale.split(/[-_]/)[0].toLowerCase()) ? 'rtl' : 'ltr';\n}\n\n/** The exact decimal string of an integer amount in minor units: 4217, 2 → \"42.17\". */\nfunction decimalString(amountMinor: number, digits: number): string {\n const abs = String(Math.abs(amountMinor)).padStart(digits + 1, '0');\n const value = digits === 0 ? abs : `${abs.slice(0, -digits)}.${abs.slice(-digits)}`;\n return amountMinor < 0 ? `-${value}` : value; // −0 has no sign\n}\n\n/** `Intl.NumberFormat` for `locale`, or for `en-US` when the locale is invalid. */\nfunction numberFormat(locale: string, options: Intl.NumberFormatOptions): Intl.NumberFormat {\n try {\n return new Intl.NumberFormat(locale, options);\n } catch {\n return new Intl.NumberFormat('en-US', options);\n }\n}\n\n/**\n * The parts without the currency: drops the `currency` part and the whitespace\n * of the literals right next to it (U+0020, U+00A0, U+202F, U+2009), keeping\n * bidi marks. Never trims the whole string: fr-FR groups with U+202F.\n */\nfunction withoutCurrency(parts: Intl.NumberFormatPart[]): Intl.NumberFormatPart[] {\n const at = parts.findIndex((p) => p.type === 'currency');\n if (at < 0) return parts;\n return parts\n .map((p, i) => (p.type === 'literal' && Math.abs(i - at) === 1 ? { ...p, value: p.value.replace(/\\s/g, '') } : p))\n .filter((p, i) => i !== at && p.value !== '');\n}\n\n/**\n * Formats an amount of money given in integer minor units (cents, yen, fils)\n * exactly, never through a float: the decimal string goes into `Intl`.\n * Returns `null` for an amount that is not a safe integer or a currency that\n * is not a three-letter code. This is the formatter of `lc-money`, for table\n * `formatter`s and texts. `showCurrency: false` leaves the symbol and its\n * space out of `text` (a column headed „Kosten in €“); `spoken` keeps it.\n *\n * @example\n * ```ts\n * formatMoney(-4217, 'EUR', { locale: 'de-DE' });\n * // { text: '−42,17 €', spoken: 'minus 42,17 Euro' }\n * formatMoney(-4217, 'EUR', { locale: 'de-DE', showCurrency: false });\n * // { text: '−42,17', spoken: 'minus 42,17 Euro' }\n * ```\n */\nexport function formatMoney(amountMinor: number, currency: string, options: MoneyFormatOptions = {}): MoneyText | null {\n if (!Number.isSafeInteger(amountMinor) || !/^[A-Za-z]{3}$/.test(currency ?? '')) return null;\n const { locale = 'en-US', signDisplay = 'auto', minusLabel = 'minus', plusLabel = 'plus', showCurrency = true } = options;\n const digits = moneyMinorUnits(currency);\n const value = decimalString(amountMinor, digits) as unknown as number; // exact decimal string (Intl.NumberFormat v3)\n const base: Intl.NumberFormatOptions = {\n style: 'currency',\n currency: currency.toUpperCase(),\n signDisplay,\n minimumFractionDigits: digits,\n maximumFractionDigits: digits,\n };\n let visible: Intl.NumberFormatPart[];\n let named: Intl.NumberFormatPart[];\n try {\n visible = numberFormat(locale || 'en-US', base).formatToParts(value);\n named = numberFormat(locale || 'en-US', { ...base, currencyDisplay: 'name' }).formatToParts(value);\n } catch {\n return null;\n }\n if (showCurrency === false) visible = withoutCurrency(visible);\n const text = visible.map((p) => (p.type === 'minusSign' ? p.value.replace(/-/g, '−') : p.value)).join('');\n const spoken = named\n .map((p) => (p.type === 'minusSign' ? `${minusLabel} ` : p.type === 'plusSign' ? `${plusLabel} ` : p.value))\n .join('')\n .replace(/\\s+/g, ' ')\n .trim();\n return { text, spoken };\n}\n","import { ChangeDetectionStrategy, Component, LOCALE_ID, computed, effect, inject, input, isDevMode } from '@angular/core';\nimport { formatMoney, moneyDirection, type MoneySignDisplay } from './money-format';\n\n/**\n * Displays an amount of money (3.16, BA-4): locale, currency, sign, tabular\n * figures and a spoken text. Display only, no input parsing or conversion.\n *\n * - `amountMinor` is an integer in the currency's minor units (cents, yen,\n * fils), formatted exactly through a decimal string, never a float. Minor\n * units follow ISO 4217: 2, except 0 (BIF CLP DJF GNF ISK JPY KMF KRW PYG\n * RWF UGX UYI VND VUV XAF XOF XPF), 3 (BHD IQD JOD KWD LYD OMR TND) and 4\n * (CLF UYW).\n * - The visible amount („−42,17 €“, U+2212 minus, a no-break space from\n * `Intl`) is `aria-hidden`; a visually hidden span holds the words\n * („minus 42,17 Euro“), so a screen reader reads the amount once.\n * - Tabular figures, no wrapping inside the amount; the amount is a `dir`\n * isolate (`ltr`, or `rtl` for an RTL locale), safe inside RTL text.\n * - Font and colour come from the context; colour never carries the sign.\n * - `showCurrency=false`: no symbol in the visible amount (a column headed\n * „Kosten in €“); the spoken text keeps the currency.\n * - `locale` empty: the app's `LOCALE_ID` (Angular's default `en-US`), the\n * same on the server and in the browser.\n * - For table `formatter`s and texts use {@link formatMoney}.\n *\n * Separate a `lc-money` from adjacent text with a space in your template, so\n * the spoken text does not run into the words around it.\n *\n * @example\n * ```html\n * <lc-money [amountMinor]=\"-4217\" currency=\"EUR\" locale=\"de-DE\" />\n * ```\n */\n@Component({\n selector: 'lc-money',\n standalone: true,\n // No whitespace between the spans: the visible amount and the words are separate texts.\n template:\n '@if (formatted(); as m) {<span class=\"lc-money__amount\" aria-hidden=\"true\" [attr.dir]=\"dir()\">{{ m.text }}</span><span class=\"lc-money__spoken\">{{ m.spoken }}</span>}',\n styleUrl: './money.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { class: 'lc-money' },\n})\nexport class MoneyComponent {\n private readonly appLocale = inject(LOCALE_ID);\n\n /**\n * Amount in minor units of `currency` (cents, yen, fils): a safe integer\n * (±9,007,199,254,740,991), formatted exactly. Anything else renders\n * nothing (a dev warning).\n */\n readonly amountMinor = input.required<number>();\n\n /**\n * ISO 4217 currency code (`EUR`, `USD`, `JPY`, `KWD`). It sets the minor\n * units and the symbol. Not a three-letter code: renders nothing (a dev\n * warning).\n */\n readonly currency = input.required<string>();\n\n /**\n * BCP 47 locale of the amount (`de-DE`, `en-GB`). Empty: the app's\n * `LOCALE_ID` (Angular's default `en-US`). An invalid locale falls back to\n * `en-US`.\n * @default ''\n */\n readonly locale = input<string>('');\n\n /**\n * Which signs show, as `Intl.NumberFormat`: `auto` (negative only),\n * `always`, `exceptZero`, `never`. The spoken text says the sign whenever\n * it shows.\n * @default 'auto'\n */\n readonly signDisplay = input<MoneySignDisplay>('auto');\n\n /**\n * Spoken word for the minus sign („minus 42,17 Euro“; the same in German).\n * @default 'minus'\n */\n readonly minusLabel = input<string>('minus');\n\n /**\n * Spoken word for the plus sign („plus 42,17 Euro“; the same in German).\n * @default 'plus'\n */\n readonly plusLabel = input<string>('plus');\n\n /**\n * Shows the currency symbol in the visible amount. `false` leaves out the\n * symbol and its space („−42,17“) for a table column or a title that\n * already names the unit („Kosten in €“). Screen readers still hear the\n * currency („minus 42,17 Euro“), and `currency` still sets the minor units.\n * Use it only where the unit is visible next to the amount.\n * @default true\n */\n readonly showCurrency = input<boolean>(true);\n\n /** The locale in use: the `locale` input or the app's `LOCALE_ID`. */\n protected readonly effectiveLocale = computed(() => this.locale() || this.appLocale || 'en-US');\n\n protected readonly formatted = computed(() =>\n formatMoney(this.amountMinor(), this.currency(), {\n locale: this.effectiveLocale(),\n signDisplay: this.signDisplay(),\n minusLabel: this.minusLabel(),\n plusLabel: this.plusLabel(),\n showCurrency: this.showCurrency(),\n }),\n );\n\n protected readonly dir = computed(() => moneyDirection(this.effectiveLocale()));\n\n constructor() {\n effect(() => {\n if (!isDevMode()) return;\n if (!Number.isSafeInteger(this.amountMinor())) {\n console.warn('[lc-money] amountMinor must be a safe integer');\n } else if (!this.formatted()) {\n console.warn(`[lc-money] unknown currency \"${this.currency()}\"`);\n }\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"lifecorner-angular-ui-kit-money.mjs","names":[],"sources":["../../../../libs/angular-ui-kit/src/lib/money/money-format.ts","../../../../libs/angular-ui-kit/src/lib/money/money.component.ts"],"sourcesContent":["/**\n * How the sign of an amount shows, as `Intl.NumberFormat`'s `signDisplay`:\n * - `auto`: negative amounts only (−42,17 €)\n * - `always`: plus and minus, also on zero (+0,00 €)\n * - `exceptZero`: plus and minus, no sign on zero\n * - `never`: no sign\n */\nexport type MoneySignDisplay = 'auto' | 'always' | 'exceptZero' | 'never';\n\n/** Options of {@link formatMoney}. */\nexport interface MoneyFormatOptions {\n /** BCP 47 locale. An invalid one falls back to `en-US`. @default 'en-US' */\n locale?: string;\n /** As `Intl.NumberFormat`'s `signDisplay`. @default 'auto' */\n signDisplay?: MoneySignDisplay;\n /** Spoken word for the minus sign. @default 'minus' */\n minusLabel?: string;\n /** Spoken word for the plus sign. @default 'plus' */\n plusLabel?: string;\n /**\n * Whether the visible `text` shows the currency symbol (or code). `false`\n * leaves out the symbol and the space that belongs to it („−42,17“), for a\n * column or title that already names the unit („Kosten in €“). Digits,\n * grouping, sign and minor units stay. The `spoken` text still names the\n * currency.\n * @default true\n */\n showCurrency?: boolean;\n}\n\n/** Options of {@link formatMoneyRange}: those of {@link formatMoney}, for both amounts, and the joining word. */\nexport interface MoneyRangeFormatOptions extends MoneyFormatOptions {\n /**\n * Word between the two amounts, in `text` and in `spoken`. Empty: from\n * `locale`, „bis“ for German (`de`), \"to\" for every other locale.\n * @default ''\n */\n separatorLabel?: string;\n}\n\n/** A formatted amount: the visible text and the words a screen reader speaks. */\nexport interface MoneyText {\n /**\n * Visible text, e.g. „−42,17 €“ (U+2212 minus, U+00A0 from `Intl`), or\n * „−42,17“ with `showCurrency: false`.\n */\n text: string;\n /** Spoken text, e.g. „minus 42,17 Euro“. */\n spoken: string;\n}\n\n/**\n * Minor-unit exponents per ISO 4217 that are not 2. Not `Intl`'s digits:\n * CLDR gives 0 for HUF, IDR, RSD and IQD, which ISO 4217 does not.\n */\nconst MINOR_UNITS: Readonly<Record<string, number>> = {\n BIF: 0, CLP: 0, DJF: 0, GNF: 0, ISK: 0, JPY: 0, KMF: 0, KRW: 0, PYG: 0,\n RWF: 0, UGX: 0, UYI: 0, VND: 0, VUV: 0, XAF: 0, XOF: 0, XPF: 0,\n BHD: 3, IQD: 3, JOD: 3, KWD: 3, LYD: 3, OMR: 3, TND: 3,\n CLF: 4, UYW: 4,\n};\n\n/** The ISO 4217 minor-unit exponent of `currency` (2 unless listed). */\nexport function moneyMinorUnits(currency: string): number {\n return MINOR_UNITS[currency.toUpperCase()] ?? 2;\n}\n\n/** Primary language subtags written right to left (a fixed list: the same on server and browser). */\nconst RTL_LANGUAGES = new Set(['ar', 'ckb', 'dv', 'fa', 'he', 'iw', 'ks', 'ps', 'sd', 'ug', 'ur', 'yi']);\n\n/** Text direction of an amount formatted for `locale`. */\nexport function moneyDirection(locale: string): 'ltr' | 'rtl' {\n return RTL_LANGUAGES.has(locale.split(/[-_]/)[0].toLowerCase()) ? 'rtl' : 'ltr';\n}\n\n/** The exact decimal string of an integer amount in minor units: 4217, 2 → \"42.17\". */\nfunction decimalString(amountMinor: number, digits: number): string {\n const abs = String(Math.abs(amountMinor)).padStart(digits + 1, '0');\n const value = digits === 0 ? abs : `${abs.slice(0, -digits)}.${abs.slice(-digits)}`;\n return amountMinor < 0 ? `-${value}` : value; // −0 has no sign\n}\n\n/** `Intl.NumberFormat` for `locale`, or for `en-US` when the locale is invalid. */\nfunction numberFormat(locale: string, options: Intl.NumberFormatOptions): Intl.NumberFormat {\n try {\n return new Intl.NumberFormat(locale, options);\n } catch {\n return new Intl.NumberFormat('en-US', options);\n }\n}\n\n/**\n * The parts without the currency: drops the `currency` part and the whitespace\n * of the literals right next to it (U+0020, U+00A0, U+202F, U+2009), keeping\n * bidi marks. Never trims the whole string: fr-FR groups with U+202F.\n */\nfunction withoutCurrency(parts: Intl.NumberFormatPart[]): Intl.NumberFormatPart[] {\n const at = parts.findIndex((p) => p.type === 'currency');\n if (at < 0) return parts;\n return parts\n .map((p, i) => (p.type === 'literal' && Math.abs(i - at) === 1 ? { ...p, value: p.value.replace(/\\s/g, '') } : p))\n .filter((p, i) => i !== at && p.value !== '');\n}\n\n/**\n * Formats an amount of money given in integer minor units (cents, yen, fils)\n * exactly, never through a float: the decimal string goes into `Intl`.\n * Returns `null` for an amount that is not a safe integer or a currency that\n * is not a three-letter code. This is the formatter of `lc-money`, for table\n * `formatter`s and texts. `showCurrency: false` leaves the symbol and its\n * space out of `text` (a column headed „Kosten in €“); `spoken` keeps it.\n *\n * @example\n * ```ts\n * formatMoney(-4217, 'EUR', { locale: 'de-DE' });\n * // { text: '−42,17 €', spoken: 'minus 42,17 Euro' }\n * formatMoney(-4217, 'EUR', { locale: 'de-DE', showCurrency: false });\n * // { text: '−42,17', spoken: 'minus 42,17 Euro' }\n * ```\n */\nexport function formatMoney(amountMinor: number, currency: string, options: MoneyFormatOptions = {}): MoneyText | null {\n if (!Number.isSafeInteger(amountMinor) || !/^[A-Za-z]{3}$/.test(currency ?? '')) return null;\n const { locale = 'en-US', signDisplay = 'auto', minusLabel = 'minus', plusLabel = 'plus', showCurrency = true } = options;\n const digits = moneyMinorUnits(currency);\n const value = decimalString(amountMinor, digits) as unknown as number; // exact decimal string (Intl.NumberFormat v3)\n const base: Intl.NumberFormatOptions = {\n style: 'currency',\n currency: currency.toUpperCase(),\n signDisplay,\n minimumFractionDigits: digits,\n maximumFractionDigits: digits,\n };\n let visible: Intl.NumberFormatPart[];\n let named: Intl.NumberFormatPart[];\n try {\n visible = numberFormat(locale || 'en-US', base).formatToParts(value);\n named = numberFormat(locale || 'en-US', { ...base, currencyDisplay: 'name' }).formatToParts(value);\n } catch {\n return null;\n }\n if (showCurrency === false) visible = withoutCurrency(visible);\n const text = visible.map((p) => (p.type === 'minusSign' ? p.value.replace(/-/g, '−') : p.value)).join('');\n const spoken = named\n .map((p) => (p.type === 'minusSign' ? `${minusLabel} ` : p.type === 'plusSign' ? `${plusLabel} ` : p.value))\n .join('')\n .replace(/\\s+/g, ' ')\n .trim();\n return { text, spoken };\n}\n\n/** U+00A0: glues the joining word of a range to the second amount. */\nexport const MONEY_RANGE_GLUE = String.fromCharCode(0xa0);\n\n/** The word between the amounts of a range: „bis“ for a German locale (`de`), \"to\" otherwise. */\nexport function moneyRangeSeparator(locale: string): string {\n return locale.split(/[-_]/)[0].toLowerCase() === 'de' ? 'bis' : 'to';\n}\n\n/** Both amounts of a range and the joining word; `null` if either amount fails {@link formatMoney}. */\nexport function moneyRangeParts(\n fromMinor: number,\n toMinor: number,\n currency: string,\n options: MoneyRangeFormatOptions = {},\n): { from: MoneyText; to: MoneyText; word: string } | null {\n const { separatorLabel = '', ...single } = options;\n const from = formatMoney(fromMinor, currency, single);\n const to = formatMoney(toMinor, currency, single);\n if (!from || !to) return null;\n return { from, to, word: separatorLabel || moneyRangeSeparator(single.locale || 'en-US') };\n}\n\n/**\n * Formats a range of two amounts in minor units with the same currency and\n * options („9,99 € bis 12,99 €“), for table `formatter`s and texts. The\n * joining word is glued to the second amount with a no-break space (U+00A0),\n * so a line breaks only before it. The amounts are kept as given (no\n * sorting; equal amounts give a range). Returns `null` if either amount fails\n * {@link formatMoney}. `lc-money` shows the same with `rangeToMinor`.\n *\n * @example\n * ```ts\n * formatMoneyRange(999, 1299, 'EUR', { locale: 'de-DE' });\n * // { text: '9,99 € bis 12,99 €', spoken: '9,99 Euro bis 12,99 Euro' }\n * formatMoneyRange(999, 1299, 'EUR', { locale: 'en-US' });\n * // { text: '€9.99 to €12.99', spoken: '9.99 euros to 12.99 euros' }\n * ```\n */\nexport function formatMoneyRange(\n fromMinor: number,\n toMinor: number,\n currency: string,\n options: MoneyRangeFormatOptions = {},\n): MoneyText | null {\n const parts = moneyRangeParts(fromMinor, toMinor, currency, options);\n if (!parts) return null;\n const { from, to, word } = parts;\n return { text: `${from.text} ${word}${MONEY_RANGE_GLUE}${to.text}`, spoken: `${from.spoken} ${word} ${to.spoken}` };\n}\n","import { ChangeDetectionStrategy, Component, LOCALE_ID, computed, effect, inject, input, isDevMode } from '@angular/core';\nimport { MONEY_RANGE_GLUE, formatMoney, moneyDirection, moneyRangeParts, type MoneySignDisplay } from './money-format';\n\n/**\n * Displays an amount of money (3.16, BA-4): locale, currency, sign, tabular\n * figures and a spoken text. Display only, no input parsing or conversion.\n *\n * - `amountMinor` is an integer in the currency's minor units (cents, yen,\n * fils), formatted exactly through a decimal string, never a float. Minor\n * units follow ISO 4217: 2, except 0 (BIF CLP DJF GNF ISK JPY KMF KRW PYG\n * RWF UGX UYI VND VUV XAF XOF XPF), 3 (BHD IQD JOD KWD LYD OMR TND) and 4\n * (CLF UYW).\n * - The visible amount („−42,17 €“, U+2212 minus, a no-break space from\n * `Intl`) is `aria-hidden`; a visually hidden span holds the words\n * („minus 42,17 Euro“), so a screen reader reads the amount once.\n * - Tabular figures, no wrapping inside the amount; the amount is a `dir`\n * isolate (`ltr`, or `rtl` for an RTL locale), safe inside RTL text.\n * - Font and colour come from the context; colour never carries the sign.\n * - `showCurrency=false`: no symbol in the visible amount (a column headed\n * „Kosten in €“); the spoken text keeps the currency.\n * - `locale` empty: the app's `LOCALE_ID` (Angular's default `en-US`), the\n * same on the server and in the browser.\n * - A range (3.29, CC-1): `rangeToMinor` adds an upper amount, „9,99 € bis\n * 12,99 €“, read once („9,99 Euro bis 12,99 Euro“). It may wrap before the\n * joining word, never inside an amount.\n * - For table `formatter`s and texts use {@link formatMoney} and\n * {@link formatMoneyRange}.\n *\n * Separate a `lc-money` from adjacent text with a space in your template, so\n * the spoken text does not run into the words around it.\n *\n * @example\n * ```html\n * <lc-money [amountMinor]=\"-4217\" currency=\"EUR\" locale=\"de-DE\" />\n * <lc-money [amountMinor]=\"999\" [rangeToMinor]=\"1299\" currency=\"EUR\" locale=\"de-DE\" />\n * ```\n */\n@Component({\n selector: 'lc-money',\n standalone: true,\n // No whitespace between the spans: the visible amount and the words are separate texts.\n // A range: one aria-hidden `dir` span with both amounts (each a `dir` isolate) and the joining word.\n template:\n '@if (range(); as r) {<span class=\"lc-money__range\" aria-hidden=\"true\" [attr.dir]=\"dir()\"><span class=\"lc-money__amount\" [attr.dir]=\"dir()\">{{ r.from.text }}</span>{{ r.joint }}<span class=\"lc-money__amount\" [attr.dir]=\"dir()\">{{ r.to.text }}</span></span><span class=\"lc-money__spoken\">{{ r.spoken }}</span>} @else if (formatted(); as m) {<span class=\"lc-money__amount\" aria-hidden=\"true\" [attr.dir]=\"dir()\">{{ m.text }}</span><span class=\"lc-money__spoken\">{{ m.spoken }}</span>}',\n styleUrl: './money.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { class: 'lc-money', '[class.lc-money--range]': 'range() !== null' },\n})\nexport class MoneyComponent {\n private readonly appLocale = inject(LOCALE_ID);\n\n /**\n * Amount in minor units of `currency` (cents, yen, fils): a safe integer\n * (±9,007,199,254,740,991), formatted exactly. Anything else renders\n * nothing (a dev warning).\n */\n readonly amountMinor = input.required<number>();\n\n /**\n * ISO 4217 currency code (`EUR`, `USD`, `JPY`, `KWD`). It sets the minor\n * units and the symbol. Not a three-letter code: renders nothing (a dev\n * warning).\n */\n readonly currency = input.required<string>();\n\n /**\n * BCP 47 locale of the amount (`de-DE`, `en-GB`). Empty: the app's\n * `LOCALE_ID` (Angular's default `en-US`). An invalid locale falls back to\n * `en-US`.\n * @default ''\n */\n readonly locale = input<string>('');\n\n /**\n * Which signs show, as `Intl.NumberFormat`: `auto` (negative only),\n * `always`, `exceptZero`, `never`. The spoken text says the sign whenever\n * it shows.\n * @default 'auto'\n */\n readonly signDisplay = input<MoneySignDisplay>('auto');\n\n /**\n * Spoken word for the minus sign („minus 42,17 Euro“; the same in German).\n * @default 'minus'\n */\n readonly minusLabel = input<string>('minus');\n\n /**\n * Spoken word for the plus sign („plus 42,17 Euro“; the same in German).\n * @default 'plus'\n */\n readonly plusLabel = input<string>('plus');\n\n /**\n * Shows the currency symbol in the visible amount. `false` leaves out the\n * symbol and its space („−42,17“) for a table column or a title that\n * already names the unit („Kosten in €“). Screen readers still hear the\n * currency („minus 42,17 Euro“), and `currency` still sets the minor units.\n * Use it only where the unit is visible next to the amount.\n * @default true\n */\n readonly showCurrency = input<boolean>(true);\n\n /**\n * Upper amount of a range, in minor units of the same `currency` (3.29,\n * CC-1). Shows „9,99 € bis 12,99 €“ (`de-DE`) or \"€9.99 to €12.99\"\n * (`en-US`) with the same `locale`, `signDisplay` and `showCurrency`, read\n * once („9,99 Euro bis 12,99 Euro“). Rendered as given: no sorting, equal\n * amounts show a range. The range may wrap before the joining word, never\n * inside an amount. Not a safe integer: the single amount (a dev warning).\n * `null`/`undefined`: no range.\n * @default undefined\n */\n readonly rangeToMinor = input<number | null | undefined>(undefined);\n\n /**\n * Word between the amounts of a range, shown and spoken. Empty: from the\n * locale, „bis“ for German (`de`), \"to\" for every other locale.\n * @default ''\n */\n readonly rangeSeparatorLabel = input<string>('');\n\n /** The locale in use: the `locale` input or the app's `LOCALE_ID`. */\n protected readonly effectiveLocale = computed(() => this.locale() || this.appLocale || 'en-US');\n\n protected readonly formatted = computed(() =>\n formatMoney(this.amountMinor(), this.currency(), {\n locale: this.effectiveLocale(),\n signDisplay: this.signDisplay(),\n minusLabel: this.minusLabel(),\n plusLabel: this.plusLabel(),\n showCurrency: this.showCurrency(),\n }),\n );\n\n /**\n * The range's parts (3.29): both visible amounts, the joining text between\n * them (the word glued to the second amount by U+00A0, so a line breaks\n * only before it) and the one spoken text. `null`: no range.\n */\n protected readonly range = computed(() => {\n const to = this.rangeToMinor();\n if (to === null || to === undefined || !Number.isSafeInteger(to)) return null;\n const parts = moneyRangeParts(this.amountMinor(), to, this.currency(), {\n locale: this.effectiveLocale(),\n signDisplay: this.signDisplay(),\n minusLabel: this.minusLabel(),\n plusLabel: this.plusLabel(),\n showCurrency: this.showCurrency(),\n separatorLabel: this.rangeSeparatorLabel(),\n });\n if (!parts) return null;\n const { from, to: upper, word } = parts;\n return { from, to: upper, joint: ` ${word}${MONEY_RANGE_GLUE}`, spoken: `${from.spoken} ${word} ${upper.spoken}` };\n });\n\n protected readonly dir = computed(() => moneyDirection(this.effectiveLocale()));\n\n constructor() {\n effect(() => {\n if (!isDevMode()) return;\n if (!Number.isSafeInteger(this.amountMinor())) {\n console.warn('[lc-money] amountMinor must be a safe integer');\n } else if (!this.formatted()) {\n console.warn(`[lc-money] unknown currency \"${this.currency()}\"`);\n }\n const to = this.rangeToMinor();\n if (to !== null && to !== undefined && !Number.isSafeInteger(to)) {\n console.warn('[lc-money] rangeToMinor must be a safe integer');\n }\n });\n }\n}\n"],"mappings":"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"}