@featherk/composables 0.17.0 → 0.18.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 (119) hide show
  1. package/README.md +62 -15
  2. package/dist/address.cjs +2 -0
  3. package/dist/address.cjs.map +1 -0
  4. package/dist/address.mjs +6 -0
  5. package/dist/address.mjs.map +1 -0
  6. package/dist/chunks/useActiveIdRegistry-BG8VR__Z.mjs +43 -0
  7. package/dist/chunks/useActiveIdRegistry-BG8VR__Z.mjs.map +1 -0
  8. package/dist/chunks/useActiveIdRegistry-C1b00tqW.cjs +2 -0
  9. package/dist/chunks/useActiveIdRegistry-C1b00tqW.cjs.map +1 -0
  10. package/dist/chunks/useCompositeId-DyrJ0Fqj.cjs +2 -0
  11. package/dist/chunks/useCompositeId-DyrJ0Fqj.cjs.map +1 -0
  12. package/dist/chunks/useCompositeId-xg87ehXQ.mjs +9 -0
  13. package/dist/chunks/useCompositeId-xg87ehXQ.mjs.map +1 -0
  14. package/dist/chunks/useFieldsetValidationKit-7W1XDbbr.cjs +2 -0
  15. package/dist/chunks/useFieldsetValidationKit-7W1XDbbr.cjs.map +1 -0
  16. package/dist/chunks/useFieldsetValidationKit-x0Rh48mE.mjs +64 -0
  17. package/dist/chunks/useFieldsetValidationKit-x0Rh48mE.mjs.map +1 -0
  18. package/dist/chunks/useGridRowAction-Di25yeqb.cjs +2 -0
  19. package/dist/chunks/useGridRowAction-Di25yeqb.cjs.map +1 -0
  20. package/dist/chunks/useGridRowAction-akjwkV_F.mjs +532 -0
  21. package/dist/chunks/useGridRowAction-akjwkV_F.mjs.map +1 -0
  22. package/dist/chunks/useIntersectionObserver-A4xQV_pl.mjs +23 -0
  23. package/dist/chunks/useIntersectionObserver-A4xQV_pl.mjs.map +1 -0
  24. package/dist/chunks/useIntersectionObserver-CfgNAo2N.cjs +2 -0
  25. package/dist/chunks/useIntersectionObserver-CfgNAo2N.cjs.map +1 -0
  26. package/dist/chunks/useMaskedDateInput-COOksUM_.mjs +276 -0
  27. package/dist/chunks/useMaskedDateInput-COOksUM_.mjs.map +1 -0
  28. package/dist/chunks/useMaskedDateInput-wRnYlR3L.cjs +2 -0
  29. package/dist/chunks/useMaskedDateInput-wRnYlR3L.cjs.map +1 -0
  30. package/dist/chunks/useMaskedDateRangeInput-DST5aQe0.cjs +2 -0
  31. package/dist/chunks/useMaskedDateRangeInput-DST5aQe0.cjs.map +1 -0
  32. package/dist/chunks/useMaskedDateRangeInput-owYSg36r.mjs +328 -0
  33. package/dist/chunks/useMaskedDateRangeInput-owYSg36r.mjs.map +1 -0
  34. package/dist/chunks/useMaskedTimeInput-DPd2lysd.cjs +2 -0
  35. package/dist/chunks/useMaskedTimeInput-DPd2lysd.cjs.map +1 -0
  36. package/dist/chunks/useMaskedTimeInput-DjtBdvsf.mjs +363 -0
  37. package/dist/chunks/useMaskedTimeInput-DjtBdvsf.mjs.map +1 -0
  38. package/dist/chunks/usePopupMenu-CZLtgrXk.mjs +296 -0
  39. package/dist/chunks/usePopupMenu-CZLtgrXk.mjs.map +1 -0
  40. package/dist/chunks/usePopupMenu-DeTWakUH.cjs +2 -0
  41. package/dist/chunks/usePopupMenu-DeTWakUH.cjs.map +1 -0
  42. package/dist/chunks/usePopupTrap-DQudM6YA.cjs +2 -0
  43. package/dist/chunks/usePopupTrap-DQudM6YA.cjs.map +1 -0
  44. package/dist/chunks/usePopupTrap-DeuXHLZR.mjs +105 -0
  45. package/dist/chunks/usePopupTrap-DeuXHLZR.mjs.map +1 -0
  46. package/dist/chunks/useUSAddress-BYZZfbHc.cjs +2 -0
  47. package/dist/chunks/useUSAddress-BYZZfbHc.cjs.map +1 -0
  48. package/dist/chunks/useUSAddress-CRcqdqrZ.mjs +291 -0
  49. package/dist/chunks/useUSAddress-CRcqdqrZ.mjs.map +1 -0
  50. package/dist/chunks/useWindow-C4XFBuJA.mjs +210 -0
  51. package/dist/chunks/useWindow-C4XFBuJA.mjs.map +1 -0
  52. package/dist/chunks/useWindow-Yia2I6zX.cjs +2 -0
  53. package/dist/chunks/useWindow-Yia2I6zX.cjs.map +1 -0
  54. package/dist/date/useMaskedDateInput.d.ts +4 -0
  55. package/dist/date.cjs +2 -0
  56. package/dist/date.cjs.map +1 -0
  57. package/dist/date.mjs +5 -0
  58. package/dist/date.mjs.map +1 -0
  59. package/dist/{docs-manifest.js → docs-manifest.mjs} +24 -24
  60. package/dist/form.cjs +2 -0
  61. package/dist/form.cjs.map +1 -0
  62. package/dist/form.mjs +6 -0
  63. package/dist/form.mjs.map +1 -0
  64. package/dist/geometry.cjs +2 -0
  65. package/dist/geometry.cjs.map +1 -0
  66. package/dist/geometry.mjs +60 -0
  67. package/dist/geometry.mjs.map +1 -0
  68. package/dist/grid.cjs +2 -0
  69. package/dist/grid.cjs.map +1 -0
  70. package/dist/grid.mjs +7 -0
  71. package/dist/grid.mjs.map +1 -0
  72. package/dist/id.cjs +2 -0
  73. package/dist/id.cjs.map +1 -0
  74. package/dist/id.mjs +5 -0
  75. package/dist/id.mjs.map +1 -0
  76. package/dist/index.cjs +2 -0
  77. package/dist/index.cjs.map +1 -0
  78. package/dist/index.d.ts +3 -3
  79. package/dist/index.mjs +37 -0
  80. package/dist/index.mjs.map +1 -0
  81. package/dist/menu.cjs +2 -0
  82. package/dist/menu.cjs.map +1 -0
  83. package/dist/menu.mjs +5 -0
  84. package/dist/menu.mjs.map +1 -0
  85. package/dist/observer.cjs +2 -0
  86. package/dist/observer.cjs.map +1 -0
  87. package/dist/observer.mjs +5 -0
  88. package/dist/observer.mjs.map +1 -0
  89. package/dist/range/useMaskedDateRangeInput.d.ts +4 -0
  90. package/dist/range.cjs +2 -0
  91. package/dist/range.cjs.map +1 -0
  92. package/dist/range.mjs +5 -0
  93. package/dist/range.mjs.map +1 -0
  94. package/dist/registry.cjs +2 -0
  95. package/dist/registry.cjs.map +1 -0
  96. package/dist/registry.mjs +6 -0
  97. package/dist/registry.mjs.map +1 -0
  98. package/dist/time/useMaskedTimeInput.d.ts +4 -0
  99. package/dist/time.cjs +2 -0
  100. package/dist/time.cjs.map +1 -0
  101. package/dist/time.mjs +5 -0
  102. package/dist/time.mjs.map +1 -0
  103. package/dist/trap.cjs +2 -0
  104. package/dist/trap.cjs.map +1 -0
  105. package/dist/trap.mjs +7 -0
  106. package/dist/trap.mjs.map +1 -0
  107. package/dist/window.cjs +2 -0
  108. package/dist/window.cjs.map +1 -0
  109. package/dist/window.mjs +6 -0
  110. package/dist/window.mjs.map +1 -0
  111. package/docs/date/useMaskedDateInput.md +3 -0
  112. package/docs/range/useMaskedDateRangeInput.md +6 -7
  113. package/docs/time/useMaskedTimeInput.md +3 -0
  114. package/package.json +38 -36
  115. package/dist/featherk-composables.es.js +0 -2628
  116. package/dist/featherk-composables.es.js.map +0 -1
  117. package/dist/featherk-composables.umd.js +0 -2
  118. package/dist/featherk-composables.umd.js.map +0 -1
  119. /package/dist/{docs-manifest.d.ts → docs-manifest.d.mts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMaskedTimeInput-DPd2lysd.cjs","sources":["../../src/time/useMaskedTimeInput.ts"],"sourcesContent":["import {\n computed,\n nextTick,\n onMounted,\n readonly,\n ref,\n watch,\n type Ref,\n} from \"vue\";\n\nexport type ChangePayload = { value: Date | null; event: any };\n\ntype PopupAction = \"now\" | \"set\" | null;\ntype AnyArgsHandler = (...args: unknown[]) => void;\n\nexport function useMaskedTimeInput(args: {\n id: string;\n onChange: (p: ChangePayload) => void;\n onShowPicker: (e: KeyboardEvent) => void;\n externalValue?: Ref<string | Date | null | undefined>;\n // Minute stepping granularity for ArrowUp/ArrowDown when focused in minutes.\n // Supported values: 1, 5, 10, 15, 20, 30. If not provided, defaults to 1-minute steps.\n minuteStep?: 1 | 5 | 10 | 15 | 20 | 30;\n // Reactive alternative: pass a Ref to allow dynamic updates at runtime.\n minuteStepRef?: Ref<1 | 5 | 10 | 15 | 20 | 30 | undefined>;\n timeFormat?: string;\n min?: Date | null | undefined;\n max?: Date | null | undefined;\n /** When true, empty/incomplete value is considered invalid after blur */\n required?: boolean;\n debug?: boolean;\n}) {\n const raw = ref(\"\");\n const cursorPos = ref<number | undefined>(undefined);\n const debugEnabled = ref<boolean>(!!args.debug);\n const placeholder = ref<string>(args.timeFormat ?? \"hh:mm AM\");\n const isRequired = computed(() => !!args.required);\n const isTouched = ref(false);\n\n const steppers: string[] = [\"ArrowUp\", \"ArrowDown\"];\n const cursorKeys: string[] = [\"ArrowLeft\", \"ArrowRight\"];\n\n const digitsOnly = computed(() => (raw.value ?? \"\").replace(/\\D/g, \"\"));\n\n // Mask rules to be used by MaskedTextBox\n // Relax numeric constraints: allow any digits, then validate afterwards\n const rules = {\n H: /[0-9]/,\n h: /[0-9]/,\n M: /[0-9]/,\n m: /[0-9]/,\n A: /[AaPp]/,\n a: /[Mm]/,\n } as const;\n\n const partAt = (pos: number) => {\n if (pos <= 2) return \"hh\"; // hours\n if (pos <= 5) return \"mm\"; // minutes\n return \"ampm\"; // AM/PM\n };\n\n const hour = computed(() => {\n const h = raw.value\n ? raw.value.substring(0, 2).replace(/\\D/g, \"0\") || \"0\"\n : \"0\";\n const v = parseInt(h);\n return Math.min(Math.max(v, 0), 23); // keep as 0-23 for parsing convenience\n });\n const minute = computed(() => {\n const m = raw.value\n ? raw.value.substring(3, 5).replace(/\\D/g, \"0\") || \"0\"\n : \"0\";\n const v = parseInt(m);\n return Math.min(Math.max(v, 0), 59);\n });\n const period = computed(() => {\n const p = (raw.value?.substring(6, 8) || \"AM\").toUpperCase();\n return p.startsWith(\"P\") ? \"PM\" : \"AM\";\n });\n\n const hour24 = computed(() => {\n const h12 = parseInt(raw.value?.substring(0, 2).replace(/\\D/g, \"0\") || \"0\");\n const p = period.value;\n\n // Convert 12-hour to 24-hour format\n if (h12 === 12) {\n return p === \"AM\" ? 0 : 12;\n }\n return p === \"PM\" ? h12 + 12 : h12;\n });\n\n const time24 = computed(() => {\n if (!isComplete.value) return null;\n return `${String(hour24.value).padStart(2, \"0\")}:${String(minute.value).padStart(2, \"0\")}:00`;\n });\n\n const isComplete = computed(() =>\n /^(\\d{2}):(\\d{2})\\s([AP]M)$/i.test(raw.value ?? \"\"),\n );\n\n const toDisplay = (h24: number, m: number, ap: \"AM\" | \"PM\") => {\n // display uses 12-hour formatting in the field\n let h12 = h24 % 12;\n if (h12 === 0) h12 = 12;\n return `${String(h12).padStart(2, \"0\")}:${String(m).padStart(\n 2,\n \"0\",\n )} ${ap}`;\n };\n\n const toDateFromDisplay = (display: string) => {\n const match = display.match(/^(\\d{2}):(\\d{2})\\s([AP]M)$/i);\n if (!match) return null;\n const hh = parseInt(match[1]);\n const mm = parseInt(match[2]);\n const ap = match[3].toUpperCase();\n // Enforce 12-hour bounds and minute bounds; reject invalid formats like 99:99 AM\n if (hh < 1 || hh > 12 || mm < 0 || mm > 59) return null;\n let h24 = hh % 12;\n if (ap === \"PM\") h24 += 12;\n const d = new Date();\n d.setSeconds(0, 0);\n d.setHours(h24);\n d.setMinutes(mm);\n return d;\n };\n\n const emitParsedIfComplete = (event: any) => {\n if (digitsOnly.value.length === 0) {\n args.onChange({ value: null, event });\n return;\n }\n if (!isComplete.value) {\n args.onChange({ value: null, event });\n return;\n }\n const date = toDateFromDisplay(raw.value);\n if (date && inRangeTime(date)) {\n args.onChange({ value: date, event });\n } else {\n args.onChange({ value: null, event });\n }\n };\n const minutesSinceMidnight = (d: Date) => d.getHours() * 60 + d.getMinutes();\n const inRangeTime = (d: Date) => {\n const min = args.min ?? undefined;\n const max = args.max ?? undefined;\n const m = minutesSinceMidnight(d);\n if (min) {\n const minM = minutesSinceMidnight(min);\n if (m < minM) return false;\n }\n if (max) {\n const maxM = minutesSinceMidnight(max);\n if (m > maxM) return false;\n }\n return true;\n };\n\n const syncRawFromDate = (date: Date) => {\n const h24 = date.getHours();\n const ap = h24 >= 12 ? \"PM\" : \"AM\";\n raw.value = toDisplay(h24, date.getMinutes(), ap);\n };\n\n const emitValue = (value: Date | null, event: any) => {\n args.onChange({ value, event });\n };\n\n const focusInputAfterPopupClose = () => {\n // Defer focus long enough for the popup close lifecycle to complete.\n nextTick(() => {\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const inputEl = document.getElementById(\n args.id,\n ) as HTMLInputElement | null;\n if (inputEl) {\n inputEl.focus();\n const end = (inputEl.value ?? \"\").length;\n inputEl.setSelectionRange(end, end);\n }\n });\n });\n });\n };\n\n const inferPopupAction = (event: any): PopupAction => {\n const target = event?.event?.target as HTMLElement | null | undefined;\n if (!target) return null;\n if (target.closest(\".k-time-now\")) return \"now\";\n if (target.closest(\".k-time-accept\")) return \"set\";\n return null;\n };\n\n const emitParsedDate = (date: Date | null, event: any) => {\n if (date && inRangeTime(date)) {\n emitValue(date, event);\n } else {\n emitValue(null, event);\n }\n };\n\n const handleChange: AnyArgsHandler = (...eventArgs) => {\n const event = eventArgs[0] as any;\n if (!event) return;\n\n const action = inferPopupAction(event);\n\n // TimePicker popup path: distinguish NOW vs SET and normalize value handling.\n if (action === \"now\") {\n const now = new Date();\n syncRawFromDate(now);\n emitParsedDate(now, event);\n focusInputAfterPopupClose();\n return;\n }\n\n if (event?.value instanceof Date) {\n const nextValue = new Date(event.value);\n syncRawFromDate(nextValue);\n emitParsedDate(nextValue, event);\n if (action === \"set\") {\n focusInputAfterPopupClose();\n }\n return;\n }\n\n if (event?.value === null) {\n raw.value = \"\";\n emitValue(null, event);\n return;\n }\n\n // Set raw first from event\n raw.value = event.value as string;\n const src = event.event?.target as HTMLInputElement;\n cursorPos.value = src?.selectionStart ?? 0;\n // If caret is in AM/PM segment and user typed A/a or P/p, auto-complete to AM/PM\n try {\n const pos = cursorPos.value ?? 0;\n if (partAt(pos) === \"ampm\" && (raw.value ?? \"\").length >= 8) {\n const first = raw.value.charAt(6);\n if (/[Aa]/.test(first)) {\n raw.value = `${raw.value.slice(0, 6)}AM${raw.value.slice(8)}`;\n // Move caret to end of AM/PM\n nextTick(() => {\n requestAnimationFrame(() => {\n const inputEl = document.getElementById(\n args.id,\n ) as HTMLInputElement | null;\n if (inputEl) {\n inputEl.focus();\n inputEl.setSelectionRange(8, 8);\n }\n });\n });\n } else if (/[Pp]/.test(first)) {\n raw.value = `${raw.value.slice(0, 6)}PM${raw.value.slice(8)}`;\n nextTick(() => {\n requestAnimationFrame(() => {\n const inputEl = document.getElementById(\n args.id,\n ) as HTMLInputElement | null;\n if (inputEl) {\n inputEl.focus();\n inputEl.setSelectionRange(8, 8);\n }\n });\n });\n }\n }\n } catch {}\n emitParsedIfComplete(event);\n };\n\n const handleClick = (event: MouseEvent): void => {\n cursorPos.value = (event.target as HTMLInputElement).selectionStart ?? 0;\n };\n\n const applyStep = (\n direction: \"ArrowUp\" | \"ArrowDown\",\n sourceEl: HTMLInputElement | null | undefined,\n event: Event,\n ): void => {\n const pos = sourceEl?.selectionStart ?? cursorPos.value ?? 0;\n cursorPos.value = pos;\n const part = partAt(pos);\n\n const dispMatch = (raw.value ?? \"\").match(/^(\\d{2}):(\\d{2})\\s([AP]M)$/i);\n if (!dispMatch) {\n // If empty, initialize to current time on first step\n if ((raw.value ?? \"\").length === 0 || digitsOnly.value.length === 0) {\n const now = new Date();\n const h24 = now.getHours();\n const ap = h24 >= 12 ? \"PM\" : \"AM\";\n raw.value = toDisplay(h24, now.getMinutes(), ap);\n const date = toDateFromDisplay(raw.value);\n emitParsedDate(date, event);\n nextTick(() => {\n requestAnimationFrame(() => {\n const inputEl = document.getElementById(\n args.id,\n ) as HTMLInputElement | null;\n const p = cursorPos.value ?? 0;\n if (inputEl) {\n inputEl.focus();\n inputEl.setSelectionRange(p, p);\n }\n });\n });\n }\n // For non-empty but invalid formats, do not auto-correct\n return;\n }\n let hh = parseInt(dispMatch[1]);\n let mm = parseInt(dispMatch[2]);\n let ap = dispMatch[3].toUpperCase() as \"AM\" | \"PM\";\n\n if (part === \"hh\") {\n if (direction === \"ArrowUp\") hh = hh < 12 ? hh + 1 : 1;\n else hh = hh > 1 ? hh - 1 : 12;\n } else if (part === \"mm\") {\n const step = args.minuteStepRef?.value ?? args.minuteStep ?? 1;\n if (step === 1) {\n if (direction === \"ArrowUp\") mm = mm < 59 ? mm + 1 : 0;\n else mm = mm > 0 ? mm - 1 : 59;\n } else {\n if (direction === \"ArrowUp\") {\n const rem = mm % step;\n let next = rem === 0 ? mm + step : mm + (step - rem);\n if (next >= 60) next = 0; // wrap to top of hour\n mm = next;\n } else {\n const rem = mm % step;\n let prev = rem === 0 ? mm - step : mm - rem;\n if (prev < 0) prev = 60 - step; // wrap to last step in hour\n mm = prev;\n }\n }\n } else if (part === \"ampm\") {\n ap = ap === \"AM\" ? \"PM\" : \"AM\";\n }\n\n raw.value = `${String(hh).padStart(2, \"0\")}:${String(mm).padStart(\n 2,\n \"0\",\n )} ${ap}`;\n const date = toDateFromDisplay(raw.value);\n emitParsedDate(date, event);\n\n nextTick(() => {\n requestAnimationFrame(() => {\n const inputEl = document.getElementById(\n args.id,\n ) as HTMLInputElement | null;\n const p = cursorPos.value ?? 0;\n if (inputEl) {\n inputEl.focus();\n inputEl.setSelectionRange(p, p);\n }\n });\n });\n };\n\n // Wheel events can target the MaskedTextBox wrapper, so fall back to the input by id.\n const resolveInput = (event: Event): HTMLInputElement | null =>\n event.target instanceof HTMLInputElement\n ? event.target\n : (document.getElementById(args.id) as HTMLInputElement | null);\n\n // Native disabled/readonly is the source of truth, so plain Kendo inputs get the guard too.\n const isEditable = (el: HTMLInputElement | null): boolean =>\n !el?.disabled && !el?.readOnly;\n\n const handleKeyDown = (event: KeyboardEvent): void => {\n if (!isEditable(resolveInput(event))) return;\n if (event.code === \"Space\" || event.key === \" \") {\n // Open the picker without modifying the input\n // Justified: Space opens the time picker popup instead of inserting a space.\n event.preventDefault();\n // Justified: Parent containers such as grid keyboard handlers should not consume this.\n event.stopPropagation();\n args.onShowPicker(event);\n return;\n }\n\n // Alt+Down opens the picker; allow other Alt+arrow combinations to pass through\n if (event.key === \"ArrowDown\" && event.altKey) {\n // Justified: Alt+Down is reserved for opening the time picker popup.\n event.preventDefault();\n // Justified: Prevent parent keyboard navigation from treating this as row movement.\n event.stopPropagation();\n args.onShowPicker(event);\n return;\n }\n\n if (steppers.includes(event.key)) {\n if (event.altKey) return;\n // Justified: ArrowUp/Down act as time-part steppers instead of native caret/page behavior.\n event.preventDefault();\n // Justified: Prevent parent containers such as the grid from also handling these arrows.\n event.stopPropagation();\n const src = event.target as HTMLInputElement;\n applyStep(event.key as \"ArrowUp\" | \"ArrowDown\", src, event);\n return;\n }\n };\n\n const handleWheel = (event: WheelEvent): void => {\n const input = resolveInput(event);\n // Let the page scroll when the input can't be edited.\n if (!isEditable(input)) return;\n // Map mouse wheel to stepper behavior (up/down) based on caret segment\n // Prevent page scroll when interacting with the input\n event.preventDefault();\n const direction = event.deltaY < 0 ? \"ArrowUp\" : \"ArrowDown\";\n applyStep(direction, input, event);\n };\n\n const handleKeyUp = (event: KeyboardEvent): void => {\n const src = event.target as HTMLInputElement;\n if (cursorKeys.includes(event.key)) {\n // Do not prevent default for caret navigation\n cursorPos.value = src?.selectionStart ?? 0;\n return;\n }\n if (steppers.includes(event.key)) {\n if (event.altKey) return;\n cursorPos.value = src?.selectionStart ?? 0;\n }\n };\n\n const handleBlur = (event: FocusEvent): void => {\n isTouched.value = true;\n\n // If required and value is still undefined/blank, coerce external\n // value from undefined -> \"\" so downstream validation can treat\n // this as an incomplete required field.\n if (\n isRequired.value &&\n args.externalValue &&\n args.externalValue.value === undefined &&\n digitsOnly.value.length === 0\n ) {\n (args.externalValue as Ref<any>).value = \"\";\n }\n\n const src = event.target as HTMLInputElement | null;\n if (src) {\n cursorPos.value = src.selectionStart ?? 0;\n }\n };\n\n // Sync external value into raw when provided\n if (args.externalValue) {\n watch(\n args.externalValue,\n (newVal) => {\n if (newVal) {\n const date = new Date(newVal as any);\n if (date.toString() !== \"Invalid Date\") {\n const h24 = date.getHours();\n const ap = h24 >= 12 ? \"PM\" : \"AM\";\n raw.value = toDisplay(h24, date.getMinutes(), ap);\n return;\n }\n }\n // If external value is null/invalid, keep current raw as-is\n },\n { immediate: true },\n );\n }\n\n const debugLines = computed(() => {\n return [\n [\"Time\", raw.value || \"--:-- --\"],\n [\"Hour (12h)\", hour.value],\n [\"Hour (24h)\", hour24.value],\n [\"Minute\", minute.value],\n [\"Period\", period.value],\n [\"Time (24h)\", time24.value ?? \"--:--:--\"],\n [\"Digits only\", digitsOnly.value],\n [\n \"Parsed Date\",\n parsedRawTime.value?.toLocaleDateString(\"en-US\", {\n hour: \"2-digit\",\n minute: \"2-digit\",\n }) ?? null,\n ],\n [\n \"min\",\n args.min?.toLocaleTimeString(\"en-US\", {\n hour: \"2-digit\",\n minute: \"2-digit\",\n }) ?? null,\n ],\n [\n \"max\",\n args.max?.toLocaleTimeString(\"en-US\", {\n hour: \"2-digit\",\n minute: \"2-digit\",\n }) ?? null,\n ],\n [\"valid\", isValid.value],\n [\"reason\", reason.value],\n [\"validationMessage\", validationMessage.value],\n ];\n });\n\n // Validation based on completeness and parse-ability\n const parsedRawTime = computed<Date | null>(\n () => toDateFromDisplay(raw.value) ?? null,\n );\n const isValid = computed(() => {\n // Optional field preserves forgiving behavior\n if (!isRequired.value) {\n if (!isComplete.value) return true;\n const t = parsedRawTime.value;\n if (!t) return false;\n return inRangeTime(t);\n }\n\n // Required field: do not flag invalid until after blur\n if (!isTouched.value) return true;\n\n const t = parsedRawTime.value;\n if (!isComplete.value) return false;\n if (!t) return false;\n return inRangeTime(t);\n });\n\n const reason = computed<string | undefined>(() => {\n // Optional: only report reasons for completed-but-bad values\n if (!isRequired.value) {\n if (!isComplete.value) return undefined;\n const t = parsedRawTime.value;\n if (!t) return \"invalid-time\";\n if (!inRangeTime(t)) return \"out-of-bounds\";\n return \"valid\";\n }\n\n // Required: only validate after blur\n if (!isTouched.value) return undefined;\n\n if (digitsOnly.value.length === 0 || !isComplete.value) {\n return \"incomplete\";\n }\n\n const t = parsedRawTime.value;\n if (!t) return \"invalid-time\";\n if (!inRangeTime(t)) return \"out-of-bounds\";\n return \"valid\";\n });\n\n const validationMessage = computed(() => {\n const r = reason.value;\n if (!r || r === \"valid\") return \"\";\n\n if (r === \"incomplete\") {\n return \"Required\";\n }\n\n if (r === \"invalid-time\") {\n return `Must be in ${placeholder.value} format.`;\n }\n\n const opts: Intl.DateTimeFormatOptions = {\n hour: \"2-digit\",\n minute: \"2-digit\",\n };\n const minStr = args.min ? args.min.toLocaleTimeString(\"en-US\", opts) : null;\n const maxStr = args.max ? args.max.toLocaleTimeString(\"en-US\", opts) : null;\n if (r === \"out-of-bounds\") {\n if (minStr && maxStr) return `Must be between ${minStr} and ${maxStr}.`;\n if (minStr) return `Must be ${minStr} or later.`;\n if (maxStr) return `Must be ${maxStr} or earlier.`;\n }\n\n return \"\";\n });\n\n const initStyling = () => {\n // Idempotent application of the `fk-timepicker` class to the time picker's parent\n nextTick(() => {\n const inputEl = document.getElementById(args.id) as HTMLElement | null;\n if (!inputEl) {\n console.warn(`#${args.id} not found for styling.`);\n return;\n }\n const timePicker = inputEl.closest(\".k-timepicker\");\n if (!timePicker) {\n console.warn(\n `.k-timepicker parent of #${args.id} not found for styling.`,\n );\n return;\n }\n const parent = timePicker.parentElement;\n if (!parent) {\n console.warn(\n `Parent of .k-timepicker not found for #${args.id} styling.`,\n );\n return;\n }\n if (parent.classList.contains(\"fk-timepicker\")) return;\n parent.classList.add(\"fk-timepicker\");\n });\n };\n\n onMounted(() => {\n initStyling();\n });\n\n return {\n id: args.id,\n min: args.min,\n max: args.max,\n raw,\n rules,\n debugEnabled,\n debugLines,\n placeholder,\n isValid,\n reason: readonly(reason),\n validationMessage,\n isComplete,\n inRangeTime,\n cursorPos,\n hour: readonly(hour),\n hour24: readonly(hour24),\n minute: readonly(minute),\n period: readonly(period),\n time24: readonly(time24),\n parsedRawTime: readonly(parsedRawTime),\n handleChange,\n handleKeyDown,\n handleKeyUp,\n handleClick,\n handleWheel,\n handleBlur,\n // Expose so consumers can reapply theming when Kendo updates DOM\n initStyling,\n };\n}\n\nexport type UseMaskedTimeInputReturn = ReturnType<typeof useMaskedTimeInput>;\n"],"names":["useMaskedTimeInput","args","raw","ref","cursorPos","debugEnabled","placeholder","isRequired","computed","isTouched","steppers","cursorKeys","digitsOnly","rules","partAt","pos","hour","h","v","minute","m","period","hour24","h12","p","time24","isComplete","toDisplay","h24","ap","toDateFromDisplay","display","match","hh","mm","d","emitParsedIfComplete","event","date","inRangeTime","minutesSinceMidnight","min","max","minM","maxM","syncRawFromDate","emitValue","value","focusInputAfterPopupClose","nextTick","inputEl","end","inferPopupAction","target","emitParsedDate","handleChange","eventArgs","action","now","nextValue","src","first","handleClick","applyStep","direction","sourceEl","part","dispMatch","step","rem","next","prev","resolveInput","isEditable","el","handleKeyDown","handleWheel","input","handleKeyUp","handleBlur","watch","newVal","debugLines","parsedRawTime","isValid","reason","validationMessage","t","r","opts","minStr","maxStr","initStyling","timePicker","parent","onMounted","readonly"],"mappings":"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"}
@@ -0,0 +1,363 @@
1
+ import { ref as w, computed as c, watch as se, onMounted as ce, readonly as g, nextTick as S } from "vue";
2
+ function fe(n) {
3
+ const i = w(""), m = w(void 0), N = w(!!n.debug), L = w(n.timeFormat ?? "hh:mm AM"), D = c(() => !!n.required), k = w(!1), q = ["ArrowUp", "ArrowDown"], Q = ["ArrowLeft", "ArrowRight"], A = c(() => (i.value ?? "").replace(/\D/g, "")), X = {
4
+ H: /[0-9]/,
5
+ h: /[0-9]/,
6
+ M: /[0-9]/,
7
+ m: /[0-9]/,
8
+ A: /[AaPp]/,
9
+ a: /[Mm]/
10
+ }, F = (e) => e <= 2 ? "hh" : e <= 5 ? "mm" : "ampm", H = c(() => {
11
+ const e = i.value && i.value.substring(0, 2).replace(/\D/g, "0") || "0", t = parseInt(e);
12
+ return Math.min(Math.max(t, 0), 23);
13
+ }), $ = c(() => {
14
+ const e = i.value && i.value.substring(3, 5).replace(/\D/g, "0") || "0", t = parseInt(e);
15
+ return Math.min(Math.max(t, 0), 59);
16
+ }), x = c(() => (i.value?.substring(6, 8) || "AM").toUpperCase().startsWith("P") ? "PM" : "AM"), I = c(() => {
17
+ const e = parseInt(i.value?.substring(0, 2).replace(/\D/g, "0") || "0"), t = x.value;
18
+ return e === 12 ? t === "AM" ? 0 : 12 : t === "PM" ? e + 12 : e;
19
+ }), B = c(() => v.value ? `${String(I.value).padStart(2, "0")}:${String($.value).padStart(2, "0")}:00` : null), v = c(
20
+ () => /^(\d{2}):(\d{2})\s([AP]M)$/i.test(i.value ?? "")
21
+ ), b = (e, t, o) => {
22
+ let r = e % 12;
23
+ return r === 0 && (r = 12), `${String(r).padStart(2, "0")}:${String(t).padStart(
24
+ 2,
25
+ "0"
26
+ )} ${o}`;
27
+ }, y = (e) => {
28
+ const t = e.match(/^(\d{2}):(\d{2})\s([AP]M)$/i);
29
+ if (!t) return null;
30
+ const o = parseInt(t[1]), r = parseInt(t[2]), a = t[3].toUpperCase();
31
+ if (o < 1 || o > 12 || r < 0 || r > 59) return null;
32
+ let d = o % 12;
33
+ a === "PM" && (d += 12);
34
+ const u = /* @__PURE__ */ new Date();
35
+ return u.setSeconds(0, 0), u.setHours(d), u.setMinutes(r), u;
36
+ }, Z = (e) => {
37
+ if (A.value.length === 0) {
38
+ n.onChange({ value: null, event: e });
39
+ return;
40
+ }
41
+ if (!v.value) {
42
+ n.onChange({ value: null, event: e });
43
+ return;
44
+ }
45
+ const t = y(i.value);
46
+ t && h(t) ? n.onChange({ value: t, event: e }) : n.onChange({ value: null, event: e });
47
+ }, E = (e) => e.getHours() * 60 + e.getMinutes(), h = (e) => {
48
+ const t = n.min ?? void 0, o = n.max ?? void 0, r = E(e);
49
+ if (t) {
50
+ const a = E(t);
51
+ if (r < a) return !1;
52
+ }
53
+ if (o) {
54
+ const a = E(o);
55
+ if (r > a) return !1;
56
+ }
57
+ return !0;
58
+ }, V = (e) => {
59
+ const t = e.getHours(), o = t >= 12 ? "PM" : "AM";
60
+ i.value = b(t, e.getMinutes(), o);
61
+ }, U = (e, t) => {
62
+ n.onChange({ value: e, event: t });
63
+ }, K = () => {
64
+ S(() => {
65
+ requestAnimationFrame(() => {
66
+ requestAnimationFrame(() => {
67
+ const e = document.getElementById(
68
+ n.id
69
+ );
70
+ if (e) {
71
+ e.focus();
72
+ const t = (e.value ?? "").length;
73
+ e.setSelectionRange(t, t);
74
+ }
75
+ });
76
+ });
77
+ });
78
+ }, _ = (e) => {
79
+ const t = e?.event?.target;
80
+ return t ? t.closest(".k-time-now") ? "now" : t.closest(".k-time-accept") ? "set" : null : null;
81
+ }, P = (e, t) => {
82
+ e && h(e) ? U(e, t) : U(null, t);
83
+ }, ee = (...e) => {
84
+ const t = e[0];
85
+ if (!t) return;
86
+ const o = _(t);
87
+ if (o === "now") {
88
+ const a = /* @__PURE__ */ new Date();
89
+ V(a), P(a, t), K();
90
+ return;
91
+ }
92
+ if (t?.value instanceof Date) {
93
+ const a = new Date(t.value);
94
+ V(a), P(a, t), o === "set" && K();
95
+ return;
96
+ }
97
+ if (t?.value === null) {
98
+ i.value = "", U(null, t);
99
+ return;
100
+ }
101
+ i.value = t.value;
102
+ const r = t.event?.target;
103
+ m.value = r?.selectionStart ?? 0;
104
+ try {
105
+ const a = m.value ?? 0;
106
+ if (F(a) === "ampm" && (i.value ?? "").length >= 8) {
107
+ const d = i.value.charAt(6);
108
+ /[Aa]/.test(d) ? (i.value = `${i.value.slice(0, 6)}AM${i.value.slice(8)}`, S(() => {
109
+ requestAnimationFrame(() => {
110
+ const u = document.getElementById(
111
+ n.id
112
+ );
113
+ u && (u.focus(), u.setSelectionRange(8, 8));
114
+ });
115
+ })) : /[Pp]/.test(d) && (i.value = `${i.value.slice(0, 6)}PM${i.value.slice(8)}`, S(() => {
116
+ requestAnimationFrame(() => {
117
+ const u = document.getElementById(
118
+ n.id
119
+ );
120
+ u && (u.focus(), u.setSelectionRange(8, 8));
121
+ });
122
+ }));
123
+ }
124
+ } catch {
125
+ }
126
+ Z(t);
127
+ }, te = (e) => {
128
+ m.value = e.target.selectionStart ?? 0;
129
+ }, O = (e, t, o) => {
130
+ const r = t?.selectionStart ?? m.value ?? 0;
131
+ m.value = r;
132
+ const a = F(r), d = (i.value ?? "").match(/^(\d{2}):(\d{2})\s([AP]M)$/i);
133
+ if (!d) {
134
+ if ((i.value ?? "").length === 0 || A.value.length === 0) {
135
+ const s = /* @__PURE__ */ new Date(), f = s.getHours(), p = f >= 12 ? "PM" : "AM";
136
+ i.value = b(f, s.getMinutes(), p);
137
+ const le = y(i.value);
138
+ P(le, o), S(() => {
139
+ requestAnimationFrame(() => {
140
+ const T = document.getElementById(
141
+ n.id
142
+ ), J = m.value ?? 0;
143
+ T && (T.focus(), T.setSelectionRange(J, J));
144
+ });
145
+ });
146
+ }
147
+ return;
148
+ }
149
+ let u = parseInt(d[1]), l = parseInt(d[2]), R = d[3].toUpperCase();
150
+ if (a === "hh")
151
+ e === "ArrowUp" ? u = u < 12 ? u + 1 : 1 : u = u > 1 ? u - 1 : 12;
152
+ else if (a === "mm") {
153
+ const s = n.minuteStepRef?.value ?? n.minuteStep ?? 1;
154
+ if (s === 1)
155
+ e === "ArrowUp" ? l = l < 59 ? l + 1 : 0 : l = l > 0 ? l - 1 : 59;
156
+ else if (e === "ArrowUp") {
157
+ const f = l % s;
158
+ let p = f === 0 ? l + s : l + (s - f);
159
+ p >= 60 && (p = 0), l = p;
160
+ } else {
161
+ const f = l % s;
162
+ let p = f === 0 ? l - s : l - f;
163
+ p < 0 && (p = 60 - s), l = p;
164
+ }
165
+ } else a === "ampm" && (R = R === "AM" ? "PM" : "AM");
166
+ i.value = `${String(u).padStart(2, "0")}:${String(l).padStart(
167
+ 2,
168
+ "0"
169
+ )} ${R}`;
170
+ const ae = y(i.value);
171
+ P(ae, o), S(() => {
172
+ requestAnimationFrame(() => {
173
+ const s = document.getElementById(
174
+ n.id
175
+ ), f = m.value ?? 0;
176
+ s && (s.focus(), s.setSelectionRange(f, f));
177
+ });
178
+ });
179
+ }, W = (e) => e.target instanceof HTMLInputElement ? e.target : document.getElementById(n.id), Y = (e) => !e?.disabled && !e?.readOnly, ne = (e) => {
180
+ if (Y(W(e))) {
181
+ if (e.code === "Space" || e.key === " ") {
182
+ e.preventDefault(), e.stopPropagation(), n.onShowPicker(e);
183
+ return;
184
+ }
185
+ if (e.key === "ArrowDown" && e.altKey) {
186
+ e.preventDefault(), e.stopPropagation(), n.onShowPicker(e);
187
+ return;
188
+ }
189
+ if (q.includes(e.key)) {
190
+ if (e.altKey) return;
191
+ e.preventDefault(), e.stopPropagation();
192
+ const t = e.target;
193
+ O(e.key, t, e);
194
+ return;
195
+ }
196
+ }
197
+ }, ie = (e) => {
198
+ const t = W(e);
199
+ if (!Y(t)) return;
200
+ e.preventDefault();
201
+ const o = e.deltaY < 0 ? "ArrowUp" : "ArrowDown";
202
+ O(o, t, e);
203
+ }, oe = (e) => {
204
+ const t = e.target;
205
+ if (Q.includes(e.key)) {
206
+ m.value = t?.selectionStart ?? 0;
207
+ return;
208
+ }
209
+ if (q.includes(e.key)) {
210
+ if (e.altKey) return;
211
+ m.value = t?.selectionStart ?? 0;
212
+ }
213
+ }, re = (e) => {
214
+ k.value = !0, D.value && n.externalValue && n.externalValue.value === void 0 && A.value.length === 0 && (n.externalValue.value = "");
215
+ const t = e.target;
216
+ t && (m.value = t.selectionStart ?? 0);
217
+ };
218
+ n.externalValue && se(
219
+ n.externalValue,
220
+ (e) => {
221
+ if (e) {
222
+ const t = new Date(e);
223
+ if (t.toString() !== "Invalid Date") {
224
+ const o = t.getHours(), r = o >= 12 ? "PM" : "AM";
225
+ i.value = b(o, t.getMinutes(), r);
226
+ return;
227
+ }
228
+ }
229
+ },
230
+ { immediate: !0 }
231
+ );
232
+ const ue = c(() => [
233
+ ["Time", i.value || "--:-- --"],
234
+ ["Hour (12h)", H.value],
235
+ ["Hour (24h)", I.value],
236
+ ["Minute", $.value],
237
+ ["Period", x.value],
238
+ ["Time (24h)", B.value ?? "--:--:--"],
239
+ ["Digits only", A.value],
240
+ [
241
+ "Parsed Date",
242
+ M.value?.toLocaleDateString("en-US", {
243
+ hour: "2-digit",
244
+ minute: "2-digit"
245
+ }) ?? null
246
+ ],
247
+ [
248
+ "min",
249
+ n.min?.toLocaleTimeString("en-US", {
250
+ hour: "2-digit",
251
+ minute: "2-digit"
252
+ }) ?? null
253
+ ],
254
+ [
255
+ "max",
256
+ n.max?.toLocaleTimeString("en-US", {
257
+ hour: "2-digit",
258
+ minute: "2-digit"
259
+ }) ?? null
260
+ ],
261
+ ["valid", j.value],
262
+ ["reason", C.value],
263
+ ["validationMessage", z.value]
264
+ ]), M = c(
265
+ () => y(i.value) ?? null
266
+ ), j = c(() => {
267
+ if (!D.value) {
268
+ if (!v.value) return !0;
269
+ const t = M.value;
270
+ return t ? h(t) : !1;
271
+ }
272
+ if (!k.value) return !0;
273
+ const e = M.value;
274
+ return !v.value || !e ? !1 : h(e);
275
+ }), C = c(() => {
276
+ if (!D.value) {
277
+ if (!v.value) return;
278
+ const t = M.value;
279
+ return t ? h(t) ? "valid" : "out-of-bounds" : "invalid-time";
280
+ }
281
+ if (!k.value) return;
282
+ if (A.value.length === 0 || !v.value)
283
+ return "incomplete";
284
+ const e = M.value;
285
+ return e ? h(e) ? "valid" : "out-of-bounds" : "invalid-time";
286
+ }), z = c(() => {
287
+ const e = C.value;
288
+ if (!e || e === "valid") return "";
289
+ if (e === "incomplete")
290
+ return "Required";
291
+ if (e === "invalid-time")
292
+ return `Must be in ${L.value} format.`;
293
+ const t = {
294
+ hour: "2-digit",
295
+ minute: "2-digit"
296
+ }, o = n.min ? n.min.toLocaleTimeString("en-US", t) : null, r = n.max ? n.max.toLocaleTimeString("en-US", t) : null;
297
+ if (e === "out-of-bounds") {
298
+ if (o && r) return `Must be between ${o} and ${r}.`;
299
+ if (o) return `Must be ${o} or later.`;
300
+ if (r) return `Must be ${r} or earlier.`;
301
+ }
302
+ return "";
303
+ }), G = () => {
304
+ S(() => {
305
+ const e = document.getElementById(n.id);
306
+ if (!e) {
307
+ console.warn(`#${n.id} not found for styling.`);
308
+ return;
309
+ }
310
+ const t = e.closest(".k-timepicker");
311
+ if (!t) {
312
+ console.warn(
313
+ `.k-timepicker parent of #${n.id} not found for styling.`
314
+ );
315
+ return;
316
+ }
317
+ const o = t.parentElement;
318
+ if (!o) {
319
+ console.warn(
320
+ `Parent of .k-timepicker not found for #${n.id} styling.`
321
+ );
322
+ return;
323
+ }
324
+ o.classList.contains("fk-timepicker") || o.classList.add("fk-timepicker");
325
+ });
326
+ };
327
+ return ce(() => {
328
+ G();
329
+ }), {
330
+ id: n.id,
331
+ min: n.min,
332
+ max: n.max,
333
+ raw: i,
334
+ rules: X,
335
+ debugEnabled: N,
336
+ debugLines: ue,
337
+ placeholder: L,
338
+ isValid: j,
339
+ reason: g(C),
340
+ validationMessage: z,
341
+ isComplete: v,
342
+ inRangeTime: h,
343
+ cursorPos: m,
344
+ hour: g(H),
345
+ hour24: g(I),
346
+ minute: g($),
347
+ period: g(x),
348
+ time24: g(B),
349
+ parsedRawTime: g(M),
350
+ handleChange: ee,
351
+ handleKeyDown: ne,
352
+ handleKeyUp: oe,
353
+ handleClick: te,
354
+ handleWheel: ie,
355
+ handleBlur: re,
356
+ // Expose so consumers can reapply theming when Kendo updates DOM
357
+ initStyling: G
358
+ };
359
+ }
360
+ export {
361
+ fe as u
362
+ };
363
+ //# sourceMappingURL=useMaskedTimeInput-DjtBdvsf.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMaskedTimeInput-DjtBdvsf.mjs","sources":["../../src/time/useMaskedTimeInput.ts"],"sourcesContent":["import {\n computed,\n nextTick,\n onMounted,\n readonly,\n ref,\n watch,\n type Ref,\n} from \"vue\";\n\nexport type ChangePayload = { value: Date | null; event: any };\n\ntype PopupAction = \"now\" | \"set\" | null;\ntype AnyArgsHandler = (...args: unknown[]) => void;\n\nexport function useMaskedTimeInput(args: {\n id: string;\n onChange: (p: ChangePayload) => void;\n onShowPicker: (e: KeyboardEvent) => void;\n externalValue?: Ref<string | Date | null | undefined>;\n // Minute stepping granularity for ArrowUp/ArrowDown when focused in minutes.\n // Supported values: 1, 5, 10, 15, 20, 30. If not provided, defaults to 1-minute steps.\n minuteStep?: 1 | 5 | 10 | 15 | 20 | 30;\n // Reactive alternative: pass a Ref to allow dynamic updates at runtime.\n minuteStepRef?: Ref<1 | 5 | 10 | 15 | 20 | 30 | undefined>;\n timeFormat?: string;\n min?: Date | null | undefined;\n max?: Date | null | undefined;\n /** When true, empty/incomplete value is considered invalid after blur */\n required?: boolean;\n debug?: boolean;\n}) {\n const raw = ref(\"\");\n const cursorPos = ref<number | undefined>(undefined);\n const debugEnabled = ref<boolean>(!!args.debug);\n const placeholder = ref<string>(args.timeFormat ?? \"hh:mm AM\");\n const isRequired = computed(() => !!args.required);\n const isTouched = ref(false);\n\n const steppers: string[] = [\"ArrowUp\", \"ArrowDown\"];\n const cursorKeys: string[] = [\"ArrowLeft\", \"ArrowRight\"];\n\n const digitsOnly = computed(() => (raw.value ?? \"\").replace(/\\D/g, \"\"));\n\n // Mask rules to be used by MaskedTextBox\n // Relax numeric constraints: allow any digits, then validate afterwards\n const rules = {\n H: /[0-9]/,\n h: /[0-9]/,\n M: /[0-9]/,\n m: /[0-9]/,\n A: /[AaPp]/,\n a: /[Mm]/,\n } as const;\n\n const partAt = (pos: number) => {\n if (pos <= 2) return \"hh\"; // hours\n if (pos <= 5) return \"mm\"; // minutes\n return \"ampm\"; // AM/PM\n };\n\n const hour = computed(() => {\n const h = raw.value\n ? raw.value.substring(0, 2).replace(/\\D/g, \"0\") || \"0\"\n : \"0\";\n const v = parseInt(h);\n return Math.min(Math.max(v, 0), 23); // keep as 0-23 for parsing convenience\n });\n const minute = computed(() => {\n const m = raw.value\n ? raw.value.substring(3, 5).replace(/\\D/g, \"0\") || \"0\"\n : \"0\";\n const v = parseInt(m);\n return Math.min(Math.max(v, 0), 59);\n });\n const period = computed(() => {\n const p = (raw.value?.substring(6, 8) || \"AM\").toUpperCase();\n return p.startsWith(\"P\") ? \"PM\" : \"AM\";\n });\n\n const hour24 = computed(() => {\n const h12 = parseInt(raw.value?.substring(0, 2).replace(/\\D/g, \"0\") || \"0\");\n const p = period.value;\n\n // Convert 12-hour to 24-hour format\n if (h12 === 12) {\n return p === \"AM\" ? 0 : 12;\n }\n return p === \"PM\" ? h12 + 12 : h12;\n });\n\n const time24 = computed(() => {\n if (!isComplete.value) return null;\n return `${String(hour24.value).padStart(2, \"0\")}:${String(minute.value).padStart(2, \"0\")}:00`;\n });\n\n const isComplete = computed(() =>\n /^(\\d{2}):(\\d{2})\\s([AP]M)$/i.test(raw.value ?? \"\"),\n );\n\n const toDisplay = (h24: number, m: number, ap: \"AM\" | \"PM\") => {\n // display uses 12-hour formatting in the field\n let h12 = h24 % 12;\n if (h12 === 0) h12 = 12;\n return `${String(h12).padStart(2, \"0\")}:${String(m).padStart(\n 2,\n \"0\",\n )} ${ap}`;\n };\n\n const toDateFromDisplay = (display: string) => {\n const match = display.match(/^(\\d{2}):(\\d{2})\\s([AP]M)$/i);\n if (!match) return null;\n const hh = parseInt(match[1]);\n const mm = parseInt(match[2]);\n const ap = match[3].toUpperCase();\n // Enforce 12-hour bounds and minute bounds; reject invalid formats like 99:99 AM\n if (hh < 1 || hh > 12 || mm < 0 || mm > 59) return null;\n let h24 = hh % 12;\n if (ap === \"PM\") h24 += 12;\n const d = new Date();\n d.setSeconds(0, 0);\n d.setHours(h24);\n d.setMinutes(mm);\n return d;\n };\n\n const emitParsedIfComplete = (event: any) => {\n if (digitsOnly.value.length === 0) {\n args.onChange({ value: null, event });\n return;\n }\n if (!isComplete.value) {\n args.onChange({ value: null, event });\n return;\n }\n const date = toDateFromDisplay(raw.value);\n if (date && inRangeTime(date)) {\n args.onChange({ value: date, event });\n } else {\n args.onChange({ value: null, event });\n }\n };\n const minutesSinceMidnight = (d: Date) => d.getHours() * 60 + d.getMinutes();\n const inRangeTime = (d: Date) => {\n const min = args.min ?? undefined;\n const max = args.max ?? undefined;\n const m = minutesSinceMidnight(d);\n if (min) {\n const minM = minutesSinceMidnight(min);\n if (m < minM) return false;\n }\n if (max) {\n const maxM = minutesSinceMidnight(max);\n if (m > maxM) return false;\n }\n return true;\n };\n\n const syncRawFromDate = (date: Date) => {\n const h24 = date.getHours();\n const ap = h24 >= 12 ? \"PM\" : \"AM\";\n raw.value = toDisplay(h24, date.getMinutes(), ap);\n };\n\n const emitValue = (value: Date | null, event: any) => {\n args.onChange({ value, event });\n };\n\n const focusInputAfterPopupClose = () => {\n // Defer focus long enough for the popup close lifecycle to complete.\n nextTick(() => {\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n const inputEl = document.getElementById(\n args.id,\n ) as HTMLInputElement | null;\n if (inputEl) {\n inputEl.focus();\n const end = (inputEl.value ?? \"\").length;\n inputEl.setSelectionRange(end, end);\n }\n });\n });\n });\n };\n\n const inferPopupAction = (event: any): PopupAction => {\n const target = event?.event?.target as HTMLElement | null | undefined;\n if (!target) return null;\n if (target.closest(\".k-time-now\")) return \"now\";\n if (target.closest(\".k-time-accept\")) return \"set\";\n return null;\n };\n\n const emitParsedDate = (date: Date | null, event: any) => {\n if (date && inRangeTime(date)) {\n emitValue(date, event);\n } else {\n emitValue(null, event);\n }\n };\n\n const handleChange: AnyArgsHandler = (...eventArgs) => {\n const event = eventArgs[0] as any;\n if (!event) return;\n\n const action = inferPopupAction(event);\n\n // TimePicker popup path: distinguish NOW vs SET and normalize value handling.\n if (action === \"now\") {\n const now = new Date();\n syncRawFromDate(now);\n emitParsedDate(now, event);\n focusInputAfterPopupClose();\n return;\n }\n\n if (event?.value instanceof Date) {\n const nextValue = new Date(event.value);\n syncRawFromDate(nextValue);\n emitParsedDate(nextValue, event);\n if (action === \"set\") {\n focusInputAfterPopupClose();\n }\n return;\n }\n\n if (event?.value === null) {\n raw.value = \"\";\n emitValue(null, event);\n return;\n }\n\n // Set raw first from event\n raw.value = event.value as string;\n const src = event.event?.target as HTMLInputElement;\n cursorPos.value = src?.selectionStart ?? 0;\n // If caret is in AM/PM segment and user typed A/a or P/p, auto-complete to AM/PM\n try {\n const pos = cursorPos.value ?? 0;\n if (partAt(pos) === \"ampm\" && (raw.value ?? \"\").length >= 8) {\n const first = raw.value.charAt(6);\n if (/[Aa]/.test(first)) {\n raw.value = `${raw.value.slice(0, 6)}AM${raw.value.slice(8)}`;\n // Move caret to end of AM/PM\n nextTick(() => {\n requestAnimationFrame(() => {\n const inputEl = document.getElementById(\n args.id,\n ) as HTMLInputElement | null;\n if (inputEl) {\n inputEl.focus();\n inputEl.setSelectionRange(8, 8);\n }\n });\n });\n } else if (/[Pp]/.test(first)) {\n raw.value = `${raw.value.slice(0, 6)}PM${raw.value.slice(8)}`;\n nextTick(() => {\n requestAnimationFrame(() => {\n const inputEl = document.getElementById(\n args.id,\n ) as HTMLInputElement | null;\n if (inputEl) {\n inputEl.focus();\n inputEl.setSelectionRange(8, 8);\n }\n });\n });\n }\n }\n } catch {}\n emitParsedIfComplete(event);\n };\n\n const handleClick = (event: MouseEvent): void => {\n cursorPos.value = (event.target as HTMLInputElement).selectionStart ?? 0;\n };\n\n const applyStep = (\n direction: \"ArrowUp\" | \"ArrowDown\",\n sourceEl: HTMLInputElement | null | undefined,\n event: Event,\n ): void => {\n const pos = sourceEl?.selectionStart ?? cursorPos.value ?? 0;\n cursorPos.value = pos;\n const part = partAt(pos);\n\n const dispMatch = (raw.value ?? \"\").match(/^(\\d{2}):(\\d{2})\\s([AP]M)$/i);\n if (!dispMatch) {\n // If empty, initialize to current time on first step\n if ((raw.value ?? \"\").length === 0 || digitsOnly.value.length === 0) {\n const now = new Date();\n const h24 = now.getHours();\n const ap = h24 >= 12 ? \"PM\" : \"AM\";\n raw.value = toDisplay(h24, now.getMinutes(), ap);\n const date = toDateFromDisplay(raw.value);\n emitParsedDate(date, event);\n nextTick(() => {\n requestAnimationFrame(() => {\n const inputEl = document.getElementById(\n args.id,\n ) as HTMLInputElement | null;\n const p = cursorPos.value ?? 0;\n if (inputEl) {\n inputEl.focus();\n inputEl.setSelectionRange(p, p);\n }\n });\n });\n }\n // For non-empty but invalid formats, do not auto-correct\n return;\n }\n let hh = parseInt(dispMatch[1]);\n let mm = parseInt(dispMatch[2]);\n let ap = dispMatch[3].toUpperCase() as \"AM\" | \"PM\";\n\n if (part === \"hh\") {\n if (direction === \"ArrowUp\") hh = hh < 12 ? hh + 1 : 1;\n else hh = hh > 1 ? hh - 1 : 12;\n } else if (part === \"mm\") {\n const step = args.minuteStepRef?.value ?? args.minuteStep ?? 1;\n if (step === 1) {\n if (direction === \"ArrowUp\") mm = mm < 59 ? mm + 1 : 0;\n else mm = mm > 0 ? mm - 1 : 59;\n } else {\n if (direction === \"ArrowUp\") {\n const rem = mm % step;\n let next = rem === 0 ? mm + step : mm + (step - rem);\n if (next >= 60) next = 0; // wrap to top of hour\n mm = next;\n } else {\n const rem = mm % step;\n let prev = rem === 0 ? mm - step : mm - rem;\n if (prev < 0) prev = 60 - step; // wrap to last step in hour\n mm = prev;\n }\n }\n } else if (part === \"ampm\") {\n ap = ap === \"AM\" ? \"PM\" : \"AM\";\n }\n\n raw.value = `${String(hh).padStart(2, \"0\")}:${String(mm).padStart(\n 2,\n \"0\",\n )} ${ap}`;\n const date = toDateFromDisplay(raw.value);\n emitParsedDate(date, event);\n\n nextTick(() => {\n requestAnimationFrame(() => {\n const inputEl = document.getElementById(\n args.id,\n ) as HTMLInputElement | null;\n const p = cursorPos.value ?? 0;\n if (inputEl) {\n inputEl.focus();\n inputEl.setSelectionRange(p, p);\n }\n });\n });\n };\n\n // Wheel events can target the MaskedTextBox wrapper, so fall back to the input by id.\n const resolveInput = (event: Event): HTMLInputElement | null =>\n event.target instanceof HTMLInputElement\n ? event.target\n : (document.getElementById(args.id) as HTMLInputElement | null);\n\n // Native disabled/readonly is the source of truth, so plain Kendo inputs get the guard too.\n const isEditable = (el: HTMLInputElement | null): boolean =>\n !el?.disabled && !el?.readOnly;\n\n const handleKeyDown = (event: KeyboardEvent): void => {\n if (!isEditable(resolveInput(event))) return;\n if (event.code === \"Space\" || event.key === \" \") {\n // Open the picker without modifying the input\n // Justified: Space opens the time picker popup instead of inserting a space.\n event.preventDefault();\n // Justified: Parent containers such as grid keyboard handlers should not consume this.\n event.stopPropagation();\n args.onShowPicker(event);\n return;\n }\n\n // Alt+Down opens the picker; allow other Alt+arrow combinations to pass through\n if (event.key === \"ArrowDown\" && event.altKey) {\n // Justified: Alt+Down is reserved for opening the time picker popup.\n event.preventDefault();\n // Justified: Prevent parent keyboard navigation from treating this as row movement.\n event.stopPropagation();\n args.onShowPicker(event);\n return;\n }\n\n if (steppers.includes(event.key)) {\n if (event.altKey) return;\n // Justified: ArrowUp/Down act as time-part steppers instead of native caret/page behavior.\n event.preventDefault();\n // Justified: Prevent parent containers such as the grid from also handling these arrows.\n event.stopPropagation();\n const src = event.target as HTMLInputElement;\n applyStep(event.key as \"ArrowUp\" | \"ArrowDown\", src, event);\n return;\n }\n };\n\n const handleWheel = (event: WheelEvent): void => {\n const input = resolveInput(event);\n // Let the page scroll when the input can't be edited.\n if (!isEditable(input)) return;\n // Map mouse wheel to stepper behavior (up/down) based on caret segment\n // Prevent page scroll when interacting with the input\n event.preventDefault();\n const direction = event.deltaY < 0 ? \"ArrowUp\" : \"ArrowDown\";\n applyStep(direction, input, event);\n };\n\n const handleKeyUp = (event: KeyboardEvent): void => {\n const src = event.target as HTMLInputElement;\n if (cursorKeys.includes(event.key)) {\n // Do not prevent default for caret navigation\n cursorPos.value = src?.selectionStart ?? 0;\n return;\n }\n if (steppers.includes(event.key)) {\n if (event.altKey) return;\n cursorPos.value = src?.selectionStart ?? 0;\n }\n };\n\n const handleBlur = (event: FocusEvent): void => {\n isTouched.value = true;\n\n // If required and value is still undefined/blank, coerce external\n // value from undefined -> \"\" so downstream validation can treat\n // this as an incomplete required field.\n if (\n isRequired.value &&\n args.externalValue &&\n args.externalValue.value === undefined &&\n digitsOnly.value.length === 0\n ) {\n (args.externalValue as Ref<any>).value = \"\";\n }\n\n const src = event.target as HTMLInputElement | null;\n if (src) {\n cursorPos.value = src.selectionStart ?? 0;\n }\n };\n\n // Sync external value into raw when provided\n if (args.externalValue) {\n watch(\n args.externalValue,\n (newVal) => {\n if (newVal) {\n const date = new Date(newVal as any);\n if (date.toString() !== \"Invalid Date\") {\n const h24 = date.getHours();\n const ap = h24 >= 12 ? \"PM\" : \"AM\";\n raw.value = toDisplay(h24, date.getMinutes(), ap);\n return;\n }\n }\n // If external value is null/invalid, keep current raw as-is\n },\n { immediate: true },\n );\n }\n\n const debugLines = computed(() => {\n return [\n [\"Time\", raw.value || \"--:-- --\"],\n [\"Hour (12h)\", hour.value],\n [\"Hour (24h)\", hour24.value],\n [\"Minute\", minute.value],\n [\"Period\", period.value],\n [\"Time (24h)\", time24.value ?? \"--:--:--\"],\n [\"Digits only\", digitsOnly.value],\n [\n \"Parsed Date\",\n parsedRawTime.value?.toLocaleDateString(\"en-US\", {\n hour: \"2-digit\",\n minute: \"2-digit\",\n }) ?? null,\n ],\n [\n \"min\",\n args.min?.toLocaleTimeString(\"en-US\", {\n hour: \"2-digit\",\n minute: \"2-digit\",\n }) ?? null,\n ],\n [\n \"max\",\n args.max?.toLocaleTimeString(\"en-US\", {\n hour: \"2-digit\",\n minute: \"2-digit\",\n }) ?? null,\n ],\n [\"valid\", isValid.value],\n [\"reason\", reason.value],\n [\"validationMessage\", validationMessage.value],\n ];\n });\n\n // Validation based on completeness and parse-ability\n const parsedRawTime = computed<Date | null>(\n () => toDateFromDisplay(raw.value) ?? null,\n );\n const isValid = computed(() => {\n // Optional field preserves forgiving behavior\n if (!isRequired.value) {\n if (!isComplete.value) return true;\n const t = parsedRawTime.value;\n if (!t) return false;\n return inRangeTime(t);\n }\n\n // Required field: do not flag invalid until after blur\n if (!isTouched.value) return true;\n\n const t = parsedRawTime.value;\n if (!isComplete.value) return false;\n if (!t) return false;\n return inRangeTime(t);\n });\n\n const reason = computed<string | undefined>(() => {\n // Optional: only report reasons for completed-but-bad values\n if (!isRequired.value) {\n if (!isComplete.value) return undefined;\n const t = parsedRawTime.value;\n if (!t) return \"invalid-time\";\n if (!inRangeTime(t)) return \"out-of-bounds\";\n return \"valid\";\n }\n\n // Required: only validate after blur\n if (!isTouched.value) return undefined;\n\n if (digitsOnly.value.length === 0 || !isComplete.value) {\n return \"incomplete\";\n }\n\n const t = parsedRawTime.value;\n if (!t) return \"invalid-time\";\n if (!inRangeTime(t)) return \"out-of-bounds\";\n return \"valid\";\n });\n\n const validationMessage = computed(() => {\n const r = reason.value;\n if (!r || r === \"valid\") return \"\";\n\n if (r === \"incomplete\") {\n return \"Required\";\n }\n\n if (r === \"invalid-time\") {\n return `Must be in ${placeholder.value} format.`;\n }\n\n const opts: Intl.DateTimeFormatOptions = {\n hour: \"2-digit\",\n minute: \"2-digit\",\n };\n const minStr = args.min ? args.min.toLocaleTimeString(\"en-US\", opts) : null;\n const maxStr = args.max ? args.max.toLocaleTimeString(\"en-US\", opts) : null;\n if (r === \"out-of-bounds\") {\n if (minStr && maxStr) return `Must be between ${minStr} and ${maxStr}.`;\n if (minStr) return `Must be ${minStr} or later.`;\n if (maxStr) return `Must be ${maxStr} or earlier.`;\n }\n\n return \"\";\n });\n\n const initStyling = () => {\n // Idempotent application of the `fk-timepicker` class to the time picker's parent\n nextTick(() => {\n const inputEl = document.getElementById(args.id) as HTMLElement | null;\n if (!inputEl) {\n console.warn(`#${args.id} not found for styling.`);\n return;\n }\n const timePicker = inputEl.closest(\".k-timepicker\");\n if (!timePicker) {\n console.warn(\n `.k-timepicker parent of #${args.id} not found for styling.`,\n );\n return;\n }\n const parent = timePicker.parentElement;\n if (!parent) {\n console.warn(\n `Parent of .k-timepicker not found for #${args.id} styling.`,\n );\n return;\n }\n if (parent.classList.contains(\"fk-timepicker\")) return;\n parent.classList.add(\"fk-timepicker\");\n });\n };\n\n onMounted(() => {\n initStyling();\n });\n\n return {\n id: args.id,\n min: args.min,\n max: args.max,\n raw,\n rules,\n debugEnabled,\n debugLines,\n placeholder,\n isValid,\n reason: readonly(reason),\n validationMessage,\n isComplete,\n inRangeTime,\n cursorPos,\n hour: readonly(hour),\n hour24: readonly(hour24),\n minute: readonly(minute),\n period: readonly(period),\n time24: readonly(time24),\n parsedRawTime: readonly(parsedRawTime),\n handleChange,\n handleKeyDown,\n handleKeyUp,\n handleClick,\n handleWheel,\n handleBlur,\n // Expose so consumers can reapply theming when Kendo updates DOM\n initStyling,\n };\n}\n\nexport type UseMaskedTimeInputReturn = ReturnType<typeof useMaskedTimeInput>;\n"],"names":["useMaskedTimeInput","args","raw","ref","cursorPos","debugEnabled","placeholder","isRequired","computed","isTouched","steppers","cursorKeys","digitsOnly","rules","partAt","pos","hour","h","v","minute","m","period","hour24","h12","p","time24","isComplete","toDisplay","h24","ap","toDateFromDisplay","display","match","hh","mm","d","emitParsedIfComplete","event","date","inRangeTime","minutesSinceMidnight","min","max","minM","maxM","syncRawFromDate","emitValue","value","focusInputAfterPopupClose","nextTick","inputEl","end","inferPopupAction","target","emitParsedDate","handleChange","eventArgs","action","now","nextValue","src","first","handleClick","applyStep","direction","sourceEl","part","dispMatch","step","rem","next","prev","resolveInput","isEditable","el","handleKeyDown","handleWheel","input","handleKeyUp","handleBlur","watch","newVal","debugLines","parsedRawTime","isValid","reason","validationMessage","t","r","opts","minStr","maxStr","initStyling","timePicker","parent","onMounted","readonly"],"mappings":"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"}