@ehfuse/mui-form-controls 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/SearchTextField.tsx", "../src/hooks/useTextFieldBase.ts", "../src/hooks/useKoreanHolidays.ts", "../src/hooks/useGroupedInput.ts", "../src/utils/koreanIme.ts", "../src/ClearTextField.tsx", "../src/PasswordTextField.tsx", "../src/utils/date.ts", "../src/utils/time.ts", "../src/utils/number.ts", "../src/utils/email.ts", "../src/utils/phone.ts", "../src/utils/password.ts", "../src/utils/biznum.ts", "../src/utils/card.ts", "../src/utils/jumin.ts", "../src/TextField.tsx", "../src/TextArea.tsx", "../src/Checkbox.tsx", "../src/RadioGroup.tsx", "../src/Switch.tsx", "../src/Rating.tsx", "../src/ToggleButton.tsx", "../src/ToggleButtonGroup.tsx", "../src/ButtonGroup.tsx", "../src/DateRange.tsx", "../src/DateTextField.tsx", "../node_modules/@ehfuse/mui-datetime-picker/src/utils/index.ts", "../node_modules/@ehfuse/mui-datetime-picker/src/locale.ts", "../node_modules/@ehfuse/mui-datetime-picker/src/SimpleCalendar.tsx", "../node_modules/@ehfuse/mui-datetime-picker/src/icons/index.tsx", "../node_modules/@ehfuse/mui-datetime-picker/src/TimeSelector.tsx", "../node_modules/@ehfuse/mui-datetime-picker/src/TimePicker.tsx", "../node_modules/@ehfuse/mui-datetime-picker/src/DatePicker.tsx", "../node_modules/@ehfuse/mui-datetime-picker/src/DateTimePicker.tsx", "../src/icons/CalendarIcon.tsx", "../src/icons/ChevronLeft.tsx", "../src/icons/ChevronRight.tsx", "../src/icons/ClockIcon.tsx", "../src/icons/ColonIcon.tsx", "../src/icons/DashIcon.tsx", "../src/icons/CopyIcon.tsx", "../src/icons/card-icons.tsx", "../src/Slider.tsx", "../src/Stepper.tsx", "../src/components/NumberField.tsx", "../src/components/NumberSpinner.tsx", "../src/Autocomplete.tsx", "../src/Select.tsx", "../src/LabelSelect.tsx", "../src/PhoneTextField.tsx", "../src/AddressTextField.tsx", "../src/NumberTextField.tsx", "../src/JuminTextField.tsx", "../src/components/GroupedInputWrapper.tsx", "../src/components/ColonBox.tsx", "../src/VerificationCodeTextField.tsx", "../src/EmailTextField.tsx", "../src/icons/email-icons.tsx", "../src/TimeTextField.tsx", "../src/DateTimeTextField.tsx", "../src/BizNumTextField.tsx", "../src/CardNumTextField.tsx"],
4
- "sourcesContent": ["/**\r\n * SearchTextField.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n forwardRef,\r\n useCallback,\r\n useEffect,\r\n useRef,\r\n useImperativeHandle,\r\n useState,\r\n} from \"react\";\r\nimport {\r\n TextField,\r\n IconButton,\r\n InputAdornment,\r\n CircularProgress,\r\n} from \"@mui/material\";\r\nimport ClearIcon from \"@mui/icons-material/Clear\";\r\nimport SearchIcon from \"@mui/icons-material/Search\";\r\nimport type { SearchTextFieldProps } from \"./types\";\r\nimport { useTextFieldBase } from \"./hooks\";\r\nimport type { BaseTextFieldProps as MuiBaseTextFieldProps } from \"@mui/material/TextField\";\r\nimport {\r\n convertMistypedKoreanImeToEnglish,\r\n shouldAutoConvertKoreanImeQuery,\r\n} from \"./utils/koreanIme\";\r\n\r\nconst SearchTextFieldBase = forwardRef<HTMLDivElement, SearchTextFieldProps>(\r\n function SearchTextFieldBase(\r\n {\r\n value,\r\n form,\r\n loading = false,\r\n searchIcon = true,\r\n searchIconColor = \"#666\",\r\n clearIcon = true,\r\n clearIconColor = \"#666\",\r\n debounce = 300,\r\n readonly,\r\n spellCheck = false,\r\n autoConvertKoreanImeToEnglish = false,\r\n autoConvertKoreanImeDelay = 500,\r\n minLength,\r\n onChange,\r\n onBlur,\r\n onFocus,\r\n onCompositionStart,\r\n onCompositionEnd,\r\n onClear,\r\n onSearch,\r\n slotProps,\r\n size,\r\n inputRef: externalInputRef,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const {\r\n internalValue,\r\n setInternalValue,\r\n handleChange,\r\n handleBlur,\r\n emitChange,\r\n } = useTextFieldBase({\r\n value: (value as string) ?? \"\",\r\n name: props.name,\r\n debounce,\r\n onChange,\r\n onBlur,\r\n });\r\n\r\n const [isFocused, setIsFocused] = useState(false);\r\n const [forceShrink, setForceShrink] = useState(false);\r\n const [internalLoading, setInternalLoading] = useState(false);\r\n const isClearingRef = useRef(false);\r\n const onSearchTimer = useRef<ReturnType<typeof setTimeout> | null>(\r\n null,\r\n );\r\n const autoConvertTimer = useRef<ReturnType<typeof setTimeout> | null>(\r\n null,\r\n );\r\n const lastSearchValueRef = useRef<string | null>(null);\r\n const restoreFocusAfterAutoConvertRef = useRef(false);\r\n const isComposingRef = useRef(false);\r\n const compositionTaskIdRef = useRef(0);\r\n const forcedAutoConvertTaskRef = useRef<number | null>(null);\r\n const suppressBlurRef = useRef(false);\r\n\r\n // input ref for focus after clear\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n\r\n useEffect(() => {\r\n return () => {\r\n if (onSearchTimer.current) {\r\n clearTimeout(onSearchTimer.current);\r\n onSearchTimer.current = null;\r\n }\r\n if (autoConvertTimer.current) {\r\n clearTimeout(autoConvertTimer.current);\r\n autoConvertTimer.current = null;\r\n }\r\n };\r\n }, []);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLInputElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n // size\uC5D0 \uB530\uB978 \uC544\uC774\uCF58 \uD06C\uAE30\r\n const iconSize = size === \"small\" ? 20 : 24;\r\n\r\n const clearAutoConvertTimer = useCallback(() => {\r\n if (autoConvertTimer.current) {\r\n clearTimeout(autoConvertTimer.current);\r\n autoConvertTimer.current = null;\r\n }\r\n }, []);\r\n\r\n const getResolvedInputValue = useCallback(\r\n (fallbackValue = \"\") =>\r\n internalInputRef.current?.value ?? fallbackValue,\r\n [],\r\n );\r\n\r\n const createSyntheticChangeEvent = useCallback(\r\n (nextValue: string) =>\r\n ({\r\n target: {\r\n name: props.name || \"\",\r\n value: nextValue,\r\n },\r\n }) as React.ChangeEvent<HTMLInputElement>,\r\n [props.name],\r\n );\r\n\r\n // \uD074\uB9AC\uC5B4 \uBC84\uD2BC \uD578\uB4E4\uB7EC\r\n const handleClear = () => {\r\n isClearingRef.current = true;\r\n setForceShrink(true);\r\n setIsFocused(true);\r\n setInternalValue(\"\");\r\n clearAutoConvertTimer();\r\n // onSearch \uD0C0\uC774\uBA38 \uCDE8\uC18C\r\n if (onSearchTimer.current) {\r\n clearTimeout(onSearchTimer.current);\r\n onSearchTimer.current = null;\r\n }\r\n setInternalLoading(false);\r\n // \uC989\uC2DC emit\uC744 \uC704\uD574 fake \uC774\uBCA4\uD2B8 \uC0DD\uC131\r\n const fakeEvent = {\r\n target: { name: props.name || \"\", value: \"\" },\r\n } as React.ChangeEvent<HTMLInputElement>;\r\n emitChange(fakeEvent, \"\", true);\r\n if (onSearch && minLength !== undefined) {\r\n lastSearchValueRef.current = \"\";\r\n onSearch(\"\");\r\n }\r\n onClear?.();\r\n // \uD074\uB9AC\uC5B4 \uD6C4 \uD3EC\uCEE4\uC2A4\r\n internalInputRef.current?.focus();\r\n setTimeout(() => {\r\n isClearingRef.current = false;\r\n }, 0);\r\n };\r\n\r\n const triggerSearch = useCallback(\r\n (nextValue: string, immediate = false) => {\r\n if (!onSearch || minLength === undefined) {\r\n return;\r\n }\r\n\r\n if (onSearchTimer.current) {\r\n clearTimeout(onSearchTimer.current);\r\n onSearchTimer.current = null;\r\n }\r\n\r\n const normalizedValue = nextValue;\r\n const shouldReset = normalizedValue.length === 0;\r\n const shouldSearch = normalizedValue.length >= minLength;\r\n\r\n if (!shouldReset && !shouldSearch) {\r\n setInternalLoading(false);\r\n if (lastSearchValueRef.current !== \"\") {\r\n lastSearchValueRef.current = \"\";\r\n onSearch(\"\");\r\n }\r\n return;\r\n }\r\n\r\n const runSearch = () => {\r\n setInternalLoading(false);\r\n if (lastSearchValueRef.current === normalizedValue) {\r\n return;\r\n }\r\n lastSearchValueRef.current = normalizedValue;\r\n onSearch(normalizedValue);\r\n };\r\n\r\n if (immediate || debounce === undefined || debounce === 0) {\r\n runSearch();\r\n return;\r\n }\r\n\r\n setInternalLoading(true);\r\n onSearchTimer.current = setTimeout(() => {\r\n runSearch();\r\n onSearchTimer.current = null;\r\n }, debounce);\r\n },\r\n [debounce, minLength, onSearch],\r\n );\r\n\r\n const applyImmediateValue = useCallback(\r\n (nextValue: string, selectionStart?: number | null) => {\r\n clearAutoConvertTimer();\r\n setInternalValue(nextValue);\r\n emitChange(\r\n createSyntheticChangeEvent(nextValue),\r\n nextValue,\r\n true,\r\n );\r\n\r\n if (onSearch && minLength !== undefined) {\r\n triggerSearch(nextValue, true);\r\n }\r\n\r\n if (selectionStart == null) {\r\n return;\r\n }\r\n\r\n setTimeout(() => {\r\n internalInputRef.current?.focus();\r\n internalInputRef.current?.setSelectionRange(\r\n selectionStart,\r\n selectionStart,\r\n );\r\n }, 0);\r\n },\r\n [\r\n clearAutoConvertTimer,\r\n createSyntheticChangeEvent,\r\n emitChange,\r\n minLength,\r\n onSearch,\r\n triggerSearch,\r\n ],\r\n );\r\n\r\n const commitAutoConvertedValue = useCallback(\r\n (nextValue: string) => {\r\n isComposingRef.current = false;\r\n\r\n setInternalValue(nextValue);\r\n emitChange(\r\n createSyntheticChangeEvent(nextValue),\r\n nextValue,\r\n true,\r\n );\r\n\r\n if (onSearch && minLength !== undefined) {\r\n triggerSearch(nextValue, true);\r\n }\r\n\r\n if (restoreFocusAfterAutoConvertRef.current) {\r\n restoreFocusAfterAutoConvertRef.current = false;\r\n setTimeout(() => {\r\n internalInputRef.current?.focus();\r\n const length =\r\n internalInputRef.current?.value.length ?? 0;\r\n internalInputRef.current?.setSelectionRange(\r\n length,\r\n length,\r\n );\r\n }, 0);\r\n }\r\n },\r\n [\r\n createSyntheticChangeEvent,\r\n emitChange,\r\n minLength,\r\n onSearch,\r\n triggerSearch,\r\n ],\r\n );\r\n\r\n const scheduleAutoConvert = useCallback(\r\n (rawValue: string) => {\r\n clearAutoConvertTimer();\r\n\r\n if (onSearchTimer.current) {\r\n clearTimeout(onSearchTimer.current);\r\n onSearchTimer.current = null;\r\n }\r\n setInternalLoading(false);\r\n\r\n autoConvertTimer.current = setTimeout(() => {\r\n autoConvertTimer.current = null;\r\n\r\n if (isComposingRef.current) {\r\n const input = internalInputRef.current;\r\n const taskId = compositionTaskIdRef.current + 1;\r\n const composingValue = input?.value ?? rawValue;\r\n\r\n forcedAutoConvertTaskRef.current = taskId;\r\n suppressBlurRef.current = true;\r\n input?.blur();\r\n\r\n setTimeout(() => {\r\n if (forcedAutoConvertTaskRef.current !== taskId) {\r\n return;\r\n }\r\n\r\n forcedAutoConvertTaskRef.current = null;\r\n const resolvedValue =\r\n getResolvedInputValue(composingValue);\r\n const converted =\r\n convertMistypedKoreanImeToEnglish(\r\n resolvedValue,\r\n );\r\n\r\n if (converted === resolvedValue) {\r\n commitAutoConvertedValue(resolvedValue);\r\n return;\r\n }\r\n\r\n commitAutoConvertedValue(converted);\r\n }, 0);\r\n return;\r\n }\r\n\r\n const converted =\r\n convertMistypedKoreanImeToEnglish(rawValue);\r\n\r\n if (converted === rawValue) {\r\n commitAutoConvertedValue(rawValue);\r\n return;\r\n }\r\n\r\n commitAutoConvertedValue(converted);\r\n }, autoConvertKoreanImeDelay);\r\n },\r\n [\r\n autoConvertKoreanImeDelay,\r\n clearAutoConvertTimer,\r\n commitAutoConvertedValue,\r\n getResolvedInputValue,\r\n ],\r\n );\r\n\r\n const resolvedLoading = loading || internalLoading;\r\n\r\n const handleManualDelete = useCallback(\r\n (deleteDirection: \"backward\" | \"forward\") => {\r\n if (\r\n readonly ||\r\n !autoConvertKoreanImeToEnglish ||\r\n isComposingRef.current\r\n ) {\r\n return false;\r\n }\r\n\r\n const input = internalInputRef.current;\r\n const currentValue = input?.value ?? internalValue;\r\n\r\n if (!/^[\\x20-\\x7E]*$/.test(currentValue)) {\r\n return false;\r\n }\r\n\r\n const selectionStart =\r\n input?.selectionStart ?? currentValue.length;\r\n const selectionEnd = input?.selectionEnd ?? currentValue.length;\r\n\r\n if (\r\n deleteDirection === \"backward\" &&\r\n selectionStart === 0 &&\r\n selectionEnd === 0\r\n ) {\r\n return true;\r\n }\r\n\r\n if (\r\n deleteDirection === \"forward\" &&\r\n selectionStart === currentValue.length &&\r\n selectionEnd === currentValue.length\r\n ) {\r\n return true;\r\n }\r\n\r\n const hasSelection = selectionStart !== selectionEnd;\r\n const nextValue = hasSelection\r\n ? `${currentValue.slice(0, selectionStart)}${currentValue.slice(selectionEnd)}`\r\n : deleteDirection === \"backward\"\r\n ? `${currentValue.slice(0, Math.max(0, selectionStart - 1))}${currentValue.slice(selectionEnd)}`\r\n : `${currentValue.slice(0, selectionStart)}${currentValue.slice(selectionStart + 1)}`;\r\n const nextSelectionStart = hasSelection\r\n ? selectionStart\r\n : deleteDirection === \"backward\"\r\n ? Math.max(0, selectionStart - 1)\r\n : selectionStart;\r\n applyImmediateValue(nextValue, nextSelectionStart);\r\n return true;\r\n },\r\n [\r\n applyImmediateValue,\r\n autoConvertKoreanImeToEnglish,\r\n internalValue,\r\n readonly,\r\n ],\r\n );\r\n\r\n useEffect(() => {\r\n const input = internalInputRef.current;\r\n if (!input) {\r\n return;\r\n }\r\n\r\n const ownerDocument = input.ownerDocument;\r\n\r\n const handleNativeDelete = (\r\n deleteDirection: \"backward\" | \"forward\",\r\n ) => {\r\n if (ownerDocument.activeElement !== internalInputRef.current) {\r\n return false;\r\n }\r\n\r\n if (handleManualDelete(deleteDirection)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n };\r\n\r\n const handleNativeKeyDownCapture = (event: KeyboardEvent) => {\r\n if (event.defaultPrevented) {\r\n return;\r\n }\r\n\r\n const deleteDirection =\r\n event.key === \"Backspace\"\r\n ? \"backward\"\r\n : event.key === \"Delete\"\r\n ? \"forward\"\r\n : null;\r\n\r\n if (!deleteDirection) {\r\n return;\r\n }\r\n\r\n if (handleNativeDelete(deleteDirection)) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n };\r\n\r\n const handleNativeBeforeInputCapture = (event: InputEvent) => {\r\n if (event.defaultPrevented) {\r\n return;\r\n }\r\n\r\n const deleteDirection =\r\n event.inputType === \"deleteContentBackward\"\r\n ? \"backward\"\r\n : event.inputType === \"deleteContentForward\"\r\n ? \"forward\"\r\n : null;\r\n\r\n if (!deleteDirection) {\r\n return;\r\n }\r\n\r\n if (handleNativeDelete(deleteDirection)) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n };\r\n\r\n ownerDocument.addEventListener(\r\n \"keydown\",\r\n handleNativeKeyDownCapture,\r\n true,\r\n );\r\n ownerDocument.addEventListener(\r\n \"beforeinput\",\r\n handleNativeBeforeInputCapture,\r\n true,\r\n );\r\n\r\n return () => {\r\n ownerDocument.removeEventListener(\r\n \"keydown\",\r\n handleNativeKeyDownCapture,\r\n true,\r\n );\r\n ownerDocument.removeEventListener(\r\n \"beforeinput\",\r\n handleNativeBeforeInputCapture,\r\n true,\r\n );\r\n };\r\n }, [handleManualDelete]);\r\n\r\n const handleKeyDown = useCallback(\r\n (event: React.KeyboardEvent<HTMLInputElement>) => {\r\n props.onKeyDown?.(event);\r\n },\r\n [props],\r\n );\r\n\r\n const handleInputChange = useCallback(\r\n (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const nextValue = e.target.value;\r\n\r\n setInternalValue(nextValue);\r\n\r\n if (isComposingRef.current) {\r\n if (\r\n autoConvertKoreanImeToEnglish &&\r\n shouldAutoConvertKoreanImeQuery(nextValue)\r\n ) {\r\n restoreFocusAfterAutoConvertRef.current =\r\n document.activeElement === internalInputRef.current;\r\n scheduleAutoConvert(nextValue);\r\n } else {\r\n clearAutoConvertTimer();\r\n }\r\n emitChange(e, nextValue, true);\r\n return;\r\n }\r\n\r\n if (\r\n autoConvertKoreanImeToEnglish &&\r\n shouldAutoConvertKoreanImeQuery(nextValue)\r\n ) {\r\n restoreFocusAfterAutoConvertRef.current =\r\n document.activeElement === internalInputRef.current;\r\n scheduleAutoConvert(nextValue);\r\n return;\r\n }\r\n\r\n clearAutoConvertTimer();\r\n emitChange(e, nextValue);\r\n\r\n if (onSearch && minLength !== undefined) {\r\n triggerSearch(nextValue);\r\n }\r\n },\r\n [\r\n autoConvertKoreanImeToEnglish,\r\n autoConvertKoreanImeDelay,\r\n clearAutoConvertTimer,\r\n emitChange,\r\n minLength,\r\n onSearch,\r\n scheduleAutoConvert,\r\n setInternalValue,\r\n triggerSearch,\r\n ],\r\n );\r\n\r\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\r\n setIsFocused(true);\r\n onFocus?.(event);\r\n };\r\n\r\n const handleBlurWithFocus = (\r\n event: React.FocusEvent<HTMLInputElement>,\r\n ) => {\r\n if (suppressBlurRef.current) {\r\n suppressBlurRef.current = false;\r\n setIsFocused(false);\r\n setForceShrink(false);\r\n return;\r\n }\r\n\r\n if (isClearingRef.current) {\r\n isClearingRef.current = false;\r\n handleBlur(event);\r\n return;\r\n }\r\n\r\n if (\r\n autoConvertKoreanImeToEnglish &&\r\n autoConvertTimer.current &&\r\n shouldAutoConvertKoreanImeQuery(internalValue)\r\n ) {\r\n setIsFocused(false);\r\n setForceShrink(false);\r\n onBlur?.(event);\r\n return;\r\n }\r\n\r\n setIsFocused(false);\r\n setForceShrink(false);\r\n handleBlur(event);\r\n };\r\n\r\n const handleCompositionStartInternal = (\r\n event: React.CompositionEvent<HTMLInputElement>,\r\n ) => {\r\n compositionTaskIdRef.current += 1;\r\n isComposingRef.current = true;\r\n clearAutoConvertTimer();\r\n onCompositionStart?.(event);\r\n };\r\n\r\n const handleCompositionEndInternal = (\r\n event: React.CompositionEvent<HTMLInputElement>,\r\n ) => {\r\n compositionTaskIdRef.current += 1;\r\n const compositionTaskId = compositionTaskIdRef.current;\r\n isComposingRef.current = false;\r\n onCompositionEnd?.(event);\r\n\r\n if (forcedAutoConvertTaskRef.current != null) {\r\n return;\r\n }\r\n\r\n const fallbackValue = event.currentTarget.value ?? \"\";\r\n\r\n setTimeout(() => {\r\n if (compositionTaskId !== compositionTaskIdRef.current) {\r\n return;\r\n }\r\n\r\n const nextValue = getResolvedInputValue(fallbackValue);\r\n setInternalValue(nextValue);\r\n\r\n if (\r\n autoConvertKoreanImeToEnglish &&\r\n shouldAutoConvertKoreanImeQuery(nextValue)\r\n ) {\r\n restoreFocusAfterAutoConvertRef.current =\r\n document.activeElement === internalInputRef.current;\r\n scheduleAutoConvert(nextValue);\r\n return;\r\n }\r\n\r\n clearAutoConvertTimer();\r\n emitChange(\r\n createSyntheticChangeEvent(nextValue),\r\n nextValue,\r\n true,\r\n );\r\n\r\n if (onSearch && minLength !== undefined) {\r\n triggerSearch(nextValue, true);\r\n }\r\n }, 0);\r\n };\r\n\r\n // readonly\uC77C \uB54C \uD3EC\uCEE4\uC2A4 \uC2A4\uD0C0\uC77C \uC81C\uAC70\r\n const readonlyStyles = readonly\r\n ? {\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n const shouldShrink = forceShrink || isFocused || internalValue !== \"\";\r\n const hasLabel = Boolean(props.label);\r\n const labelTranslateX = size === \"small\" ? 42 : 46;\r\n const labelTranslateY = size === \"small\" ? 9 : 16;\r\n const labelOffsetSx =\r\n searchIcon && hasLabel\r\n ? {\r\n \"&:not(.MuiInputLabel-shrink)\": {\r\n transform: `translate(${labelTranslateX}px, ${labelTranslateY}px) scale(1)`,\r\n },\r\n }\r\n : undefined;\r\n\r\n const resolveInputLabelSlotProps = (\r\n ownerState: MuiBaseTextFieldProps,\r\n ): Record<string, unknown> => {\r\n const baseInputLabel = slotProps?.inputLabel;\r\n const resolvedInputLabel =\r\n typeof baseInputLabel === \"function\"\r\n ? baseInputLabel(ownerState)\r\n : baseInputLabel;\r\n\r\n const resolvedSx = (resolvedInputLabel as { sx?: unknown })?.sx;\r\n const mergedSx = labelOffsetSx\r\n ? Array.isArray(resolvedSx)\r\n ? [labelOffsetSx, ...resolvedSx]\r\n : resolvedSx\r\n ? [labelOffsetSx, resolvedSx]\r\n : [labelOffsetSx]\r\n : resolvedSx;\r\n\r\n return {\r\n ...resolvedInputLabel,\r\n shrink:\r\n (resolvedInputLabel as { shrink?: boolean })?.shrink ??\r\n shouldShrink,\r\n sx: mergedSx,\r\n };\r\n };\r\n\r\n return (\r\n <TextField\r\n {...props}\r\n ref={ref}\r\n inputRef={internalInputRef}\r\n size={size}\r\n value={internalValue}\r\n onChange={handleInputChange}\r\n onFocus={handleFocus}\r\n onBlur={handleBlurWithFocus}\r\n onKeyDown={handleKeyDown}\r\n onCompositionStart={handleCompositionStartInternal}\r\n onCompositionEnd={handleCompositionEndInternal}\r\n focused={isFocused || isClearingRef.current}\r\n autoComplete=\"off\"\r\n spellCheck={spellCheck}\r\n sx={{\r\n backgroundColor: \"#fff\",\r\n \"& .MuiOutlinedInput-root\": {\r\n backgroundColor: \"#fff\",\r\n },\r\n ...readonlyStyles,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...props.sx,\r\n }}\r\n slotProps={{\r\n ...slotProps,\r\n inputLabel: resolveInputLabelSlotProps,\r\n input: {\r\n ...slotProps?.input,\r\n readOnly: readonly,\r\n notched: shouldShrink,\r\n startAdornment: searchIcon ? (\r\n <InputAdornment\r\n position=\"start\"\r\n sx={{ m: \"0 !important\", mr: \"8px !important\" }}\r\n >\r\n <SearchIcon\r\n sx={{\r\n color: searchIconColor,\r\n fontSize: iconSize,\r\n }}\r\n />\r\n </InputAdornment>\r\n ) : undefined,\r\n endAdornment:\r\n clearIcon && !readonly ? (\r\n <InputAdornment\r\n position=\"end\"\r\n sx={{\r\n visibility: internalValue\r\n ? \"visible\"\r\n : \"hidden\",\r\n mr: 0,\r\n }}\r\n >\r\n {resolvedLoading ? (\r\n <CircularProgress\r\n size={size === \"small\" ? 14 : 16}\r\n />\r\n ) : (\r\n <IconButton\r\n size=\"small\"\r\n onMouseDown={(event) => {\r\n event.preventDefault();\r\n if (!readonly) {\r\n handleClear();\r\n }\r\n }}\r\n edge=\"end\"\r\n tabIndex={-1}\r\n disabled={readonly}\r\n sx={{\r\n padding:\r\n size === \"small\"\r\n ? \"2px\"\r\n : \"4px\",\r\n color: clearIconColor,\r\n \"&:hover\": {\r\n color: \"#333\",\r\n backgroundColor:\r\n \"rgba(0, 0, 0, 0.04)\",\r\n },\r\n }}\r\n >\r\n <ClearIcon\r\n sx={{ fontSize: iconSize - 4 }}\r\n />\r\n </IconButton>\r\n )}\r\n </InputAdornment>\r\n ) : undefined,\r\n },\r\n }}\r\n />\r\n );\r\n },\r\n);\r\n\r\nconst SearchTextFieldWithForm = forwardRef<\r\n HTMLDivElement,\r\n SearchTextFieldProps\r\n>(function SearchTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"SearchTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"SearchTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <SearchTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const SearchTextField = forwardRef<HTMLDivElement, SearchTextFieldProps>(\r\n function SearchTextField(props, ref) {\r\n if (props.form) {\r\n return <SearchTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <SearchTextFieldBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * useTextFieldBase.ts\r\n *\r\n * TextField \uCEF4\uD3EC\uB10C\uD2B8\uB4E4\uC758 \uACF5\uD1B5 \uB85C\uC9C1\uC744 \uB2F4\uB2F9\uD558\uB294 \uD6C5\r\n * - \uB514\uBC14\uC6B4\uC2A4 \uCC98\uB9AC\r\n * - \uB0B4\uBD80 \uC0C1\uD0DC \uAD00\uB9AC\r\n * - blur \uC2DC flush\r\n * - \uC678\uBD80 value \uB3D9\uAE30\uD654\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { useState, useRef, useEffect, useCallback, ChangeEvent } from \"react\";\r\n\r\nexport interface UseTextFieldBaseOptions {\r\n value: string; // \uC678\uBD80\uC5D0\uC11C \uC804\uB2EC\uBC1B\uC740 value\r\n name?: string; // \uD544\uB4DC \uC774\uB984 (name \uC18D\uC131)\r\n debounce?: number; // \uB514\uBC14\uC6B4\uC2A4 \uC9C0\uC5F0 \uC2DC\uAC04 (ms). undefined\uBA74 \uB514\uBC14\uC6B4\uC2A4 \uC5C6\uC74C\r\n onChange?: (e: ChangeEvent<HTMLInputElement>) => void; // \uAC12 \uBCC0\uACBD \uC2DC \uD638\uCD9C\uB418\uB294 \uCF5C\uBC31\r\n onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void; // blur \uC774\uBCA4\uD2B8 \uCF5C\uBC31\r\n // \uB0B4\uBD80 \uAC12\uC744 \uBCC0\uD658\uD558\uB294 \uD568\uC218 (\uC608: \uC804\uD654\uBC88\uD638 \uD3EC\uB9F7\uD305, \uC22B\uC790 \uD3EC\uB9F7\uD305 \uB4F1)\r\n transformValue?: (\r\n inputValue: string,\r\n currentDisplayValue: string,\r\n ) => {\r\n displayValue: string;\r\n emitValue: string;\r\n };\r\n}\r\n\r\nexport interface UseTextFieldBaseReturn {\r\n internalValue: string; // \uD654\uBA74\uC5D0 \uD45C\uC2DC\uD560 \uB0B4\uBD80 \uAC12\r\n setInternalValue: (value: string) => void; // \uB0B4\uBD80 \uAC12\uC744 \uC9C1\uC811 \uC124\uC815\r\n handleChange: (e: ChangeEvent<HTMLInputElement>) => void; // TextField onChange \uD578\uB4E4\uB7EC\r\n handleBlur: (e: React.FocusEvent<HTMLInputElement>) => void; // TextField onBlur \uD578\uB4E4\uB7EC\r\n emitChange: (\r\n // \uD2B9\uC815 \uAC12\uC73C\uB85C \uBCC0\uACBD\uC744 emit (immediate=true\uBA74 \uB514\uBC14\uC6B4\uC2A4 \uBB34\uC2DC)\r\n e: ChangeEvent<HTMLInputElement> | React.FocusEvent<HTMLInputElement>,\r\n newValue: string,\r\n immediate?: boolean,\r\n ) => void;\r\n lastEmittedValue: React.MutableRefObject<string>; // \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uB41C \uAC12\r\n debounceTimer: React.MutableRefObject<ReturnType<typeof setTimeout> | null>; // \uB514\uBC14\uC6B4\uC2A4 \uD0C0\uC774\uBA38 ref\r\n}\r\n\r\nexport function useTextFieldBase({\r\n value,\r\n name = \"\",\r\n debounce,\r\n onChange,\r\n onBlur,\r\n transformValue,\r\n}: UseTextFieldBaseOptions): UseTextFieldBaseReturn {\r\n // \uD654\uBA74\uC5D0 \uD45C\uC2DC\uB418\uB294 \uB0B4\uBD80 \uAC12\r\n const [internalValue, setInternalValue] = useState<string>(value ?? \"\");\r\n\r\n // \uB9C8\uC9C0\uB9C9\uC73C\uB85C onChange\uAC00 \uD638\uCD9C\uB41C \uAC12 (\uC911\uBCF5 \uD638\uCD9C \uBC29\uC9C0)\r\n const lastEmittedValue = useRef<string>(value ?? \"\");\r\n\r\n // \uB514\uBC14\uC6B4\uC2A4 \uD0C0\uC774\uBA38\r\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n // \uC774\uC804 \uC678\uBD80 value (\uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uAC83\uC778\uC9C0 \uAC10\uC9C0)\r\n const prevExternalValue = useRef<string>(value ?? \"\");\r\n\r\n // \uCEF4\uD3EC\uB10C\uD2B8 \uC5B8\uB9C8\uC6B4\uD2B8 \uC2DC \uD0C0\uC774\uBA38 \uC815\uB9AC\r\n useEffect(() => {\r\n return () => {\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n }\r\n };\r\n }, []);\r\n\r\n // \uC678\uBD80 value prop \uBCC0\uACBD \uC2DC \uB0B4\uBD80 \uC0C1\uD0DC \uB3D9\uAE30\uD654\r\n useEffect(() => {\r\n const newValue = value ?? \"\";\r\n // \uC678\uBD80\uC5D0\uC11C \uAC12\uC774 \uBCC0\uACBD\uB418\uC5C8\uACE0, \uADF8 \uAC12\uC774 \uC6B0\uB9AC\uAC00 \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uD55C \uAC12\uACFC \uB2E4\uB974\uBA74 \uB3D9\uAE30\uD654\r\n if (\r\n newValue !== prevExternalValue.current &&\r\n newValue !== lastEmittedValue.current\r\n ) {\r\n setInternalValue(newValue);\r\n lastEmittedValue.current = newValue;\r\n }\r\n prevExternalValue.current = newValue;\r\n }, [value]);\r\n\r\n // onChange\uB97C emit\uD558\uB294 \uD568\uC218\r\n const emitChange = useCallback(\r\n (\r\n e:\r\n | ChangeEvent<HTMLInputElement>\r\n | React.FocusEvent<HTMLInputElement>,\r\n newValue: string,\r\n immediate = false,\r\n ) => {\r\n // \uAC19\uC740 \uAC12\uC774\uBA74 \uD638\uCD9C\uD558\uC9C0 \uC54A\uC74C\r\n if (newValue === lastEmittedValue.current) {\r\n return;\r\n }\r\n\r\n const doEmit = () => {\r\n if (newValue !== lastEmittedValue.current) {\r\n lastEmittedValue.current = newValue;\r\n if (onChange) {\r\n const syntheticEvent = {\r\n ...e,\r\n target: {\r\n ...e.target,\r\n name: name,\r\n value: newValue,\r\n },\r\n } as ChangeEvent<HTMLInputElement>;\r\n onChange(syntheticEvent);\r\n }\r\n }\r\n };\r\n\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n }\r\n\r\n if (immediate || debounce === undefined || debounce === 0) {\r\n doEmit();\r\n } else {\r\n debounceTimer.current = setTimeout(doEmit, debounce);\r\n }\r\n },\r\n [onChange, debounce, name],\r\n );\r\n\r\n // TextField onChange \uD578\uB4E4\uB7EC\r\n const handleChange = useCallback(\r\n (e: ChangeEvent<HTMLInputElement>) => {\r\n const inputValue = e.target.value;\r\n\r\n if (transformValue) {\r\n // \uBCC0\uD658 \uD568\uC218\uAC00 \uC788\uC73C\uBA74 \uC0AC\uC6A9\r\n const { displayValue, emitValue } = transformValue(\r\n inputValue,\r\n internalValue,\r\n );\r\n setInternalValue(displayValue);\r\n emitChange(e, emitValue);\r\n } else {\r\n // \uBCC0\uD658 \uC5C6\uC774 \uADF8\uB300\uB85C \uC0AC\uC6A9\r\n setInternalValue(inputValue);\r\n emitChange(e, inputValue);\r\n }\r\n },\r\n [transformValue, internalValue, emitChange],\r\n );\r\n\r\n // blur \uC2DC \uB300\uAE30 \uC911\uC778 \uB514\uBC14\uC6B4\uC2A4 \uC989\uC2DC \uC2E4\uD589\r\n const handleBlur = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>) => {\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n debounceTimer.current = null;\r\n\r\n // \uD604\uC7AC \uB0B4\uBD80 \uAC12\uC73C\uB85C \uC989\uC2DC emit\r\n if (internalValue !== lastEmittedValue.current) {\r\n lastEmittedValue.current = internalValue;\r\n if (onChange) {\r\n const syntheticEvent = {\r\n ...e,\r\n target: {\r\n ...e.target,\r\n name: name,\r\n value: internalValue,\r\n },\r\n } as ChangeEvent<HTMLInputElement>;\r\n onChange(syntheticEvent);\r\n }\r\n }\r\n }\r\n\r\n // \uC6D0\uB798 onBlur \uD638\uCD9C\r\n if (onBlur) {\r\n onBlur(e);\r\n }\r\n },\r\n [internalValue, onChange, onBlur, name],\r\n );\r\n\r\n return {\r\n internalValue,\r\n setInternalValue,\r\n handleChange,\r\n handleBlur,\r\n emitChange,\r\n lastEmittedValue,\r\n debounceTimer,\r\n };\r\n}\r\n\r\n// \uB514\uBC14\uC6B4\uC2A4\uB41C onChange emit\uB9CC \uB2F4\uB2F9\uD558\uB294 \uAC04\uB2E8\uD55C \uD6C5 (\uBCF5\uC7A1\uD55C \uD3EC\uB9F7\uD305 \uB85C\uC9C1\uC774 \uC788\uB294 \uCEF4\uD3EC\uB10C\uD2B8\uC5D0\uC11C \uC0AC\uC6A9)\r\nexport interface UseDebouncedEmitOptions {\r\n name?: string; // \uD544\uB4DC \uC774\uB984 (name \uC18D\uC131)\r\n debounce?: number; // \uB514\uBC14\uC6B4\uC2A4 \uC9C0\uC5F0 \uC2DC\uAC04 (ms). undefined\uBA74 \uB514\uBC14\uC6B4\uC2A4 \uC5C6\uC74C\r\n onChange?: (e: ChangeEvent<HTMLInputElement>) => void; // \uAC12 \uBCC0\uACBD \uC2DC \uD638\uCD9C\uB418\uB294 \uCF5C\uBC31\r\n}\r\n\r\nexport interface UseDebouncedEmitReturn {\r\n emitChange: (\r\n // \uB514\uBC14\uC6B4\uC2A4\uB41C onChange emit\r\n e:\r\n | ChangeEvent<HTMLInputElement>\r\n | React.FocusEvent<HTMLInputElement>\r\n | null,\r\n newValue: string,\r\n immediate?: boolean,\r\n ) => void;\r\n flushOnBlur: (\r\n // blur \uC2DC \uB300\uAE30 \uC911\uC778 \uB514\uBC14\uC6B4\uC2A4 flush\r\n e: React.FocusEvent<HTMLInputElement>,\r\n currentValue: string,\r\n ) => void;\r\n lastEmittedValue: React.MutableRefObject<string>; // \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uB41C \uAC12\r\n debounceTimer: React.MutableRefObject<ReturnType<typeof setTimeout> | null>; // \uB514\uBC14\uC6B4\uC2A4 \uD0C0\uC774\uBA38 ref\r\n}\r\n\r\nexport function useDebouncedEmit({\r\n name = \"\",\r\n debounce,\r\n onChange,\r\n}: UseDebouncedEmitOptions): UseDebouncedEmitReturn {\r\n // \uB9C8\uC9C0\uB9C9\uC73C\uB85C onChange\uAC00 \uD638\uCD9C\uB41C \uAC12 (\uC911\uBCF5 \uD638\uCD9C \uBC29\uC9C0)\r\n const lastEmittedValue = useRef<string>(\"\");\r\n\r\n // \uB514\uBC14\uC6B4\uC2A4 \uD0C0\uC774\uBA38\r\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n // \uCEF4\uD3EC\uB10C\uD2B8 \uC5B8\uB9C8\uC6B4\uD2B8 \uC2DC \uD0C0\uC774\uBA38 \uC815\uB9AC\r\n useEffect(() => {\r\n return () => {\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n }\r\n };\r\n }, []);\r\n\r\n // onChange\uB97C emit\uD558\uB294 \uD568\uC218\r\n const emitChange = useCallback(\r\n (\r\n e:\r\n | ChangeEvent<HTMLInputElement>\r\n | React.FocusEvent<HTMLInputElement>\r\n | null,\r\n newValue: string,\r\n immediate = false,\r\n ) => {\r\n // \uAC19\uC740 \uAC12\uC774\uBA74 \uD638\uCD9C\uD558\uC9C0 \uC54A\uC74C\r\n if (newValue === lastEmittedValue.current) {\r\n return;\r\n }\r\n\r\n const doEmit = () => {\r\n if (newValue !== lastEmittedValue.current) {\r\n lastEmittedValue.current = newValue;\r\n if (onChange) {\r\n const syntheticEvent = {\r\n ...(e || {}),\r\n target: {\r\n ...(e?.target || {}),\r\n name: name,\r\n value: newValue,\r\n },\r\n } as ChangeEvent<HTMLInputElement>;\r\n onChange(syntheticEvent);\r\n }\r\n }\r\n };\r\n\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n }\r\n\r\n if (immediate || debounce === undefined || debounce === 0) {\r\n doEmit();\r\n } else {\r\n debounceTimer.current = setTimeout(doEmit, debounce);\r\n }\r\n },\r\n [onChange, debounce, name],\r\n );\r\n\r\n // blur \uC2DC \uB300\uAE30 \uC911\uC778 \uB514\uBC14\uC6B4\uC2A4 flush\r\n const flushOnBlur = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>, currentValue: string) => {\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n debounceTimer.current = null;\r\n\r\n if (currentValue !== lastEmittedValue.current) {\r\n lastEmittedValue.current = currentValue;\r\n if (onChange) {\r\n const syntheticEvent = {\r\n ...e,\r\n target: {\r\n ...e.target,\r\n name: name,\r\n value: currentValue,\r\n },\r\n } as ChangeEvent<HTMLInputElement>;\r\n onChange(syntheticEvent);\r\n }\r\n }\r\n }\r\n },\r\n [onChange, name],\r\n );\r\n\r\n return {\r\n emitChange,\r\n flushOnBlur,\r\n lastEmittedValue,\r\n debounceTimer,\r\n };\r\n}\r\n", "/**\r\n * useKoreanHolidays.ts\r\n *\r\n * \uD55C\uAD6D\uCC9C\uBB38\uC5F0\uAD6C\uC6D0 \uD2B9\uC77C \uC815\uBCF4 API\uB97C \uC774\uC6A9\uD558\uC5EC \uACF5\uD734\uC77C\uC744 \uC870\uD68C\uD558\uB294 \uCEE4\uC2A4\uD140 \uD6C5\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { useState, useEffect, useCallback } from \"react\";\r\n\r\n// \uB85C\uCEEC\uC2A4\uD1A0\uB9AC\uC9C0 \uD0A4 prefix\r\nconst STORAGE_KEY_PREFIX = \"korean-holidays-\";\r\n\r\n// API \uC751\uB2F5 \uD0C0\uC785\r\ninterface HolidayItem {\r\n dateKind: string;\r\n dateName: string;\r\n isHoliday: string;\r\n locdate: number;\r\n seq: number;\r\n}\r\n\r\ninterface ApiResponse {\r\n response: {\r\n header: {\r\n resultCode: string;\r\n resultMsg: string;\r\n };\r\n body: {\r\n items: {\r\n item: HolidayItem | HolidayItem[];\r\n };\r\n numOfRows: number;\r\n pageNo: number;\r\n totalCount: number;\r\n };\r\n };\r\n}\r\n\r\n// \uCE90\uC2DC\uB41C \uACF5\uD734\uC77C \uB370\uC774\uD130 \uD0C0\uC785\r\ninterface CachedHolidays {\r\n year: number;\r\n holidays: string[]; // YYYYMMDD \uD615\uC2DD\r\n fetchedAt: number; // timestamp\r\n}\r\n\r\n/**\r\n * \uD55C\uAD6D \uACF5\uD734\uC77C\uC744 \uC870\uD68C\uD558\uB294 \uCEE4\uC2A4\uD140 \uD6C5\r\n *\r\n * @param apiKey - \uACF5\uACF5\uB370\uC774\uD130\uD3EC\uD138 API \uC778\uC99D\uD0A4 (Encoding)\r\n * @param year - \uC870\uD68C\uD560 \uC5F0\uB3C4 (\uAE30\uBCF8\uAC12: \uD604\uC7AC \uC5F0\uB3C4)\r\n * @returns { holidays: Date[], loading: boolean, error: string | null }\r\n */\r\nexport function useKoreanHolidays(apiKey?: string, year?: number) {\r\n const targetYear = year ?? new Date().getFullYear();\r\n const [holidays, setHolidays] = useState<Date[]>([]);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n // \uB85C\uCEEC\uC2A4\uD1A0\uB9AC\uC9C0\uC5D0\uC11C \uCE90\uC2DC\uB41C \uB370\uC774\uD130 \uAC00\uC838\uC624\uAE30\r\n const getCachedHolidays = useCallback((year: number): Date[] | null => {\r\n try {\r\n const cached = localStorage.getItem(`${STORAGE_KEY_PREFIX}${year}`);\r\n if (!cached) return null;\r\n\r\n const data: CachedHolidays = JSON.parse(cached);\r\n\r\n // 1\uB144 \uC774\uC0C1 \uB41C \uCE90\uC2DC\uB294 \uBB34\uD6A8\uD654 (\uB2E4\uC74C \uD574\uC5D0 \uB2E4\uC2DC \uC870\uD68C)\r\n const oneYearMs = 365 * 24 * 60 * 60 * 1000;\r\n if (Date.now() - data.fetchedAt > oneYearMs) {\r\n localStorage.removeItem(`${STORAGE_KEY_PREFIX}${year}`);\r\n return null;\r\n }\r\n\r\n // YYYYMMDD \uBB38\uC790\uC5F4\uC744 Date \uAC1D\uCCB4\uB85C \uBCC0\uD658\r\n return data.holidays.map((dateStr) => {\r\n const y = parseInt(dateStr.slice(0, 4), 10);\r\n const m = parseInt(dateStr.slice(4, 6), 10) - 1;\r\n const d = parseInt(dateStr.slice(6, 8), 10);\r\n return new Date(y, m, d);\r\n });\r\n } catch {\r\n return null;\r\n }\r\n }, []);\r\n\r\n // \uB85C\uCEEC\uC2A4\uD1A0\uB9AC\uC9C0\uC5D0 \uCE90\uC2DC \uC800\uC7A5\r\n const setCachedHolidays = useCallback(\r\n (year: number, holidays: string[]) => {\r\n try {\r\n const data: CachedHolidays = {\r\n year,\r\n holidays,\r\n fetchedAt: Date.now(),\r\n };\r\n localStorage.setItem(\r\n `${STORAGE_KEY_PREFIX}${year}`,\r\n JSON.stringify(data)\r\n );\r\n } catch {\r\n // \uB85C\uCEEC\uC2A4\uD1A0\uB9AC\uC9C0 \uC6A9\uB7C9 \uCD08\uACFC \uB4F1\uC758 \uC5D0\uB7EC \uBB34\uC2DC\r\n }\r\n },\r\n []\r\n );\r\n\r\n // API\uC5D0\uC11C \uACF5\uD734\uC77C \uC870\uD68C\r\n const fetchHolidays = useCallback(\r\n async (year: number): Promise<Date[]> => {\r\n if (!apiKey) {\r\n throw new Error(\"API \uD0A4\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.\");\r\n }\r\n\r\n const baseUrl =\r\n \"https://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/getRestDeInfo\";\r\n const params = new URLSearchParams({\r\n serviceKey: apiKey,\r\n solYear: String(year),\r\n numOfRows: \"100\",\r\n _type: \"json\",\r\n });\r\n\r\n const response = await fetch(`${baseUrl}?${params.toString()}`);\r\n\r\n if (!response.ok) {\r\n throw new Error(`API \uC694\uCCAD \uC2E4\uD328: ${response.status}`);\r\n }\r\n\r\n const data: ApiResponse = await response.json();\r\n\r\n if (data.response.header.resultCode !== \"00\") {\r\n throw new Error(`API \uC5D0\uB7EC: ${data.response.header.resultMsg}`);\r\n }\r\n\r\n const items = data.response.body.items?.item;\r\n if (!items) {\r\n return [];\r\n }\r\n\r\n // \uB2E8\uC77C \uD56D\uBAA9\uC77C \uACBD\uC6B0 \uBC30\uC5F4\uB85C \uBCC0\uD658\r\n const itemArray = Array.isArray(items) ? items : [items];\r\n\r\n // isHoliday\uAC00 \"Y\"\uC778 \uD56D\uBAA9\uB9CC \uD544\uD130\uB9C1\r\n const holidayDates = itemArray\r\n .filter((item) => item.isHoliday === \"Y\")\r\n .map((item) => {\r\n const dateStr = String(item.locdate);\r\n const y = parseInt(dateStr.slice(0, 4), 10);\r\n const m = parseInt(dateStr.slice(4, 6), 10) - 1;\r\n const d = parseInt(dateStr.slice(6, 8), 10);\r\n return new Date(y, m, d);\r\n });\r\n\r\n // \uCE90\uC2DC\uC5D0 \uC800\uC7A5 (YYYYMMDD \uD615\uC2DD\uC73C\uB85C)\r\n const holidayStrings = itemArray\r\n .filter((item) => item.isHoliday === \"Y\")\r\n .map((item) => String(item.locdate));\r\n setCachedHolidays(year, holidayStrings);\r\n\r\n return holidayDates;\r\n },\r\n [apiKey, setCachedHolidays]\r\n );\r\n\r\n useEffect(() => {\r\n if (!apiKey) {\r\n setHolidays([]);\r\n return;\r\n }\r\n\r\n // \uCE90\uC2DC\uB41C \uB370\uC774\uD130 \uD655\uC778\r\n const cached = getCachedHolidays(targetYear);\r\n if (cached) {\r\n setHolidays(cached);\r\n return;\r\n }\r\n\r\n // API \uD638\uCD9C\r\n setLoading(true);\r\n setError(null);\r\n\r\n fetchHolidays(targetYear)\r\n .then((dates) => {\r\n setHolidays(dates);\r\n })\r\n .catch((err) => {\r\n setError(err.message);\r\n setHolidays([]);\r\n })\r\n .finally(() => {\r\n setLoading(false);\r\n });\r\n }, [apiKey, targetYear, getCachedHolidays, fetchHolidays]);\r\n\r\n return { holidays, loading, error };\r\n}\r\n\r\n/**\r\n * \uC5EC\uB7EC \uC5F0\uB3C4\uC758 \uACF5\uD734\uC77C\uC744 \uD55C\uBC88\uC5D0 \uC870\uD68C\uD558\uB294 \uD6C5\r\n */\r\nexport function useKoreanHolidaysRange(\r\n apiKey?: string,\r\n startYear?: number,\r\n endYear?: number\r\n) {\r\n const currentYear = new Date().getFullYear();\r\n const start = startYear ?? currentYear;\r\n const end = endYear ?? currentYear;\r\n\r\n const [holidays, setHolidays] = useState<Date[]>([]);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n useEffect(() => {\r\n if (!apiKey) {\r\n setHolidays([]);\r\n return;\r\n }\r\n\r\n const years: number[] = [];\r\n for (let y = start; y <= end; y++) {\r\n years.push(y);\r\n }\r\n\r\n setLoading(true);\r\n setError(null);\r\n\r\n // \uAC01 \uC5F0\uB3C4\uBCC4\uB85C \uCE90\uC2DC \uD655\uC778 \uB610\uB294 API \uD638\uCD9C\r\n Promise.all(\r\n years.map(async (year) => {\r\n const storageKey = `${STORAGE_KEY_PREFIX}${year}`;\r\n const cached = localStorage.getItem(storageKey);\r\n\r\n if (cached) {\r\n try {\r\n const data: CachedHolidays = JSON.parse(cached);\r\n return data.holidays.map((dateStr) => {\r\n const y = parseInt(dateStr.slice(0, 4), 10);\r\n const m = parseInt(dateStr.slice(4, 6), 10) - 1;\r\n const d = parseInt(dateStr.slice(6, 8), 10);\r\n return new Date(y, m, d);\r\n });\r\n } catch {\r\n // \uD30C\uC2F1 \uC2E4\uD328 \uC2DC API \uD638\uCD9C\r\n }\r\n }\r\n\r\n // API \uD638\uCD9C\r\n const baseUrl =\r\n \"https://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/getRestDeInfo\";\r\n const params = new URLSearchParams({\r\n serviceKey: apiKey,\r\n solYear: String(year),\r\n numOfRows: \"100\",\r\n _type: \"json\",\r\n });\r\n\r\n const response = await fetch(`${baseUrl}?${params.toString()}`);\r\n if (!response.ok) {\r\n throw new Error(`API \uC694\uCCAD \uC2E4\uD328: ${response.status}`);\r\n }\r\n\r\n const data: ApiResponse = await response.json();\r\n if (data.response.header.resultCode !== \"00\") {\r\n throw new Error(data.response.header.resultMsg);\r\n }\r\n\r\n const items = data.response.body.items?.item;\r\n if (!items) return [];\r\n\r\n const itemArray = Array.isArray(items) ? items : [items];\r\n const holidayStrings = itemArray\r\n .filter((item) => item.isHoliday === \"Y\")\r\n .map((item) => String(item.locdate));\r\n\r\n // \uCE90\uC2DC \uC800\uC7A5\r\n const cacheData: CachedHolidays = {\r\n year,\r\n holidays: holidayStrings,\r\n fetchedAt: Date.now(),\r\n };\r\n localStorage.setItem(storageKey, JSON.stringify(cacheData));\r\n\r\n return holidayStrings.map((dateStr) => {\r\n const y = parseInt(dateStr.slice(0, 4), 10);\r\n const m = parseInt(dateStr.slice(4, 6), 10) - 1;\r\n const d = parseInt(dateStr.slice(6, 8), 10);\r\n return new Date(y, m, d);\r\n });\r\n })\r\n )\r\n .then((results) => {\r\n const allHolidays = results.flat();\r\n setHolidays(allHolidays);\r\n })\r\n .catch((err) => {\r\n setError(err.message);\r\n setHolidays([]);\r\n })\r\n .finally(() => {\r\n setLoading(false);\r\n });\r\n }, [apiKey, start, end]);\r\n\r\n return { holidays, loading, error };\r\n}\r\n", "/**\r\n * useGroupedInput.ts\r\n *\r\n * \uADF8\uB8F9\uD654\uB41C \uC785\uB825 \uD544\uB4DC(\uC8FC\uBBFC\uBC88\uD638, \uC0AC\uC5C5\uC790\uBC88\uD638, \uC2DC\uAC04 \uB4F1)\uC5D0\uC11C \uACF5\uD1B5\uC73C\uB85C \uC0AC\uC6A9\uD558\uB294\r\n * \uCEE4\uC11C \uAD00\uB9AC, \uD3EC\uCEE4\uC2A4 \uAD00\uB9AC, \uD0A4\uBCF4\uB4DC \uD578\uB4E4\uB9C1 \uB85C\uC9C1\uC744 \uC81C\uACF5\uD558\uB294 \uD6C5\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { useRef, useState, useCallback, useMemo, RefObject } from \"react\";\r\n\r\nexport interface GroupConfig {\r\n maxLength: number;\r\n ref: RefObject<HTMLInputElement | null>;\r\n value: string;\r\n setValue: (value: string) => void;\r\n}\r\n\r\nexport interface UseGroupedInputOptions {\r\n groups: GroupConfig[];\r\n fontFamily?: string;\r\n fontSize: number;\r\n onComplete?: () => void;\r\n disabled?: boolean;\r\n readonly?: boolean;\r\n}\r\n\r\nexport interface UseGroupedInputReturn {\r\n focusedGroup: number | null;\r\n setFocusedGroup: (group: number | null) => void;\r\n cursorVisible: boolean;\r\n setCursorVisible: (visible: boolean) => void;\r\n cursorPosRef: RefObject<number>;\r\n isClickFocusRef: RefObject<boolean>;\r\n inputComplete: boolean;\r\n setInputComplete: (complete: boolean) => void;\r\n renderTrigger: number;\r\n measureTextWidth: (text: string) => number;\r\n getCursorLeft: (groupIndex: number) => number;\r\n createMouseDownHandler: (\r\n groupIndex: number\r\n ) => (e: React.MouseEvent) => void;\r\n createClickHandler: (groupIndex: number) => (e: React.MouseEvent) => void;\r\n createContainerClickHandler: () => (e: React.MouseEvent) => void;\r\n createFocusHandler: (groupIndex: number) => () => void;\r\n createBlurHandler: () => () => void;\r\n createKeyDownHandler: (\r\n groupIndex: number,\r\n onValueChange?: (newValue: string, groupIndex: number) => void\r\n ) => (e: React.KeyboardEvent<HTMLInputElement>) => void;\r\n createChangeHandler: (\r\n groupIndex: number,\r\n onAfterChange?: (\r\n newValue: string,\r\n groupIndex: number,\r\n isComplete: boolean\r\n ) => void\r\n ) => (e: React.ChangeEvent<HTMLInputElement>) => void;\r\n getCursorPosFromClick: (\r\n e: React.MouseEvent,\r\n value: string,\r\n inputRef: RefObject<HTMLInputElement | null>\r\n ) => number;\r\n forceRender: () => void;\r\n}\r\n\r\nexport function useGroupedInput({\r\n groups,\r\n fontFamily,\r\n fontSize,\r\n onComplete,\r\n disabled = false,\r\n readonly = false,\r\n}: UseGroupedInputOptions): UseGroupedInputReturn {\r\n const [focusedGroup, setFocusedGroup] = useState<number | null>(null);\r\n const [cursorVisible, setCursorVisible] = useState(false);\r\n const [inputComplete, setInputComplete] = useState(false);\r\n const [renderTrigger, setRenderTrigger] = useState(0);\r\n\r\n const cursorPosRef = useRef(0);\r\n const isClickFocusRef = useRef(false);\r\n const isArrowFocusRef = useRef(false);\r\n const arrowTargetPosRef = useRef(0);\r\n\r\n // \uD14D\uC2A4\uD2B8 \uB108\uBE44 \uCE21\uC815\r\n const measureTextWidth = useCallback(\r\n (text: string): number => {\r\n if (typeof document === \"undefined\")\r\n return text.length * fontSize * 0.6;\r\n const canvas = document.createElement(\"canvas\");\r\n const ctx = canvas.getContext(\"2d\");\r\n if (!ctx) return text.length * fontSize * 0.6;\r\n ctx.font = `${fontSize}px ${fontFamily || \"Roboto, sans-serif\"}`;\r\n return ctx.measureText(text).width;\r\n },\r\n [fontSize, fontFamily]\r\n );\r\n\r\n // \uD074\uB9AD \uC704\uCE58\uC5D0\uC11C \uCEE4\uC11C \uC704\uCE58 \uACC4\uC0B0\r\n const getCursorPosFromClick = useCallback(\r\n (\r\n e: React.MouseEvent,\r\n value: string,\r\n inputRef: RefObject<HTMLInputElement | null>\r\n ): number => {\r\n const input = inputRef.current;\r\n if (!input) return value.length;\r\n\r\n const rect = input.getBoundingClientRect();\r\n const clickX = e.clientX - rect.left - 4; // padding \uBCF4\uC815\r\n\r\n let newPos = value.length;\r\n for (let i = 0; i <= value.length; i++) {\r\n const textWidth = measureTextWidth(value.slice(0, i));\r\n if (clickX < textWidth + measureTextWidth(\"0\") / 2) {\r\n newPos = i;\r\n break;\r\n }\r\n }\r\n return newPos;\r\n },\r\n [measureTextWidth]\r\n );\r\n\r\n // \uCEE4\uC11C \uC704\uCE58 \uACC4\uC0B0 (\uB80C\uB354\uB9C1\uC6A9)\r\n const getCursorLeft = useCallback(\r\n (groupIndex: number): number => {\r\n if (focusedGroup !== groupIndex) return 0;\r\n const group = groups[groupIndex];\r\n if (!group) return 0;\r\n const textBeforeCursor = group.value.slice(0, cursorPosRef.current);\r\n return measureTextWidth(textBeforeCursor);\r\n },\r\n [focusedGroup, groups, measureTextWidth]\r\n );\r\n\r\n // \uAC15\uC81C \uB9AC\uB80C\uB354\uB9C1\r\n const forceRender = useCallback(() => {\r\n setRenderTrigger((prev) => prev + 1);\r\n }, []);\r\n\r\n // MouseDown \uD578\uB4E4\uB7EC \uC0DD\uC131\r\n const createMouseDownHandler = useCallback(\r\n (groupIndex: number) => {\r\n return (e: React.MouseEvent) => {\r\n if (disabled || readonly) return;\r\n isClickFocusRef.current = true;\r\n const group = groups[groupIndex];\r\n const newPos = getCursorPosFromClick(e, group.value, group.ref);\r\n cursorPosRef.current = newPos;\r\n };\r\n },\r\n [disabled, readonly, groups, getCursorPosFromClick]\r\n );\r\n\r\n // Click \uD578\uB4E4\uB7EC \uC0DD\uC131 - \uD074\uB9AD \uC2DC \uC804\uCCB4 \uC120\uD0DD\r\n const createClickHandler = useCallback(\r\n (groupIndex: number) => {\r\n return (e: React.MouseEvent) => {\r\n if (disabled || readonly) return;\r\n e.stopPropagation();\r\n\r\n const group = groups[groupIndex];\r\n const input = group.ref.current;\r\n\r\n // \uAC12\uC774 \uC788\uC73C\uBA74 \uC804\uCCB4 \uC120\uD0DD\r\n if (input && group.value.length > 0) {\r\n setTimeout(() => {\r\n input.setSelectionRange(0, group.value.length);\r\n }, 0);\r\n setCursorVisible(false); // \uC804\uCCB4 \uC120\uD0DD \uC2DC \uCEE4\uC11C \uC228\uAE40\r\n } else {\r\n // \uAC12\uC774 \uC5C6\uC73C\uBA74 \uCEE4\uC11C \uD45C\uC2DC\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n\r\n setInputComplete(false);\r\n setFocusedGroup(groupIndex);\r\n setRenderTrigger((prev) => prev + 1);\r\n };\r\n },\r\n [disabled, readonly, groups]\r\n );\r\n\r\n // \uCEE8\uD14C\uC774\uB108 \uD074\uB9AD \uD578\uB4E4\uB7EC \uC0DD\uC131 - \uC678\uACFD \uD074\uB9AD \uC2DC \uCCAB \uBC88\uC9F8 \uBE48 \uCE78 \uB610\uB294 \uB9C8\uC9C0\uB9C9 \uCE78\uC73C\uB85C \uC774\uB3D9\r\n const createContainerClickHandler = useCallback(() => {\r\n return (e: React.MouseEvent) => {\r\n if (disabled || readonly) return;\r\n\r\n // \uC774\uBBF8 input\uC5D0\uC11C \uCC98\uB9AC\uB41C \uD074\uB9AD\uC774\uBA74 \uBB34\uC2DC\r\n const target = e.target as HTMLElement;\r\n if (target.tagName === \"INPUT\") return;\r\n\r\n // \uCCAB \uBC88\uC9F8 \uBE48 \uCE78 \uCC3E\uAE30\r\n let targetIndex = -1;\r\n for (let i = 0; i < groups.length; i++) {\r\n if (groups[i].value.length === 0) {\r\n targetIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n // \uBE48 \uCE78\uC774 \uC5C6\uC73C\uBA74 \uB9C8\uC9C0\uB9C9 \uCE78 \uC120\uD0DD\r\n if (targetIndex === -1) {\r\n targetIndex = groups.length - 1;\r\n }\r\n\r\n const targetGroup = groups[targetIndex];\r\n const input = targetGroup.ref.current;\r\n\r\n if (targetGroup.value.length > 0) {\r\n // \uAC12\uC774 \uC788\uC73C\uBA74 \uC804\uCCB4 \uC120\uD0DD\r\n input?.focus();\r\n setTimeout(() => {\r\n input?.setSelectionRange(0, targetGroup.value.length);\r\n }, 0);\r\n setCursorVisible(false);\r\n } else {\r\n // \uAC12\uC774 \uC5C6\uC73C\uBA74 \uCEE4\uC11C \uD45C\uC2DC\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n input?.focus();\r\n }\r\n\r\n setFocusedGroup(targetIndex);\r\n setInputComplete(false);\r\n setRenderTrigger((prev) => prev + 1);\r\n };\r\n }, [disabled, readonly, groups]);\r\n\r\n // Focus \uD578\uB4E4\uB7EC \uC0DD\uC131\r\n const createFocusHandler = useCallback(\r\n (groupIndex: number) => {\r\n return () => {\r\n const group = groups[groupIndex];\r\n\r\n // \uD074\uB9AD\uC73C\uB85C \uC778\uD55C \uD3EC\uCEE4\uC2A4\uBA74 \uD074\uB9AD \uD578\uB4E4\uB7EC\uC5D0\uC11C \uCC98\uB9AC \uC644\uB8CC\uB428\r\n if (isClickFocusRef.current) {\r\n isClickFocusRef.current = false;\r\n // \uD074\uB9AD \uD578\uB4E4\uB7EC\uC5D0\uC11C \uC804\uCCB4 \uC120\uD0DD \uCC98\uB9AC\uD588\uC73C\uBBC0\uB85C \uC5EC\uAE30\uC11C\uB294 \uC0C1\uD0DC\uB9CC \uC124\uC815\r\n setFocusedGroup(groupIndex);\r\n return;\r\n }\r\n\r\n // \uBC29\uD5A5\uD0A4\uB85C \uC778\uD55C \uD3EC\uCEE4\uC2A4\uBA74 \uC9C0\uC815\uB41C \uC704\uCE58\uB85C\r\n if (isArrowFocusRef.current) {\r\n isArrowFocusRef.current = false;\r\n cursorPosRef.current = arrowTargetPosRef.current;\r\n setCursorVisible(true);\r\n setFocusedGroup(groupIndex);\r\n setRenderTrigger((prev) => prev + 1);\r\n return;\r\n }\r\n\r\n // \uC77C\uBC18 \uD3EC\uCEE4\uC2A4 (\uD0ED \uB4F1) - \uC804\uCCB4 \uC120\uD0DD\r\n const input = group.ref.current;\r\n if (input && group.value.length > 0) {\r\n setTimeout(() => {\r\n input.setSelectionRange(0, group.value.length);\r\n }, 0);\r\n setCursorVisible(false);\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n setFocusedGroup(groupIndex);\r\n };\r\n },\r\n [groups]\r\n );\r\n\r\n // Blur \uD578\uB4E4\uB7EC \uC0DD\uC131\r\n const createBlurHandler = useCallback(() => {\r\n return () => {\r\n setTimeout(() => {\r\n const activeElement = document.activeElement;\r\n const isStillFocused = groups.some(\r\n (group) => group.ref.current === activeElement\r\n );\r\n if (!isStillFocused) {\r\n setCursorVisible(false);\r\n setFocusedGroup(null);\r\n }\r\n }, 0);\r\n };\r\n }, [groups]);\r\n\r\n // KeyDown \uD578\uB4E4\uB7EC \uC0DD\uC131\r\n const createKeyDownHandler = useCallback(\r\n (\r\n groupIndex: number,\r\n onValueChange?: (newValue: string, groupIndex: number) => void\r\n ) => {\r\n return (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n const group = groups[groupIndex];\r\n const input = group.ref.current;\r\n const selectionStart = input?.selectionStart ?? 0;\r\n const selectionEnd = input?.selectionEnd ?? 0;\r\n const hasSelection = selectionEnd > selectionStart;\r\n\r\n if (e.key === \"ArrowLeft\") {\r\n // 3-2. \uD604\uC7AC\uCE78 \uCCAB\uBC88\uC9F8\uC5D0\uC11C \uC67C\uCABD\uD0A4 \u2192 \uC774\uC804\uCE78 \uB9C8\uC9C0\uB9C9 \uBB38\uC790\uB85C\r\n if (selectionStart === 0 && groupIndex > 0) {\r\n e.preventDefault();\r\n const prevGroup = groups[groupIndex - 1];\r\n // \uB9C8\uC9C0\uB9C9 \uBB38\uC790 \uC704\uCE58 (length - 1), \uBE48 \uACBD\uC6B0 0\r\n const newPos =\r\n prevGroup.value.length > 0\r\n ? prevGroup.value.length - 1\r\n : 0;\r\n isArrowFocusRef.current = true;\r\n arrowTargetPosRef.current = newPos;\r\n prevGroup.ref.current?.focus();\r\n prevGroup.ref.current?.setSelectionRange(\r\n newPos,\r\n newPos\r\n );\r\n } else if (selectionStart > 0) {\r\n e.preventDefault();\r\n const newPos = selectionStart - 1;\r\n input?.setSelectionRange(newPos, newPos);\r\n cursorPosRef.current = newPos;\r\n setCursorVisible(true);\r\n setRenderTrigger((prev) => prev + 1);\r\n }\r\n } else if (e.key === \"ArrowRight\") {\r\n // 3-1. \uD604\uC7AC\uCE78 \uB9C8\uC9C0\uB9C9 \uBB38\uC790\uC5D0\uC11C \uC624\uB978\uCABD\uD0A4 \u2192 \uB2E4\uC74C\uCE78 \uCCAB\uBC88\uC9F8\uB85C\r\n if (\r\n selectionEnd >= group.value.length - 1 &&\r\n group.value.length > 0 &&\r\n groupIndex < groups.length - 1\r\n ) {\r\n e.preventDefault();\r\n const nextGroup = groups[groupIndex + 1];\r\n isArrowFocusRef.current = true;\r\n arrowTargetPosRef.current = 0;\r\n nextGroup.ref.current?.focus();\r\n nextGroup.ref.current?.setSelectionRange(0, 0);\r\n } else if (selectionEnd < group.value.length - 1) {\r\n // \uB9C8\uC9C0\uB9C9 \uBB38\uC790 \uC804\uAE4C\uC9C0\uB9CC \uC624\uB978\uCABD \uC774\uB3D9\r\n e.preventDefault();\r\n const newPos = selectionEnd + 1;\r\n input?.setSelectionRange(newPos, newPos);\r\n cursorPosRef.current = newPos;\r\n setCursorVisible(true);\r\n setRenderTrigger((prev) => prev + 1);\r\n }\r\n } else if (e.key === \"Backspace\") {\r\n // \uC804\uCCB4 \uC120\uD0DD \uC0C1\uD0DC\uC5D0\uC11C\uB294 \uC804\uCCB4 \uC0AD\uC81C\r\n if (hasSelection) {\r\n e.preventDefault();\r\n const newValue =\r\n group.value.slice(0, selectionStart) +\r\n group.value.slice(selectionEnd);\r\n group.setValue(newValue);\r\n cursorPosRef.current = selectionStart;\r\n setCursorVisible(true);\r\n setInputComplete(false);\r\n setRenderTrigger((prev) => prev + 1);\r\n setTimeout(() => {\r\n input?.setSelectionRange(\r\n selectionStart,\r\n selectionStart\r\n );\r\n }, 0);\r\n onValueChange?.(newValue, groupIndex);\r\n } else if (selectionStart > 0) {\r\n // 1-3. \uD604\uC7AC\uCEE4\uC11C \uC55E\uC790\uB9AC \uC0AD\uC81C\r\n e.preventDefault();\r\n const newValue =\r\n group.value.slice(0, selectionStart - 1) +\r\n group.value.slice(selectionStart);\r\n group.setValue(newValue);\r\n const newPos = selectionStart - 1;\r\n cursorPosRef.current = newPos;\r\n setCursorVisible(true);\r\n setInputComplete(false);\r\n setRenderTrigger((prev) => prev + 1);\r\n setTimeout(() => {\r\n input?.setSelectionRange(newPos, newPos);\r\n }, 0);\r\n onValueChange?.(newValue, groupIndex);\r\n } else if (groupIndex > 0) {\r\n // 1-4. \uD604\uC7AC\uCE78 \uC81C\uC77C \uC55E\uC5D0\uC11C \u2192 \uC774\uC804\uCE78 \uB9C8\uC9C0\uB9C9 \uC790\uB9AC\uAC12 \uC0AD\uC81C \uB610\uB294 \uCEE4\uC11C \uC774\uB3D9\r\n e.preventDefault();\r\n const prevGroup = groups[groupIndex - 1];\r\n const prevLen = prevGroup.value.length;\r\n\r\n if (prevLen > 0) {\r\n // \uC774\uC804 \uCE78\uC5D0 \uAC12\uC774 \uC788\uC73C\uBA74 \uB9C8\uC9C0\uB9C9 \uAC12 \uC0AD\uC81C\r\n const newPrevValue = prevGroup.value.slice(0, -1);\r\n prevGroup.setValue(newPrevValue);\r\n cursorPosRef.current = newPrevValue.length;\r\n setInputComplete(false);\r\n onValueChange?.(newPrevValue, groupIndex - 1);\r\n } else {\r\n // \uC774\uC804 \uCE78\uC774 \uBE44\uC5B4\uC788\uC73C\uBA74 \uCEE4\uC11C\uB9CC \uC774\uB3D9\r\n cursorPosRef.current = 0;\r\n }\r\n\r\n setCursorVisible(true);\r\n setFocusedGroup(groupIndex - 1);\r\n setRenderTrigger((prev) => prev + 1);\r\n prevGroup.ref.current?.focus();\r\n const finalPos = prevLen > 0 ? prevLen - 1 : 0;\r\n prevGroup.ref.current?.setSelectionRange(\r\n finalPos,\r\n finalPos\r\n );\r\n }\r\n } else if (e.key === \"Delete\") {\r\n // \uC804\uCCB4 \uC120\uD0DD \uC0C1\uD0DC\uC5D0\uC11C\uB294 \uC804\uCCB4 \uC0AD\uC81C\r\n if (hasSelection) {\r\n e.preventDefault();\r\n const newValue =\r\n group.value.slice(0, selectionStart) +\r\n group.value.slice(selectionEnd);\r\n group.setValue(newValue);\r\n cursorPosRef.current = selectionStart;\r\n setCursorVisible(true);\r\n setInputComplete(false);\r\n setRenderTrigger((prev) => prev + 1);\r\n setTimeout(() => {\r\n input?.setSelectionRange(\r\n selectionStart,\r\n selectionStart\r\n );\r\n }, 0);\r\n onValueChange?.(newValue, groupIndex);\r\n } else if (selectionStart < group.value.length) {\r\n // 1-5. del \uD0A4\uB85C \uD604\uC7AC \uCEE4\uC11C \uC704\uCE58 \uAC12 \uC0AD\uC81C\r\n e.preventDefault();\r\n const newValue =\r\n group.value.slice(0, selectionStart) +\r\n group.value.slice(selectionStart + 1);\r\n group.setValue(newValue);\r\n cursorPosRef.current = selectionStart;\r\n setCursorVisible(true);\r\n setInputComplete(false);\r\n setRenderTrigger((prev) => prev + 1);\r\n setTimeout(() => {\r\n input?.setSelectionRange(\r\n selectionStart,\r\n selectionStart\r\n );\r\n }, 0);\r\n onValueChange?.(newValue, groupIndex);\r\n }\r\n }\r\n };\r\n },\r\n [groups]\r\n );\r\n\r\n // Change \uD578\uB4E4\uB7EC \uC0DD\uC131\r\n const createChangeHandler = useCallback(\r\n (\r\n groupIndex: number,\r\n onAfterChange?: (\r\n newValue: string,\r\n groupIndex: number,\r\n isComplete: boolean\r\n ) => void\r\n ) => {\r\n return (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const group = groups[groupIndex];\r\n const numbers = e.target.value\r\n .replace(/\\D/g, \"\")\r\n .slice(0, group.maxLength);\r\n group.setValue(numbers);\r\n cursorPosRef.current = numbers.length;\r\n setCursorVisible(true); // \uC785\uB825 \uC2DC \uCEE4\uC11C \uD45C\uC2DC\r\n\r\n // \uCD5C\uB300 \uAE38\uC774 \uC785\uB825 \uC2DC \uB2E4\uC74C \uADF8\uB8F9\uC73C\uB85C \uC774\uB3D9\r\n const isGroupComplete = numbers.length === group.maxLength;\r\n if (isGroupComplete && groupIndex < groups.length - 1) {\r\n setTimeout(() => {\r\n const nextGroup = groups[groupIndex + 1];\r\n nextGroup.ref.current?.focus();\r\n nextGroup.ref.current?.setSelectionRange(0, 0);\r\n cursorPosRef.current = 0;\r\n }, 0);\r\n }\r\n\r\n // \uC804\uCCB4 \uC644\uB8CC \uCCB4\uD06C\r\n const allComplete =\r\n isGroupComplete &&\r\n groupIndex === groups.length - 1 &&\r\n groups\r\n .slice(0, -1)\r\n .every((g) => g.value.length === g.maxLength);\r\n\r\n if (allComplete) {\r\n setInputComplete(true);\r\n onComplete?.();\r\n } else {\r\n setInputComplete(false);\r\n }\r\n\r\n setRenderTrigger((prev) => prev + 1);\r\n onAfterChange?.(numbers, groupIndex, allComplete);\r\n };\r\n },\r\n [groups, onComplete]\r\n );\r\n\r\n return {\r\n focusedGroup,\r\n setFocusedGroup,\r\n cursorVisible,\r\n setCursorVisible,\r\n cursorPosRef,\r\n isClickFocusRef,\r\n inputComplete,\r\n setInputComplete,\r\n renderTrigger,\r\n measureTextWidth,\r\n getCursorLeft,\r\n createMouseDownHandler,\r\n createClickHandler,\r\n createContainerClickHandler,\r\n createFocusHandler,\r\n createBlurHandler,\r\n createKeyDownHandler,\r\n createChangeHandler,\r\n getCursorPosFromClick,\r\n forceRender,\r\n };\r\n}\r\n", "const HANGUL_SYLLABLE_START = 0xac00;\r\nconst HANGUL_SYLLABLE_END = 0xd7a3;\r\nconst HANGUL_SYLLABLE_BASE = 0xac00;\r\nconst HANGUL_JUNGSEONG_COUNT = 21;\r\nconst HANGUL_JONGSEONG_COUNT = 28;\r\n\r\nconst CHOSEONG_TO_ENGLISH_KEYS = [\r\n \"r\",\r\n \"R\",\r\n \"s\",\r\n \"e\",\r\n \"E\",\r\n \"f\",\r\n \"a\",\r\n \"q\",\r\n \"Q\",\r\n \"t\",\r\n \"T\",\r\n \"d\",\r\n \"w\",\r\n \"W\",\r\n \"c\",\r\n \"z\",\r\n \"x\",\r\n \"v\",\r\n \"g\",\r\n] as const;\r\n\r\nconst JUNGSEONG_TO_ENGLISH_KEYS = [\r\n \"k\",\r\n \"o\",\r\n \"i\",\r\n \"O\",\r\n \"j\",\r\n \"p\",\r\n \"u\",\r\n \"P\",\r\n \"h\",\r\n \"hk\",\r\n \"ho\",\r\n \"hl\",\r\n \"y\",\r\n \"n\",\r\n \"nj\",\r\n \"np\",\r\n \"nl\",\r\n \"b\",\r\n \"m\",\r\n \"ml\",\r\n \"l\",\r\n] as const;\r\n\r\nconst JONGSEONG_TO_ENGLISH_KEYS = [\r\n \"\",\r\n \"r\",\r\n \"R\",\r\n \"rt\",\r\n \"s\",\r\n \"sw\",\r\n \"sg\",\r\n \"e\",\r\n \"f\",\r\n \"fr\",\r\n \"fa\",\r\n \"fq\",\r\n \"ft\",\r\n \"fx\",\r\n \"fv\",\r\n \"fg\",\r\n \"a\",\r\n \"q\",\r\n \"qt\",\r\n \"t\",\r\n \"T\",\r\n \"d\",\r\n \"w\",\r\n \"c\",\r\n \"z\",\r\n \"x\",\r\n \"v\",\r\n \"g\",\r\n] as const;\r\n\r\nconst COMPATIBILITY_JAMO_TO_ENGLISH_KEYS: Record<string, string> = {\r\n \u3131: \"r\",\r\n \u3132: \"R\",\r\n \u3133: \"rt\",\r\n \u3134: \"s\",\r\n \u3135: \"sw\",\r\n \u3136: \"sg\",\r\n \u3137: \"e\",\r\n \u3138: \"E\",\r\n \u3139: \"f\",\r\n \u313A: \"fr\",\r\n \u313B: \"fa\",\r\n \u313C: \"fq\",\r\n \u313D: \"ft\",\r\n \u313E: \"fx\",\r\n \u313F: \"fv\",\r\n \u3140: \"fg\",\r\n \u3141: \"a\",\r\n \u3142: \"q\",\r\n \u3143: \"Q\",\r\n \u3144: \"qt\",\r\n \u3145: \"t\",\r\n \u3146: \"T\",\r\n \u3147: \"d\",\r\n \u3148: \"w\",\r\n \u3149: \"W\",\r\n \u314A: \"c\",\r\n \u314B: \"z\",\r\n \u314C: \"x\",\r\n \u314D: \"v\",\r\n \u314E: \"g\",\r\n \u314F: \"k\",\r\n \u3150: \"o\",\r\n \u3151: \"i\",\r\n \u3152: \"O\",\r\n \u3153: \"j\",\r\n \u3154: \"p\",\r\n \u3155: \"u\",\r\n \u3156: \"P\",\r\n \u3157: \"h\",\r\n \u3158: \"hk\",\r\n \u3159: \"ho\",\r\n \u315A: \"hl\",\r\n \u315B: \"y\",\r\n \u315C: \"n\",\r\n \u315D: \"nj\",\r\n \u315E: \"np\",\r\n \u315F: \"nl\",\r\n \u3160: \"b\",\r\n \u3161: \"m\",\r\n \u3162: \"ml\",\r\n \u3163: \"l\",\r\n};\r\n\r\nconst MODERN_CHOSEONG_TO_ENGLISH_KEYS: Record<string, string> = {\r\n \u1100: \"r\",\r\n \u1101: \"R\",\r\n \u1102: \"s\",\r\n \u1103: \"e\",\r\n \u1104: \"E\",\r\n \u1105: \"f\",\r\n \u1106: \"a\",\r\n \u1107: \"q\",\r\n \u1108: \"Q\",\r\n \u1109: \"t\",\r\n \u110A: \"T\",\r\n \u110B: \"d\",\r\n \u110C: \"w\",\r\n \u110D: \"W\",\r\n \u110E: \"c\",\r\n \u110F: \"z\",\r\n \u1110: \"x\",\r\n \u1111: \"v\",\r\n \u1112: \"g\",\r\n};\r\n\r\nconst MODERN_JUNGSEONG_TO_ENGLISH_KEYS: Record<string, string> = {\r\n \u1161: \"k\",\r\n \u1162: \"o\",\r\n \u1163: \"i\",\r\n \u1164: \"O\",\r\n \u1165: \"j\",\r\n \u1166: \"p\",\r\n \u1167: \"u\",\r\n \u1168: \"P\",\r\n \u1169: \"h\",\r\n \u116A: \"hk\",\r\n \u116B: \"ho\",\r\n \u116C: \"hl\",\r\n \u116D: \"y\",\r\n \u116E: \"n\",\r\n \u116F: \"nj\",\r\n \u1170: \"np\",\r\n \u1171: \"nl\",\r\n \u1172: \"b\",\r\n \u1173: \"m\",\r\n \u1174: \"ml\",\r\n \u1175: \"l\",\r\n};\r\n\r\nconst MODERN_JONGSEONG_TO_ENGLISH_KEYS: Record<string, string> = {\r\n \u11A8: \"r\",\r\n \u11A9: \"R\",\r\n \u11AA: \"rt\",\r\n \u11AB: \"s\",\r\n \u11AC: \"sw\",\r\n \u11AD: \"sg\",\r\n \u11AE: \"e\",\r\n \u11AF: \"f\",\r\n \u11B0: \"fr\",\r\n \u11B1: \"fa\",\r\n \u11B2: \"fq\",\r\n \u11B3: \"ft\",\r\n \u11B4: \"fx\",\r\n \u11B5: \"fv\",\r\n \u11B6: \"fg\",\r\n \u11B7: \"a\",\r\n \u11B8: \"q\",\r\n \u11B9: \"qt\",\r\n \u11BA: \"t\",\r\n \u11BB: \"T\",\r\n \u11BC: \"d\",\r\n \u11BD: \"w\",\r\n \u11BE: \"c\",\r\n \u11BF: \"z\",\r\n \u11C0: \"x\",\r\n \u11C1: \"v\",\r\n \u11C2: \"g\",\r\n};\r\n\r\nconst KOREAN_CHAR_RE = /[\u3131-\u314E\u314F-\u3163\uAC00-\uD7A3\u1100-\u11C2]/;\r\nconst KOREAN_IME_QUERY_RE = /^[0-9\u3131-\u314E\u314F-\u3163\uAC00-\uD7A3\u1100-\u11C2\\s]+$/;\r\n\r\nconst convertCompatibilityJamoToEnglish = (char: string) =>\r\n COMPATIBILITY_JAMO_TO_ENGLISH_KEYS[char] ?? null;\r\n\r\nconst convertModernJamoToEnglish = (char: string) =>\r\n MODERN_CHOSEONG_TO_ENGLISH_KEYS[char] ??\r\n MODERN_JUNGSEONG_TO_ENGLISH_KEYS[char] ??\r\n MODERN_JONGSEONG_TO_ENGLISH_KEYS[char] ??\r\n null;\r\n\r\nconst convertHangulSyllableToEnglish = (char: string) => {\r\n const codePoint = char.codePointAt(0);\r\n if (codePoint == null) {\r\n return null;\r\n }\r\n if (codePoint < HANGUL_SYLLABLE_START || codePoint > HANGUL_SYLLABLE_END) {\r\n return null;\r\n }\r\n\r\n const syllableIndex = codePoint - HANGUL_SYLLABLE_BASE;\r\n const choseongIndex = Math.floor(\r\n syllableIndex / (HANGUL_JUNGSEONG_COUNT * HANGUL_JONGSEONG_COUNT),\r\n );\r\n const jungseongIndex = Math.floor(\r\n (syllableIndex % (HANGUL_JUNGSEONG_COUNT * HANGUL_JONGSEONG_COUNT)) /\r\n HANGUL_JONGSEONG_COUNT,\r\n );\r\n const jongseongIndex = syllableIndex % HANGUL_JONGSEONG_COUNT;\r\n\r\n return `${CHOSEONG_TO_ENGLISH_KEYS[choseongIndex] ?? \"\"}${JUNGSEONG_TO_ENGLISH_KEYS[jungseongIndex] ?? \"\"}${JONGSEONG_TO_ENGLISH_KEYS[jongseongIndex] ?? \"\"}`;\r\n};\r\n\r\nexport const convertMistypedKoreanImeToEnglish = (\r\n value: string | null | undefined,\r\n) =>\r\n Array.from(value ?? \"\")\r\n .map((char) => {\r\n const compatibilityJamo = convertCompatibilityJamoToEnglish(char);\r\n if (compatibilityJamo != null) {\r\n return compatibilityJamo;\r\n }\r\n\r\n const modernJamo = convertModernJamoToEnglish(char);\r\n if (modernJamo != null) {\r\n return modernJamo;\r\n }\r\n\r\n const syllable = convertHangulSyllableToEnglish(char);\r\n if (syllable != null) {\r\n return syllable;\r\n }\r\n\r\n return char;\r\n })\r\n .join(\"\");\r\n\r\nexport const shouldAutoConvertKoreanImeQuery = (\r\n value: string | null | undefined,\r\n) => {\r\n const trimmed = (value ?? \"\").trim();\r\n if (!trimmed) {\r\n return false;\r\n }\r\n\r\n if (!KOREAN_CHAR_RE.test(trimmed)) {\r\n return false;\r\n }\r\n\r\n return KOREAN_IME_QUERY_RE.test(trimmed);\r\n};\r\n", "/**\r\n * ClearTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n forwardRef,\r\n useCallback,\r\n useRef,\r\n useImperativeHandle,\r\n useState,\r\n} from \"react\";\r\nimport { TextField, IconButton, InputAdornment } from \"@mui/material\";\r\nimport type { BaseTextFieldProps as MuiBaseTextFieldProps } from \"@mui/material/TextField\";\r\nimport ClearIcon from \"@mui/icons-material/Clear\";\r\nimport type { ClearTextFieldProps } from \"./types\";\r\nimport { useTextFieldBase } from \"./hooks\";\r\n\r\nconst ClearTextFieldBase = forwardRef<HTMLDivElement, ClearTextFieldProps>(\r\n function ClearTextFieldBase(\r\n {\r\n value,\r\n clearIcon = true,\r\n debounce = 0,\r\n readonly,\r\n spellCheck = false,\r\n onChange,\r\n onBlur,\r\n onFocus,\r\n onClear,\r\n slotProps,\r\n size,\r\n inputRef: externalInputRef,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const {\r\n internalValue,\r\n setInternalValue,\r\n handleChange,\r\n handleBlur,\r\n emitChange,\r\n lastEmittedValue,\r\n debounceTimer,\r\n } = useTextFieldBase({\r\n value: (value as string) ?? \"\",\r\n name: props.name,\r\n debounce,\r\n onChange,\r\n onBlur,\r\n });\r\n\r\n const [isFocused, setIsFocused] = useState(false);\r\n const [forceShrink, setForceShrink] = useState(false);\r\n const isClearingRef = useRef(false);\r\n\r\n // input ref for focus after clear\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLInputElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n // size\uC5D0 \uB530\uB978 \uC544\uC774\uCF58 \uD06C\uAE30\r\n const iconSize = size === \"small\" ? 20 : 24;\r\n\r\n // \uD074\uB9AC\uC5B4 \uBC84\uD2BC \uD578\uB4E4\uB7EC\r\n const handleClear = () => {\r\n isClearingRef.current = true;\r\n setForceShrink(true);\r\n setIsFocused(true);\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n debounceTimer.current = null;\r\n }\r\n\r\n if (internalValue !== \"\") {\r\n lastEmittedValue.current = internalValue;\r\n }\r\n setInternalValue(\"\");\r\n // \uC989\uC2DC emit\uC744 \uC704\uD574 fake \uC774\uBCA4\uD2B8 \uC0DD\uC131\r\n const eventTarget = {\r\n name: props.name || \"\",\r\n value: \"\",\r\n } as HTMLInputElement;\r\n const fakeEvent = {\r\n target: eventTarget,\r\n currentTarget: eventTarget,\r\n } as unknown as React.ChangeEvent<HTMLInputElement>;\r\n emitChange(fakeEvent, \"\", true);\r\n onClear?.();\r\n // \uD074\uB9AC\uC5B4 \uD6C4 \uD3EC\uCEE4\uC2A4\r\n internalInputRef.current?.focus();\r\n setTimeout(() => {\r\n isClearingRef.current = false;\r\n }, 0);\r\n };\r\n\r\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\r\n setIsFocused(true);\r\n onFocus?.(event);\r\n };\r\n\r\n const handleBlurWithFocus = (\r\n event: React.FocusEvent<HTMLInputElement>,\r\n ) => {\r\n if (isClearingRef.current) {\r\n isClearingRef.current = false;\r\n handleBlur(event);\r\n return;\r\n }\r\n\r\n setIsFocused(false);\r\n setForceShrink(false);\r\n handleBlur(event);\r\n };\r\n\r\n // readonly\uC77C \uB54C \uD3EC\uCEE4\uC2A4 \uC2A4\uD0C0\uC77C \uC81C\uAC70\r\n const readonlyStyles = readonly\r\n ? {\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n const shouldShrink = forceShrink || isFocused || internalValue !== \"\";\r\n\r\n const resolveInputLabelSlotProps = (\r\n ownerState: MuiBaseTextFieldProps,\r\n ): Record<string, unknown> => {\r\n const baseInputLabel = slotProps?.inputLabel;\r\n const resolvedInputLabel =\r\n typeof baseInputLabel === \"function\"\r\n ? baseInputLabel(ownerState)\r\n : baseInputLabel;\r\n\r\n return {\r\n ...resolvedInputLabel,\r\n shrink:\r\n (resolvedInputLabel as { shrink?: boolean })?.shrink ??\r\n shouldShrink,\r\n };\r\n };\r\n\r\n return (\r\n <TextField\r\n {...props}\r\n ref={ref}\r\n inputRef={internalInputRef}\r\n size={size}\r\n focused={isFocused || isClearingRef.current}\r\n value={internalValue}\r\n onChange={handleChange}\r\n onFocus={handleFocus}\r\n onBlur={handleBlurWithFocus}\r\n autoComplete=\"off\"\r\n spellCheck={spellCheck}\r\n sx={{\r\n ...readonlyStyles,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...(props.sx ?? {}),\r\n }}\r\n slotProps={{\r\n ...slotProps,\r\n inputLabel: resolveInputLabelSlotProps,\r\n input: {\r\n ...slotProps?.input,\r\n readOnly: readonly,\r\n notched: shouldShrink,\r\n endAdornment:\r\n clearIcon && !readonly ? (\r\n <InputAdornment\r\n position=\"end\"\r\n sx={{\r\n visibility: internalValue\r\n ? isFocused\r\n ? \"visible\"\r\n : \"hidden\"\r\n : \"hidden\",\r\n mr: 0,\r\n }}\r\n >\r\n <IconButton\r\n size=\"small\"\r\n onMouseDown={(event) => {\r\n event.preventDefault();\r\n if (!readonly) {\r\n handleClear();\r\n }\r\n }}\r\n edge=\"end\"\r\n tabIndex={-1}\r\n disabled={readonly}\r\n sx={{\r\n padding:\r\n size === \"small\"\r\n ? \"2px\"\r\n : \"4px\",\r\n color: \"#666\",\r\n \"&:hover\": {\r\n color: \"#333\",\r\n backgroundColor:\r\n \"rgba(0, 0, 0, 0.04)\",\r\n },\r\n }}\r\n >\r\n <ClearIcon\r\n sx={{ fontSize: iconSize - 4 }}\r\n />\r\n </IconButton>\r\n </InputAdornment>\r\n ) : undefined,\r\n },\r\n }}\r\n />\r\n );\r\n },\r\n);\r\n\r\nconst ClearTextFieldWithForm = forwardRef<HTMLDivElement, ClearTextFieldProps>(\r\n function ClearTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"ClearTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"ClearTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <ClearTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const ClearTextField = forwardRef<HTMLDivElement, ClearTextFieldProps>(\r\n function ClearTextField(props, ref) {\r\n if (props.form) {\r\n return <ClearTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <ClearTextFieldBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * PasswordTextField.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n forwardRef,\r\n useRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField, IconButton, InputAdornment } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport Visibility from \"@mui/icons-material/Visibility\";\r\nimport VisibilityOff from \"@mui/icons-material/VisibilityOff\";\r\nimport type { PasswordTextFieldProps } from \"./types\";\r\nimport { useTextFieldBase } from \"./hooks\";\r\nimport {\r\n DEFAULT_PASSWORD_VALIDATION_RULES as DEFAULT_VALIDATION_RULES,\r\n validatePassword,\r\n} from \"./utils\";\r\n\r\nconst PasswordTextFieldBase = forwardRef<\r\n HTMLDivElement,\r\n PasswordTextFieldProps\r\n>(function PasswordTextFieldBase(\r\n {\r\n showToggle = true,\r\n label,\r\n validationRules,\r\n onValidationChange,\r\n invalidBorderColor,\r\n debounce,\r\n readonly,\r\n slotProps,\r\n sx,\r\n size,\r\n value,\r\n onChange,\r\n onBlur,\r\n inputRef: externalInputRef,\r\n ...props\r\n },\r\n ref,\r\n) {\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLInputElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n const [showPassword, setShowPassword] = useState(false);\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n\r\n // useTextFieldBase \uD6C5 \uC0AC\uC6A9\r\n const { internalValue, handleChange, handleBlur } = useTextFieldBase({\r\n value: (value as string) ?? \"\",\r\n name: props.name,\r\n debounce,\r\n onChange,\r\n onBlur,\r\n });\r\n\r\n // size\uC5D0 \uB530\uB978 \uC544\uC774\uCF58 \uD06C\uAE30\r\n const iconSize = size === \"small\" ? 20 : 24;\r\n\r\n const handleTogglePassword = () => {\r\n setShowPassword((prev) => !prev);\r\n };\r\n const performValidation = useCallback(\r\n (inputValue: string) => {\r\n const rules = validationRules || {};\r\n const mergedRules = { ...DEFAULT_VALIDATION_RULES, ...rules };\r\n const result = validatePassword(inputValue, mergedRules);\r\n // \uCD5C\uC18C\uAE38\uC774 \uC774\uC0C1 \uC785\uB825\uB418\uC5C8\uC744 \uB54C\uB9CC invalid \uC0C1\uD0DC \uC801\uC6A9\r\n const minLength = mergedRules.minLength || 8;\r\n setIsInvalid(\r\n !result.isValid &&\r\n inputValue.length >= minLength &&\r\n inputValue.length > 0,\r\n );\r\n if (onValidationChange) {\r\n onValidationChange(result);\r\n }\r\n },\r\n [validationRules, onValidationChange],\r\n );\r\n\r\n // internalValue \uBCC0\uACBD \uC2DC \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n useEffect(() => {\r\n performValidation(internalValue);\r\n }, [internalValue, performValidation]);\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uC2E4\uD328 \uC2DC \uD14C\uB450\uB9AC \uC2A4\uD0C0\uC77C (invalidBorderColor\uAC00 \uC124\uC815\uB41C \uACBD\uC6B0\uC5D0\uB9CC)\r\n const invalidStyles: SxProps<Theme> =\r\n isInvalid && invalidBorderColor\r\n ? {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n \"&:hover fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n \"&.Mui-focused fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n },\r\n \"& .MuiFilledInput-root\": {\r\n \"&:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:hover:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:after\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n },\r\n \"& .MuiInput-root\": {\r\n \"&:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:hover:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:after\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n },\r\n }\r\n : {};\r\n\r\n // readonly\uC77C \uB54C \uD3EC\uCEE4\uC2A4 \uC2A4\uD0C0\uC77C \uC81C\uAC70\r\n const readonlyStyles = readonly\r\n ? {\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n return (\r\n <TextField\r\n {...props}\r\n ref={ref}\r\n inputRef={internalInputRef}\r\n value={internalValue}\r\n onChange={handleChange}\r\n onBlur={handleBlur}\r\n label={label}\r\n size={size}\r\n type={showPassword ? \"text\" : \"password\"}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n sx={{\r\n ...invalidStyles,\r\n ...readonlyStyles,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...sx,\r\n }}\r\n slotProps={{\r\n ...slotProps,\r\n input: {\r\n ...slotProps?.input,\r\n readOnly: readonly,\r\n endAdornment:\r\n showToggle && !readonly ? (\r\n <InputAdornment\r\n position=\"end\"\r\n sx={{ ml: 1, mr: size === \"small\" ? -0.5 : 1 }}\r\n >\r\n <IconButton\r\n onClick={handleTogglePassword}\r\n edge=\"end\"\r\n tabIndex={-1}\r\n size={size}\r\n sx={{\r\n color: \"#666\",\r\n \"&:hover\": {\r\n color: \"#333\",\r\n backgroundColor:\r\n \"rgba(0, 0, 0, 0.04)\",\r\n },\r\n }}\r\n >\r\n {showPassword ? (\r\n <VisibilityOff\r\n sx={{ fontSize: iconSize }}\r\n />\r\n ) : (\r\n <Visibility\r\n sx={{ fontSize: iconSize }}\r\n />\r\n )}\r\n </IconButton>\r\n </InputAdornment>\r\n ) : undefined,\r\n },\r\n }}\r\n />\r\n );\r\n});\r\n\r\nconst PasswordTextFieldWithForm = forwardRef<\r\n HTMLDivElement,\r\n PasswordTextFieldProps\r\n>(function PasswordTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"PasswordTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"PasswordTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name) as string | undefined;\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <PasswordTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const PasswordTextField = forwardRef<\r\n HTMLDivElement,\r\n PasswordTextFieldProps\r\n>(function PasswordTextField(props, ref) {\r\n if (props.form) {\r\n return <PasswordTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <PasswordTextFieldBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * date.ts - \uB0A0\uC9DC \uAD00\uB828 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport type { DateFormat, DateTimeFormat } from \"../types\";\r\n\r\n/**\r\n * \uC724\uB144 \uCCB4\uD06C\r\n */\r\nexport function isLeapYear(year: number): boolean {\r\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\r\n}\r\n\r\n/**\r\n * \uD574\uB2F9 \uC6D4\uC758 \uB9D0\uC77C \uACC4\uC0B0\r\n */\r\nexport function getDaysInMonth(year: number, month: number): number {\r\n if (month === 2) {\r\n return isLeapYear(year) ? 29 : 28;\r\n }\r\n if ([4, 6, 9, 11].includes(month)) {\r\n return 30;\r\n }\r\n return 31;\r\n}\r\n\r\n/**\r\n * \uB0A0\uC9DC \uD3EC\uB9F7\uC5D0 \uB530\uB978 \uAD6C\uBD84\uC790 \uAC00\uC838\uC624\uAE30\r\n */\r\nexport function getSeparator(format: DateFormat): string {\r\n if (format.includes(\".\")) return \".\";\r\n if (format.includes(\"/\")) return \"/\";\r\n return \"-\";\r\n}\r\n\r\n/**\r\n * \uB0A0\uC9DC \uC790\uB3D9 \uD3EC\uB9F7\uD305 \uD568\uC218\r\n */\r\nexport function formatDate(value: string, format: DateFormat): string {\r\n const rawNumbers = value.replace(/\\D/g, \"\");\r\n const separator = getSeparator(format);\r\n\r\n if (rawNumbers.length === 0) return \"\";\r\n\r\n // \uC785\uB825\uB41C \uC22B\uC790\uB97C \uC720\uD6A8\uD55C \uBC94\uC704\uB85C \uBCF4\uC815\r\n const numbers = constrainDateNumbers(rawNumbers, format);\r\n\r\n // YYYY-MM-DD, YYYY.MM.DD, YYYY/MM/DD (\uAE30\uBCF8)\r\n if (format.startsWith(\"YYYY\")) {\r\n if (numbers.length < 4) return numbers;\r\n if (numbers.length === 4) return `${numbers}${separator}`;\r\n if (numbers.length < 6)\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(4)}`;\r\n if (numbers.length === 6)\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(\r\n 4\r\n )}${separator}`;\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(\r\n 4,\r\n 6\r\n )}${separator}${numbers.slice(6, 8)}`;\r\n }\r\n\r\n // MM-DD-YYYY, MM.DD.YYYY, MM/DD/YYYY (\uBBF8\uAD6D\uC2DD)\r\n if (\r\n format.startsWith(\"MM\") &&\r\n format.includes(\"DD\") &&\r\n format.endsWith(\"YYYY\")\r\n ) {\r\n if (numbers.length < 2) return numbers;\r\n if (numbers.length === 2) return `${numbers}${separator}`;\r\n if (numbers.length < 4)\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(2)}`;\r\n if (numbers.length === 4)\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(\r\n 2\r\n )}${separator}`;\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(\r\n 2,\r\n 4\r\n )}${separator}${numbers.slice(4, 8)}`;\r\n }\r\n\r\n // MM-DD, MM.DD, MM/DD (\uC6D4\uC77C\uB9CC)\r\n if (\r\n format.startsWith(\"MM\") &&\r\n format.includes(\"DD\") &&\r\n !format.includes(\"YYYY\")\r\n ) {\r\n if (numbers.length < 2) return numbers;\r\n if (numbers.length === 2) return `${numbers}${separator}`;\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(2, 4)}`;\r\n }\r\n\r\n // DD-MM-YYYY, DD.MM.YYYY, DD/MM/YYYY (\uC720\uB7FD\uC2DD)\r\n if (format.startsWith(\"DD\") && format.endsWith(\"YYYY\")) {\r\n if (numbers.length < 2) return numbers;\r\n if (numbers.length === 2) return `${numbers}${separator}`;\r\n if (numbers.length < 4)\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(2)}`;\r\n if (numbers.length === 4)\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(\r\n 2\r\n )}${separator}`;\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(\r\n 2,\r\n 4\r\n )}${separator}${numbers.slice(4, 8)}`;\r\n }\r\n\r\n // DD-MM, DD.MM, DD/MM (\uC77C\uC6D4\uB9CC)\r\n if (\r\n format.startsWith(\"DD\") &&\r\n format.includes(\"MM\") &&\r\n !format.includes(\"YYYY\")\r\n ) {\r\n if (numbers.length < 2) return numbers;\r\n if (numbers.length === 2) return `${numbers}${separator}`;\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(2, 4)}`;\r\n }\r\n\r\n // YY-MM-DD, YY.MM.DD (2\uC790\uB9AC \uC5F0\uB3C4)\r\n if (format.startsWith(\"YY\") && !format.startsWith(\"YYYY\")) {\r\n if (numbers.length < 2) return numbers;\r\n if (numbers.length === 2) return `${numbers}${separator}`;\r\n if (numbers.length < 4)\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(2)}`;\r\n if (numbers.length === 4)\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(\r\n 2\r\n )}${separator}`;\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(\r\n 2,\r\n 4\r\n )}${separator}${numbers.slice(4, 6)}`;\r\n }\r\n\r\n // \uAE30\uBCF8: YYYY-MM-DD\r\n if (numbers.length < 4) return numbers;\r\n if (numbers.length === 4) return `${numbers}${separator}`;\r\n if (numbers.length < 6)\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(4)}`;\r\n if (numbers.length === 6)\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(\r\n 4\r\n )}${separator}`;\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(\r\n 4,\r\n 6\r\n )}${separator}${numbers.slice(6, 8)}`;\r\n}\r\n\r\n/**\r\n * \uD3EC\uB9F7\uC5D0 \uB530\uB978 \uCD5C\uB300 \uAE38\uC774 \uACC4\uC0B0\r\n */\r\nexport function getMaxLength(format: DateFormat): number {\r\n if (format === \"MM-DD\" || format === \"MM.DD\" || format === \"MM/DD\")\r\n return 5;\r\n if (format === \"DD-MM\" || format === \"DD.MM\" || format === \"DD/MM\")\r\n return 5;\r\n if (format === \"YY-MM\" || format === \"YY.MM\" || format === \"YY/MM\")\r\n return 5;\r\n if (format === \"YYYY-MM\" || format === \"YYYY.MM\" || format === \"YYYY/MM\")\r\n return 7;\r\n if (format.startsWith(\"YY\") && !format.startsWith(\"YYYY\")) return 8;\r\n return 10;\r\n}\r\n\r\n/**\r\n * \uD3EC\uB9F7\uC5D0 \uB530\uB978 \uC644\uC131 \uC22B\uC790 \uAE38\uC774\r\n */\r\nexport function getCompleteLength(format: DateFormat): number {\r\n if (format === \"MM-DD\" || format === \"MM.DD\" || format === \"MM/DD\")\r\n return 4;\r\n if (format === \"DD-MM\" || format === \"DD.MM\" || format === \"DD/MM\")\r\n return 4;\r\n if (format === \"YY-MM\" || format === \"YY.MM\" || format === \"YY/MM\")\r\n return 4;\r\n if (format === \"YYYY-MM\" || format === \"YYYY.MM\" || format === \"YYYY/MM\")\r\n return 6;\r\n if (format.startsWith(\"YY\") && !format.startsWith(\"YYYY\")) return 6;\r\n return 8;\r\n}\r\n\r\n/**\r\n * \uB0A0\uC9DC \uBB38\uC790\uC5F4\uC5D0\uC11C \uC5F0/\uC6D4/\uC77C \uCD94\uCD9C\r\n */\r\nexport function parseDateParts(\r\n value: string,\r\n format: DateFormat\r\n): { year: number; month: number; day: number } | null {\r\n const numbers = value.replace(/\\D/g, \"\");\r\n const completeLength = getCompleteLength(format);\r\n\r\n if (numbers.length !== completeLength) return null;\r\n\r\n let year: number, month: number, day: number;\r\n\r\n if (format === \"YYYY-MM\" || format === \"YYYY.MM\" || format === \"YYYY/MM\") {\r\n year = parseInt(numbers.slice(0, 4), 10);\r\n month = parseInt(numbers.slice(4, 6), 10);\r\n day = 1;\r\n } else if (format === \"YY-MM\" || format === \"YY.MM\" || format === \"YY/MM\") {\r\n const yy = parseInt(numbers.slice(0, 2), 10);\r\n year = yy >= 50 ? 1900 + yy : 2000 + yy;\r\n month = parseInt(numbers.slice(2, 4), 10);\r\n day = 1;\r\n } else if (format === \"MM-DD\" || format === \"MM.DD\" || format === \"MM/DD\") {\r\n month = parseInt(numbers.slice(0, 2), 10);\r\n day = parseInt(numbers.slice(2, 4), 10);\r\n year = new Date().getFullYear();\r\n } else if (format === \"DD-MM\" || format === \"DD.MM\" || format === \"DD/MM\") {\r\n day = parseInt(numbers.slice(0, 2), 10);\r\n month = parseInt(numbers.slice(2, 4), 10);\r\n year = new Date().getFullYear();\r\n } else if (format.startsWith(\"YYYY\")) {\r\n year = parseInt(numbers.slice(0, 4), 10);\r\n month = parseInt(numbers.slice(4, 6), 10);\r\n day = parseInt(numbers.slice(6, 8), 10);\r\n } else if (format.startsWith(\"MM\") && format.endsWith(\"YYYY\")) {\r\n month = parseInt(numbers.slice(0, 2), 10);\r\n day = parseInt(numbers.slice(2, 4), 10);\r\n year = parseInt(numbers.slice(4, 8), 10);\r\n } else if (format.startsWith(\"DD\") && format.endsWith(\"YYYY\")) {\r\n day = parseInt(numbers.slice(0, 2), 10);\r\n month = parseInt(numbers.slice(2, 4), 10);\r\n year = parseInt(numbers.slice(4, 8), 10);\r\n } else if (format.startsWith(\"YY\") && !format.startsWith(\"YYYY\")) {\r\n const yy = parseInt(numbers.slice(0, 2), 10);\r\n year = yy >= 50 ? 1900 + yy : 2000 + yy;\r\n month = parseInt(numbers.slice(2, 4), 10);\r\n day = parseInt(numbers.slice(4, 6), 10);\r\n } else {\r\n year = parseInt(numbers.slice(0, 4), 10);\r\n month = parseInt(numbers.slice(4, 6), 10);\r\n day = parseInt(numbers.slice(6, 8), 10);\r\n }\r\n\r\n return { year, month, day };\r\n}\r\n\r\n/**\r\n * \uB0A0\uC9DC \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n */\r\nexport function validateDate(\r\n value: string,\r\n format: DateFormat,\r\n minDate?: Date,\r\n maxDate?: Date\r\n): boolean {\r\n const parts = parseDateParts(value, format);\r\n if (!parts) return false;\r\n\r\n const { year, month, day } = parts;\r\n\r\n if (month < 1 || month > 12) return false;\r\n if (day < 1 || day > 31) return false;\r\n\r\n const daysInMonth = new Date(year, month, 0).getDate();\r\n if (day > daysInMonth) return false;\r\n\r\n const date = new Date(year, month - 1, day);\r\n\r\n if (minDate && date < minDate) return false;\r\n if (maxDate && date > maxDate) return false;\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * \uB0A0\uC9DC \uBB38\uC790\uC5F4\uC744 Date \uAC1D\uCCB4\uB85C \uBCC0\uD658\r\n */\r\nexport function parseToDate(value: string, format: DateFormat): Date | null {\r\n const parts = parseDateParts(value, format);\r\n if (!parts) return null;\r\n\r\n const { year, month, day } = parts;\r\n\r\n if (month < 1 || month > 12 || day < 1 || day > 31) return null;\r\n\r\n return new Date(year, month - 1, day);\r\n}\r\n\r\n/**\r\n * \uB0A0\uC9DC \uAC12 \uC81C\uD55C (\uB144/\uC6D4/\uC77C)\r\n */\r\nexport function clampDateValue(\r\n value: string,\r\n type: \"year\" | \"month\" | \"day\",\r\n yearValue?: string,\r\n monthValue?: string\r\n): string {\r\n if (value.length === 0) return value;\r\n\r\n if (type === \"year\") {\r\n if (value.length === 1) {\r\n const digit = parseInt(value, 10);\r\n if (digit !== 1 && digit !== 2) return \"2\";\r\n }\r\n return value;\r\n }\r\n\r\n if (type === \"month\") {\r\n if (value.length === 1) {\r\n const digit = parseInt(value, 10);\r\n if (digit > 1) return \"0\" + value;\r\n }\r\n if (value.length === 2) {\r\n const num = parseInt(value, 10);\r\n if (num > 12) return \"12\";\r\n if (num < 1) return \"01\";\r\n }\r\n return value;\r\n }\r\n\r\n if (type === \"day\") {\r\n if (value.length === 1) {\r\n const digit = parseInt(value, 10);\r\n if (digit > 3) return \"0\" + value;\r\n }\r\n if (value.length === 2) {\r\n const num = parseInt(value, 10);\r\n const year = yearValue ? parseInt(yearValue, 10) : 0;\r\n const month = monthValue ? parseInt(monthValue, 10) : 0;\r\n const maxDay = year && month ? getDaysInMonth(year, month) : 31;\r\n if (num > maxDay) return String(maxDay).padStart(2, \"0\");\r\n if (num < 1) return \"01\";\r\n }\r\n return value;\r\n }\r\n\r\n return value;\r\n}\r\n\r\n/**\r\n * DateTimeFormat\uC5D0\uC11C DateFormat \uBD80\uBD84 \uCD94\uCD9C\r\n */\r\nexport function extractDateFormat(format: DateTimeFormat): DateFormat {\r\n const datePart = format.split(\" \")[0];\r\n return datePart as DateFormat;\r\n}\r\n\r\n/**\r\n * \uCD08 \uD544\uB4DC\uAC00 \uC788\uB294\uC9C0 \uD655\uC778\r\n */\r\nexport function hasSecondField(format: DateTimeFormat): boolean {\r\n return format.includes(\":ss\");\r\n}\r\n\r\n/**\r\n * \uC785\uB825\uB41C \uC22B\uC790\uB97C \uC720\uD6A8\uD55C \uBC94\uC704\uB85C \uBCF4\uC815 (\uB0A0\uC9DC\uC6A9)\r\n */\r\nexport function constrainDateNumbers(\r\n numbers: string,\r\n format: DateFormat\r\n): string {\r\n if (numbers.length === 0) return \"\";\r\n\r\n let result = \"\";\r\n let year = 0;\r\n let month = 0;\r\n\r\n // YYYY-MM-DD, YYYY.MM.DD, YYYY/MM/DD\r\n if (format.startsWith(\"YYYY\")) {\r\n if (numbers.length >= 1) {\r\n const firstDigit = numbers[0];\r\n if (firstDigit !== \"1\" && firstDigit !== \"2\") {\r\n result += \"2\";\r\n } else {\r\n result += firstDigit;\r\n }\r\n }\r\n if (numbers.length >= 2) result += numbers[1];\r\n if (numbers.length >= 3) result += numbers[2];\r\n if (numbers.length >= 4) {\r\n result += numbers[3];\r\n year = parseInt(result, 10);\r\n }\r\n\r\n if (numbers.length >= 5) {\r\n let monthStr = numbers.slice(4, 6);\r\n if (monthStr.length === 1) {\r\n if (parseInt(monthStr, 10) > 1) {\r\n monthStr = \"0\" + monthStr;\r\n } else {\r\n result += monthStr;\r\n return result;\r\n }\r\n }\r\n month = parseInt(monthStr, 10);\r\n if (month > 12) month = 12;\r\n if (month < 1 && monthStr.length === 2) month = 1;\r\n result += month.toString().padStart(2, \"0\");\r\n }\r\n\r\n if (numbers.length >= 7) {\r\n let dayStr = numbers.slice(6, 8);\r\n if (dayStr.length === 1) {\r\n if (parseInt(dayStr, 10) > 3) {\r\n dayStr = \"0\" + dayStr;\r\n } else {\r\n result += dayStr;\r\n return result;\r\n }\r\n }\r\n let day = parseInt(dayStr, 10);\r\n const maxDay =\r\n year > 0 && month > 0 ? getDaysInMonth(year, month) : 31;\r\n if (day > maxDay) day = maxDay;\r\n if (day < 1 && dayStr.length === 2) day = 1;\r\n result += day.toString().padStart(2, \"0\");\r\n }\r\n\r\n return result;\r\n }\r\n\r\n // MM-DD, MM.DD, MM/DD (\uC6D4\uC77C\uB9CC)\r\n if (\r\n format.startsWith(\"MM\") &&\r\n format.includes(\"DD\") &&\r\n !format.includes(\"YYYY\") &&\r\n !format.includes(\"YY\")\r\n ) {\r\n // \uC6D4 \uCC98\uB9AC\r\n if (numbers.length >= 1) {\r\n let monthStr = numbers.slice(0, 2);\r\n if (monthStr.length === 1) {\r\n if (parseInt(monthStr, 10) > 1) {\r\n monthStr = \"0\" + monthStr;\r\n } else {\r\n result += monthStr;\r\n return result;\r\n }\r\n }\r\n month = parseInt(monthStr, 10);\r\n if (month > 12) month = 12;\r\n if (month < 1 && monthStr.length === 2) month = 1;\r\n result += month.toString().padStart(2, \"0\");\r\n }\r\n\r\n // \uC77C \uCC98\uB9AC\r\n if (numbers.length >= 3) {\r\n let dayStr = numbers.slice(2, 4);\r\n if (dayStr.length === 1) {\r\n if (parseInt(dayStr, 10) > 3) {\r\n dayStr = \"0\" + dayStr;\r\n } else {\r\n result += dayStr;\r\n return result;\r\n }\r\n }\r\n let day = parseInt(dayStr, 10);\r\n const maxDay =\r\n month > 0\r\n ? getDaysInMonth(new Date().getFullYear(), month)\r\n : 31;\r\n if (day > maxDay) day = maxDay;\r\n if (day < 1 && dayStr.length === 2) day = 1;\r\n result += day.toString().padStart(2, \"0\");\r\n }\r\n\r\n return result;\r\n }\r\n\r\n // DD-MM, DD.MM, DD/MM (\uC77C\uC6D4\uB9CC)\r\n if (\r\n format.startsWith(\"DD\") &&\r\n format.includes(\"MM\") &&\r\n !format.includes(\"YYYY\") &&\r\n !format.includes(\"YY\")\r\n ) {\r\n // \uC77C \uCC98\uB9AC (\uC6D4\uC744 \uBAA8\uB974\uBBC0\uB85C \uCD5C\uB300 31\uAE4C\uC9C0)\r\n if (numbers.length >= 1) {\r\n let dayStr = numbers.slice(0, 2);\r\n if (dayStr.length === 1) {\r\n if (parseInt(dayStr, 10) > 3) {\r\n dayStr = \"0\" + dayStr;\r\n } else {\r\n result += dayStr;\r\n return result;\r\n }\r\n }\r\n let day = parseInt(dayStr, 10);\r\n if (day > 31) day = 31;\r\n if (day < 1 && dayStr.length === 2) day = 1;\r\n result += day.toString().padStart(2, \"0\");\r\n }\r\n\r\n // \uC6D4 \uCC98\uB9AC\r\n if (numbers.length >= 3) {\r\n let monthStr = numbers.slice(2, 4);\r\n if (monthStr.length === 1) {\r\n if (parseInt(monthStr, 10) > 1) {\r\n monthStr = \"0\" + monthStr;\r\n } else {\r\n result += monthStr;\r\n return result;\r\n }\r\n }\r\n month = parseInt(monthStr, 10);\r\n if (month > 12) month = 12;\r\n if (month < 1 && monthStr.length === 2) month = 1;\r\n result += month.toString().padStart(2, \"0\");\r\n }\r\n\r\n return result;\r\n }\r\n\r\n // MM-DD-YYYY, MM.DD.YYYY (\uBBF8\uAD6D\uC2DD)\r\n if (\r\n format.startsWith(\"MM\") &&\r\n format.includes(\"DD\") &&\r\n format.endsWith(\"YYYY\")\r\n ) {\r\n // \uC6D4 \uCC98\uB9AC\r\n if (numbers.length >= 1) {\r\n let monthStr = numbers.slice(0, 2);\r\n if (monthStr.length === 1) {\r\n if (parseInt(monthStr, 10) > 1) {\r\n monthStr = \"0\" + monthStr;\r\n } else {\r\n result += monthStr;\r\n return result;\r\n }\r\n }\r\n month = parseInt(monthStr, 10);\r\n if (month > 12) month = 12;\r\n if (month < 1 && monthStr.length === 2) month = 1;\r\n result += month.toString().padStart(2, \"0\");\r\n }\r\n\r\n // \uC77C \uCC98\uB9AC\r\n if (numbers.length >= 3) {\r\n let dayStr = numbers.slice(2, 4);\r\n if (dayStr.length === 1) {\r\n if (parseInt(dayStr, 10) > 3) {\r\n dayStr = \"0\" + dayStr;\r\n } else {\r\n result += dayStr;\r\n return result;\r\n }\r\n }\r\n let day = parseInt(dayStr, 10);\r\n if (day > 31) day = 31;\r\n if (day < 1 && dayStr.length === 2) day = 1;\r\n result += day.toString().padStart(2, \"0\");\r\n }\r\n\r\n // \uC5F0\uB3C4 \uCC98\uB9AC\r\n if (numbers.length >= 5) {\r\n const yearStr = numbers.slice(4, 8);\r\n if (yearStr.length >= 1) {\r\n const firstDigit = yearStr[0];\r\n if (firstDigit !== \"1\" && firstDigit !== \"2\") {\r\n result += \"2\";\r\n } else {\r\n result += firstDigit;\r\n }\r\n }\r\n if (yearStr.length >= 2) result += yearStr[1];\r\n if (yearStr.length >= 3) result += yearStr[2];\r\n if (yearStr.length >= 4) result += yearStr[3];\r\n }\r\n\r\n return result;\r\n }\r\n\r\n // DD-MM-YYYY, DD.MM.YYYY (\uC720\uB7FD\uC2DD)\r\n if (format.startsWith(\"DD\") && format.endsWith(\"YYYY\")) {\r\n // \uC77C \uCC98\uB9AC\r\n if (numbers.length >= 1) {\r\n let dayStr = numbers.slice(0, 2);\r\n if (dayStr.length === 1) {\r\n if (parseInt(dayStr, 10) > 3) {\r\n dayStr = \"0\" + dayStr;\r\n } else {\r\n result += dayStr;\r\n return result;\r\n }\r\n }\r\n let day = parseInt(dayStr, 10);\r\n if (day > 31) day = 31;\r\n if (day < 1 && dayStr.length === 2) day = 1;\r\n result += day.toString().padStart(2, \"0\");\r\n }\r\n\r\n // \uC6D4 \uCC98\uB9AC\r\n if (numbers.length >= 3) {\r\n let monthStr = numbers.slice(2, 4);\r\n if (monthStr.length === 1) {\r\n if (parseInt(monthStr, 10) > 1) {\r\n monthStr = \"0\" + monthStr;\r\n } else {\r\n result += monthStr;\r\n return result;\r\n }\r\n }\r\n month = parseInt(monthStr, 10);\r\n if (month > 12) month = 12;\r\n if (month < 1 && monthStr.length === 2) month = 1;\r\n result += month.toString().padStart(2, \"0\");\r\n }\r\n\r\n // \uC5F0\uB3C4 \uCC98\uB9AC\r\n if (numbers.length >= 5) {\r\n const yearStr = numbers.slice(4, 8);\r\n if (yearStr.length >= 1) {\r\n const firstDigit = yearStr[0];\r\n if (firstDigit !== \"1\" && firstDigit !== \"2\") {\r\n result += \"2\";\r\n } else {\r\n result += firstDigit;\r\n }\r\n }\r\n if (yearStr.length >= 2) result += yearStr[1];\r\n if (yearStr.length >= 3) result += yearStr[2];\r\n if (yearStr.length >= 4) result += yearStr[3];\r\n }\r\n\r\n return result;\r\n }\r\n\r\n // YY-MM-DD (2\uC790\uB9AC \uC5F0\uB3C4)\r\n if (format.startsWith(\"YY\") && !format.startsWith(\"YYYY\")) {\r\n // \uC5F0\uB3C4 \uCC98\uB9AC (2\uC790\uB9AC)\r\n if (numbers.length >= 1) result += numbers[0];\r\n if (numbers.length >= 2) result += numbers[1];\r\n\r\n // \uC6D4 \uCC98\uB9AC\r\n if (numbers.length >= 3) {\r\n let monthStr = numbers.slice(2, 4);\r\n if (monthStr.length === 1) {\r\n if (parseInt(monthStr, 10) > 1) {\r\n monthStr = \"0\" + monthStr;\r\n } else {\r\n result += monthStr;\r\n return result;\r\n }\r\n }\r\n month = parseInt(monthStr, 10);\r\n if (month > 12) month = 12;\r\n if (month < 1 && monthStr.length === 2) month = 1;\r\n result += month.toString().padStart(2, \"0\");\r\n }\r\n\r\n // \uC77C \uCC98\uB9AC\r\n if (numbers.length >= 5) {\r\n let dayStr = numbers.slice(4, 6);\r\n if (dayStr.length === 1) {\r\n if (parseInt(dayStr, 10) > 3) {\r\n dayStr = \"0\" + dayStr;\r\n } else {\r\n result += dayStr;\r\n return result;\r\n }\r\n }\r\n let day = parseInt(dayStr, 10);\r\n const maxDay =\r\n month > 0\r\n ? getDaysInMonth(new Date().getFullYear(), month)\r\n : 31;\r\n if (day > maxDay) day = maxDay;\r\n if (day < 1 && dayStr.length === 2) day = 1;\r\n result += day.toString().padStart(2, \"0\");\r\n }\r\n\r\n return result;\r\n }\r\n\r\n return numbers;\r\n}\r\n\r\n/**\r\n * \uB0A0\uC9DC \uC790\uB3D9 \uD3EC\uB9F7\uD305 \uD568\uC218 (DateTimeTextField\uC6A9)\r\n */\r\nexport function formatDateValue(value: string, format: DateFormat): string {\r\n const rawNumbers = value.replace(/\\D/g, \"\");\r\n const separator = getSeparator(format);\r\n\r\n if (rawNumbers.length === 0) return \"\";\r\n\r\n const numbers = constrainDateNumbers(rawNumbers, format);\r\n\r\n if (format.startsWith(\"YYYY\")) {\r\n if (numbers.length <= 4) return numbers;\r\n if (numbers.length === 4) return `${numbers}${separator}`;\r\n if (numbers.length <= 6)\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(4)}`;\r\n if (numbers.length === 6)\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(\r\n 4\r\n )}${separator}`;\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(\r\n 4,\r\n 6\r\n )}${separator}${numbers.slice(6, 8)}`;\r\n }\r\n\r\n return numbers;\r\n}\r\n\r\n/**\r\n * \uB0A0\uC9DC \uD3EC\uB9F7\uC744 \uBC11\uC904 placeholder\uB85C \uBCC0\uD658\r\n */\r\nexport function formatToPlaceholder(format: DateFormat): string {\r\n return format\r\n .replace(/YYYY/g, \"Y___\")\r\n .replace(/YY/g, \"__\")\r\n .replace(/MM/g, \"__\")\r\n .replace(/DD/g, \"__\");\r\n}\r\n\r\n/**\r\n * \uD074\uB9AD \uC704\uCE58\uC5D0 \uB530\uB77C \uC120\uD0DD\uD560 \uC601\uC5ED\uC758 \uC2DC\uC791/\uB05D \uC778\uB371\uC2A4 \uBC18\uD658\r\n */\r\nexport function getSegmentRange(\r\n cursorPos: number,\r\n format: DateFormat\r\n): { start: number; end: number } {\r\n if (format === \"MM-DD\" || format === \"MM.DD\" || format === \"MM/DD\") {\r\n if (cursorPos <= 2) return { start: 0, end: 2 };\r\n return { start: 3, end: 5 };\r\n }\r\n\r\n if (format === \"DD-MM\" || format === \"DD.MM\" || format === \"DD/MM\") {\r\n if (cursorPos <= 2) return { start: 0, end: 2 };\r\n return { start: 3, end: 5 };\r\n }\r\n\r\n if (format === \"YYYY-MM\" || format === \"YYYY.MM\" || format === \"YYYY/MM\") {\r\n if (cursorPos <= 4) return { start: 0, end: 4 };\r\n return { start: 5, end: 7 };\r\n }\r\n\r\n if (format === \"YY-MM\" || format === \"YY.MM\" || format === \"YY/MM\") {\r\n if (cursorPos <= 2) return { start: 0, end: 2 };\r\n return { start: 3, end: 5 };\r\n }\r\n\r\n if (format.startsWith(\"YY\") && !format.startsWith(\"YYYY\")) {\r\n if (cursorPos <= 2) return { start: 0, end: 2 };\r\n if (cursorPos <= 5) return { start: 3, end: 5 };\r\n return { start: 6, end: 8 };\r\n }\r\n\r\n if (\r\n format.startsWith(\"MM\") &&\r\n format.includes(\"DD\") &&\r\n format.endsWith(\"YYYY\")\r\n ) {\r\n if (cursorPos <= 2) return { start: 0, end: 2 };\r\n if (cursorPos <= 5) return { start: 3, end: 5 };\r\n return { start: 6, end: 10 };\r\n }\r\n\r\n if (format.startsWith(\"DD\") && format.endsWith(\"YYYY\")) {\r\n if (cursorPos <= 2) return { start: 0, end: 2 };\r\n if (cursorPos <= 5) return { start: 3, end: 5 };\r\n return { start: 6, end: 10 };\r\n }\r\n\r\n if (cursorPos <= 4) return { start: 0, end: 4 };\r\n if (cursorPos <= 7) return { start: 5, end: 7 };\r\n return { start: 8, end: 10 };\r\n}\r\n\r\n/**\r\n * \uD3EC\uB9F7\uC5D0 \uC5F0\uB3C4\uAC00 \uD3EC\uD568\uB418\uC5B4 \uC788\uB294\uC9C0 \uD655\uC778\r\n * - YYYY \uB610\uB294 YY\uAC00 \uD3EC\uD568\uB418\uC5B4 \uC788\uC73C\uBA74 \uC5F0\uB3C4\uAC00 \uC788\uB294 \uD3EC\uB9F7\r\n */\r\nexport function hasYearInFormat(format: DateFormat): boolean {\r\n return format.includes(\"YYYY\") || format.includes(\"YY\");\r\n}\r\n\r\n/**\r\n * \uD3EC\uB9F7\uC774 2\uC790\uB9AC \uC5F0\uB3C4(YY)\uB97C \uC0AC\uC6A9\uD558\uB294\uC9C0 \uD655\uC778\r\n */\r\nexport function has2DigitYear(format: DateFormat): boolean {\r\n return format.includes(\"YY\") && !format.includes(\"YYYY\");\r\n}\r\n\r\n/**\r\n * 2\uC790\uB9AC \uC5F0\uB3C4\uB97C 4\uC790\uB9AC \uC5F0\uB3C4\uB85C \uBCC0\uD658\r\n * - 50 \uC774\uC0C1\uC774\uBA74 1900\uB144\uB300, 50 \uBBF8\uB9CC\uC774\uBA74 2000\uB144\uB300\r\n */\r\nexport function convertYY2YYYY(yy: number): number {\r\n return yy >= 50 ? 1900 + yy : 2000 + yy;\r\n}\r\n\r\n/**\r\n * \uD3EC\uB9F7\uC5D0\uC11C \uB0A0\uC9DC \uD30C\uC2F1 (\uC5F0\uB3C4 \uC5C6\uB294 \uD3EC\uB9F7 \uC9C0\uC6D0, internalYear \uD65C\uC6A9)\r\n */\r\nexport function parseDateWithInternalYear(\r\n formattedValue: string,\r\n format: DateFormat,\r\n internalYear?: number | null\r\n): { year: number; month: number; day: number } | null {\r\n const numbers = formattedValue.replace(/\\D/g, \"\");\r\n const completeLength = getCompleteLength(format);\r\n\r\n if (numbers.length !== completeLength) return null;\r\n\r\n let year: number, month: number, day: number;\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\r\n if (!hasYearInFormat(format)) {\r\n year = internalYear || new Date().getFullYear();\r\n if (format.startsWith(\"MM\")) {\r\n month = parseInt(numbers.slice(0, 2), 10);\r\n day = parseInt(numbers.slice(2, 4), 10);\r\n } else {\r\n day = parseInt(numbers.slice(0, 2), 10);\r\n month = parseInt(numbers.slice(2, 4), 10);\r\n }\r\n } else if (has2DigitYear(format)) {\r\n // 2\uC790\uB9AC \uC5F0\uB3C4 \uD3EC\uB9F7\r\n const yy = parseInt(numbers.slice(0, 2), 10);\r\n year = convertYY2YYYY(yy);\r\n month = parseInt(numbers.slice(2, 4), 10);\r\n day = numbers.length >= 6 ? parseInt(numbers.slice(4, 6), 10) : 1;\r\n } else if (format.startsWith(\"YYYY\")) {\r\n year = parseInt(numbers.slice(0, 4), 10);\r\n month = parseInt(numbers.slice(4, 6), 10);\r\n day = numbers.length >= 8 ? parseInt(numbers.slice(6, 8), 10) : 1;\r\n } else if (format.startsWith(\"MM\") && format.endsWith(\"YYYY\")) {\r\n month = parseInt(numbers.slice(0, 2), 10);\r\n day = parseInt(numbers.slice(2, 4), 10);\r\n year = parseInt(numbers.slice(4, 8), 10);\r\n } else if (format.startsWith(\"DD\") && format.endsWith(\"YYYY\")) {\r\n day = parseInt(numbers.slice(0, 2), 10);\r\n month = parseInt(numbers.slice(2, 4), 10);\r\n year = parseInt(numbers.slice(4, 8), 10);\r\n } else {\r\n // \uAE30\uBCF8: YYYY-MM-DD\r\n year = parseInt(numbers.slice(0, 4), 10);\r\n month = parseInt(numbers.slice(4, 6), 10);\r\n day = numbers.length >= 8 ? parseInt(numbers.slice(6, 8), 10) : 1;\r\n }\r\n\r\n if (month < 1 || month > 12 || day < 1 || day > 31) return null;\r\n\r\n return { year, month, day };\r\n}\r\n\r\n/**\r\n * \uB2EC\uB825 \uC120\uD0DD \uB610\uB294 \uC785\uB825\uAC12\uC744 \uCD9C\uB825\uC6A9 \uBB38\uC790\uC5F4\uB85C \uBCC0\uD658 (\uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC774\uC5B4\uB3C4 \uC5F0\uB3C4 \uD3EC\uD568)\r\n * @param formattedValue - \uD3EC\uB9F7\uB41C \uB0A0\uC9DC \uBB38\uC790\uC5F4 (\uC608: \"12-25\")\r\n * @param format - \uB0A0\uC9DC \uD3EC\uB9F7\r\n * @param separator - \uCD9C\uB825 \uAD6C\uBD84\uC790\r\n * @param internalYear - \uB0B4\uBD80\uC801\uC73C\uB85C \uAD00\uB9AC\uD558\uB294 \uC5F0\uB3C4 (\uC5F0\uB3C4 \uC5C6\uB294 \uD3EC\uB9F7\uC6A9)\r\n * @returns \uCD9C\uB825\uC6A9 \uB0A0\uC9DC \uBB38\uC790\uC5F4 (\uD56D\uC0C1 \uC5F0\uB3C4 \uD3EC\uD568, \uC608: \"2024-12-25\")\r\n */\r\nexport function buildDateOutputValue(\r\n formattedValue: string,\r\n format: DateFormat,\r\n separator: string,\r\n internalYear?: number | null\r\n): string {\r\n const formatSeparator = getSeparator(format);\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC788\uB294 \uD3EC\uB9F7: \uAD6C\uBD84\uC790\uB9CC \uBCC0\uD658\r\n if (hasYearInFormat(format)) {\r\n return formattedValue.replace(\r\n new RegExp(`\\\\${formatSeparator}`, \"g\"),\r\n separator\r\n );\r\n }\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7: \uC5F0\uB3C4 \uCD94\uAC00\uD558\uC5EC YYYY-MM-DD \uD615\uC2DD\uC73C\uB85C \uCD9C\uB825\r\n const numbers = formattedValue.replace(/\\D/g, \"\");\r\n const completeLength = getCompleteLength(format);\r\n\r\n if (numbers.length !== completeLength) {\r\n // \uC644\uC131\uB418\uC9C0 \uC54A\uC740 \uACBD\uC6B0 \uAD6C\uBD84\uC790\uB9CC \uBCC0\uD658\r\n return formattedValue.replace(\r\n new RegExp(`\\\\${formatSeparator}`, \"g\"),\r\n separator\r\n );\r\n }\r\n\r\n const yearToUse = internalYear || new Date().getFullYear();\r\n let month: string, day: string;\r\n\r\n if (format.startsWith(\"MM\")) {\r\n month = numbers.slice(0, 2);\r\n day = numbers.slice(2, 4);\r\n } else {\r\n day = numbers.slice(0, 2);\r\n month = numbers.slice(2, 4);\r\n }\r\n\r\n return `${yearToUse}${separator}${month}${separator}${day}`;\r\n}\r\n\r\n/**\r\n * Date \uAC1D\uCCB4\uC5D0\uC11C \uD3EC\uB9F7\uC5D0 \uB9DE\uB294 \uC22B\uC790 \uBB38\uC790\uC5F4 \uC0DD\uC131\r\n */\r\nexport function dateToNumbers(date: Date, format: DateFormat): string {\r\n const year = String(date.getFullYear());\r\n const year2 = year.slice(-2);\r\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\r\n const day = String(date.getDate()).padStart(2, \"0\");\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\r\n if (!hasYearInFormat(format)) {\r\n return format.startsWith(\"MM\") ? `${month}${day}` : `${day}${month}`;\r\n }\r\n\r\n // YYYY-MM, YY-MM (\uB144\uC6D4\uB9CC)\r\n if (!format.includes(\"DD\")) {\r\n return has2DigitYear(format) ? `${year2}${month}` : `${year}${month}`;\r\n }\r\n\r\n // 2\uC790\uB9AC \uC5F0\uB3C4\r\n if (has2DigitYear(format)) {\r\n return `${year2}${month}${day}`;\r\n }\r\n\r\n // DD-MM-YYYY (\uC720\uB7FD\uC2DD)\r\n if (format.startsWith(\"DD\") && format.endsWith(\"YYYY\")) {\r\n return `${day}${month}${year}`;\r\n }\r\n\r\n // MM-DD-YYYY (\uBBF8\uAD6D\uC2DD)\r\n if (\r\n format.startsWith(\"MM\") &&\r\n format.includes(\"DD\") &&\r\n format.endsWith(\"YYYY\")\r\n ) {\r\n return `${month}${day}${year}`;\r\n }\r\n\r\n // \uAE30\uBCF8: YYYY-MM-DD\r\n return `${year}${month}${day}`;\r\n}\r\n", "/**\r\n * time.ts - \uC2DC\uAC04 \uAD00\uB828 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport type { TimeFormat } from \"../types\";\r\n\r\n/**\r\n * \uD3EC\uB9F7\uC5D0 \uB530\uB978 \uD544\uB4DC \uAC1C\uC218 (2: \uC2DC:\uBD84, 3: \uC2DC:\uBD84:\uCD08)\r\n */\r\nexport function getTimeFieldCount(format: TimeFormat): number {\r\n if (format === \"HH:mm:ss\" || format === \"hh:mm:ss\") {\r\n return 3;\r\n }\r\n return 2;\r\n}\r\n\r\n/**\r\n * 12\uC2DC\uAC04 \uD615\uC2DD\uC778\uC9C0 \uD655\uC778\r\n */\r\nexport function is12HourFormat(format: string): boolean {\r\n return format.includes(\"hh:\");\r\n}\r\n\r\n/**\r\n * \uC2DC\uAC04 \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n * @param formatOrIs12Hour - TimeFormat \uBB38\uC790\uC5F4 \uB610\uB294 12\uC2DC\uAC04\uC81C \uC5EC\uBD80 boolean\r\n */\r\nexport function validateTime(\r\n hour: string,\r\n minute: string,\r\n second: string,\r\n formatOrIs12Hour: TimeFormat | boolean,\r\n minTime?: string,\r\n maxTime?: string\r\n): boolean {\r\n const is12Hour = typeof formatOrIs12Hour === \"boolean\" ? formatOrIs12Hour : is12HourFormat(formatOrIs12Hour);\r\n const h = parseInt(hour, 10);\r\n const m = parseInt(minute, 10);\r\n const s = second ? parseInt(second, 10) : 0;\r\n\r\n if (isNaN(h) || isNaN(m) || (second && isNaN(s))) return false;\r\n\r\n if (is12Hour) {\r\n if (h < 0 || h > 12) return false;\r\n } else {\r\n if (h < 0 || h > 23) return false;\r\n }\r\n\r\n if (m < 0 || m > 59) return false;\r\n if (s < 0 || s > 59) return false;\r\n\r\n if (minTime || maxTime) {\r\n const timeValue = h * 3600 + m * 60 + s;\r\n\r\n if (minTime) {\r\n const minParts = minTime.split(\":\");\r\n const minH = parseInt(minParts[0], 10) || 0;\r\n const minM = parseInt(minParts[1], 10) || 0;\r\n const minS = parseInt(minParts[2], 10) || 0;\r\n const minValue = minH * 3600 + minM * 60 + minS;\r\n if (timeValue < minValue) return false;\r\n }\r\n\r\n if (maxTime) {\r\n const maxParts = maxTime.split(\":\");\r\n const maxH = parseInt(maxParts[0], 10) || 0;\r\n const maxM = parseInt(maxParts[1], 10) || 0;\r\n const maxS = parseInt(maxParts[2], 10) || 0;\r\n const maxValue = maxH * 3600 + maxM * 60 + maxS;\r\n if (timeValue > maxValue) return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * \uC2DC\uAC04 \uAC12 \uC81C\uD55C (\uC2DC/\uBD84/\uCD08)\r\n * - 24\uC2DC\uAC04 \uD615\uC2DD\uC5D0\uC11C 24 \uC774\uC0C1\uC744 \uC785\uB825\uD558\uBA74 24\uB97C \uBE7C\uC11C \uBCC0\uD658 (24\u219200, 25\u219201, 26\u219202, ...)\r\n * - \uCCAB \uC790\uB9AC\uAC00 \uBC94\uC704 \uCD08\uACFC \uC2DC \uC55E\uC5D0 0\uC744 \uBD99\uC5EC\uC11C \uB450 \uC790\uB9AC\uB85C \uBCC0\uD658\r\n */\r\nexport function clampTimeValue(value: string, type: \"hour\" | \"minute\" | \"second\", is12Hour: boolean = false): string {\r\n if (value.length === 0) return value;\r\n\r\n if (value.length === 1) {\r\n const digit = parseInt(value, 10);\r\n if (type === \"hour\") {\r\n const maxFirstDigit = is12Hour ? 1 : 2;\r\n // \uCCAB \uC790\uB9AC\uAC00 \uBC94\uC704 \uCD08\uACFC\uD558\uBA74 \uC55E\uC5D0 0\uC744 \uBD99\uC5EC\uC11C \uB450 \uC790\uB9AC\uB85C \uB9CC\uB4E6\r\n if (digit > maxFirstDigit) return `0${digit}`;\r\n } else {\r\n // \uBD84/\uCD08: \uCCAB \uC790\uB9AC\uAC00 6-9\uBA74 \uC55E\uC5D0 0 \uBD99\uC784\r\n if (digit > 5) return `0${digit}`;\r\n }\r\n return value;\r\n }\r\n\r\n const num = parseInt(value, 10);\r\n if (isNaN(num)) return value;\r\n\r\n if (type === \"hour\") {\r\n // 24\uC2DC\uAC04 \uD615\uC2DD\uC5D0\uC11C 24 \uC774\uC0C1\uC744 \uC785\uB825\uD558\uBA74 24\uB97C \uBE7C\uC11C \uBCC0\uD658\r\n if (!is12Hour && num >= 24) {\r\n return String(num - 24).padStart(2, \"0\");\r\n }\r\n const maxHour = is12Hour ? 12 : 23;\r\n if (num > maxHour) return String(maxHour).padStart(2, \"0\");\r\n } else {\r\n if (num > 59) return \"59\";\r\n }\r\n return value;\r\n}\r\n", "/**\r\n * number.ts - \uC22B\uC790 \uD3EC\uB9F7\uD305 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\n/**\r\n * \uC22B\uC790 \uD3EC\uB9F7\uD305 \uD568\uC218\r\n */\r\nexport function formatNumber(value: string, thousandSeparator: boolean, decimalLength?: number): string {\r\n if (!value) return \"\";\r\n\r\n // \uB9C8\uC774\uB108\uC2A4\uB9CC \uC788\uB294 \uACBD\uC6B0 \uADF8\uB300\uB85C \uBC18\uD658\r\n if (value === \"-\") return \"-\";\r\n\r\n // \uC22B\uC790, \uC18C\uC218\uC810, \uB9C8\uC774\uB108\uC2A4\uB9CC \uD5C8\uC6A9\r\n let cleaned = value.replace(/[^\\d.-]/g, \"\");\r\n\r\n // \uB9C8\uC774\uB108\uC2A4\uB294 \uB9E8 \uC55E\uC5D0\uB9CC \uD5C8\uC6A9\r\n const isNegative = cleaned.startsWith(\"-\");\r\n cleaned = cleaned.replace(/-/g, \"\");\r\n\r\n // \uC18C\uC218\uC810 \uCC98\uB9AC\r\n const parts = cleaned.split(\".\");\r\n let integerPart = parts[0] || \"\";\r\n let decimalPart = parts.length > 1 ? parts[1] : \"\";\r\n\r\n // \uC18C\uC218\uC810 \uAE38\uC774 \uC81C\uD55C\r\n if (decimalLength !== undefined && decimalPart.length > decimalLength) {\r\n decimalPart = decimalPart.slice(0, decimalLength);\r\n }\r\n\r\n // \uCC9C \uB2E8\uC704 \uAD6C\uBD84\uC790 \uCD94\uAC00\r\n if (thousandSeparator && integerPart) {\r\n integerPart = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\r\n }\r\n\r\n // \uACB0\uACFC \uC870\uD569\r\n let result = integerPart;\r\n if (parts.length > 1 || value.endsWith(\".\")) {\r\n result += \".\" + decimalPart;\r\n }\r\n if (isNegative && result) {\r\n result = \"-\" + result;\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * \uD45C\uC2DC \uAC12\uC5D0\uC11C \uC2E4\uC81C \uC22B\uC790 \uAC12 \uCD94\uCD9C\r\n */\r\nexport function parseNumber(displayValue: string): string {\r\n return displayValue.replace(/,/g, \"\");\r\n}\r\n", "/**\r\n * email.ts - \uC774\uBA54\uC77C \uAD00\uB828 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\n/**\r\n * \uAE30\uBCF8 \uB3C4\uBA54\uC778 \uC81C\uC548 \uBAA9\uB85D\r\n */\r\nexport const DEFAULT_EMAIL_DOMAINS = [\r\n \"gmail.com\",\r\n \"naver.com\",\r\n \"daum.net\",\r\n \"hanmail.net\",\r\n \"kakao.com\",\r\n \"nate.com\",\r\n \"hotmail.com\",\r\n \"outlook.com\",\r\n \"yahoo.com\",\r\n \"icloud.com\",\r\n];\r\n\r\n/**\r\n * \uC774\uBA54\uC77C \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n */\r\nexport function validateEmail(email: string): boolean {\r\n if (!email) return false;\r\n // RFC 5322 \uAE30\uBC18 \uAC04\uC18C\uD654\uB41C \uC774\uBA54\uC77C \uC815\uADDC\uC2DD\r\n const emailRegex =\r\n /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;\r\n return emailRegex.test(email);\r\n}\r\n", "/**\r\n * phone.ts - \uC804\uD654\uBC88\uD638 \uAD00\uB828 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport type { PhoneFormat } from \"../types\";\r\n\r\n/**\r\n * \uC804\uD654\uBC88\uD638 \uC790\uB3D9 \uD3EC\uB9F7\uD305 \uD568\uC218\r\n * \uC785\uB825\uB41C \uBC88\uD638\uB97C \uBCF4\uACE0 \uC790\uB3D9\uC73C\uB85C \uD3EC\uB9F7 \uD310\uB2E8\r\n */\r\nexport function formatPhoneNumber(value: string, customFormat?: PhoneFormat): string {\r\n const numbers = value.replace(/\\D/g, \"\");\r\n\r\n if (numbers.length === 0) return \"\";\r\n\r\n // prefix\uC640 \uD568\uAED8 \uC0AC\uC6A9\uB418\uB294 \uCEE4\uC2A4\uD140 \uD3EC\uB9F7 (010-000-0000: 3-3-4)\r\n if (customFormat === \"010-000-0000\") {\r\n if (numbers.length < 3) return numbers;\r\n if (numbers.length === 3) return `${numbers}-`;\r\n if (numbers.length < 6) return `${numbers.slice(0, 3)}-${numbers.slice(3)}`;\r\n if (numbers.length === 6) return `${numbers.slice(0, 3)}-${numbers.slice(3, 6)}-`;\r\n return `${numbers.slice(0, 3)}-${numbers.slice(3, 6)}-${numbers.slice(6, 10)}`;\r\n }\r\n\r\n // prefix\uC640 \uD568\uAED8 \uC0AC\uC6A9\uB418\uB294 \uCEE4\uC2A4\uD140 \uD3EC\uB9F7 (010-0000-0000: 3-4-4)\r\n if (customFormat === \"010-0000-0000\") {\r\n if (numbers.length < 3) return numbers;\r\n if (numbers.length === 3) return `${numbers}-`;\r\n if (numbers.length < 7) return `${numbers.slice(0, 3)}-${numbers.slice(3)}`;\r\n if (numbers.length === 7) return `${numbers.slice(0, 3)}-${numbers.slice(3, 7)}-`;\r\n return `${numbers.slice(0, 3)}-${numbers.slice(3, 7)}-${numbers.slice(7, 11)}`;\r\n }\r\n\r\n // \uC804\uAD6D\uB300\uD45C\uBC88\uD638 (1588, 1577, 1544, 1600, 1800 \uB4F1)\r\n if (/^1[0-9]{3}/.test(numbers)) {\r\n if (numbers.length <= 4) return numbers;\r\n if (numbers.length === 4) return `${numbers}-`;\r\n return `${numbers.slice(0, 4)}-${numbers.slice(4, 8)}`;\r\n }\r\n\r\n // \uC11C\uC6B8 \uC9C0\uC5ED\uBC88\uD638 (02)\r\n if (numbers.startsWith(\"02\")) {\r\n if (numbers.length < 2) return numbers;\r\n if (numbers.length === 2) return `${numbers}-`;\r\n // 9\uC790\uB9AC \uC774\uD558: 02-000-0000 (2-3-4)\r\n if (numbers.length <= 9) {\r\n if (numbers.length < 5) return `${numbers.slice(0, 2)}-${numbers.slice(2)}`;\r\n if (numbers.length === 5) return `${numbers.slice(0, 2)}-${numbers.slice(2, 5)}-`;\r\n return `${numbers.slice(0, 2)}-${numbers.slice(2, 5)}-${numbers.slice(5, 9)}`;\r\n }\r\n // 10\uC790\uB9AC: 02-0000-0000 (2-4-4)\r\n return `${numbers.slice(0, 2)}-${numbers.slice(2, 6)}-${numbers.slice(6, 10)}`;\r\n }\r\n\r\n // \uD734\uB300\uD3F0 (010, 011, 016, 017, 018, 019) \uB610\uB294 \uC9C0\uC5ED\uBC88\uD638 (031, 032, 033 \uB4F1)\r\n if (numbers.length < 3) return numbers;\r\n if (numbers.length === 3) return `${numbers}-`;\r\n\r\n // 10\uC790\uB9AC: 000-000-0000 (3-3-4)\r\n if (numbers.length <= 10) {\r\n if (numbers.length < 6) return `${numbers.slice(0, 3)}-${numbers.slice(3)}`;\r\n if (numbers.length === 6) return `${numbers.slice(0, 3)}-${numbers.slice(3, 6)}-`;\r\n return `${numbers.slice(0, 3)}-${numbers.slice(3, 6)}-${numbers.slice(6, 10)}`;\r\n }\r\n\r\n // 11\uC790\uB9AC: 000-0000-0000 (3-4-4)\r\n return `${numbers.slice(0, 3)}-${numbers.slice(3, 7)}-${numbers.slice(7, 11)}`;\r\n}\r\n\r\n/**\r\n * \uC785\uB825\uB41C \uBC88\uD638\uC5D0 \uB530\uB978 \uCD5C\uB300 \uAE38\uC774 \uACC4\uC0B0\r\n */\r\nexport function getPhoneMaxLength(numbers: string): number {\r\n // \uC804\uAD6D\uB300\uD45C\uBC88\uD638\r\n if (/^1[0-9]{0,3}/.test(numbers)) {\r\n return 9; // 1588-1234\r\n }\r\n // \uC11C\uC6B8\r\n if (numbers.startsWith(\"02\")) {\r\n return 12; // 02-1234-5678\r\n }\r\n // \uD734\uB300\uD3F0/\uC9C0\uC5ED\uBC88\uD638\r\n return 13; // 010-1234-5678\r\n}\r\n", "/**\r\n * password.ts - \uBE44\uBC00\uBC88\uD638 \uAD00\uB828 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport type { PasswordValidationRules, PasswordValidationResult } from \"../types\";\r\n\r\nexport const DEFAULT_SPECIAL_CHARS = \"!@#$%^&*()_+-=[]{}|;:,.<>?\";\r\n\r\n/**\r\n * \uAE30\uBCF8 \uC720\uD6A8\uC131 \uAC80\uC0AC \uADDC\uCE59\r\n */\r\nexport const DEFAULT_PASSWORD_VALIDATION_RULES: PasswordValidationRules = {\r\n minLength: 8,\r\n maxLength: 20,\r\n requireLowercase: true,\r\n requireNumber: true,\r\n};\r\n\r\n/**\r\n * \uBE44\uBC00\uBC88\uD638 \uC720\uD6A8\uC131 \uAC80\uC0AC \uD568\uC218\r\n */\r\nexport function validatePassword(value: string, rules: PasswordValidationRules): PasswordValidationResult {\r\n // \uAE30\uBCF8\uAC12\uACFC \uBCD1\uD569\r\n const mergedRules = { ...DEFAULT_PASSWORD_VALIDATION_RULES, ...rules };\r\n const errors: PasswordValidationResult[\"errors\"] = {};\r\n\r\n if (mergedRules.minLength !== undefined && value.length < mergedRules.minLength) {\r\n errors.minLength = true;\r\n }\r\n\r\n if (mergedRules.maxLength !== undefined && value.length > mergedRules.maxLength) {\r\n errors.maxLength = true;\r\n }\r\n\r\n if (mergedRules.requireUppercase && !/[A-Z]/.test(value)) {\r\n errors.requireUppercase = true;\r\n }\r\n\r\n if (mergedRules.requireLowercase && !/[a-z]/.test(value)) {\r\n errors.requireLowercase = true;\r\n }\r\n\r\n if (mergedRules.requireNumber && !/[0-9]/.test(value)) {\r\n errors.requireNumber = true;\r\n }\r\n\r\n if (mergedRules.requireSpecialChar) {\r\n const specialChars = mergedRules.specialChars || DEFAULT_SPECIAL_CHARS;\r\n const escapedChars = specialChars.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, \"\\\\$&\");\r\n const regex = new RegExp(`[${escapedChars}]`);\r\n if (!regex.test(value)) {\r\n errors.requireSpecialChar = true;\r\n }\r\n }\r\n\r\n return {\r\n isValid: Object.keys(errors).length === 0,\r\n errors,\r\n };\r\n}\r\n", "/**\r\n * biznum.ts - \uC0AC\uC5C5\uC790\uBC88\uD638 \uAD00\uB828 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\n/**\r\n * \uC0AC\uC5C5\uC790\uBC88\uD638 \uC720\uD6A8\uC131 \uAC80\uC0AC (\uAC80\uC99D \uC54C\uACE0\uB9AC\uC998)\r\n * \uC0AC\uC5C5\uC790\uB4F1\uB85D\uBC88\uD638\uB294 10\uC790\uB9AC \uC22B\uC790\uC774\uBA70, \uB9C8\uC9C0\uB9C9 \uC790\uB9AC\uAC00 \uAC80\uC99D\uBC88\uD638\uC785\uB2C8\uB2E4.\r\n */\r\nexport function validateBusinessNumber(value: string): boolean {\r\n const numbers = value.replace(/\\D/g, \"\");\r\n\r\n if (numbers.length !== 10) {\r\n return false;\r\n }\r\n\r\n // \uC0AC\uC5C5\uC790\uB4F1\uB85D\uBC88\uD638 \uAC80\uC99D \uC54C\uACE0\uB9AC\uC998\r\n const checkKey = [1, 3, 7, 1, 3, 7, 1, 3, 5];\r\n let sum = 0;\r\n\r\n for (let i = 0; i < 9; i++) {\r\n sum += parseInt(numbers[i], 10) * checkKey[i];\r\n }\r\n\r\n // 8\uBC88\uC9F8 \uC790\uB9AC * 5 \uC758 \uC2ED\uC758 \uC790\uB9AC \uCD94\uAC00\r\n sum += Math.floor((parseInt(numbers[8], 10) * 5) / 10);\r\n\r\n // \uAC80\uC99D\uBC88\uD638 \uACC4\uC0B0\r\n const checkNum = (10 - (sum % 10)) % 10;\r\n\r\n return checkNum === parseInt(numbers[9], 10);\r\n}\r\n", "/**\r\n * card.ts - \uCE74\uB4DC\uBC88\uD638 \uAD00\uB828 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\n/** \uCE74\uB4DC \uBE0C\uB79C\uB4DC \uD0C0\uC785 */\r\nexport type CardBrand = \"visa\" | \"mastercard\" | \"amex\" | \"jcb\" | \"diners\" | \"discover\" | \"unionpay\" | \"bc\" | null;\r\n\r\n/**\r\n * \uCE74\uB4DC\uBC88\uD638 \uC720\uD6A8\uC131 \uAC80\uC0AC (Luhn \uC54C\uACE0\uB9AC\uC998)\r\n */\r\nexport function validateCardNumber(value: string): boolean {\r\n const numbers = value.replace(/\\D/g, \"\");\r\n\r\n if (numbers.length !== 16) {\r\n return false;\r\n }\r\n\r\n // Luhn \uC54C\uACE0\uB9AC\uC998\r\n let sum = 0;\r\n let isEven = false;\r\n\r\n for (let i = numbers.length - 1; i >= 0; i--) {\r\n let digit = parseInt(numbers[i], 10);\r\n\r\n if (isEven) {\r\n digit *= 2;\r\n if (digit > 9) {\r\n digit -= 9;\r\n }\r\n }\r\n\r\n sum += digit;\r\n isEven = !isEven;\r\n }\r\n\r\n return sum % 10 === 0;\r\n}\r\n\r\n/**\r\n * \uCE74\uB4DC \uBE0C\uB79C\uB4DC \uAC10\uC9C0 (\uAD6D\uC81C \uBE0C\uB79C\uB4DC \uAE30\uC900)\r\n */\r\nexport function detectCardBrand(value: string): CardBrand {\r\n const numbers = value.replace(/\\D/g, \"\");\r\n\r\n if (!numbers) return null;\r\n\r\n // Visa: 4\uB85C \uC2DC\uC791\r\n if (/^4/.test(numbers)) return \"visa\";\r\n\r\n // Mastercard: 51-55 \uB610\uB294 2221-2720\r\n if (/^5[1-5]/.test(numbers) || /^2(2[2-9]|[3-6]\\d|7[01]|720)/.test(numbers)) return \"mastercard\";\r\n\r\n // AMEX: 34, 37\r\n if (/^3[47]/.test(numbers)) return \"amex\";\r\n\r\n // JCB: 3528-3589\r\n if (/^35(2[89]|[3-8]\\d)/.test(numbers)) return \"jcb\";\r\n\r\n // Diners Club: 36, 38, 300-305, 309\r\n if (/^3(6|8|0[0-59])/.test(numbers)) return \"diners\";\r\n\r\n // Discover: 6011, 622126-622925, 644-649, 65\r\n if (/^(6011|65|64[4-9]|622(1[2-9][6-9]|[2-8]\\d\\d|9[01]\\d|92[0-5]))/.test(numbers)) return \"discover\";\r\n\r\n // UnionPay (\uC911\uAD6D\uC740\uB828): 62\uB85C \uC2DC\uC791 (Discover\uC640 \uACB9\uCE58\uC9C0 \uC54A\uB294 \uBC94\uC704)\r\n if (/^62(?!(2(1[2-9][6-9]|[2-8]\\d\\d|9[01]\\d|92[0-5])))/.test(numbers)) return \"unionpay\";\r\n\r\n // BC\uCE74\uB4DC: 94\uB85C \uC2DC\uC791\r\n if (/^94/.test(numbers)) return \"bc\";\r\n\r\n return null;\r\n}\r\n", "/**\r\n * jumin.ts - \uC8FC\uBBFC\uB4F1\uB85D\uBC88\uD638 \uAD00\uB828 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport type { JuminInfo } from \"../types\";\r\n\r\n/**\r\n * \uC8FC\uBBFC\uBC88\uD638 \uB4B7\uC790\uB9AC 2~3\uBC88\uC9F8 \uC22B\uC790\uB85C \uC9C0\uC5ED \uCD94\uCD9C\r\n * (2020\uB144 10\uC6D4 \uC774\uD6C4 \uCD9C\uC0DD\uC790\uB294 \uB79C\uB364 \uBD80\uC5EC\uB85C \uC758\uBBF8 \uC5C6\uC74C)\r\n */\r\nexport const REGION_MAP: Record<string, string> = {\r\n \"0\": \"\uC11C\uC6B8\",\r\n \"1\": \"\uC11C\uC6B8\",\r\n \"2\": \"\uC11C\uC6B8\",\r\n \"3\": \"\uC11C\uC6B8\",\r\n \"4\": \"\uC11C\uC6B8\",\r\n \"5\": \"\uC11C\uC6B8\",\r\n \"6\": \"\uC11C\uC6B8\",\r\n \"7\": \"\uC11C\uC6B8\",\r\n \"8\": \"\uC11C\uC6B8\",\r\n \"9\": \"\uBD80\uC0B0\",\r\n \"10\": \"\uBD80\uC0B0\",\r\n \"11\": \"\uBD80\uC0B0\",\r\n \"12\": \"\uBD80\uC0B0\",\r\n \"13\": \"\uC778\uCC9C\",\r\n \"14\": \"\uC778\uCC9C\",\r\n \"15\": \"\uC778\uCC9C\",\r\n \"16\": \"\uACBD\uAE30\",\r\n \"17\": \"\uACBD\uAE30\",\r\n \"18\": \"\uACBD\uAE30\",\r\n \"19\": \"\uACBD\uAE30\",\r\n \"20\": \"\uACBD\uAE30\",\r\n \"21\": \"\uACBD\uAE30\",\r\n \"22\": \"\uACBD\uAE30\",\r\n \"23\": \"\uACBD\uAE30\",\r\n \"24\": \"\uACBD\uAE30\",\r\n \"25\": \"\uACBD\uAE30\",\r\n \"26\": \"\uAC15\uC6D0\",\r\n \"27\": \"\uAC15\uC6D0\",\r\n \"28\": \"\uAC15\uC6D0\",\r\n \"29\": \"\uAC15\uC6D0\",\r\n \"30\": \"\uAC15\uC6D0\",\r\n \"31\": \"\uAC15\uC6D0\",\r\n \"32\": \"\uAC15\uC6D0\",\r\n \"33\": \"\uAC15\uC6D0\",\r\n \"34\": \"\uAC15\uC6D0\",\r\n \"35\": \"\uCDA9\uBD81\",\r\n \"36\": \"\uCDA9\uBD81\",\r\n \"37\": \"\uCDA9\uBD81\",\r\n \"38\": \"\uCDA9\uBD81\",\r\n \"39\": \"\uCDA9\uB0A8\",\r\n \"40\": \"\uCDA9\uB0A8\",\r\n \"41\": \"\uB300\uC804\",\r\n \"42\": \"\uCDA9\uB0A8\",\r\n \"43\": \"\uCDA9\uB0A8\",\r\n \"44\": \"\uCDA9\uB0A8\",\r\n \"45\": \"\uCDA9\uB0A8\",\r\n \"46\": \"\uCDA9\uB0A8\",\r\n \"47\": \"\uCDA9\uB0A8\",\r\n \"48\": \"\uC804\uBD81\",\r\n \"49\": \"\uC804\uBD81\",\r\n \"50\": \"\uC804\uBD81\",\r\n \"51\": \"\uC804\uBD81\",\r\n \"52\": \"\uC804\uBD81\",\r\n \"53\": \"\uC804\uBD81\",\r\n \"54\": \"\uC804\uB0A8\",\r\n \"55\": \"\uC804\uB0A8\",\r\n \"56\": \"\uAD11\uC8FC\",\r\n \"57\": \"\uC804\uB0A8\",\r\n \"58\": \"\uC804\uB0A8\",\r\n \"59\": \"\uC804\uB0A8\",\r\n \"60\": \"\uC804\uB0A8\",\r\n \"61\": \"\uC804\uB0A8\",\r\n \"62\": \"\uC804\uB0A8\",\r\n \"63\": \"\uC804\uB0A8\",\r\n \"64\": \"\uC804\uB0A8\",\r\n \"65\": \"\uACBD\uBD81\",\r\n \"66\": \"\uACBD\uBD81\",\r\n \"67\": \"\uACBD\uBD81\",\r\n \"68\": \"\uACBD\uBD81\",\r\n \"69\": \"\uACBD\uBD81\",\r\n \"70\": \"\uACBD\uBD81\",\r\n \"71\": \"\uACBD\uBD81\",\r\n \"72\": \"\uACBD\uBD81\",\r\n \"73\": \"\uACBD\uBD81\",\r\n \"74\": \"\uACBD\uBD81\",\r\n \"75\": \"\uACBD\uBD81\",\r\n \"76\": \"\uB300\uAD6C\",\r\n \"77\": \"\uB300\uAD6C\",\r\n \"78\": \"\uB300\uAD6C\",\r\n \"79\": \"\uACBD\uB0A8\",\r\n \"80\": \"\uACBD\uB0A8\",\r\n \"81\": \"\uACBD\uB0A8\",\r\n \"82\": \"\uACBD\uB0A8\",\r\n \"83\": \"\uC6B8\uC0B0\",\r\n \"84\": \"\uACBD\uB0A8\",\r\n \"85\": \"\uACBD\uB0A8\",\r\n \"86\": \"\uACBD\uB0A8\",\r\n \"87\": \"\uACBD\uB0A8\",\r\n \"88\": \"\uACBD\uB0A8\",\r\n \"89\": \"\uACBD\uB0A8\",\r\n \"90\": \"\uACBD\uB0A8\",\r\n \"91\": \"\uC81C\uC8FC\",\r\n \"92\": \"\uC81C\uC8FC\",\r\n \"93\": \"\uC138\uC885\",\r\n};\r\n\r\n/**\r\n * \uC8FC\uBBFC\uBC88\uD638\uC5D0\uC11C \uC815\uBCF4 \uCD94\uCD9C\r\n */\r\nexport function extractJuminInfo(value: string): Omit<JuminInfo, \"isValid\"> {\r\n const numbers = value.replace(/\\D/g, \"\");\r\n\r\n const result: Omit<JuminInfo, \"isValid\"> = {\r\n value: numbers,\r\n birthDate: null,\r\n gender: null,\r\n isForeigner: null,\r\n region: null,\r\n };\r\n\r\n if (numbers.length < 7) {\r\n return result;\r\n }\r\n\r\n // \uB4B7\uC790\uB9AC \uCCAB \uBC88\uC9F8 \uC22B\uC790 (\uC131\uBCC4/\uC138\uAE30/\uC678\uAD6D\uC778 \uAD6C\uBD84)\r\n const genderCode = numbers[6];\r\n\r\n // \uC131\uBCC4 \uBC0F \uC678\uAD6D\uC778 \uC5EC\uBD80 \uD310\uB2E8\r\n // 1, 2: 1900\uB144\uB300 \uB0B4\uAD6D\uC778 (\uB0A8/\uC5EC)\r\n // 3, 4: 2000\uB144\uB300 \uB0B4\uAD6D\uC778 (\uB0A8/\uC5EC)\r\n // 5, 6: 1900\uB144\uB300 \uC678\uAD6D\uC778 (\uB0A8/\uC5EC)\r\n // 7, 8: 2000\uB144\uB300 \uC678\uAD6D\uC778 (\uB0A8/\uC5EC)\r\n // 9, 0: 1800\uB144\uB300 \uB0B4\uAD6D\uC778 (\uB0A8/\uC5EC)\r\n switch (genderCode) {\r\n case \"1\":\r\n case \"3\":\r\n case \"5\":\r\n case \"7\":\r\n case \"9\":\r\n result.gender = \"male\";\r\n break;\r\n case \"2\":\r\n case \"4\":\r\n case \"6\":\r\n case \"8\":\r\n case \"0\":\r\n result.gender = \"female\";\r\n break;\r\n }\r\n\r\n // \uC678\uAD6D\uC778 \uC5EC\uBD80\r\n if ([\"5\", \"6\", \"7\", \"8\"].includes(genderCode)) {\r\n result.isForeigner = true;\r\n } else if ([\"1\", \"2\", \"3\", \"4\", \"9\", \"0\"].includes(genderCode)) {\r\n result.isForeigner = false;\r\n }\r\n\r\n // \uC0DD\uB144\uC6D4\uC77C \uCD94\uCD9C\r\n if (numbers.length >= 6) {\r\n const yy = numbers.slice(0, 2);\r\n const mm = numbers.slice(2, 4);\r\n const dd = numbers.slice(4, 6);\r\n\r\n let century = \"19\";\r\n if ([\"3\", \"4\", \"7\", \"8\"].includes(genderCode)) {\r\n century = \"20\";\r\n } else if ([\"9\", \"0\"].includes(genderCode)) {\r\n century = \"18\";\r\n }\r\n\r\n const year = century + yy;\r\n result.birthDate = `${year}-${mm}-${dd}`;\r\n }\r\n\r\n // \uC9C0\uC5ED \uCD94\uCD9C (\uB0B4\uAD6D\uC778\uB9CC, \uB4B7\uC790\uB9AC 2~3\uBC88\uC9F8 \uC22B\uC790)\r\n if (numbers.length >= 9 && result.isForeigner === false) {\r\n const regionCode = numbers.slice(7, 9);\r\n const regionNum = parseInt(regionCode, 10);\r\n result.region = REGION_MAP[String(regionNum)] || null;\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * \uC8FC\uBBFC\uB4F1\uB85D\uBC88\uD638 \uCCB4\uD06C\uC12C \uAC80\uC99D\r\n * - 13\uC790\uB9AC \uAC01 \uC22B\uC790\uC5D0 \uAC00\uC911\uCE58 [2,3,4,5,6,7,8,9,2,3,4,5]\uB97C \uACF1\uD558\uC5EC \uD569\uC0B0\r\n * - (11 - (\uD569\uACC4 % 11)) % 10 === \uB9C8\uC9C0\uB9C9 \uC790\uB9AC\r\n */\r\nexport function validateJuminChecksum(numbers: string): boolean {\r\n if (numbers.length !== 13) return false;\r\n\r\n const weights = [2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5];\r\n let sum = 0;\r\n\r\n for (let i = 0; i < 12; i++) {\r\n sum += parseInt(numbers[i], 10) * weights[i];\r\n }\r\n\r\n const checkDigit = (11 - (sum % 11)) % 10;\r\n const lastDigit = parseInt(numbers[12], 10);\r\n\r\n return checkDigit === lastDigit;\r\n}\r\n\r\n/**\r\n * \uC8FC\uBBFC\uB4F1\uB85D\uBC88\uD638 \uC0DD\uB144\uC6D4\uC77C \uC720\uD6A8\uC131 \uAC80\uC99D\r\n */\r\nexport function validateJuminBirthDate(numbers: string): boolean {\r\n if (numbers.length < 7) return false;\r\n\r\n const yy = parseInt(numbers.slice(0, 2), 10);\r\n const mm = parseInt(numbers.slice(2, 4), 10);\r\n const dd = parseInt(numbers.slice(4, 6), 10);\r\n const genderCode = numbers[6];\r\n\r\n // \uC6D4 \uAC80\uC99D (1-12)\r\n if (mm < 1 || mm > 12) return false;\r\n\r\n // \uC138\uAE30 \uACB0\uC815\r\n let century = 1900;\r\n if ([\"3\", \"4\", \"7\", \"8\"].includes(genderCode)) {\r\n century = 2000;\r\n } else if ([\"9\", \"0\"].includes(genderCode)) {\r\n century = 1800;\r\n }\r\n\r\n const year = century + yy;\r\n\r\n // \uAC01 \uC6D4\uC758 \uC77C\uC218 (\uC724\uB144 \uACE0\uB824)\r\n const isLeapYear = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\r\n const daysInMonth = [31, isLeapYear ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\r\n\r\n // \uC77C \uAC80\uC99D\r\n if (dd < 1 || dd > daysInMonth[mm - 1]) return false;\r\n\r\n return true;\r\n}\r\n", "/**\r\n * TextField.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \u0010a8ud10a8uc601uc9c4 (Kim Young Jin)\r\n * @author \u0010a8ud10a8uc601uc9c4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useRef, useImperativeHandle } from \"react\";\r\nimport { TextField as MuiTextField } from \"@mui/material\";\r\nimport type { TextFieldProps } from \"@mui/material/TextField\";\r\nimport type { BaseTextFieldProps } from \"./types\";\r\nimport { useTextFieldBase } from \"./hooks\";\r\n\r\ntype CombinedTextFieldProps = TextFieldProps & BaseTextFieldProps;\r\n\r\nconst TextFieldBase = forwardRef<HTMLDivElement, CombinedTextFieldProps>(function TextFieldBase(\r\n { value, onChange, onBlur, debounce, readonly, slotProps, inputRef: externalInputRef, sx, ...props },\r\n ref\r\n) {\r\n const resolvedValue = value === undefined || value === null ? \"\" : String(value);\r\n\r\n const { internalValue, handleChange, handleBlur } = useTextFieldBase({\r\n value: resolvedValue,\r\n name: props.name,\r\n debounce,\r\n onChange,\r\n onBlur,\r\n });\r\n\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n\r\n useImperativeHandle(externalInputRef as React.Ref<HTMLInputElement>, () => internalInputRef.current!, []);\r\n\r\n const readonlyStyles = readonly\r\n ? {\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n return (\r\n <MuiTextField\r\n {...props}\r\n ref={ref}\r\n inputRef={internalInputRef}\r\n value={internalValue}\r\n onChange={handleChange}\r\n onBlur={handleBlur}\r\n sx={{\r\n ...readonlyStyles,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...sx,\r\n }}\r\n slotProps={{\r\n ...slotProps,\r\n input: {\r\n ...slotProps?.input,\r\n readOnly: readonly,\r\n },\r\n }}\r\n />\r\n );\r\n});\r\n\r\nconst TextFieldWithForm = forwardRef<HTMLDivElement, CombinedTextFieldProps>(function TextFieldWithForm(\r\n { form, name, onChange, ...rest },\r\n ref\r\n) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\"TextField form prop is missing. Provide a form from useForm or useGlobalForm.\");\r\n }\r\n if (!name) {\r\n throw new Error(\"TextField requires a name when form prop is provided.\");\r\n }\r\n\r\n const formValue = form.useFormValue(name) as string | number | null;\r\n const handleFormChange = (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n };\r\n\r\n return <TextFieldBase {...rest} ref={ref} name={name} value={formValue ?? \"\"} onChange={handleFormChange} />;\r\n});\r\n\r\nexport const TextField = forwardRef<HTMLDivElement, CombinedTextFieldProps>(function TextField(props, ref) {\r\n if (props.form) {\r\n return <TextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <TextFieldBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * TextArea.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n forwardRef,\r\n useCallback,\r\n useImperativeHandle,\r\n useRef,\r\n useState,\r\n} from \"react\";\r\nimport { Box, FormControl, InputLabel, TextareaAutosize } from \"@mui/material\";\r\nimport type { TextAreaProps } from \"./types\";\r\nimport { useTextFieldBase } from \"./hooks\";\r\n\r\nconst TextAreaBase = forwardRef<HTMLTextAreaElement, TextAreaProps>(\r\n function TextAreaBase(\r\n {\r\n label,\r\n value,\r\n name,\r\n onChange,\r\n onBlur,\r\n onFocus,\r\n minRows = 3,\r\n maxRows,\r\n placeholder,\r\n disabled,\r\n readonly,\r\n fullWidth = true,\r\n inputRef: externalInputRef,\r\n sx,\r\n inputProps,\r\n debounce,\r\n form,\r\n ...rest\r\n },\r\n ref,\r\n ) {\r\n const internalInputRef = useRef<HTMLTextAreaElement>(null);\r\n const [isFocused, setIsFocused] = useState(false);\r\n\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLTextAreaElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n const { internalValue, setInternalValue, emitChange, handleBlur } =\r\n useTextFieldBase({\r\n value: (value as string) ?? \"\",\r\n name,\r\n debounce,\r\n onChange: onChange as unknown as (\r\n e: React.ChangeEvent<HTMLInputElement>,\r\n ) => void,\r\n onBlur: onBlur as unknown as (\r\n e: React.FocusEvent<HTMLInputElement>,\r\n ) => void,\r\n });\r\n\r\n const handleChange = useCallback(\r\n (event: React.ChangeEvent<HTMLTextAreaElement>) => {\r\n const newValue = event.target.value;\r\n setInternalValue(newValue);\r\n emitChange(\r\n event as unknown as React.ChangeEvent<HTMLInputElement>,\r\n newValue,\r\n );\r\n },\r\n [emitChange, setInternalValue],\r\n );\r\n\r\n const handleFocus = useCallback(\r\n (event: React.FocusEvent<HTMLTextAreaElement>) => {\r\n setIsFocused(true);\r\n onFocus?.(event);\r\n },\r\n [onFocus],\r\n );\r\n\r\n const handleBlurWithFocus = useCallback(\r\n (event: React.FocusEvent<HTMLTextAreaElement>) => {\r\n setIsFocused(false);\r\n handleBlur(\r\n event as unknown as React.FocusEvent<HTMLInputElement>,\r\n );\r\n },\r\n [handleBlur],\r\n );\r\n\r\n return (\r\n <FormControl\r\n fullWidth={fullWidth}\r\n disabled={disabled}\r\n sx={{ width: fullWidth ? \"100%\" : undefined, ...sx }}\r\n >\r\n {label && (\r\n <InputLabel\r\n shrink={isFocused || internalValue.length > 0}\r\n sx={{\r\n position: \"static\",\r\n transform: \"none\",\r\n mb: 1,\r\n color: readonly\r\n ? \"rgba(0, 0, 0, 0.6)\"\r\n : \"text.primary\",\r\n }}\r\n >\r\n {label}\r\n </InputLabel>\r\n )}\r\n <Box\r\n sx={{\r\n border: \"1px solid rgba(0, 0, 0, 0.23)\",\r\n borderRadius: 1,\r\n px: 1.5,\r\n py: 1.25,\r\n transition: \"border-color 0.15s ease\",\r\n ...(isFocused &&\r\n !readonly && {\r\n borderColor: \"primary.main\",\r\n }),\r\n ...(readonly && {\r\n backgroundColor: \"rgba(0, 0, 0, 0.02)\",\r\n }),\r\n }}\r\n >\r\n <TextareaAutosize\r\n {...inputProps}\r\n {...rest}\r\n ref={(node: HTMLTextAreaElement | null) => {\r\n internalInputRef.current = node;\r\n if (typeof ref === \"function\") {\r\n ref(node);\r\n } else if (ref) {\r\n (\r\n ref as React.MutableRefObject<HTMLTextAreaElement | null>\r\n ).current = node;\r\n }\r\n }}\r\n name={name}\r\n value={internalValue}\r\n minRows={minRows}\r\n maxRows={maxRows}\r\n placeholder={placeholder}\r\n disabled={disabled}\r\n readOnly={readonly}\r\n onChange={handleChange}\r\n onFocus={handleFocus}\r\n onBlur={handleBlurWithFocus}\r\n style={{\r\n width: \"100%\",\r\n border: \"none\",\r\n outline: \"none\",\r\n resize: \"vertical\",\r\n background: \"transparent\",\r\n font: \"inherit\",\r\n color: \"inherit\",\r\n }}\r\n />\r\n </Box>\r\n </FormControl>\r\n );\r\n },\r\n);\r\n\r\nconst TextAreaWithForm = forwardRef<HTMLTextAreaElement, TextAreaProps>(\r\n function TextAreaWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"TextArea form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"TextArea requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLTextAreaElement>) => {\r\n form.handleFormChange(\r\n event as unknown as React.ChangeEvent<HTMLInputElement>,\r\n );\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <TextAreaBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue as string}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(\r\n function TextArea(props, ref) {\r\n if (props.form) {\r\n return <TextAreaWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <TextAreaBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * Checkbox.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback } from \"react\";\r\nimport { Checkbox as MuiCheckbox, FormControlLabel } from \"@mui/material\";\r\nimport type { CheckboxProps } from \"./types\";\r\n\r\nconst CheckboxBase = forwardRef<HTMLButtonElement, CheckboxProps>(\r\n function CheckboxBase(\r\n { label, name, checked, onChange, readonly, disabled, form, ...props },\r\n ref,\r\n ) {\r\n return (\r\n <FormControlLabel\r\n label={label}\r\n control={\r\n <MuiCheckbox\r\n {...props}\r\n ref={ref}\r\n name={name}\r\n checked={!!checked}\r\n onChange={onChange}\r\n disabled={disabled || readonly}\r\n />\r\n }\r\n />\r\n );\r\n },\r\n);\r\n\r\nconst CheckboxWithForm = forwardRef<HTMLButtonElement, CheckboxProps>(\r\n function CheckboxWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"Checkbox form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"Checkbox requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (\r\n event: React.ChangeEvent<HTMLInputElement>,\r\n nextChecked: boolean,\r\n ) => {\r\n const syntheticEvent = {\r\n ...event,\r\n target: {\r\n ...event.target,\r\n name,\r\n value: nextChecked,\r\n checked: nextChecked,\r\n },\r\n } as unknown as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n onChange?.(event, nextChecked);\r\n },\r\n [form, name, onChange],\r\n );\r\n\r\n return (\r\n <CheckboxBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n checked={Boolean(formValue)}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const Checkbox = forwardRef<HTMLButtonElement, CheckboxProps>(\r\n function Checkbox(props, ref) {\r\n if (props.form) {\r\n return <CheckboxWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <CheckboxBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * RadioGroup.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback } from \"react\";\r\nimport {\r\n FormControl,\r\n FormLabel,\r\n RadioGroup as MuiRadioGroup,\r\n FormControlLabel,\r\n Radio,\r\n} from \"@mui/material\";\r\nimport type { RadioGroupProps } from \"./types\";\r\n\r\nconst RadioGroupBase = forwardRef<HTMLDivElement, RadioGroupProps>(\r\n function RadioGroupBase(\r\n { label, name, value, options, onChange, readonly, disabled, ...props },\r\n ref,\r\n ) {\r\n return (\r\n <FormControl ref={ref} disabled={disabled}>\r\n {label && <FormLabel>{label}</FormLabel>}\r\n <MuiRadioGroup\r\n {...props}\r\n name={name}\r\n value={value ?? \"\"}\r\n onChange={onChange}\r\n >\r\n {options.map((option) => (\r\n <FormControlLabel\r\n key={option.value}\r\n value={option.value}\r\n control={<Radio />}\r\n label={option.label}\r\n disabled={disabled || option.disabled || readonly}\r\n />\r\n ))}\r\n </MuiRadioGroup>\r\n </FormControl>\r\n );\r\n },\r\n);\r\n\r\nconst RadioGroupWithForm = forwardRef<HTMLDivElement, RadioGroupProps>(\r\n function RadioGroupWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"RadioGroup form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"RadioGroup requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>, nextValue: string) => {\r\n const syntheticEvent = {\r\n ...event,\r\n target: {\r\n ...event.target,\r\n name,\r\n value: nextValue,\r\n },\r\n } as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n onChange?.(event, nextValue);\r\n },\r\n [form, name, onChange],\r\n );\r\n\r\n return (\r\n <RadioGroupBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={(formValue as string) ?? \"\"}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(\r\n function RadioGroup(props, ref) {\r\n if (props.form) {\r\n return <RadioGroupWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <RadioGroupBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * Switch.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback } from \"react\";\r\nimport { Switch as MuiSwitch, FormControlLabel } from \"@mui/material\";\r\nimport type { SwitchProps } from \"./types\";\r\n\r\nconst SwitchBase = forwardRef<HTMLButtonElement, SwitchProps>(\r\n function SwitchBase(\r\n { label, name, checked, onChange, readonly, disabled, form, ...props },\r\n ref,\r\n ) {\r\n const switchNode = (\r\n <MuiSwitch\r\n {...props}\r\n ref={ref}\r\n name={name}\r\n checked={!!checked}\r\n onChange={onChange}\r\n disabled={disabled || readonly}\r\n />\r\n );\r\n\r\n if (label !== undefined) {\r\n return <FormControlLabel label={label} control={switchNode} />;\r\n }\r\n\r\n return (\r\n switchNode\r\n );\r\n },\r\n);\r\n\r\nconst SwitchWithForm = forwardRef<HTMLButtonElement, SwitchProps>(\r\n function SwitchWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"Switch form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"Switch requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (\r\n event: React.ChangeEvent<HTMLInputElement>,\r\n nextChecked: boolean,\r\n ) => {\r\n const syntheticEvent = {\r\n ...event,\r\n target: {\r\n ...event.target,\r\n name,\r\n value: nextChecked,\r\n checked: nextChecked,\r\n },\r\n } as unknown as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n onChange?.(event, nextChecked);\r\n },\r\n [form, name, onChange],\r\n );\r\n\r\n return (\r\n <SwitchBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n checked={Boolean(formValue)}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const Switch = forwardRef<HTMLButtonElement, SwitchProps>(\r\n function Switch(props, ref) {\r\n if (props.form) {\r\n return <SwitchWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <SwitchBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * Rating.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \u0010a8ud10a8uc601uc9c4 (Kim Young Jin)\r\n * @author \u0010a8ud10a8uc601uc9c4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback } from \"react\";\r\nimport { Rating as MuiRating } from \"@mui/material\";\r\nimport type { RatingProps } from \"./types\";\r\n\r\nconst RatingBase = forwardRef<HTMLSpanElement, RatingProps>(function RatingBase(\r\n { name, value, onChange, readonly, disabled, ...props },\r\n ref,\r\n) {\r\n return (\r\n <MuiRating\r\n {...props}\r\n ref={ref}\r\n name={name}\r\n value={value ?? null}\r\n onChange={onChange}\r\n readOnly={readonly}\r\n disabled={disabled}\r\n />\r\n );\r\n});\r\n\r\nconst RatingWithForm = forwardRef<HTMLSpanElement, RatingProps>(\r\n function RatingWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"Rating form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"Rating requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name) as number | null | undefined;\r\n const resolvedValue =\r\n formValue !== undefined ? formValue : (rest.value ?? null);\r\n\r\n const handleFormChange = useCallback(\r\n (event: React.SyntheticEvent, nextValue: number | null) => {\r\n const syntheticEvent = {\r\n target: {\r\n name,\r\n value: nextValue ?? \"\",\r\n },\r\n } as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n onChange?.(event, nextValue);\r\n },\r\n [form, name, onChange],\r\n );\r\n\r\n return (\r\n <RatingBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={resolvedValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const Rating = forwardRef<HTMLSpanElement, RatingProps>(\r\n function Rating(props, ref) {\r\n if (props.form) {\r\n return <RatingWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <RatingBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * ToggleButton.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \u0010a8ud10a8uc601uc9c4 (Kim Young Jin)\r\n * @author \u0010a8ud10a8uc601uc9c4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback } from \"react\";\r\nimport { ToggleButton as MuiToggleButton } from \"@mui/material\";\r\nimport type { ToggleButtonProps } from \"./types\";\r\n\r\nconst ToggleButtonBase = forwardRef<HTMLButtonElement, Omit<ToggleButtonProps, \"form\">>(function ToggleButtonBase(\r\n { name, value, selected, onChange, readonly, disabled, ...props },\r\n ref\r\n) {\r\n if (selected === undefined) {\r\n return (\r\n <MuiToggleButton\r\n {...props}\r\n ref={ref}\r\n name={name}\r\n value={value ?? \"\"}\r\n onChange={readonly ? undefined : onChange}\r\n disabled={disabled || readonly}\r\n />\r\n );\r\n }\r\n\r\n return (\r\n <MuiToggleButton\r\n {...props}\r\n ref={ref}\r\n name={name}\r\n value={value ?? \"\"}\r\n selected={selected}\r\n onChange={readonly ? undefined : onChange}\r\n disabled={disabled || readonly}\r\n />\r\n );\r\n});\r\n\r\nconst ToggleButtonWithForm = forwardRef<HTMLButtonElement, ToggleButtonProps>(function ToggleButtonWithForm(\r\n { form, name, onChange, selected, value, readonly, disabled, ...rest },\r\n ref\r\n) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\"ToggleButton form prop is missing. Provide a form from useForm or useGlobalForm.\");\r\n }\r\n if (!name) {\r\n throw new Error(\"ToggleButton requires a name when form prop is provided.\");\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const resolvedSelected =\r\n formValue !== undefined ? (value !== undefined ? formValue === value : Boolean(formValue)) : Boolean(selected);\r\n\r\n const handleFormChange = useCallback(\r\n (event: React.MouseEvent<HTMLElement>) => {\r\n if (readonly || disabled) {\r\n return;\r\n }\r\n\r\n const nextSelected = !resolvedSelected;\r\n const nextValue = value !== undefined ? (nextSelected ? value : \"\") : nextSelected;\r\n\r\n const syntheticEvent = {\r\n target: {\r\n name,\r\n value: nextValue,\r\n },\r\n } as React.ChangeEvent<HTMLInputElement>;\r\n\r\n form.handleFormChange(syntheticEvent);\r\n onChange?.(event, value as never);\r\n },\r\n [disabled, form, name, onChange, readonly, resolvedSelected, value]\r\n );\r\n\r\n return (\r\n <ToggleButtonBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={value}\r\n selected={resolvedSelected}\r\n readonly={readonly}\r\n disabled={disabled}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const ToggleButton = forwardRef<HTMLButtonElement, ToggleButtonProps>(function ToggleButton(props, ref) {\r\n if (props.form) {\r\n return <ToggleButtonWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <ToggleButtonBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * ToggleButtonGroup.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback } from \"react\";\r\nimport {\r\n ToggleButton as MuiToggleButton,\r\n ToggleButtonGroup as MuiToggleButtonGroup,\r\n} from \"@mui/material\";\r\nimport type { ToggleButtonGroupProps } from \"./types\";\r\n\r\nconst ToggleButtonGroupBase = forwardRef<\r\n HTMLDivElement,\r\n ToggleButtonGroupProps\r\n>(function ToggleButtonGroupBase(\r\n {\r\n options,\r\n value,\r\n onChange,\r\n fullWidth = false,\r\n readonly,\r\n disabled,\r\n form,\r\n onDeselect,\r\n ...props\r\n },\r\n ref,\r\n) {\r\n return (\r\n <MuiToggleButtonGroup\r\n {...props}\r\n ref={ref}\r\n value={value}\r\n onChange={readonly ? undefined : onChange}\r\n disabled={disabled || readonly}\r\n sx={{\r\n ...(fullWidth ? { width: \"100%\" } : undefined),\r\n ...props.sx,\r\n }}\r\n >\r\n {options.map((option) => (\r\n <MuiToggleButton\r\n key={String(option.value)}\r\n value={option.value}\r\n disabled={option.disabled}\r\n >\r\n {option.label}\r\n </MuiToggleButton>\r\n ))}\r\n </MuiToggleButtonGroup>\r\n );\r\n});\r\n\r\nconst ToggleButtonGroupWithForm = forwardRef<\r\n HTMLDivElement,\r\n ToggleButtonGroupProps\r\n>(function ToggleButtonGroupWithForm(\r\n { form, name, onChange, onDeselect = \"keep\", exclusive, ...rest },\r\n ref,\r\n) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"ToggleButtonGroup form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"ToggleButtonGroup requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.MouseEvent<HTMLElement>, nextValue: unknown) => {\r\n const resolvedValue =\r\n nextValue === null && onDeselect === \"keep\"\r\n ? formValue\r\n : nextValue;\r\n\r\n if (typeof form.setFormValue === \"function\") {\r\n form.setFormValue(name, resolvedValue);\r\n } else {\r\n const syntheticEvent = {\r\n target: {\r\n name,\r\n value: resolvedValue,\r\n },\r\n } as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n }\r\n\r\n onChange?.(event, resolvedValue);\r\n },\r\n [form, formValue, name, onChange, onDeselect],\r\n );\r\n\r\n return (\r\n <ToggleButtonGroupBase\r\n {...rest}\r\n ref={ref}\r\n exclusive={exclusive}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const ToggleButtonGroup = forwardRef<\r\n HTMLDivElement,\r\n ToggleButtonGroupProps\r\n>(function ToggleButtonGroup(props, ref) {\r\n if (props.form) {\r\n return <ToggleButtonGroupWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <ToggleButtonGroupBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * ButtonGroup.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \u0010a8ud10a8uc601uc9c4 (Kim Young Jin)\r\n * @author \u0010a8ud10a8uc601uc9c4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { forwardRef } from \"react\";\r\nimport { ButtonGroup as MuiButtonGroup } from \"@mui/material\";\r\nimport type { ButtonGroupProps as MuiButtonGroupProps } from \"@mui/material/ButtonGroup\";\r\n\r\nexport const ButtonGroup = forwardRef<HTMLDivElement, MuiButtonGroupProps>(function ButtonGroup(props, ref) {\r\n return <MuiButtonGroup ref={ref} {...props} />;\r\n});\r\n", "/**\r\n * DateRange.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { Box } from \"@mui/material\";\r\nimport type { DateRangeProps } from \"./types\";\r\nimport { DateTextField } from \"./DateTextField\";\r\n\r\nexport function DateRange({\r\n form,\r\n startName,\r\n endName,\r\n startLabel = \"\uC2DC\uC791\uC77C\",\r\n endLabel = \"\uC885\uB8CC\uC77C\",\r\n startValue,\r\n endValue,\r\n onStartChange,\r\n onEndChange,\r\n fullWidth = true,\r\n size,\r\n readonly,\r\n gap = 2,\r\n startProps,\r\n endProps,\r\n}: DateRangeProps) {\r\n if (form) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\"DateRange form prop is missing. Provide a form from useForm or useGlobalForm.\");\r\n }\r\n if (!startName || !endName) {\r\n throw new Error(\"DateRange requires startName and endName when form prop is provided.\");\r\n }\r\n\r\n return (\r\n <Box\r\n sx={{\r\n display: \"grid\",\r\n gap,\r\n gridTemplateColumns: { xs: \"1fr\", sm: \"1fr 1fr\" },\r\n }}\r\n >\r\n <DateTextField\r\n {...startProps}\r\n name={startName}\r\n label={startLabel}\r\n form={form}\r\n fullWidth={fullWidth}\r\n size={size}\r\n readonly={readonly}\r\n />\r\n <DateTextField\r\n {...endProps}\r\n name={endName}\r\n label={endLabel}\r\n form={form}\r\n fullWidth={fullWidth}\r\n size={size}\r\n readonly={readonly}\r\n />\r\n </Box>\r\n );\r\n }\r\n\r\n return (\r\n <Box\r\n sx={{\r\n display: \"grid\",\r\n gap,\r\n gridTemplateColumns: { xs: \"1fr\", sm: \"1fr 1fr\" },\r\n }}\r\n >\r\n <DateTextField\r\n {...startProps}\r\n name={startName}\r\n label={startLabel}\r\n value={startValue}\r\n onChange={onStartChange}\r\n fullWidth={fullWidth}\r\n size={size}\r\n readonly={readonly}\r\n />\r\n <DateTextField\r\n {...endProps}\r\n name={endName}\r\n label={endLabel}\r\n value={endValue}\r\n onChange={onEndChange}\r\n fullWidth={fullWidth}\r\n size={size}\r\n readonly={readonly}\r\n />\r\n </Box>\r\n );\r\n}\r\n", "/**\r\n * DateTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n ChangeEvent,\r\n useMemo,\r\n useRef,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField, InputAdornment, IconButton } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport type { DateTextFieldProps } from \"./types\";\r\nimport { DatePicker } from \"@ehfuse/mui-datetime-picker\";\r\nimport { CalendarIcon } from \"./icons\";\r\nimport { useDebouncedEmit } from \"./hooks\";\r\nimport {\r\n getSeparator,\r\n formatDate,\r\n getMaxLength,\r\n getCompleteLength,\r\n validateDate,\r\n formatToPlaceholder,\r\n hasYearInFormat,\r\n parseDateWithInternalYear,\r\n buildDateOutputValue,\r\n dateToNumbers,\r\n} from \"./utils\";\r\n\r\nconst DateTextFieldBase = forwardRef<HTMLDivElement, DateTextFieldProps>(\r\n function DateTextFieldBase(\r\n {\r\n label,\r\n format = \"YYYY-MM-DD\",\r\n separator = \"-\",\r\n minDate,\r\n maxDate,\r\n holidays = [],\r\n holidayColor = \"red\",\r\n calendarIcon = true,\r\n selectedColor,\r\n showToday = true,\r\n invalidBorderColor,\r\n debounce,\r\n slotProps,\r\n sx,\r\n value,\r\n onChange,\r\n onBlur,\r\n placeholder,\r\n onCalendarDismiss,\r\n onCalendarOpen,\r\n onCalendarClose,\r\n name = \"\",\r\n disabled,\r\n readonly = false,\r\n size,\r\n inputRef: externalInputRef,\r\n calendarAnchorOrigin,\r\n calendarTransformOrigin,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n const [displayValue, setDisplayValue] = useState(\"\");\r\n const [prevNumbers, setPrevNumbers] = useState(\"\");\r\n const [calendarOpen, setCalendarOpen] = useState(false);\r\n const [calendarAnchorPos, setCalendarAnchorPos] = useState(\r\n null as { top: number; left: number } | null,\r\n );\r\n const calendarCloseReasonRef = useRef<\"select\" | null>(null);\r\n const [internalYear, setInternalYear] = useState<number | null>(null); // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC6A9\r\n\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLInputElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange, flushOnBlur, lastEmittedValue } = useDebouncedEmit({\r\n name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n const maxLength = getMaxLength(format);\r\n const completeLength = getCompleteLength(format);\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC778\uC9C0 \uD655\uC778 (YYYY, YY\uAC00 \uC5C6\uB294 \uD3EC\uB9F7)\r\n const isYearlessFormat = !hasYearInFormat(format);\r\n\r\n // \uD604\uC7AC \uC120\uD0DD\uB41C \uB0A0\uC9DC \uACC4\uC0B0\r\n const selectedDate = useMemo((): Date | null => {\r\n const parsed = parseDateWithInternalYear(\r\n displayValue,\r\n format,\r\n internalYear,\r\n );\r\n if (!parsed) return null;\r\n return new Date(parsed.year, parsed.month - 1, parsed.day);\r\n }, [displayValue, format, internalYear]);\r\n\r\n // \uB2EC\uB825\uC5D0 \uC804\uB2EC\uD560 \uB0A0\uC9DC \uACC4\uC0B0\r\n const calendarSelectedDate = useMemo((): Date => {\r\n // \uC120\uD0DD\uB41C \uB0A0\uC9DC\uAC00 \uC788\uC73C\uBA74 \uADF8\uB300\uB85C \uC0AC\uC6A9\r\n if (selectedDate) return selectedDate;\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC758 \uACBD\uC6B0 internalYear \uB610\uB294 \uD604\uC7AC \uC5F0\uB3C4 \uC0AC\uC6A9\r\n if (isYearlessFormat) {\r\n const yearToUse = internalYear || new Date().getFullYear();\r\n const parsed = parseDateWithInternalYear(\r\n displayValue,\r\n format,\r\n yearToUse,\r\n );\r\n if (\r\n parsed &&\r\n parsed.month >= 1 &&\r\n parsed.month <= 12 &&\r\n parsed.day >= 1 &&\r\n parsed.day <= 31\r\n ) {\r\n return new Date(yearToUse, parsed.month - 1, parsed.day);\r\n }\r\n return new Date(\r\n yearToUse,\r\n new Date().getMonth(),\r\n new Date().getDate(),\r\n );\r\n }\r\n\r\n return new Date();\r\n }, [\r\n selectedDate,\r\n displayValue,\r\n format,\r\n isYearlessFormat,\r\n internalYear,\r\n ]);\r\n\r\n // onChange\uB85C \uC804\uB2EC\uD560 \uAC12 \uC0DD\uC131 (\uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC774\uC5B4\uB3C4 \uC5F0\uB3C4 \uD3EC\uD568)\r\n const buildOutputValue = useCallback(\r\n (formattedValue: string): string => {\r\n return buildDateOutputValue(\r\n formattedValue,\r\n format,\r\n separator,\r\n internalYear,\r\n );\r\n },\r\n [format, separator, internalYear],\r\n );\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uC218\uD589\r\n const performValidation = useCallback(\r\n (inputValue: string) => {\r\n const numbers = inputValue.replace(/\\D/g, \"\");\r\n\r\n // \uC644\uC131\uB41C \uACBD\uC6B0\uC5D0\uB9CC \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n if (numbers.length === completeLength) {\r\n const isValid = validateDate(\r\n inputValue,\r\n format,\r\n minDate,\r\n maxDate,\r\n );\r\n setIsInvalid(!isValid);\r\n } else {\r\n setIsInvalid(false);\r\n }\r\n },\r\n [format, minDate, maxDate, completeLength],\r\n );\r\n\r\n // value \uBCC0\uACBD \uC2DC displayValue \uC5C5\uB370\uC774\uD2B8 (\uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uACBD\uC6B0\uB9CC)\r\n useEffect(() => {\r\n if (value !== undefined && value !== null) {\r\n const strValue = String(value);\r\n const formattedValue = formatDate(strValue, format);\r\n const currentNumbers = formattedValue.replace(/\\D/g, \"\");\r\n\r\n // \uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uAC12\uC774 \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uD55C \uAC12\uACFC \uB2E4\uB97C \uB54C\uB9CC \uB3D9\uAE30\uD654\r\n // (\uC0AC\uC6A9\uC790 \uC785\uB825 \uC911 \uB514\uBC14\uC6B4\uC2A4\uB85C \uC778\uD55C \uB418\uB3CC\uB9BC \uBC29\uC9C0)\r\n if (strValue !== lastEmittedValue.current) {\r\n setDisplayValue(formattedValue);\r\n setPrevNumbers(currentNumbers);\r\n performValidation(formattedValue);\r\n lastEmittedValue.current = strValue;\r\n }\r\n } else {\r\n if (lastEmittedValue.current !== \"\") {\r\n setDisplayValue(\"\");\r\n setPrevNumbers(\"\");\r\n lastEmittedValue.current = \"\";\r\n }\r\n }\r\n }, [value, format, performValidation, lastEmittedValue]);\r\n\r\n // \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\r\n const input = e.target;\r\n const newValue = input.value;\r\n const newNumbers = newValue.replace(/\\D/g, \"\");\r\n\r\n // \uBC31\uC2A4\uD398\uC774\uC2A4 \uAC10\uC9C0\r\n const isBackspace =\r\n newNumbers.length <= prevNumbers.length &&\r\n newValue.length < displayValue.length;\r\n\r\n let formattedValue: string;\r\n\r\n if (isBackspace && newNumbers.length === prevNumbers.length) {\r\n // \uAD6C\uBD84\uC790\uB9CC \uC0AD\uC81C\uB41C \uACBD\uC6B0: \uC22B\uC790\uB3C4 \uD558\uB098 \uC0AD\uC81C\r\n const trimmedNumbers = newNumbers.slice(0, -1);\r\n formattedValue = formatDate(trimmedNumbers, format);\r\n } else {\r\n // \uC22B\uC790\uAC00 completeLength\uB97C \uCD08\uACFC\uD558\uC9C0 \uC54A\uB3C4\uB85D \uC81C\uD55C\r\n const limitedNumbers = newNumbers.slice(0, completeLength);\r\n formattedValue = formatDate(limitedNumbers, format);\r\n }\r\n\r\n setDisplayValue(formattedValue);\r\n const currentNumbers = formattedValue.replace(/\\D/g, \"\");\r\n setPrevNumbers(currentNumbers);\r\n\r\n // \uCEE4\uC11C \uC704\uCE58 \uC870\uC815: \uD3EC\uB9F7\uD305\uB41C \uC22B\uC790 \uAC1C\uC218\uC5D0 \uB9DE\uAC8C \uC704\uCE58 \uACB0\uC815\r\n requestAnimationFrame(() => {\r\n if (input) {\r\n const formatSep = getSeparator(format);\r\n let cursorPos = formattedValue.length; // \uAE30\uBCF8\uAC12: \uB05D\r\n\r\n if (!isBackspace) {\r\n // \uD3EC\uB9F7\uD305\uB41C \uBB38\uC790\uC5F4\uC758 \uC2E4\uC81C \uC22B\uC790 \uAC1C\uC218 \uC0AC\uC6A9 (constrainDateNumbers\uAC00 \uC790\uB3D9\uC73C\uB85C 0\uC744 \uCD94\uAC00\uD560 \uC218 \uC788\uC74C)\r\n const inputNumberCount = currentNumbers.length;\r\n\r\n // \uD3EC\uB9F7\uD305\uB41C \uBB38\uC790\uC5F4\uC5D0\uC11C \uD574\uB2F9 \uC22B\uC790 \uC704\uCE58 \uCC3E\uAE30\r\n let numberCount = 0;\r\n\r\n for (let i = 0; i < formattedValue.length; i++) {\r\n if (/\\d/.test(formattedValue[i])) {\r\n numberCount++;\r\n // \uC785\uB825\uB41C \uC22B\uC790 \uAC1C\uC218\uC640 \uC77C\uCE58\uD558\uB294 \uC704\uCE58 \uCC3E\uAE30\r\n if (numberCount === inputNumberCount) {\r\n cursorPos = i + 1;\r\n // \uB2E4\uC74C \uBB38\uC790\uAC00 \uAD6C\uBD84\uC790\uBA74 \uAC74\uB108\uB6F0\uAE30 (\uC608: \"2024-\"\uC5D0\uC11C \"-\" \uB4A4\uB85C)\r\n if (\r\n cursorPos < formattedValue.length &&\r\n formattedValue[cursorPos] === formatSep\r\n ) {\r\n cursorPos++;\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // \uC22B\uC790\uB97C \uCC3E\uC9C0 \uBABB\uD55C \uACBD\uC6B0 (\uC774\uB860\uC801\uC73C\uB85C \uBC1C\uC0DD\uD558\uC9C0 \uC54A\uC544\uC57C \uD568)\r\n if (numberCount < inputNumberCount) {\r\n cursorPos = formattedValue.length;\r\n }\r\n } else {\r\n // \uBC31\uC2A4\uD398\uC774\uC2A4\uC778 \uACBD\uC6B0: \uD604\uC7AC \uC22B\uC790 \uAC1C\uC218\uC5D0 \uB9DE\uAC8C \uC704\uCE58 \uACB0\uC815\r\n const targetNumberCount = currentNumbers.length;\r\n let numberCount = 0;\r\n\r\n for (let i = 0; i < formattedValue.length; i++) {\r\n if (/\\d/.test(formattedValue[i])) {\r\n numberCount++;\r\n if (numberCount === targetNumberCount) {\r\n cursorPos = i + 1;\r\n // \uB2E4\uC74C \uBB38\uC790\uAC00 \uAD6C\uBD84\uC790\uBA74 \uAC74\uB108\uB6F0\uAE30\r\n if (\r\n cursorPos < formattedValue.length &&\r\n formattedValue[cursorPos] === formatSep\r\n ) {\r\n cursorPos++;\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n input.setSelectionRange(cursorPos, cursorPos);\r\n }\r\n });\r\n\r\n performValidation(formattedValue);\r\n\r\n // onChange\uB85C \uC804\uB2EC\uD560 \uAC12\r\n const outputValue = buildOutputValue(formattedValue);\r\n\r\n // \uB514\uBC14\uC6B4\uC2A4 \uC801\uC6A9\r\n emitChange(e, outputValue);\r\n };\r\n\r\n // blur \uC2DC \uB300\uAE30 \uC911\uC778 \uB514\uBC14\uC6B4\uC2A4 \uC989\uC2DC \uC2E4\uD589\r\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\r\n const outputValue = buildOutputValue(displayValue);\r\n flushOnBlur(e, outputValue);\r\n if (onBlur) {\r\n onBlur(e);\r\n }\r\n };\r\n\r\n // \uD074\uB9AD \uC2DC \uC804\uCCB4 \uC120\uD0DD (\uC785\uB825\uD558\uBA74 \uCC98\uC74C\uBD80\uD130 \uC0C8\uB85C \uC785\uB825)\r\n const handleClick = useCallback(\r\n (e: React.MouseEvent<HTMLInputElement>) => {\r\n if (disabled || readonly) return;\r\n\r\n const input = e.target as HTMLInputElement;\r\n\r\n // \uAC12\uC774 \uC788\uC744 \uB54C \uC804\uCCB4 \uC120\uD0DD\r\n if (displayValue.length > 0) {\r\n requestAnimationFrame(() => {\r\n if (\r\n input &&\r\n typeof input.setSelectionRange === \"function\"\r\n ) {\r\n input.setSelectionRange(0, displayValue.length);\r\n }\r\n });\r\n }\r\n },\r\n [disabled, readonly, displayValue],\r\n );\r\n\r\n // \uD0A4 \uC785\uB825 \uC81C\uD55C \uD578\uB4E4\uB7EC (\uC5F0\uB3C4 \uCCAB \uC790\uB9AC 1, 2\uB9CC \uD5C8\uC6A9)\r\n const handleKeyDown = useCallback(\r\n (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n // \uC22B\uC790\uAC00 \uC544\uB2CC \uD0A4\uB294 \uD1B5\uACFC (\uBC31\uC2A4\uD398\uC774\uC2A4, \uD654\uC0B4\uD45C \uB4F1)\r\n if (!/^\\d$/.test(e.key)) return;\r\n\r\n const currentNumbers = displayValue.replace(/\\D/g, \"\");\r\n const numLen = currentNumbers.length;\r\n\r\n // YYYY-MM-DD \uD3EC\uB9F7: \uC5F0\uB3C4 \uCCAB \uC790\uB9AC (\uC22B\uC790 0\uBC88\uC9F8)\uB294 1 \uB610\uB294 2\uB9CC \uD5C8\uC6A9\r\n if (format.startsWith(\"YYYY\") && numLen === 0) {\r\n if (e.key !== \"1\" && e.key !== \"2\") {\r\n e.preventDefault();\r\n return;\r\n }\r\n }\r\n\r\n // MM-DD-YYYY \uD3EC\uB9F7: \uC5F0\uB3C4 \uCCAB \uC790\uB9AC (\uC22B\uC790 4\uBC88\uC9F8)\uB294 1 \uB610\uB294 2\uB9CC \uD5C8\uC6A9\r\n if (\r\n format.startsWith(\"MM\") &&\r\n format.endsWith(\"YYYY\") &&\r\n numLen === 4\r\n ) {\r\n if (e.key !== \"1\" && e.key !== \"2\") {\r\n e.preventDefault();\r\n return;\r\n }\r\n }\r\n\r\n // DD-MM-YYYY \uD3EC\uB9F7: \uC5F0\uB3C4 \uCCAB \uC790\uB9AC (\uC22B\uC790 4\uBC88\uC9F8)\uB294 1 \uB610\uB294 2\uB9CC \uD5C8\uC6A9\r\n if (\r\n format.startsWith(\"DD\") &&\r\n format.endsWith(\"YYYY\") &&\r\n numLen === 4\r\n ) {\r\n if (e.key !== \"1\" && e.key !== \"2\") {\r\n e.preventDefault();\r\n return;\r\n }\r\n }\r\n },\r\n [displayValue, format],\r\n );\r\n\r\n // \uB2EC\uB825\uC5D0\uC11C \uB0A0\uC9DC \uC120\uD0DD \uC2DC \uD578\uB4E4\uB7EC\r\n const handleCalendarSelect = (date: Date) => {\r\n const year = date.getFullYear();\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC758 \uACBD\uC6B0 internalYear\uC5D0 \uC800\uC7A5\r\n if (isYearlessFormat) {\r\n setInternalYear(year);\r\n }\r\n\r\n // \uD3EC\uB9F7\uC5D0 \uB9DE\uAC8C \uC22B\uC790 \uBB38\uC790\uC5F4 \uC0DD\uC131\r\n const numbers = dateToNumbers(date, format);\r\n\r\n // \uD604\uC7AC \uD3EC\uB9F7\uC5D0 \uB9DE\uAC8C \uBCC0\uD658\r\n const formattedValue = formatDate(numbers, format);\r\n\r\n setDisplayValue(formattedValue);\r\n setPrevNumbers(numbers);\r\n performValidation(formattedValue);\r\n\r\n // onChange \uD638\uCD9C - \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC774\uC5B4\uB3C4 \uC5F0\uB3C4 \uD3EC\uD568\r\n const outputValue = buildDateOutputValue(\r\n formattedValue,\r\n format,\r\n separator,\r\n year,\r\n );\r\n\r\n // \uB2EC\uB825 \uC120\uD0DD \uC2DC \uC989\uC2DC emit\r\n emitChange(null, outputValue, true);\r\n\r\n const activeElement = document.activeElement as HTMLElement | null;\r\n const inputRoot =\r\n internalInputRef.current?.closest(\".MuiInputBase-root\");\r\n\r\n if (activeElement && inputRoot?.contains(activeElement)) {\r\n activeElement.blur();\r\n }\r\n\r\n calendarCloseReasonRef.current = \"select\";\r\n };\r\n\r\n // \uB2EC\uB825 Popover \uC5F4\uAE30/\uB2EB\uAE30\r\n const handleOpenCalendar = () => {\r\n calendarCloseReasonRef.current = null;\r\n const inputEl = internalInputRef.current;\r\n if (inputEl) {\r\n const rect = inputEl.getBoundingClientRect();\r\n setCalendarAnchorPos({\r\n top: rect.bottom + window.scrollY,\r\n left: rect.left + window.scrollX,\r\n });\r\n }\r\n setCalendarOpen(true);\r\n onCalendarOpen?.();\r\n setTimeout(() => {\r\n const popperPaper = document.querySelector(\r\n '[data-custom-date-picker-popper=\"true\"]',\r\n ) as HTMLElement | null;\r\n popperPaper?.focus();\r\n }, 0);\r\n };\r\n\r\n const handleCloseCalendar = () => {\r\n const isSelectClose = calendarCloseReasonRef.current === \"select\";\r\n calendarCloseReasonRef.current = null;\r\n const activeElement = document.activeElement as HTMLElement | null;\r\n const inputRoot =\r\n internalInputRef.current?.closest(\".MuiInputBase-root\");\r\n\r\n if (activeElement && inputRoot?.contains(activeElement)) {\r\n activeElement.blur();\r\n }\r\n setCalendarOpen(false);\r\n onCalendarClose?.();\r\n if (!isSelectClose) {\r\n onCalendarDismiss?.();\r\n }\r\n };\r\n\r\n const isCalendarOpen = calendarOpen;\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uC2E4\uD328 \uC2DC \uD14C\uB450\uB9AC \uC2A4\uD0C0\uC77C\r\n const invalidStyles: SxProps<Theme> =\r\n isInvalid && invalidBorderColor\r\n ? {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n \"&:hover fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n \"&.Mui-focused fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n },\r\n \"& .MuiFilledInput-root\": {\r\n \"&:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:hover:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:after\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n },\r\n \"& .MuiInput-root\": {\r\n \"&:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:hover:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:after\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n },\r\n }\r\n : {};\r\n\r\n // readonly\uC77C \uB54C \uD3EC\uCEE4\uC2A4 \uC2A4\uD0C0\uC77C \uC81C\uAC70\r\n const readonlyStyles = readonly\r\n ? {\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n return (\r\n <>\r\n <TextField\r\n {...props}\r\n ref={ref}\r\n size={size}\r\n disabled={disabled}\r\n value={displayValue}\r\n label={label}\r\n placeholder={placeholder || formatToPlaceholder(format)}\r\n onChange={handleChange}\r\n onBlur={handleBlur}\r\n onClick={handleClick}\r\n onKeyDown={handleKeyDown}\r\n inputRef={internalInputRef}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n sx={{\r\n ...invalidStyles,\r\n ...readonlyStyles,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...(props.fullWidth && { minWidth: 0 }),\r\n ...sx,\r\n }}\r\n slotProps={{\r\n ...slotProps,\r\n input: {\r\n ...slotProps?.input,\r\n readOnly: readonly,\r\n endAdornment:\r\n calendarIcon && !readonly ? (\r\n <InputAdornment\r\n position=\"end\"\r\n sx={{\r\n mr: size === \"small\" ? -0.5 : 0,\r\n }}\r\n >\r\n <IconButton\r\n onMouseDown={(e) => {\r\n e.preventDefault();\r\n }}\r\n onClick={handleOpenCalendar}\r\n edge=\"end\"\r\n size=\"small\"\r\n disabled={disabled}\r\n sx={{\r\n color: \"text.secondary\",\r\n opacity: 0.5,\r\n transition:\r\n \"opacity 0.2s, color 0.2s\",\r\n \"&:hover\": {\r\n opacity: 1,\r\n color: \"text.primary\",\r\n },\r\n \"&.Mui-disabled\": {\r\n opacity: 0.5,\r\n color: \"text.secondary\",\r\n },\r\n }}\r\n >\r\n <CalendarIcon\r\n size={\r\n size === \"small\" ? 16 : 18\r\n }\r\n />\r\n </IconButton>\r\n </InputAdornment>\r\n ) : undefined,\r\n },\r\n htmlInput: {\r\n ...slotProps?.htmlInput,\r\n maxLength: maxLength,\r\n inputMode: \"numeric\",\r\n },\r\n }}\r\n />\r\n {/* MUI \uC2A4\uD0C0\uC77C \uB2EC\uB825 */}\r\n <DatePicker\r\n open={isCalendarOpen}\r\n anchorEl={internalInputRef}\r\n onClose={handleCloseCalendar}\r\n anchorReference={\r\n calendarAnchorPos ? \"anchorPosition\" : \"anchorEl\"\r\n }\r\n anchorPosition={\r\n calendarAnchorPos\r\n ? {\r\n top: calendarAnchorPos.top,\r\n left: calendarAnchorPos.left,\r\n }\r\n : undefined\r\n }\r\n anchorOrigin={\r\n calendarAnchorOrigin || {\r\n vertical: \"bottom\",\r\n horizontal: \"left\",\r\n }\r\n }\r\n transformOrigin={\r\n calendarTransformOrigin || {\r\n vertical: \"top\",\r\n horizontal: \"left\",\r\n }\r\n }\r\n selectedDate={calendarSelectedDate}\r\n onDateChange={handleCalendarSelect}\r\n minDate={minDate}\r\n maxDate={maxDate}\r\n holidays={holidays}\r\n styles={{ selectedColor, holidayColor }}\r\n showToday={showToday}\r\n autoApply={true}\r\n showFooter={false}\r\n />\r\n </>\r\n );\r\n },\r\n);\r\n\r\nconst DateTextFieldWithForm = forwardRef<HTMLDivElement, DateTextFieldProps>(\r\n function DateTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"DateTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"DateTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <DateTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const DateTextField = forwardRef<HTMLDivElement, DateTextFieldProps>(\r\n function DateTextField(props, ref) {\r\n if (props.form) {\r\n return <DateTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <DateTextFieldBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * utils/index.ts\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\n/** \uC8FC \uC815\uBCF4 \uD0C0\uC785 */\r\nexport interface WeekInfo {\r\n weekOfMonth: number; // \uD574\uB2F9 \uC6D4\uC758 \uBA87 \uBC88\uC9F8 \uC8FC (1-indexed)\r\n startDate: Date; // \uC8FC\uC758 \uC2DC\uC791\uC77C (\uC77C\uC694\uC77C)\r\n endDate: Date; // \uC8FC\uC758 \uC885\uB8CC\uC77C (\uD1A0\uC694\uC77C)\r\n}\r\n\r\n/**\r\n * \uC8FC \uC815\uBCF4 \uACC4\uC0B0 (\uD574\uB2F9 \uC6D4\uC758 \uBA87 \uBC88\uC9F8 \uC8FC, \uC8FC\uC758 \uC2DC\uC791\uC77C, \uC885\uB8CC\uC77C)\r\n * @param date - \uACC4\uC0B0\uD560 \uB0A0\uC9DC\r\n * @returns \uC8FC \uC815\uBCF4 \uAC1D\uCCB4\r\n */\r\nexport const getWeekInfo = (date: Date): WeekInfo => {\r\n const dayOfWeek = date.getDay(); // 0(\uC77C) ~ 6(\uD1A0)\r\n\r\n // \uD574\uB2F9 \uC8FC\uC758 \uC2DC\uC791\uC77C (\uC77C\uC694\uC77C)\r\n const startDate = new Date(date);\r\n startDate.setDate(date.getDate() - dayOfWeek);\r\n startDate.setHours(0, 0, 0, 0);\r\n\r\n // \uD574\uB2F9 \uC8FC\uC758 \uC885\uB8CC\uC77C (\uD1A0\uC694\uC77C)\r\n const endDate = new Date(date);\r\n endDate.setDate(date.getDate() + (6 - dayOfWeek));\r\n endDate.setHours(23, 59, 59, 999);\r\n\r\n // \uD574\uB2F9 \uC6D4\uC758 \uBA87 \uBC88\uC9F8 \uC8FC\uC778\uC9C0 \uACC4\uC0B0 (\uD574\uB2F9 \uC6D4 1\uC77C \uAE30\uC900)\r\n const firstDayOfMonth = new Date(date.getFullYear(), date.getMonth(), 1);\r\n const firstDayOfWeek = firstDayOfMonth.getDay();\r\n const weekOfMonth = Math.ceil((date.getDate() + firstDayOfWeek) / 7);\r\n\r\n return { weekOfMonth, startDate, endDate };\r\n};\r\n\r\n/**\r\n * \uB450 \uB0A0\uC9DC\uAC00 \uAC19\uC740 \uC8FC\uC778\uC9C0 \uD655\uC778\r\n * @param date1 - \uCCAB \uBC88\uC9F8 \uB0A0\uC9DC\r\n * @param date2 - \uB450 \uBC88\uC9F8 \uB0A0\uC9DC\r\n * @returns \uAC19\uC740 \uC8FC\uC774\uBA74 true\r\n */\r\nexport const isSameWeek = (date1: Date, date2: Date): boolean => {\r\n const week1 = getWeekInfo(date1);\r\n const week2 = getWeekInfo(date2);\r\n return week1.startDate.getTime() === week2.startDate.getTime();\r\n};\r\n\r\n/**\r\n * \uB450 \uB0A0\uC9DC\uAC00 \uAC19\uC740 \uB0A0\uC778\uC9C0 \uD655\uC778\r\n * @param d1 - \uCCAB \uBC88\uC9F8 \uB0A0\uC9DC\r\n * @param d2 - \uB450 \uBC88\uC9F8 \uB0A0\uC9DC\r\n * @returns \uAC19\uC740 \uB0A0\uC774\uBA74 true\r\n */\r\nexport const isSameDay = (d1: Date | null, d2: Date | null): boolean => {\r\n if (!d1 || !d2) return false;\r\n return (\r\n d1.getFullYear() === d2.getFullYear() &&\r\n d1.getMonth() === d2.getMonth() &&\r\n d1.getDate() === d2.getDate()\r\n );\r\n};\r\n\r\n/**\r\n * `showFooter === false`\uC774\uBA74 \uD655\uC778/\uCDE8\uC18C \uD478\uD130\uAC00 \uC5C6\uC5B4 `autoApply === false`(\uC784\uC2DC \uC120\uD0DD \uD6C4 \uD655\uC778)\uC640\r\n * \uB3D9\uC2DC\uC5D0 \uB458 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uC774 \uC870\uD569\uC774\uBA74 `autoApply`\uB97C true\uB85C \uB9DE\uCDB0 \uB0A0\uC9DC \uD074\uB9AD\uC774 \uACE7\uBC14\uB85C \uBC18\uC601\uB418\uAC8C \uD569\uB2C8\uB2E4.\r\n */\r\nexport function resolveFooterAndAutoApply(\r\n showFooter: boolean,\r\n autoApply: boolean,\r\n): { showFooter: boolean; autoApply: boolean } {\r\n if (!showFooter && !autoApply) {\r\n return { showFooter: false, autoApply: true };\r\n }\r\n return { showFooter, autoApply };\r\n}\r\n", "/**\r\n * locale.ts\r\n * \uCE98\uB9B0\uB354 \uB85C\uCF00\uC77C \uC815\uC758\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\n/** \uCE98\uB9B0\uB354 \uB85C\uCF00\uC77C \uD0C0\uC785 (\uD14D\uC2A4\uD2B8 \uCEE4\uC2A4\uD130\uB9C8\uC774\uC9D5) */\r\nexport interface CalendarLocale {\r\n weekdays: [string, string, string, string, string, string, string]; // \uC694\uC77C (\uC77C~\uD1A0)\r\n months: [\r\n string,\r\n string,\r\n string,\r\n string,\r\n string,\r\n string,\r\n string,\r\n string,\r\n string,\r\n string,\r\n string,\r\n string\r\n ]; // \uC6D4 (1~12\uC6D4)\r\n today: string; // \uC624\uB298 \uBC84\uD2BC\r\n confirm: string; // \uD655\uC778 \uBC84\uD2BC\r\n cancel: string; // \uCDE8\uC18C \uBC84\uD2BC\r\n close: string; // \uB2EB\uAE30 \uBC84\uD2BC\r\n}\r\n\r\n/** \uCE98\uB9B0\uB354 \uD14D\uC2A4\uD2B8 \uD0C0\uC785 (\uBD80\uBD84 \uCEE4\uC2A4\uD130\uB9C8\uC774\uC9D5\uC6A9) */\r\nexport type CalendarTexts = Partial<CalendarLocale>;\r\n\r\n/** \uD55C\uAD6D\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const koLocale: CalendarLocale = {\r\n weekdays: [\"\uC77C\", \"\uC6D4\", \"\uD654\", \"\uC218\", \"\uBAA9\", \"\uAE08\", \"\uD1A0\"],\r\n months: [\r\n \"1\uC6D4\",\r\n \"2\uC6D4\",\r\n \"3\uC6D4\",\r\n \"4\uC6D4\",\r\n \"5\uC6D4\",\r\n \"6\uC6D4\",\r\n \"7\uC6D4\",\r\n \"8\uC6D4\",\r\n \"9\uC6D4\",\r\n \"10\uC6D4\",\r\n \"11\uC6D4\",\r\n \"12\uC6D4\",\r\n ],\r\n today: \"\uC624\uB298\",\r\n confirm: \"\uD655\uC778\",\r\n cancel: \"\uCDE8\uC18C\",\r\n close: \"\uB2EB\uAE30\",\r\n};\r\n\r\n/** \uC601\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const enLocale: CalendarLocale = {\r\n weekdays: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\r\n months: [\r\n \"Jan\",\r\n \"Feb\",\r\n \"Mar\",\r\n \"Apr\",\r\n \"May\",\r\n \"Jun\",\r\n \"Jul\",\r\n \"Aug\",\r\n \"Sep\",\r\n \"Oct\",\r\n \"Nov\",\r\n \"Dec\",\r\n ],\r\n today: \"Today\",\r\n confirm: \"OK\",\r\n cancel: \"Cancel\",\r\n close: \"Close\",\r\n};\r\n\r\n/** \uC77C\uBCF8\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const jaLocale: CalendarLocale = {\r\n weekdays: [\"\u65E5\", \"\u6708\", \"\u706B\", \"\u6C34\", \"\u6728\", \"\u91D1\", \"\u571F\"],\r\n months: [\r\n \"1\u6708\",\r\n \"2\u6708\",\r\n \"3\u6708\",\r\n \"4\u6708\",\r\n \"5\u6708\",\r\n \"6\u6708\",\r\n \"7\u6708\",\r\n \"8\u6708\",\r\n \"9\u6708\",\r\n \"10\u6708\",\r\n \"11\u6708\",\r\n \"12\u6708\",\r\n ],\r\n today: \"\u4ECA\u65E5\",\r\n confirm: \"\u78BA\u8A8D\",\r\n cancel: \"\u30AD\u30E3\u30F3\u30BB\u30EB\",\r\n close: \"\u9589\u3058\u308B\",\r\n};\r\n\r\n/** \uC911\uAD6D\uC5B4 \uAC04\uCCB4 \uB85C\uCF00\uC77C */\r\nexport const zhCNLocale: CalendarLocale = {\r\n weekdays: [\"\u65E5\", \"\u4E00\", \"\u4E8C\", \"\u4E09\", \"\u56DB\", \"\u4E94\", \"\u516D\"],\r\n months: [\r\n \"1\u6708\",\r\n \"2\u6708\",\r\n \"3\u6708\",\r\n \"4\u6708\",\r\n \"5\u6708\",\r\n \"6\u6708\",\r\n \"7\u6708\",\r\n \"8\u6708\",\r\n \"9\u6708\",\r\n \"10\u6708\",\r\n \"11\u6708\",\r\n \"12\u6708\",\r\n ],\r\n today: \"\u4ECA\u5929\",\r\n confirm: \"\u786E\u8BA4\",\r\n cancel: \"\u53D6\u6D88\",\r\n close: \"\u5173\u95ED\",\r\n};\r\n\r\n/** \uC911\uAD6D\uC5B4 \uBC88\uCCB4 \uB85C\uCF00\uC77C */\r\nexport const zhTWLocale: CalendarLocale = {\r\n weekdays: [\"\u65E5\", \"\u4E00\", \"\u4E8C\", \"\u4E09\", \"\u56DB\", \"\u4E94\", \"\u516D\"],\r\n months: [\r\n \"1\u6708\",\r\n \"2\u6708\",\r\n \"3\u6708\",\r\n \"4\u6708\",\r\n \"5\u6708\",\r\n \"6\u6708\",\r\n \"7\u6708\",\r\n \"8\u6708\",\r\n \"9\u6708\",\r\n \"10\u6708\",\r\n \"11\u6708\",\r\n \"12\u6708\",\r\n ],\r\n today: \"\u4ECA\u5929\",\r\n confirm: \"\u78BA\u8A8D\",\r\n cancel: \"\u53D6\u6D88\",\r\n close: \"\u95DC\u9589\",\r\n};\r\n\r\n/** \uC2A4\uD398\uC778\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const esLocale: CalendarLocale = {\r\n weekdays: [\"Dom\", \"Lun\", \"Mar\", \"Mi\u00E9\", \"Jue\", \"Vie\", \"S\u00E1b\"],\r\n months: [\r\n \"Ene\",\r\n \"Feb\",\r\n \"Mar\",\r\n \"Abr\",\r\n \"May\",\r\n \"Jun\",\r\n \"Jul\",\r\n \"Ago\",\r\n \"Sep\",\r\n \"Oct\",\r\n \"Nov\",\r\n \"Dic\",\r\n ],\r\n today: \"Hoy\",\r\n confirm: \"Aceptar\",\r\n cancel: \"Cancelar\",\r\n close: \"Cerrar\",\r\n};\r\n\r\n/** \uD504\uB791\uC2A4\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const frLocale: CalendarLocale = {\r\n weekdays: [\"Dim\", \"Lun\", \"Mar\", \"Mer\", \"Jeu\", \"Ven\", \"Sam\"],\r\n months: [\r\n \"Jan\",\r\n \"F\u00E9v\",\r\n \"Mar\",\r\n \"Avr\",\r\n \"Mai\",\r\n \"Juin\",\r\n \"Juil\",\r\n \"Ao\u00FB\",\r\n \"Sep\",\r\n \"Oct\",\r\n \"Nov\",\r\n \"D\u00E9c\",\r\n ],\r\n today: \"Aujourd'hui\",\r\n confirm: \"OK\",\r\n cancel: \"Annuler\",\r\n close: \"Fermer\",\r\n};\r\n\r\n/** \uB3C5\uC77C\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const deLocale: CalendarLocale = {\r\n weekdays: [\"So\", \"Mo\", \"Di\", \"Mi\", \"Do\", \"Fr\", \"Sa\"],\r\n months: [\r\n \"Jan\",\r\n \"Feb\",\r\n \"M\u00E4r\",\r\n \"Apr\",\r\n \"Mai\",\r\n \"Jun\",\r\n \"Jul\",\r\n \"Aug\",\r\n \"Sep\",\r\n \"Okt\",\r\n \"Nov\",\r\n \"Dez\",\r\n ],\r\n today: \"Heute\",\r\n confirm: \"OK\",\r\n cancel: \"Abbrechen\",\r\n close: \"Schlie\u00DFen\",\r\n};\r\n\r\n/** \uD3EC\uB974\uD22C\uAC08\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const ptLocale: CalendarLocale = {\r\n weekdays: [\"Dom\", \"Seg\", \"Ter\", \"Qua\", \"Qui\", \"Sex\", \"S\u00E1b\"],\r\n months: [\r\n \"Jan\",\r\n \"Fev\",\r\n \"Mar\",\r\n \"Abr\",\r\n \"Mai\",\r\n \"Jun\",\r\n \"Jul\",\r\n \"Ago\",\r\n \"Set\",\r\n \"Out\",\r\n \"Nov\",\r\n \"Dez\",\r\n ],\r\n today: \"Hoje\",\r\n confirm: \"OK\",\r\n cancel: \"Cancelar\",\r\n close: \"Fechar\",\r\n};\r\n\r\n/** \uB7EC\uC2DC\uC544\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const ruLocale: CalendarLocale = {\r\n weekdays: [\"\u0412\u0441\", \"\u041F\u043D\", \"\u0412\u0442\", \"\u0421\u0440\", \"\u0427\u0442\", \"\u041F\u0442\", \"\u0421\u0431\"],\r\n months: [\r\n \"\u042F\u043D\u0432\",\r\n \"\u0424\u0435\u0432\",\r\n \"\u041C\u0430\u0440\",\r\n \"\u0410\u043F\u0440\",\r\n \"\u041C\u0430\u0439\",\r\n \"\u0418\u044E\u043D\",\r\n \"\u0418\u044E\u043B\",\r\n \"\u0410\u0432\u0433\",\r\n \"\u0421\u0435\u043D\",\r\n \"\u041E\u043A\u0442\",\r\n \"\u041D\u043E\u044F\",\r\n \"\u0414\u0435\u043A\",\r\n ],\r\n today: \"\u0421\u0435\u0433\u043E\u0434\u043D\u044F\",\r\n confirm: \"\u041E\u041A\",\r\n cancel: \"\u041E\u0442\u043C\u0435\u043D\u0430\",\r\n close: \"\u0417\u0430\u043A\u0440\u044B\u0442\u044C\",\r\n};\r\n\r\n/** \uC774\uD0C8\uB9AC\uC544\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const itLocale: CalendarLocale = {\r\n weekdays: [\"Dom\", \"Lun\", \"Mar\", \"Mer\", \"Gio\", \"Ven\", \"Sab\"],\r\n months: [\r\n \"Gen\",\r\n \"Feb\",\r\n \"Mar\",\r\n \"Apr\",\r\n \"Mag\",\r\n \"Giu\",\r\n \"Lug\",\r\n \"Ago\",\r\n \"Set\",\r\n \"Ott\",\r\n \"Nov\",\r\n \"Dic\",\r\n ],\r\n today: \"Oggi\",\r\n confirm: \"OK\",\r\n cancel: \"Annulla\",\r\n close: \"Chiudi\",\r\n};\r\n\r\n/** \uC544\uB78D\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const arLocale: CalendarLocale = {\r\n weekdays: [\"\u0623\u062D\u062F\", \"\u0625\u062B\u0646\", \"\u062B\u0644\u0627\", \"\u0623\u0631\u0628\", \"\u062E\u0645\u064A\", \"\u062C\u0645\u0639\", \"\u0633\u0628\u062A\"],\r\n months: [\r\n \"\u064A\u0646\u0627\u064A\u0631\",\r\n \"\u0641\u0628\u0631\u0627\u064A\u0631\",\r\n \"\u0645\u0627\u0631\u0633\",\r\n \"\u0623\u0628\u0631\u064A\u0644\",\r\n \"\u0645\u0627\u064A\u0648\",\r\n \"\u064A\u0648\u0646\u064A\u0648\",\r\n \"\u064A\u0648\u0644\u064A\u0648\",\r\n \"\u0623\u063A\u0633\u0637\u0633\",\r\n \"\u0633\u0628\u062A\u0645\u0628\u0631\",\r\n \"\u0623\u0643\u062A\u0648\u0628\u0631\",\r\n \"\u0646\u0648\u0641\u0645\u0628\u0631\",\r\n \"\u062F\u064A\u0633\u0645\u0628\u0631\",\r\n ],\r\n today: \"\u0627\u0644\u064A\u0648\u0645\",\r\n confirm: \"\u0645\u0648\u0627\u0641\u0642\",\r\n cancel: \"\u0625\u0644\u063A\u0627\u0621\",\r\n close: \"\u0625\u063A\u0644\u0627\u0642\",\r\n};\r\n\r\n/** \uD78C\uB514\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const hiLocale: CalendarLocale = {\r\n weekdays: [\"\u0930\u0935\u093F\", \"\u0938\u094B\u092E\", \"\u092E\u0902\u0917\u0932\", \"\u092C\u0941\u0927\", \"\u0917\u0941\u0930\u0941\", \"\u0936\u0941\u0915\u094D\u0930\", \"\u0936\u0928\u093F\"],\r\n months: [\r\n \"\u091C\u0928\",\r\n \"\u092B\u0930\",\r\n \"\u092E\u093E\u0930\u094D\u091A\",\r\n \"\u0905\u092A\u094D\u0930\u0948\",\r\n \"\u092E\u0908\",\r\n \"\u091C\u0942\u0928\",\r\n \"\u091C\u0941\u0932\u093E\",\r\n \"\u0905\u0917\",\r\n \"\u0938\u093F\u0924\",\r\n \"\u0905\u0915\u094D\u091F\u0942\",\r\n \"\u0928\u0935\",\r\n \"\u0926\u093F\u0938\",\r\n ],\r\n today: \"\u0906\u091C\",\r\n confirm: \"\u0920\u0940\u0915\",\r\n cancel: \"\u0930\u0926\u094D\u0926\",\r\n close: \"\u092C\u0902\u0926\",\r\n};\r\n\r\n/** \uBCA0\uD2B8\uB0A8\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const viLocale: CalendarLocale = {\r\n weekdays: [\"CN\", \"T2\", \"T3\", \"T4\", \"T5\", \"T6\", \"T7\"],\r\n months: [\r\n \"Th1\",\r\n \"Th2\",\r\n \"Th3\",\r\n \"Th4\",\r\n \"Th5\",\r\n \"Th6\",\r\n \"Th7\",\r\n \"Th8\",\r\n \"Th9\",\r\n \"Th10\",\r\n \"Th11\",\r\n \"Th12\",\r\n ],\r\n today: \"H\u00F4m nay\",\r\n confirm: \"OK\",\r\n cancel: \"H\u1EE7y\",\r\n close: \"\u0110\u00F3ng\",\r\n};\r\n\r\n/** \uD0DC\uAD6D\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const thLocale: CalendarLocale = {\r\n weekdays: [\"\u0E2D\u0E32\", \"\u0E08\", \"\u0E2D\", \"\u0E1E\", \"\u0E1E\u0E24\", \"\u0E28\", \"\u0E2A\"],\r\n months: [\r\n \"\u0E21.\u0E04.\",\r\n \"\u0E01.\u0E1E.\",\r\n \"\u0E21\u0E35.\u0E04.\",\r\n \"\u0E40\u0E21.\u0E22.\",\r\n \"\u0E1E.\u0E04.\",\r\n \"\u0E21\u0E34.\u0E22.\",\r\n \"\u0E01.\u0E04.\",\r\n \"\u0E2A.\u0E04.\",\r\n \"\u0E01.\u0E22.\",\r\n \"\u0E15.\u0E04.\",\r\n \"\u0E1E.\u0E22.\",\r\n \"\u0E18.\u0E04.\",\r\n ],\r\n today: \"\u0E27\u0E31\u0E19\u0E19\u0E35\u0E49\",\r\n confirm: \"\u0E15\u0E01\u0E25\u0E07\",\r\n cancel: \"\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01\",\r\n close: \"\u0E1B\u0E34\u0E14\",\r\n};\r\n\r\n/** \uC778\uB3C4\uB124\uC2DC\uC544\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const idLocale: CalendarLocale = {\r\n weekdays: [\"Min\", \"Sen\", \"Sel\", \"Rab\", \"Kam\", \"Jum\", \"Sab\"],\r\n months: [\r\n \"Jan\",\r\n \"Feb\",\r\n \"Mar\",\r\n \"Apr\",\r\n \"Mei\",\r\n \"Jun\",\r\n \"Jul\",\r\n \"Agu\",\r\n \"Sep\",\r\n \"Okt\",\r\n \"Nov\",\r\n \"Des\",\r\n ],\r\n today: \"Hari ini\",\r\n confirm: \"OK\",\r\n cancel: \"Batal\",\r\n close: \"Tutup\",\r\n};\r\n\r\n/** \uB124\uB35C\uB780\uB4DC\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const nlLocale: CalendarLocale = {\r\n weekdays: [\"Zo\", \"Ma\", \"Di\", \"Wo\", \"Do\", \"Vr\", \"Za\"],\r\n months: [\r\n \"Jan\",\r\n \"Feb\",\r\n \"Mrt\",\r\n \"Apr\",\r\n \"Mei\",\r\n \"Jun\",\r\n \"Jul\",\r\n \"Aug\",\r\n \"Sep\",\r\n \"Okt\",\r\n \"Nov\",\r\n \"Dec\",\r\n ],\r\n today: \"Vandaag\",\r\n confirm: \"OK\",\r\n cancel: \"Annuleren\",\r\n close: \"Sluiten\",\r\n};\r\n\r\n/** \uD3F4\uB780\uB4DC\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const plLocale: CalendarLocale = {\r\n weekdays: [\"Nd\", \"Pn\", \"Wt\", \"\u015Ar\", \"Cz\", \"Pt\", \"So\"],\r\n months: [\r\n \"Sty\",\r\n \"Lut\",\r\n \"Mar\",\r\n \"Kwi\",\r\n \"Maj\",\r\n \"Cze\",\r\n \"Lip\",\r\n \"Sie\",\r\n \"Wrz\",\r\n \"Pa\u017A\",\r\n \"Lis\",\r\n \"Gru\",\r\n ],\r\n today: \"Dzi\u015B\",\r\n confirm: \"OK\",\r\n cancel: \"Anuluj\",\r\n close: \"Zamknij\",\r\n};\r\n\r\n/** \uD130\uD0A4\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const trLocale: CalendarLocale = {\r\n weekdays: [\"Paz\", \"Pzt\", \"Sal\", \"\u00C7ar\", \"Per\", \"Cum\", \"Cmt\"],\r\n months: [\r\n \"Oca\",\r\n \"\u015Eub\",\r\n \"Mar\",\r\n \"Nis\",\r\n \"May\",\r\n \"Haz\",\r\n \"Tem\",\r\n \"A\u011Fu\",\r\n \"Eyl\",\r\n \"Eki\",\r\n \"Kas\",\r\n \"Ara\",\r\n ],\r\n today: \"Bug\u00FCn\",\r\n confirm: \"Tamam\",\r\n cancel: \"\u0130ptal\",\r\n close: \"Kapat\",\r\n};\r\n\r\n/** \uAE30\uBCF8 \uB85C\uCF00\uC77C (\uD55C\uAD6D\uC5B4) */\r\nexport const defaultLocale = koLocale;\r\n\r\n/** \uB85C\uCF00\uC77C \uB9F5 */\r\nexport const locales = {\r\n ko: koLocale,\r\n en: enLocale,\r\n ja: jaLocale,\r\n zhCN: zhCNLocale,\r\n zhTW: zhTWLocale,\r\n es: esLocale,\r\n fr: frLocale,\r\n de: deLocale,\r\n pt: ptLocale,\r\n ru: ruLocale,\r\n it: itLocale,\r\n ar: arLocale,\r\n hi: hiLocale,\r\n vi: viLocale,\r\n th: thLocale,\r\n id: idLocale,\r\n nl: nlLocale,\r\n pl: plLocale,\r\n tr: trLocale,\r\n} as const;\r\n\r\n/** \uB85C\uCF00\uC77C \uD0A4 \uD0C0\uC785 */\r\nexport type LocaleKey = keyof typeof locales;\r\n\r\n/** \uB85C\uCF00\uC77C \uD504\uB86D \uD0C0\uC785 (\uAC1D\uCCB4 \uB610\uB294 \uBB38\uC790\uC5F4) */\r\nexport type LocaleProp = CalendarLocale | LocaleKey;\r\n\r\n/**\r\n * \uB85C\uCF00\uC77C \uD504\uB86D\uC744 CalendarLocale \uAC1D\uCCB4\uB85C \uBCC0\uD658\r\n * @param locale - CalendarLocale \uAC1D\uCCB4 \uB610\uB294 \uB85C\uCF00\uC77C \uD0A4 \uBB38\uC790\uC5F4 (\uC608: 'ko', 'en')\r\n * @returns CalendarLocale \uAC1D\uCCB4\r\n */\r\nexport function resolveLocale(locale: LocaleProp | undefined): CalendarLocale {\r\n if (!locale) return defaultLocale;\r\n if (typeof locale === \"string\") {\r\n return locales[locale] ?? defaultLocale;\r\n }\r\n return locale;\r\n}\r\n", "/**\r\n * SimpleCalendar.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useMemo,\r\n useEffect,\r\n useRef,\r\n useCallback,\r\n} from \"react\";\r\nimport { Box, Typography, IconButton, Button } from \"@mui/material\";\r\nimport { ChevronLeft, ChevronRight } from \"./icons\";\r\nimport { OverlayScrollbar } from \"@ehfuse/overlay-scrollbar\";\r\nimport type { OverlayScrollbarRef } from \"@ehfuse/overlay-scrollbar\";\r\nimport { TimeSelector } from \"./TimeSelector\";\r\nimport type { SimpleCalendarProps, ViewMode } from \"./types\";\r\nimport { resolveLocale } from \"./locale\";\r\nimport {\r\n getWeekInfo,\r\n isSameDay,\r\n isSameWeek,\r\n resolveFooterAndAutoApply,\r\n} from \"./utils\";\r\n\r\n// \uC0C1\uC218\r\nconst HEADER_HEIGHT = 48;\r\nconst FOOTER_HEIGHT = 48;\r\n\r\n/**\r\n * \uAC04\uB2E8\uD55C MUI \uC2A4\uD0C0\uC77C \uB2EC\uB825 \uCEF4\uD3EC\uB10C\uD2B8\r\n *\r\n * \uAD6C\uC870:\r\n * calendar-root (flex column, 100% height)\r\n * \u251C\u2500\u2500 calendar-header (\uACF5\uD1B5, \uACE0\uC815 \uB192\uC774 40px)\r\n * \u2502 - viewMode\uC5D0 \uB530\uB77C \uB0B4\uC6A9 \uBCC0\uACBD\r\n * \u251C\u2500\u2500 calendar-content (flex: 1)\r\n * \u2502 - [calendar] \uC694\uC77C \uD5E4\uB354 + \uB0A0\uC9DC \uADF8\uB9AC\uB4DC\r\n * \u2502 - [year] \uC5F0\uB3C4 \uADF8\uB9AC\uB4DC (OverlayScrollbar)\r\n * \u2502 - [month] \uC6D4 \uADF8\uB9AC\uB4DC\r\n * \u2514\u2500\u2500 calendar-footer (\uACF5\uD1B5, \uACE0\uC815 \uB192\uC774 40px)\r\n * - viewMode\uC5D0 \uB530\uB77C \uBC84\uD2BC \uBCC0\uACBD\r\n */\r\nexport function SimpleCalendar({\r\n selectedDate,\r\n onSelect,\r\n minDate,\r\n maxDate,\r\n holidays = [],\r\n styles,\r\n onClose,\r\n showToday = true,\r\n showFooter: showFooterProp = true,\r\n autoApply: autoApplyProp = true,\r\n // \uB144\uC6D4\uB9CC \uC120\uD0DD\r\n monthOnly = false,\r\n // \uB144\uB3C4\uB9CC \uC120\uD0DD\r\n yearOnly = false,\r\n // \uB144\uC6D4/\uB144\uB3C4 \uBCC0\uACBD \uCF5C\uBC31\r\n onMonthChange,\r\n onYearChange,\r\n onWeekChange,\r\n // \uC2DC\uAC04 \uC120\uD0DD \uAD00\uB828\r\n showTimePicker = false,\r\n timeValue,\r\n onTimeChange,\r\n timeFormat = \"HH:mm\",\r\n minTime,\r\n maxTime,\r\n minuteStep = 1,\r\n secondStep = 1,\r\n hideDisabledTime = false,\r\n // \uB85C\uCF00\uC77C \uAD00\uB828\r\n locale,\r\n texts,\r\n}: SimpleCalendarProps) {\r\n const { showFooter: footerOn, autoApply: applyImmediate } =\r\n resolveFooterAndAutoApply(showFooterProp, autoApplyProp);\r\n\r\n // \uC2A4\uD0C0\uC77C \uC635\uC158 \uCD94\uCD9C (\uAE30\uBCF8\uAC12 \uC801\uC6A9)\r\n const selectedColor = styles?.selectedColor ?? \"primary.main\";\r\n const todayBorderColor = styles?.todayBorderColor ?? selectedColor;\r\n const holidayColor = styles?.holidayColor ?? \"error.main\";\r\n const saturdayColor = styles?.saturdayColor ?? \"primary.main\";\r\n\r\n // \uB85C\uCF00\uC77C \uD574\uC11D \uBC0F \uBCD1\uD569 (texts\uAC00 \uC788\uC73C\uBA74 \uBD80\uBD84 \uB36E\uC5B4\uC4F0\uAE30)\r\n const resolvedLocale = resolveLocale(locale);\r\n const mergedLocale = useMemo(\r\n () => (texts ? { ...resolvedLocale, ...texts } : resolvedLocale),\r\n [resolvedLocale, texts],\r\n );\r\n\r\n // \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 Date \uD544\uD130\uB9C1\r\n const validHolidays = useMemo(\r\n () => holidays.filter((d) => d instanceof Date && !isNaN(d.getTime())),\r\n [holidays],\r\n );\r\n\r\n const today = new Date();\r\n const [viewDate, setViewDate] = useState(() => {\r\n if (selectedDate) return new Date(selectedDate);\r\n return new Date(today.getFullYear(), today.getMonth(), 1);\r\n });\r\n // yearOnly\uC77C \uB54C\uB294 year \uBDF0\uB85C, monthOnly\uC77C \uB54C\uB294 month \uBDF0\uB85C \uC2DC\uC791\r\n const [viewMode, setViewMode] = useState<ViewMode>(\r\n yearOnly ? \"year\" : monthOnly ? \"month\" : \"calendar\",\r\n );\r\n const [tempYear, setTempYear] = useState<number>(viewDate.getFullYear());\r\n // monthOnly \uBAA8\uB4DC\uC5D0\uC11C \uC784\uC2DC \uC6D4 \uC0C1\uD0DC (autoApply\uAC00 false\uC77C \uB54C \uC0AC\uC6A9)\r\n const [tempMonth, setTempMonth] = useState<number | null>(null);\r\n // yearOnly \uBAA8\uB4DC\uC5D0\uC11C \uC784\uC2DC \uB144\uB3C4 \uC0C1\uD0DC (autoApply\uAC00 false\uC77C \uB54C \uC0AC\uC6A9)\r\n const [tempSelectedYear, setTempSelectedYear] = useState<number | null>(\r\n null,\r\n );\r\n // \uC784\uC2DC \uC120\uD0DD \uB0A0\uC9DC (\uD655\uC778 \uBC84\uD2BC \uB204\uB974\uAE30 \uC804\uAE4C\uC9C0 \uBCF4\uAD00)\r\n const [tempSelectedDate, setTempSelectedDate] = useState<Date | null>(\r\n selectedDate,\r\n );\r\n // \uC784\uC2DC \uC2DC\uAC04 (\uD655\uC778 \uBC84\uD2BC \uB204\uB974\uAE30 \uC804\uAE4C\uC9C0 \uBCF4\uAD00)\r\n const [tempTime, setTempTime] = useState<{\r\n hour: number;\r\n minute: number;\r\n second: number;\r\n }>(() => {\r\n const h = timeValue ? parseInt(timeValue.hour, 10) : NaN;\r\n const m = timeValue ? parseInt(timeValue.minute, 10) : NaN;\r\n const s = timeValue?.second ? parseInt(timeValue.second, 10) : 0;\r\n const now = new Date();\r\n return {\r\n hour: isNaN(h) ? now.getHours() : h,\r\n minute: isNaN(m)\r\n ? Math.floor(now.getMinutes() / minuteStep) * minuteStep\r\n : m,\r\n second: isNaN(s)\r\n ? Math.floor(now.getSeconds() / secondStep) * secondStep\r\n : s,\r\n };\r\n });\r\n\r\n const year = viewDate.getFullYear();\r\n const month = viewDate.getMonth();\r\n\r\n // refs\r\n const yearScrollRef = useRef<OverlayScrollbarRef>(null);\r\n const contentRef = useRef<HTMLDivElement>(null);\r\n\r\n // \uB2EC\uB825 \uB0A0\uC9DC \uC0DD\uC131 (\uD56D\uC0C1 42\uCE78 = 6\uC8FC, \uC774\uC804/\uB2E4\uC74C \uB2EC \uD3EC\uD568)\r\n const calendarDays = useMemo(() => {\r\n const firstDay = new Date(year, month, 1);\r\n const lastDay = new Date(year, month + 1, 0);\r\n const startPadding = firstDay.getDay();\r\n const daysInMonth = lastDay.getDate();\r\n\r\n const days: Date[] = [];\r\n\r\n // \uC774\uC804 \uB2EC \uB0A0\uC9DC\r\n const prevMonth = new Date(year, month, 0); // \uC774\uC804 \uB2EC \uB9C8\uC9C0\uB9C9 \uB0A0\r\n const prevMonthDays = prevMonth.getDate();\r\n for (let i = startPadding - 1; i >= 0; i--) {\r\n days.push(new Date(year, month - 1, prevMonthDays - i));\r\n }\r\n\r\n // \uD604\uC7AC \uB2EC\r\n for (let d = 1; d <= daysInMonth; d++) {\r\n days.push(new Date(year, month, d));\r\n }\r\n\r\n // \uB2E4\uC74C \uB2EC \uB0A0\uC9DC (42\uCE78 \uCC44\uC6B0\uAE30)\r\n let nextDay = 1;\r\n while (days.length < 42) {\r\n days.push(new Date(year, month + 1, nextDay++));\r\n }\r\n\r\n return days;\r\n }, [year, month]);\r\n\r\n // \uC5F0\uB3C4 \uBAA9\uB85D \uC0DD\uC131 (\uACFC\uAC70 50\uB144 ~ \uBBF8\uB798 50\uB144)\r\n const yearList = useMemo(() => {\r\n const currentYear = today.getFullYear();\r\n const years: number[] = [];\r\n for (let y = currentYear - 50; y <= currentYear + 50; y++) {\r\n years.push(y);\r\n }\r\n return years;\r\n }, [today]);\r\n\r\n const isDateDisabled = (date: Date): boolean => {\r\n const dateOnly = new Date(\r\n date.getFullYear(),\r\n date.getMonth(),\r\n date.getDate(),\r\n );\r\n\r\n if (minDate) {\r\n const min = new Date(\r\n minDate.getFullYear(),\r\n minDate.getMonth(),\r\n minDate.getDate(),\r\n );\r\n if (dateOnly.getTime() < min.getTime()) return true;\r\n }\r\n if (maxDate) {\r\n const max = new Date(\r\n maxDate.getFullYear(),\r\n maxDate.getMonth(),\r\n maxDate.getDate(),\r\n );\r\n if (dateOnly.getTime() > max.getTime()) return true;\r\n }\r\n return false;\r\n };\r\n\r\n // \uC2DC\uAC04\uC774 \uBCC0\uACBD\uB418\uC5C8\uB294\uC9C0 \uD655\uC778\r\n const isTimeChanged = (\r\n hour: number,\r\n minute: number,\r\n second?: number,\r\n ): boolean => {\r\n if (!timeValue) return true;\r\n const hasSeconds =\r\n timeFormat === \"HH:mm:ss\" || timeFormat === \"hh:mm:ss\";\r\n if (\r\n parseInt(timeValue.hour, 10) !== hour ||\r\n parseInt(timeValue.minute, 10) !== minute\r\n )\r\n return true;\r\n if (hasSeconds && parseInt(timeValue.second || \"0\", 10) !== second)\r\n return true;\r\n return false;\r\n };\r\n\r\n // \uB144\uB3C4\uAC00 \uBCC0\uACBD\uB418\uC5C8\uB294\uC9C0 \uD655\uC778 (selectedDate \uB610\uB294 \uC624\uB298 \uB0A0\uC9DC \uAE30\uC900)\r\n const isYearChanged = (newYear: number): boolean => {\r\n const compareDate = selectedDate || today;\r\n return compareDate.getFullYear() !== newYear;\r\n };\r\n\r\n // \uC6D4\uC774 \uBCC0\uACBD\uB418\uC5C8\uB294\uC9C0 \uD655\uC778 (selectedDate \uB610\uB294 \uC624\uB298 \uB0A0\uC9DC \uAE30\uC900, month\uB294 1-indexed)\r\n const isMonthChanged = (newYear: number, newMonth: number): boolean => {\r\n const compareDate = selectedDate || today;\r\n return (\r\n compareDate.getFullYear() !== newYear ||\r\n compareDate.getMonth() + 1 !== newMonth\r\n );\r\n };\r\n\r\n // \uC8FC\uAC00 \uBCC0\uACBD\uB418\uC5C8\uB294\uC9C0 \uD655\uC778\r\n const isWeekChanged = (date: Date): boolean => {\r\n const compareDate = selectedDate || today;\r\n return !isSameWeek(date, compareDate);\r\n };\r\n\r\n const goToPrevMonth = () => {\r\n const newDate = new Date(year, month - 1, 1);\r\n setViewDate(newDate);\r\n setTempSelectedDate(null);\r\n // \uC6D4 \uBCC0\uACBD \uCF5C\uBC31 \uD638\uCD9C\r\n onMonthChange?.(newDate.getFullYear(), newDate.getMonth() + 1);\r\n };\r\n\r\n const goToNextMonth = () => {\r\n const newDate = new Date(year, month + 1, 1);\r\n setViewDate(newDate);\r\n setTempSelectedDate(null);\r\n // \uC6D4 \uBCC0\uACBD \uCF5C\uBC31 \uD638\uCD9C\r\n onMonthChange?.(newDate.getFullYear(), newDate.getMonth() + 1);\r\n };\r\n\r\n // \uD720 \uC774\uBCA4\uD2B8\uB85C \uC774\uC804/\uB2E4\uC74C \uB2EC \uC774\uB3D9\r\n const handleWheel = useCallback(\r\n (e: React.WheelEvent) => {\r\n if (viewMode !== \"calendar\") return;\r\n e.preventDefault();\r\n if (e.deltaY > 0) {\r\n goToNextMonth();\r\n } else if (e.deltaY < 0) {\r\n goToPrevMonth();\r\n }\r\n },\r\n [viewMode, year, month],\r\n );\r\n\r\n const handleDateClick = (date: Date) => {\r\n if (!isDateDisabled(date)) {\r\n if (applyImmediate) {\r\n // autoApply\uAC00 true\uBA74 \uBC14\uB85C \uC801\uC6A9 (\uB2EB\uC9C0 \uC54A\uC74C)\r\n // \uAC19\uC740 \uB0A0\uC744 \uB2E4\uC2DC \uB20C\uB7EC\uB3C4 \uC0AC\uC6A9\uC790 \uC81C\uC2A4\uCC98\uC774\uBBC0\uB85C \uD56D\uC0C1 onSelect\r\n onSelect(date);\r\n if (isWeekChanged(date)) {\r\n const weekInfo = getWeekInfo(date);\r\n onWeekChange?.(\r\n weekInfo.weekOfMonth,\r\n weekInfo.startDate,\r\n weekInfo.endDate,\r\n );\r\n }\r\n // \uC2DC\uAC04 \uC120\uD0DD\uC774 \uC788\uC73C\uBA74 \uC2DC\uAC04\uB3C4 \uAC19\uC774 \uC801\uC6A9 (\uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC)\r\n if (\r\n showTimePicker &&\r\n onTimeChange &&\r\n isTimeChanged(\r\n tempTime.hour,\r\n tempTime.minute,\r\n tempTime.second,\r\n )\r\n ) {\r\n const hasSeconds =\r\n timeFormat === \"HH:mm:ss\" || timeFormat === \"hh:mm:ss\";\r\n onTimeChange(\r\n tempTime.hour,\r\n tempTime.minute,\r\n hasSeconds ? tempTime.second : undefined,\r\n );\r\n }\r\n } else {\r\n setTempSelectedDate(date);\r\n }\r\n }\r\n };\r\n\r\n const handleTodayClick = () => {\r\n if (!isDateDisabled(today)) {\r\n const todayYear = today.getFullYear();\r\n const todayMonth = today.getMonth();\r\n\r\n if (applyImmediate) {\r\n // autoApply\uAC00 true\uBA74 \uBC14\uB85C \uC801\uC6A9 (\uB2EB\uC9C0 \uC54A\uC74C)\r\n // \uD604\uC7AC viewDate\uC640 \uBE44\uAD50\uD574\uC11C \uB144/\uC6D4 \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n if (year !== todayYear) {\r\n onYearChange?.(todayYear);\r\n }\r\n if (year !== todayYear || month !== todayMonth) {\r\n onMonthChange?.(todayYear, todayMonth + 1);\r\n }\r\n // \uC624\uB298 \uBC84\uD2BC: \uAC19\uC740 \uB0A0(\uC624\uB298)\uC774\uC5B4\uB3C4 \uD56D\uC0C1 onSelect\r\n onSelect(today);\r\n // \uC2DC\uAC04 \uC120\uD0DD\uC774 \uC788\uC73C\uBA74 \uC2DC\uAC04\uB3C4 \uAC19\uC774 \uC801\uC6A9 (\uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC)\r\n if (\r\n showTimePicker &&\r\n onTimeChange &&\r\n isTimeChanged(\r\n tempTime.hour,\r\n tempTime.minute,\r\n tempTime.second,\r\n )\r\n ) {\r\n const hasSeconds =\r\n timeFormat === \"HH:mm:ss\" || timeFormat === \"hh:mm:ss\";\r\n onTimeChange(\r\n tempTime.hour,\r\n tempTime.minute,\r\n hasSeconds ? tempTime.second : undefined,\r\n );\r\n }\r\n setViewDate(new Date(todayYear, todayMonth, 1));\r\n } else {\r\n setTempSelectedDate(today);\r\n setViewDate(new Date(todayYear, todayMonth, 1));\r\n }\r\n }\r\n };\r\n\r\n const handleConfirm = () => {\r\n if (tempSelectedDate) {\r\n // \uD655\uC778: \uC784\uC2DC \uC120\uD0DD\uC774 \uC788\uC73C\uBA74 selectedDate\uC640 \uAC19\uC544\uB3C4 \uD56D\uC0C1 onSelect\r\n onSelect(tempSelectedDate);\r\n if (isWeekChanged(tempSelectedDate)) {\r\n const weekInfo = getWeekInfo(tempSelectedDate);\r\n onWeekChange?.(\r\n weekInfo.weekOfMonth,\r\n weekInfo.startDate,\r\n weekInfo.endDate,\r\n );\r\n }\r\n }\r\n // \uC2DC\uAC04 \uC120\uD0DD\uC774 \uC788\uC73C\uBA74 \uC2DC\uAC04\uB3C4 \uC801\uC6A9 (\uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC)\r\n if (\r\n showTimePicker &&\r\n onTimeChange &&\r\n isTimeChanged(tempTime.hour, tempTime.minute, tempTime.second)\r\n ) {\r\n const hasSeconds =\r\n timeFormat === \"HH:mm:ss\" || timeFormat === \"hh:mm:ss\";\r\n onTimeChange(\r\n tempTime.hour,\r\n tempTime.minute,\r\n hasSeconds ? tempTime.second : undefined,\r\n );\r\n }\r\n onClose();\r\n };\r\n\r\n // \uC784\uC2DC \uC2DC\uAC04 \uBCC0\uACBD \uD578\uB4E4\uB7EC\r\n const handleTempTimeChange = (\r\n hour: number,\r\n minute: number,\r\n second?: number,\r\n ) => {\r\n setTempTime({\r\n hour,\r\n minute,\r\n second: second ?? 0,\r\n });\r\n\r\n // autoApply\uBA74 \uBC14\uB85C \uC801\uC6A9 (\uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC)\r\n if (applyImmediate && onTimeChange && isTimeChanged(hour, minute, second)) {\r\n const hasSeconds =\r\n timeFormat === \"HH:mm:ss\" || timeFormat === \"hh:mm:ss\";\r\n onTimeChange(hour, minute, hasSeconds ? second : undefined);\r\n }\r\n };\r\n\r\n // \uB144\uC6D4 \uD0C0\uC774\uD2C0 \uD074\uB9AD \u2192 \uC5F0\uB3C4 \uC120\uD0DD \uBAA8\uB4DC\r\n const handleTitleClick = () => {\r\n setTempYear(year);\r\n setViewMode(\"year\");\r\n };\r\n\r\n // \uC5F0\uB3C4 \uC120\uD0DD\r\n const handleYearSelect = (selectedYear: number) => {\r\n if (yearOnly) {\r\n if (applyImmediate) {\r\n // autoApply\uAC00 true\uBA74 \uBC14\uB85C \uC801\uC6A9\uD558\uACE0 \uB2EB\uAE30 (\uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC)\r\n if (isYearChanged(selectedYear)) {\r\n onYearChange?.(selectedYear);\r\n }\r\n onClose();\r\n } else {\r\n // autoApply\uAC00 false\uBA74 \uC784\uC2DC \uC800\uC7A5\uB9CC\r\n setTempSelectedYear(selectedYear);\r\n }\r\n } else if (monthOnly) {\r\n // monthOnly \uBAA8\uB4DC: \uC6D4\uAE4C\uC9C0 \uC120\uD0DD\uD574\uC57C \uCD5C\uC885\uC774\uBBC0\uB85C \uB144\uB3C4 \uC120\uD0DD \uC2DC\uC5D0\uB294 \uC774\uBCA4\uD2B8 \uBC1C\uC0DD \uC548\uD568\r\n setTempYear(selectedYear);\r\n setViewMode(\"month\");\r\n } else {\r\n // \uC77C\uBC18 \uCE98\uB9B0\uB354 \uBAA8\uB4DC: \uB144\uB3C4 \uC120\uD0DD \uC2DC onYearChange \uD638\uCD9C (\uD604\uC7AC viewDate \uAE30\uC900)\r\n if (year !== selectedYear) {\r\n onYearChange?.(selectedYear);\r\n }\r\n setTempYear(selectedYear);\r\n setViewMode(\"month\");\r\n }\r\n };\r\n\r\n // yearOnly \uBAA8\uB4DC\uC5D0\uC11C \uD655\uC778 \uBC84\uD2BC \uD074\uB9AD\r\n const handleYearConfirm = () => {\r\n if (tempSelectedYear !== null) {\r\n // \uB144\uB3C4\uAC00 \uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n if (isYearChanged(tempSelectedYear)) {\r\n onYearChange?.(tempSelectedYear);\r\n }\r\n }\r\n onClose();\r\n };\r\n\r\n // \uC6D4 \uC120\uD0DD\r\n const handleMonthSelect = (selectedMonth: number) => {\r\n if (monthOnly) {\r\n if (applyImmediate) {\r\n // autoApply\uAC00 true\uBA74 \uBC14\uB85C \uC801\uC6A9\uD558\uACE0 \uB2EB\uAE30 (\uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC)\r\n if (isYearChanged(tempYear)) {\r\n onYearChange?.(tempYear);\r\n }\r\n if (isMonthChanged(tempYear, selectedMonth + 1)) {\r\n onMonthChange?.(tempYear, selectedMonth + 1);\r\n }\r\n onClose();\r\n } else {\r\n // autoApply\uAC00 false\uBA74 \uC784\uC2DC \uC800\uC7A5\uB9CC\r\n setTempMonth(selectedMonth);\r\n }\r\n } else {\r\n // \uC77C\uBC18 \uCE98\uB9B0\uB354 \uBAA8\uB4DC: \uB144/\uC6D4 \uC120\uD0DD \uBDF0\uC5D0\uC11C \uC6D4\uC744 \uC120\uD0DD\uD558\uBA74 \uD574\uB2F9 \uC6D4\uB85C \uC774\uB3D9\r\n const newDate = new Date(tempYear, selectedMonth, 1);\r\n // \uC6D4 \uBCC0\uACBD \uCF5C\uBC31 \uD638\uCD9C (\uD604\uC7AC viewDate \uAE30\uC900\uC73C\uB85C \uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC)\r\n if (year !== tempYear || month !== selectedMonth) {\r\n onMonthChange?.(tempYear, selectedMonth + 1);\r\n }\r\n setViewDate(newDate);\r\n setViewMode(\"calendar\");\r\n setTempSelectedDate(null);\r\n }\r\n };\r\n\r\n // monthOnly \uBAA8\uB4DC\uC5D0\uC11C \uD655\uC778 \uBC84\uD2BC \uD074\uB9AD\r\n const handleMonthConfirm = () => {\r\n if (tempMonth !== null) {\r\n // \uB144\uC6D4\uC774 \uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n if (isYearChanged(tempYear)) {\r\n onYearChange?.(tempYear);\r\n }\r\n if (isMonthChanged(tempYear, tempMonth + 1)) {\r\n onMonthChange?.(tempYear, tempMonth + 1);\r\n }\r\n }\r\n onClose();\r\n };\r\n\r\n // \uC5F0\uB3C4 \uC120\uD0DD \uBDF0\uAC00 \uC5F4\uB9B4 \uB54C \uD604\uC7AC\uB144\uB3C4\uB97C \uC911\uC559\uC5D0 \uC704\uCE58\r\n useEffect(() => {\r\n if (\r\n viewMode === \"year\" &&\r\n yearScrollRef.current &&\r\n contentRef.current\r\n ) {\r\n // DOM\uC774 \uB80C\uB354\uB9C1\uB41C \uD6C4 \uC2E4\uC81C \uB192\uC774\uB97C \uACC4\uC0B0\r\n requestAnimationFrame(() => {\r\n if (!yearScrollRef.current || !contentRef.current) return;\r\n\r\n const currentYear = today.getFullYear();\r\n const yearIndex = yearList.findIndex((y) => y === currentYear);\r\n if (yearIndex < 0) return;\r\n\r\n // \uC2E4\uC81C \uADF8\uB9AC\uB4DC \uC694\uC18C \uCC3E\uAE30\r\n const scrollContainer = contentRef.current.querySelector(\r\n \".overlay-scrollbar-content\",\r\n ) as HTMLElement;\r\n const gridElement = scrollContainer?.querySelector(\r\n \"[class*='MuiBox-root']\",\r\n ) as HTMLElement;\r\n\r\n if (!gridElement) return;\r\n\r\n // \uCCAB \uBC88\uC9F8 \uC5F0\uB3C4 \uC544\uC774\uD15C\uC758 \uC2E4\uC81C \uB192\uC774 \uAC00\uC838\uC624\uAE30\r\n const firstYearItem = gridElement.children[0] as HTMLElement;\r\n if (!firstYearItem) return;\r\n\r\n const itemHeight = firstYearItem.offsetHeight;\r\n const gap = 4; // gap: 0.5 = 4px\r\n const rowHeight = itemHeight + gap;\r\n\r\n const rowIndex = Math.floor(yearIndex / 4);\r\n const containerHeight = contentRef.current.clientHeight;\r\n const visibleRows = Math.floor(containerHeight / rowHeight);\r\n const centerRowOffset = Math.floor(visibleRows / 2);\r\n\r\n const scrollTop = (rowIndex - centerRowOffset) * rowHeight;\r\n yearScrollRef.current.scrollTo({\r\n top: Math.max(0, scrollTop),\r\n });\r\n });\r\n }\r\n }, [viewMode, yearList, today]);\r\n\r\n // \uD5E4\uB354 \uB80C\uB354\uB9C1 (viewMode\uC5D0 \uB530\uB77C \uB2E4\uB984)\r\n const renderHeader = () => {\r\n if (viewMode === \"year\") {\r\n // monthOnly \uB610\uB294 yearOnly \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uB4A4\uB85C \uAC08 \uACF3\uC774 \uC5C6\uC73C\uBBC0\uB85C < \uBC84\uD2BC \uC228\uAE40\r\n if (monthOnly || yearOnly) {\r\n return (\r\n <Typography variant=\"body2\" fontWeight={600}>\r\n \uC5F0\uB3C4 \uC120\uD0DD\r\n </Typography>\r\n );\r\n }\r\n // \uC77C\uBC18 \uCE98\uB9B0\uB354\uC5D0\uC11C \uB144\uB3C4 \uC120\uD0DD\uC73C\uB85C \uC654\uC744 \uB54C\uB294 < \uBC84\uD2BC \uD45C\uC2DC\r\n return (\r\n <>\r\n <IconButton\r\n size=\"small\"\r\n onClick={() => {\r\n // \uB4A4\uB85C\uAC00\uAE30 \uC2DC tempYear\uAC00 \uD604\uC7AC viewDate\uC758 year\uC640 \uB2E4\uB974\uBA74 onYearChange \uBC1C\uC0DD\r\n if (tempYear !== year) {\r\n onYearChange?.(year);\r\n }\r\n setTempYear(year);\r\n setViewMode(\"calendar\");\r\n }}\r\n >\r\n <ChevronLeft />\r\n </IconButton>\r\n <Typography\r\n variant=\"body2\"\r\n fontWeight={600}\r\n sx={{ flex: 1, textAlign: \"center\" }}\r\n >\r\n \uC5F0\uB3C4 \uC120\uD0DD\r\n </Typography>\r\n <Box sx={{ width: 28 }} />\r\n </>\r\n );\r\n }\r\n if (viewMode === \"month\") {\r\n return (\r\n <>\r\n <IconButton\r\n size=\"small\"\r\n onClick={() => setViewMode(\"year\")}\r\n >\r\n <ChevronLeft />\r\n </IconButton>\r\n <Typography\r\n variant=\"body2\"\r\n fontWeight={600}\r\n sx={{ flex: 1, textAlign: \"center\" }}\r\n >\r\n {tempYear}\uB144 - \uC6D4 \uC120\uD0DD\r\n </Typography>\r\n <Box sx={{ width: 28 }} /> {/* \uADE0\uD615\uC744 \uC704\uD55C \uBE48 \uACF5\uAC04 */}\r\n </>\r\n );\r\n }\r\n // calendar mode\r\n return (\r\n <>\r\n <IconButton size=\"small\" onClick={goToPrevMonth}>\r\n <ChevronLeft />\r\n </IconButton>\r\n <Typography\r\n variant=\"body2\"\r\n fontWeight={600}\r\n onClick={handleTitleClick}\r\n sx={{\r\n cursor: \"pointer\",\r\n px: 1,\r\n py: 0.5,\r\n borderRadius: 1,\r\n \"&:hover\": {\r\n bgcolor: \"action.hover\",\r\n },\r\n transition: \"background-color 0.15s\",\r\n }}\r\n >\r\n {year}\uB144 {mergedLocale.months[month]}\r\n </Typography>\r\n <IconButton size=\"small\" onClick={goToNextMonth}>\r\n <ChevronRight />\r\n </IconButton>\r\n </>\r\n );\r\n };\r\n\r\n // \uCF58\uD150\uCE20 \uB80C\uB354\uB9C1 (viewMode\uC5D0 \uB530\uB77C \uB2E4\uB984)\r\n const renderContent = () => {\r\n if (viewMode === \"year\") {\r\n return (\r\n <OverlayScrollbar\r\n ref={yearScrollRef}\r\n style={{ width: \"100%\", height: \"100%\" }}\r\n containerStyle={{ padding: \"12px\" }}\r\n thumb={{ width: 6, color: \"rgba(100, 100, 100, 0.5)\" }}\r\n track={{ alignment: \"right\", margin: 0 }}\r\n autoHide={{ enabled: true, delay: 1000 }}\r\n >\r\n <Box\r\n sx={{\r\n display: \"grid\",\r\n gridTemplateColumns: \"repeat(4, 1fr)\",\r\n gap: 0.5,\r\n }}\r\n >\r\n {yearList.map((y) => {\r\n // yearOnly \uBAA8\uB4DC\uC5D0\uC11C\uB294 tempSelectedYear\uB97C, \uADF8 \uC678\uC5D0\uB294 tempYear\uB97C \uAE30\uC900\uC73C\uB85C \uC120\uD0DD \uD45C\uC2DC\r\n const isSelected = yearOnly\r\n ? tempSelectedYear === y\r\n : y === tempYear;\r\n const isCurrent = y === today.getFullYear();\r\n return (\r\n <Box\r\n key={y}\r\n sx={{\r\n display: \"flex\",\r\n justifyContent: \"center\",\r\n }}\r\n >\r\n <Box\r\n onClick={() => handleYearSelect(y)}\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n py: 0.75,\r\n px: 1.5,\r\n borderRadius: 1,\r\n cursor: \"pointer\",\r\n bgcolor: isSelected\r\n ? selectedColor\r\n : \"transparent\",\r\n color: isSelected\r\n ? \"primary.contrastText\"\r\n : \"text.primary\",\r\n border:\r\n isCurrent && !isSelected\r\n ? 1\r\n : 0,\r\n borderColor: selectedColor,\r\n fontSize: \"0.8rem\",\r\n fontWeight:\r\n isSelected || isCurrent\r\n ? 600\r\n : 400,\r\n \"&:hover\": {\r\n bgcolor: isSelected\r\n ? selectedColor\r\n : \"action.hover\",\r\n transform: \"scale(1.05)\",\r\n },\r\n transition:\r\n \"background-color 0.15s, transform 0.15s\",\r\n }}\r\n >\r\n {y}\r\n </Box>\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n </OverlayScrollbar>\r\n );\r\n }\r\n\r\n if (viewMode === \"month\") {\r\n return (\r\n <Box\r\n className=\"month-grid\"\r\n sx={{\r\n display: \"grid\",\r\n gridTemplateColumns: \"repeat(3, 1fr)\",\r\n gridTemplateRows: \"repeat(4, 1fr)\",\r\n gap: 1,\r\n width: \"100%\",\r\n height: \"100%\",\r\n p: 2,\r\n boxSizing: \"border-box\",\r\n }}\r\n >\r\n {mergedLocale.months.map(\r\n (monthName: string, index: number) => {\r\n // monthOnly \uBAA8\uB4DC\uC5D0\uC11C\uB294 tempMonth\uB97C, \uADF8 \uC678\uC5D0\uB294 \uD604\uC7AC viewDate\uC758 month\uB97C \uAE30\uC900\uC73C\uB85C \uC120\uD0DD \uD45C\uC2DC\r\n const isSelected = monthOnly\r\n ? tempMonth === index\r\n : tempYear === year && index === month;\r\n const isCurrent =\r\n tempYear === today.getFullYear() &&\r\n index === today.getMonth();\r\n return (\r\n <Box\r\n key={monthName}\r\n onClick={() => handleMonthSelect(index)}\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n borderRadius: 1,\r\n cursor: \"pointer\",\r\n bgcolor: isSelected\r\n ? selectedColor\r\n : \"transparent\",\r\n color: isSelected\r\n ? \"primary.contrastText\"\r\n : \"text.primary\",\r\n border:\r\n isCurrent && !isSelected ? 1 : 0,\r\n borderColor: selectedColor,\r\n fontSize: \"0.875rem\",\r\n fontWeight:\r\n isSelected || isCurrent ? 600 : 400,\r\n \"&:hover\": {\r\n bgcolor: isSelected\r\n ? selectedColor\r\n : \"action.hover\",\r\n transform: \"scale(1.05)\",\r\n },\r\n transition:\r\n \"background-color 0.15s, transform 0.15s\",\r\n }}\r\n >\r\n {monthName}\r\n </Box>\r\n );\r\n },\r\n )}\r\n </Box>\r\n );\r\n }\r\n\r\n // calendar mode\r\n return (\r\n <Box\r\n className=\"calendar-grid\"\r\n onWheel={handleWheel}\r\n sx={{\r\n width: \"100%\",\r\n height: \"100%\",\r\n px: 2,\r\n boxSizing: \"border-box\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n }}\r\n >\r\n {/* \uC694\uC77C \uD5E4\uB354 */}\r\n <Box\r\n sx={{\r\n display: \"grid\",\r\n gridTemplateColumns: \"repeat(7, 1fr)\",\r\n gap: 0,\r\n mb: 0.5,\r\n }}\r\n >\r\n {mergedLocale.weekdays.map((day: string, i: number) => (\r\n <Box\r\n key={day}\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n height: 22,\r\n fontSize: \"0.7rem\",\r\n color:\r\n i === 0\r\n ? holidayColor\r\n : i === 6\r\n ? saturdayColor\r\n : \"text.secondary\",\r\n fontWeight: 500,\r\n }}\r\n >\r\n {day}\r\n </Box>\r\n ))}\r\n </Box>\r\n\r\n {/* \uB0A0\uC9DC \uADF8\uB9AC\uB4DC */}\r\n <Box\r\n sx={{\r\n flex: 1,\r\n display: \"grid\",\r\n gridTemplateColumns: \"repeat(7, 1fr)\",\r\n gridTemplateRows: \"repeat(6, 1fr)\",\r\n gap: 0,\r\n }}\r\n >\r\n {calendarDays.map((date, index) => {\r\n // autoApply\uC77C \uB54C\uB294 selectedDate\uB9CC, \uC544\uB2D0 \uB54C\uB294 tempSelectedDate \uC6B0\uC120\r\n const isSelected = applyImmediate\r\n ? isSameDay(date, selectedDate)\r\n : isSameDay(date, tempSelectedDate ?? selectedDate);\r\n const isToday = isSameDay(date, today);\r\n const isDisabled = isDateDisabled(date);\r\n const dayOfWeek = date.getDay();\r\n const isCurrentMonth = date.getMonth() === month;\r\n const isHoliday = validHolidays.some((h) =>\r\n isSameDay(h, date),\r\n );\r\n\r\n return (\r\n <Box\r\n key={`${date.toISOString()}-${index}`}\r\n onClick={() =>\r\n !isDisabled && handleDateClick(date)\r\n }\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n width: 32,\r\n height: 32,\r\n mx: \"auto\",\r\n borderRadius: \"50%\",\r\n cursor: isDisabled ? \"default\" : \"pointer\",\r\n bgcolor: isSelected\r\n ? selectedColor\r\n : \"transparent\",\r\n color: isDisabled\r\n ? \"text.disabled\"\r\n : isSelected\r\n ? \"primary.contrastText\"\r\n : !isCurrentMonth\r\n ? \"text.disabled\"\r\n : isHoliday || dayOfWeek === 0\r\n ? holidayColor\r\n : dayOfWeek === 6\r\n ? saturdayColor\r\n : \"text.primary\",\r\n opacity: isCurrentMonth ? 1 : 0.4,\r\n border: isToday ? 1 : 0,\r\n borderColor: todayBorderColor,\r\n \"&:hover\": {\r\n bgcolor: isDisabled\r\n ? \"transparent\"\r\n : isSelected\r\n ? selectedColor\r\n : \"action.hover\",\r\n },\r\n transition: \"background-color 0.15s\",\r\n fontSize: \"0.75rem\",\r\n fontWeight:\r\n isSelected || isToday ? 600 : 400,\r\n }}\r\n >\r\n {date.getDate()}\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n </Box>\r\n );\r\n };\r\n\r\n // \uD478\uD130 \uB80C\uB354\uB9C1 (viewMode\uC5D0 \uB530\uB77C \uB2E4\uB984)\r\n const renderFooter = () => {\r\n // yearOnly \uBAA8\uB4DC\uC77C \uB54C\r\n if (yearOnly) {\r\n if (applyImmediate) {\r\n // autoApply\uAC00 true\uBA74 \uD478\uD130 \uBD88\uD544\uC694\r\n return null;\r\n }\r\n // autoApply\uAC00 false\uBA74 \uD655\uC778/\uCDE8\uC18C \uBC84\uD2BC \uD45C\uC2DC\r\n return (\r\n <>\r\n <Box sx={{ flex: 1 }} />\r\n <Button size=\"small\" onClick={onClose}>\r\n {mergedLocale.cancel}\r\n </Button>\r\n <Button\r\n size=\"small\"\r\n onClick={handleYearConfirm}\r\n variant=\"contained\"\r\n disabled={tempSelectedYear === null}\r\n >\r\n {mergedLocale.confirm}\r\n </Button>\r\n </>\r\n );\r\n }\r\n\r\n // monthOnly \uBAA8\uB4DC\uC77C \uB54C\r\n if (monthOnly) {\r\n if (applyImmediate) {\r\n // autoApply\uAC00 true\uBA74 \uD478\uD130 \uBD88\uD544\uC694\r\n return null;\r\n }\r\n // autoApply\uAC00 false\uBA74 \uD655\uC778/\uCDE8\uC18C \uBC84\uD2BC \uD45C\uC2DC\r\n return (\r\n <>\r\n <Box sx={{ flex: 1 }} />\r\n <Button size=\"small\" onClick={onClose}>\r\n {mergedLocale.cancel}\r\n </Button>\r\n <Button\r\n size=\"small\"\r\n onClick={handleMonthConfirm}\r\n variant=\"contained\"\r\n disabled={tempMonth === null}\r\n >\r\n {mergedLocale.confirm}\r\n </Button>\r\n </>\r\n );\r\n }\r\n\r\n if (viewMode === \"year\") {\r\n return (\r\n <Button size=\"small\" onClick={() => setViewMode(\"calendar\")}>\r\n {mergedLocale.cancel}\r\n </Button>\r\n );\r\n }\r\n if (viewMode === \"month\") {\r\n return (\r\n <Button\r\n size=\"small\"\r\n onClick={() => setViewMode(\"calendar\")}\r\n sx={{ px: 2 }}\r\n >\r\n {mergedLocale.cancel}\r\n </Button>\r\n );\r\n }\r\n // calendar mode - autoApply\uBA74 \uB2EB\uAE30 \uBC84\uD2BC\uB9CC \uD45C\uC2DC\r\n if (applyImmediate) {\r\n return (\r\n <>\r\n {showToday && (\r\n <Button\r\n size=\"small\"\r\n onClick={handleTodayClick}\r\n disabled={isDateDisabled(today)}\r\n >\r\n {mergedLocale.today}\r\n </Button>\r\n )}\r\n <Box sx={{ flex: 1 }} />\r\n <Button size=\"small\" onClick={onClose}>\r\n {mergedLocale.close}\r\n </Button>\r\n </>\r\n );\r\n }\r\n return (\r\n <>\r\n {showToday && (\r\n <Button\r\n size=\"small\"\r\n onClick={handleTodayClick}\r\n disabled={isDateDisabled(today)}\r\n >\r\n {mergedLocale.today}\r\n </Button>\r\n )}\r\n <Box sx={{ flex: 1 }} />\r\n <Button size=\"small\" onClick={onClose}>\r\n {mergedLocale.cancel}\r\n </Button>\r\n <Button\r\n size=\"small\"\r\n onClick={handleConfirm}\r\n variant=\"contained\"\r\n disabled={tempSelectedDate === null}\r\n >\r\n {mergedLocale.confirm}\r\n </Button>\r\n </>\r\n );\r\n };\r\n\r\n // \uD478\uD130 \uD45C\uC2DC \uC5EC\uBD80 \uACB0\uC815 (footerOn\uC774 false\uBA74 \uBB34\uC870\uAC74 \uC228\uAE40)\r\n const showFooter =\r\n footerOn &&\r\n (yearOnly\r\n ? !applyImmediate // yearOnly\uC77C \uB54C\uB294 autoApply\uAC00 false\uBA74 \uD56D\uC0C1 \uD45C\uC2DC\r\n : monthOnly\r\n ? !applyImmediate // monthOnly\uC77C \uB54C\uB294 autoApply\uAC00 false\uBA74 \uD56D\uC0C1 \uD45C\uC2DC (year/month \uBDF0 \uBAA8\uB450)\r\n : !(applyImmediate && !showToday) && viewMode === \"calendar\"); // calendar \uBDF0\uC77C \uB54C\uB9CC \uD45C\uC2DC, year/month \uBDF0\uB294 \uD478\uD130 \uC228\uAE40\r\n\r\n // \uD1B5\uD569\uB41C \uAD6C\uC870\uB85C \uB80C\uB354\uB9C1\r\n const calendarContent = (\r\n <Box\r\n className={`calendar-root calendar-${viewMode}-view`}\r\n sx={{\r\n width: \"100%\",\r\n height: \"100%\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n boxSizing: \"border-box\",\r\n }}\r\n >\r\n {/* \uACF5\uD1B5 \uD5E4\uB354 */}\r\n <Box\r\n className=\"calendar-header\"\r\n sx={{\r\n height: HEADER_HEIGHT,\r\n minHeight: HEADER_HEIGHT,\r\n px: 2,\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent:\r\n viewMode === \"calendar\" ? \"space-between\" : \"center\",\r\n ...(viewMode !== \"calendar\" && {\r\n borderBottom: \"1px solid\",\r\n borderColor: \"divider\",\r\n }),\r\n }}\r\n >\r\n {renderHeader()}\r\n </Box>\r\n\r\n {/* \uCF58\uD150\uCE20 \uC601\uC5ED */}\r\n <Box\r\n ref={contentRef}\r\n className=\"calendar-content\"\r\n sx={{\r\n flex: \"1 1 0\",\r\n minHeight: 0,\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n overflow: \"hidden\",\r\n pb: 1,\r\n }}\r\n >\r\n {renderContent()}\r\n </Box>\r\n </Box>\r\n );\r\n\r\n // \uACF5\uD1B5 \uD478\uD130 \uCEF4\uD3EC\uB10C\uD2B8\r\n const footerContent = showFooter ? (\r\n <Box\r\n className=\"calendar-footer\"\r\n sx={{\r\n height: FOOTER_HEIGHT,\r\n minHeight: FOOTER_HEIGHT,\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-start\",\r\n gap: 1,\r\n px: 1,\r\n borderTop: \"1px solid\",\r\n borderColor: \"divider\",\r\n }}\r\n >\r\n {renderFooter()}\r\n </Box>\r\n ) : null;\r\n\r\n // \uC2DC\uAC04 \uC120\uD0DD\uC774 \uC5C6\uC73C\uBA74 \uB2EC\uB825 + \uD478\uD130\r\n if (!showTimePicker) {\r\n return (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n height: \"100%\",\r\n userSelect: \"none\",\r\n }}\r\n >\r\n {calendarContent}\r\n {footerContent}\r\n </Box>\r\n );\r\n }\r\n\r\n // \uC2DC\uAC04 \uC120\uD0DD\uC774 \uC788\uC73C\uBA74 \uC804\uCCB4 column: \uC0C1\uB2E8(\uB2EC\uB825+\uC2DC\uAC04 row) + \uD558\uB2E8(footer)\r\n return (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n height: \"100%\",\r\n userSelect: \"none\",\r\n }}\r\n >\r\n {/* \uC0C1\uB2E8: \uB2EC\uB825 + \uC2DC\uAC04 (row) */}\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n flex: 1,\r\n minHeight: 0,\r\n overflow: \"hidden\",\r\n }}\r\n >\r\n {/* \uB2EC\uB825 \uC601\uC5ED - \uACE0\uC815 \uB108\uBE44 300px */}\r\n <Box\r\n sx={{\r\n width: 300,\r\n flex: \"0 0 300px\",\r\n borderRight: \"1px solid\",\r\n borderColor: \"divider\",\r\n }}\r\n >\r\n {calendarContent}\r\n </Box>\r\n\r\n {/* \uC2DC\uAC04 \uC120\uD0DD \uC601\uC5ED */}\r\n <Box\r\n sx={{\r\n flex: 1,\r\n minWidth: 0,\r\n height: \"100%\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n overflow: \"hidden\",\r\n }}\r\n >\r\n <TimeSelector\r\n value={{\r\n hour: String(tempTime.hour).padStart(2, \"0\"),\r\n minute: String(tempTime.minute).padStart(2, \"0\"),\r\n second: String(tempTime.second).padStart(2, \"0\"),\r\n }}\r\n onChange={handleTempTimeChange}\r\n format={timeFormat}\r\n minTime={minTime}\r\n maxTime={maxTime}\r\n minuteStep={minuteStep}\r\n secondStep={secondStep}\r\n showHeader={true}\r\n hideDisabledTime={hideDisabledTime}\r\n />\r\n </Box>\r\n </Box>\r\n\r\n {/* \uD558\uB2E8: \uD478\uD130 (\uC804\uCCB4 \uB108\uBE44) */}\r\n {footerContent}\r\n </Box>\r\n );\r\n}\r\n", "/**\r\n * icons/index.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\ninterface IconProps {\r\n size?: \"small\" | \"medium\" | \"large\" | number;\r\n color?: string;\r\n}\r\n\r\nconst getSizeValue = (size: IconProps[\"size\"]) => {\r\n if (typeof size === \"number\") return size;\r\n switch (size) {\r\n case \"small\":\r\n return 16;\r\n case \"large\":\r\n return 28;\r\n case \"medium\":\r\n default:\r\n return 20;\r\n }\r\n};\r\n\r\nexport const ChevronLeft: React.FC<IconProps> = ({\r\n size = \"medium\",\r\n color = \"currentColor\",\r\n}) => {\r\n const s = getSizeValue(size);\r\n return (\r\n <svg\r\n width={s}\r\n height={s}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke={color}\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <polyline points=\"15 18 9 12 15 6\" />\r\n </svg>\r\n );\r\n};\r\n\r\nexport const ChevronRight: React.FC<IconProps> = ({\r\n size = \"medium\",\r\n color = \"currentColor\",\r\n}) => {\r\n const s = getSizeValue(size);\r\n return (\r\n <svg\r\n width={s}\r\n height={s}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke={color}\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <polyline points=\"9 18 15 12 9 6\" />\r\n </svg>\r\n );\r\n};\r\n\r\nexport const ColonIcon: React.FC<IconProps> = ({\r\n size = \"medium\",\r\n color = \"currentColor\",\r\n}) => {\r\n const s = getSizeValue(size);\r\n return (\r\n <svg width={s} height={s} viewBox=\"0 0 24 24\" fill={color}>\r\n <circle cx=\"12\" cy=\"8\" r=\"2\" />\r\n <circle cx=\"12\" cy=\"16\" r=\"2\" />\r\n </svg>\r\n );\r\n};\r\n", "/**\r\n * TimeSelector.tsx\r\n * \uC2DC\uAC04 \uC120\uD0DD UI \uCEF4\uD3EC\uB10C\uD2B8 (\uC7AC\uC0AC\uC6A9 \uAC00\uB2A5)\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { useState, useEffect, useRef, useCallback } from \"react\";\r\nimport { Box, Typography } from \"@mui/material\";\r\nimport { OverlayScrollbar } from \"@ehfuse/overlay-scrollbar\";\r\nimport type { OverlayScrollbarRef } from \"@ehfuse/overlay-scrollbar\";\r\nimport { ColonIcon } from \"./icons\";\r\nimport type { TimeSelectorProps } from \"./types\";\r\n\r\nexport function TimeSelector({\r\n value,\r\n onChange,\r\n format,\r\n minTime,\r\n maxTime,\r\n minuteStep = 1,\r\n secondStep = 1,\r\n showHeader = true,\r\n hideDisabledTime = false,\r\n}: TimeSelectorProps) {\r\n const [selectedHour, setSelectedHour] = useState<number | null>(() => {\r\n const h = parseInt(value.hour, 10);\r\n if (!isNaN(h)) return h;\r\n return new Date().getHours();\r\n });\r\n const [selectedMinute, setSelectedMinute] = useState<number | null>(() => {\r\n const m = parseInt(value.minute, 10);\r\n if (!isNaN(m)) return Math.floor(m / minuteStep) * minuteStep;\r\n return Math.floor(new Date().getMinutes() / minuteStep) * minuteStep;\r\n });\r\n const [selectedSecond, setSelectedSecond] = useState<number | null>(() => {\r\n const s = value.second ? parseInt(value.second, 10) : 0;\r\n if (!isNaN(s)) return Math.floor(s / secondStep) * secondStep;\r\n return Math.floor(new Date().getSeconds() / secondStep) * secondStep;\r\n });\r\n const initialScrollDone = useRef(false);\r\n\r\n const hourRef = useRef<OverlayScrollbarRef>(null);\r\n const minuteRef = useRef<OverlayScrollbarRef>(null);\r\n const secondRef = useRef<OverlayScrollbarRef>(null);\r\n\r\n const hasSeconds = format === \"HH:mm:ss\" || format === \"hh:mm:ss\";\r\n const is12Hour = format.startsWith(\"hh\");\r\n const maxHour = is12Hour ? 12 : 23;\r\n const minHourValue = is12Hour ? 1 : 0;\r\n\r\n // \uC2DC\uAC04 \uBC30\uC5F4 \uC0DD\uC131\r\n const hours = Array.from(\r\n { length: maxHour - minHourValue + 1 },\r\n (_, i) => minHourValue + i,\r\n );\r\n const minutes = Array.from(\r\n { length: Math.ceil(60 / minuteStep) },\r\n (_, i) => i * minuteStep,\r\n );\r\n const seconds = hasSeconds\r\n ? Array.from(\r\n { length: Math.ceil(60 / secondStep) },\r\n (_, i) => i * secondStep,\r\n )\r\n : [];\r\n\r\n // \uC120\uD0DD\uB41C \uD56D\uBAA9\uC73C\uB85C \uC2A4\uD06C\uB864 (\uC138\uB85C \uC911\uC559\uC5D0 \uC624\uB3C4\uB85D)\r\n const scrollToCenter = useCallback(\r\n (\r\n scrollbarRef: React.RefObject<OverlayScrollbarRef | null>,\r\n val: number,\r\n ) => {\r\n if (!scrollbarRef.current) return;\r\n\r\n const scrollContainer = scrollbarRef.current.getScrollContainer();\r\n if (!scrollContainer) return;\r\n\r\n const element = scrollContainer.querySelector(\r\n `[data-value=\"${val}\"]`,\r\n ) as HTMLElement;\r\n if (!element) return;\r\n\r\n const containerHeight = scrollbarRef.current.clientHeight;\r\n const elementTop = element.offsetTop;\r\n const elementHeight = element.offsetHeight;\r\n\r\n const scrollTop =\r\n elementTop - containerHeight / 2 + elementHeight / 2;\r\n scrollbarRef.current.scrollTo({ top: Math.max(0, scrollTop) });\r\n },\r\n [],\r\n );\r\n\r\n // \uCD08\uAE30 \uC2A4\uD06C\uB864 (\uD55C \uBC88\uB9CC)\r\n useEffect(() => {\r\n if (initialScrollDone.current) return;\r\n if (selectedHour === null || selectedMinute === null) return;\r\n if (hasSeconds && selectedSecond === null) return;\r\n\r\n const timer = setTimeout(() => {\r\n scrollToCenter(hourRef, selectedHour);\r\n scrollToCenter(minuteRef, selectedMinute);\r\n if (hasSeconds && selectedSecond !== null) {\r\n scrollToCenter(secondRef, selectedSecond);\r\n }\r\n initialScrollDone.current = true;\r\n }, 50);\r\n return () => clearTimeout(timer);\r\n }, [\r\n selectedHour,\r\n selectedMinute,\r\n selectedSecond,\r\n hasSeconds,\r\n scrollToCenter,\r\n ]);\r\n\r\n // \uC2DC\uAC04 \uBC94\uC704 \uCCB4\uD06C\r\n const isTimeInRange = (h: number, m: number, s: number = 0): boolean => {\r\n const timeValue = h * 3600 + m * 60 + s;\r\n\r\n if (minTime) {\r\n const minParts = minTime.split(\":\");\r\n const minH = parseInt(minParts[0], 10) || 0;\r\n const minM = parseInt(minParts[1], 10) || 0;\r\n const minS = parseInt(minParts[2], 10) || 0;\r\n const minValue = minH * 3600 + minM * 60 + minS;\r\n if (timeValue < minValue) return false;\r\n }\r\n\r\n if (maxTime) {\r\n const maxParts = maxTime.split(\":\");\r\n const maxH = parseInt(maxParts[0], 10) || 0;\r\n const maxM = parseInt(maxParts[1], 10) || 0;\r\n const maxS = parseInt(maxParts[2], 10) || 0;\r\n const maxValue = maxH * 3600 + maxM * 60 + maxS;\r\n if (timeValue > maxValue) return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n // \uC120\uD0DD \uD578\uB4E4\uB7EC - \uC120\uD0DD \uC2DC \uBC14\uB85C onChange \uD638\uCD9C\r\n const handleHourSelect = (hour: number) => {\r\n setSelectedHour(hour);\r\n onChange(\r\n hour,\r\n selectedMinute ?? 0,\r\n hasSeconds ? (selectedSecond ?? 0) : undefined,\r\n );\r\n };\r\n\r\n const handleMinuteSelect = (minute: number) => {\r\n setSelectedMinute(minute);\r\n onChange(\r\n selectedHour ?? 0,\r\n minute,\r\n hasSeconds ? (selectedSecond ?? 0) : undefined,\r\n );\r\n };\r\n\r\n const handleSecondSelect = (second: number) => {\r\n setSelectedSecond(second);\r\n onChange(selectedHour ?? 0, selectedMinute ?? 0, second);\r\n };\r\n\r\n // \uC544\uC774\uD15C \uB80C\uB354\uB9C1\r\n const renderItem = (\r\n val: number,\r\n selected: boolean,\r\n disabled: boolean,\r\n onClick: () => void,\r\n ) => (\r\n <Box\r\n key={val}\r\n data-value={val}\r\n onClick={disabled ? undefined : onClick}\r\n sx={{\r\n py: 0.5,\r\n px: 1,\r\n cursor: disabled ? \"not-allowed\" : \"pointer\",\r\n textAlign: \"center\",\r\n borderRadius: 1,\r\n backgroundColor: selected ? \"primary.main\" : \"transparent\",\r\n color: disabled\r\n ? \"text.disabled\"\r\n : selected\r\n ? \"primary.contrastText\"\r\n : \"text.primary\",\r\n opacity: disabled ? 0.4 : 1,\r\n transition: \"background-color 0.15s, color 0.15s\",\r\n \"&:hover\": {\r\n backgroundColor: disabled\r\n ? \"transparent\"\r\n : selected\r\n ? \"primary.dark\"\r\n : \"action.hover\",\r\n },\r\n fontVariantNumeric: \"tabular-nums\",\r\n minWidth: 32,\r\n }}\r\n >\r\n <Typography\r\n variant=\"body2\"\r\n sx={{ fontWeight: selected ? 600 : 400 }}\r\n >\r\n {String(val).padStart(2, \"0\")}\r\n </Typography>\r\n </Box>\r\n );\r\n\r\n // \uC5F4 \uB80C\uB354\uB9C1\r\n const renderColumn = (\r\n ref: React.RefObject<OverlayScrollbarRef | null>,\r\n items: number[],\r\n selectedValue: number | null,\r\n onSelect: (val: number) => void,\r\n checkDisabled: (val: number) => boolean,\r\n ) => (\r\n <OverlayScrollbar\r\n ref={ref as React.RefObject<OverlayScrollbarRef>}\r\n style={{ height: \"100%\" }}\r\n thumb={{ width: 4 }}\r\n track={{ alignment: \"right\" }}\r\n >\r\n <div style={{ padding: \"0.25rem\" }}>\r\n {items.map((item) => {\r\n const isDisabled = checkDisabled(item);\r\n // hideDisabledTime\uC774 true\uC774\uACE0 disabled\uBA74 \uB80C\uB354\uB9C1\uD558\uC9C0 \uC54A\uC74C\r\n if (hideDisabledTime && isDisabled) return null;\r\n return renderItem(\r\n item,\r\n selectedValue === item,\r\n isDisabled,\r\n () => onSelect(item),\r\n );\r\n })}\r\n </div>\r\n </OverlayScrollbar>\r\n );\r\n\r\n // \uC2DC\uAC04 \uBE44\uD65C\uC131\uD654 \uCCB4\uD06C\r\n const isHourDisabled = (hour: number): boolean => {\r\n for (const minute of minutes) {\r\n if (hasSeconds) {\r\n for (const second of seconds) {\r\n if (isTimeInRange(hour, minute, second)) return false;\r\n }\r\n } else {\r\n if (isTimeInRange(hour, minute)) return false;\r\n }\r\n }\r\n return true;\r\n };\r\n\r\n const isMinuteDisabled = (minute: number): boolean => {\r\n if (selectedHour === null) return false;\r\n if (hasSeconds) {\r\n for (const second of seconds) {\r\n if (isTimeInRange(selectedHour, minute, second)) return false;\r\n }\r\n return true;\r\n }\r\n return !isTimeInRange(selectedHour, minute);\r\n };\r\n\r\n const isSecondDisabled = (second: number): boolean => {\r\n if (selectedHour === null || selectedMinute === null) return false;\r\n return !isTimeInRange(selectedHour, selectedMinute, second);\r\n };\r\n\r\n return (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n height: \"100%\",\r\n userSelect: \"none\",\r\n }}\r\n >\r\n {/* \uD604\uC7AC \uC120\uD0DD\uB41C \uC2DC\uAC04 \uD45C\uC2DC */}\r\n {showHeader && (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n justifyContent: \"center\",\r\n alignItems: \"center\",\r\n height: 48,\r\n borderBottom: \"1px solid\",\r\n borderColor: \"divider\",\r\n gap: 0.5,\r\n }}\r\n >\r\n <Typography\r\n variant=\"h6\"\r\n sx={{\r\n fontWeight: 500,\r\n fontVariantNumeric: \"tabular-nums\",\r\n }}\r\n >\r\n {selectedHour !== null\r\n ? String(selectedHour).padStart(2, \"0\")\r\n : \"--\"}\r\n </Typography>\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n ml: \"1px\",\r\n }}\r\n >\r\n <ColonIcon size=\"small\" />\r\n </Box>\r\n <Typography\r\n variant=\"h6\"\r\n sx={{\r\n fontWeight: 500,\r\n fontVariantNumeric: \"tabular-nums\",\r\n }}\r\n >\r\n {selectedMinute !== null\r\n ? String(selectedMinute).padStart(2, \"0\")\r\n : \"--\"}\r\n </Typography>\r\n {hasSeconds && (\r\n <>\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n ml: \"1px\",\r\n }}\r\n >\r\n <ColonIcon size=\"small\" />\r\n </Box>\r\n <Typography\r\n variant=\"h6\"\r\n sx={{\r\n fontWeight: 500,\r\n fontVariantNumeric: \"tabular-nums\",\r\n }}\r\n >\r\n {selectedSecond !== null\r\n ? String(selectedSecond).padStart(2, \"0\")\r\n : \"--\"}\r\n </Typography>\r\n </>\r\n )}\r\n </Box>\r\n )}\r\n\r\n {/* \uC2DC\uAC04 \uC120\uD0DD \uCEF8\uB7FC */}\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n justifyContent: \"center\",\r\n flex: 1,\r\n minHeight: 0,\r\n overflow: \"hidden\",\r\n }}\r\n >\r\n {renderColumn(\r\n hourRef,\r\n hours,\r\n selectedHour,\r\n handleHourSelect,\r\n isHourDisabled,\r\n )}\r\n\r\n <Box\r\n sx={{\r\n width: \"1px\",\r\n backgroundColor: \"divider\",\r\n }}\r\n />\r\n\r\n {renderColumn(\r\n minuteRef,\r\n minutes,\r\n selectedMinute,\r\n handleMinuteSelect,\r\n isMinuteDisabled,\r\n )}\r\n\r\n {hasSeconds && (\r\n <>\r\n <Box\r\n sx={{\r\n width: \"1px\",\r\n backgroundColor: \"divider\",\r\n alignSelf: \"stretch\",\r\n }}\r\n />\r\n {renderColumn(\r\n secondRef,\r\n seconds,\r\n selectedSecond,\r\n handleSecondSelect,\r\n isSecondDisabled,\r\n )}\r\n </>\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n", "/**\r\n * TimePicker.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { useState, useEffect, useMemo } from \"react\";\r\nimport { Box, Popover, Button } from \"@mui/material\";\r\nimport type { PopoverProps } from \"@mui/material/Popover\";\r\nimport { TimeSelector } from \"./TimeSelector\";\r\nimport type { TimePickerProps, AnchorElType } from \"./types\";\r\nimport { resolveLocale } from \"./locale\";\r\n\r\n// anchorEl\uC774 RefObject\uC778\uC9C0 \uD655\uC778\uD558\uACE0 \uC2E4\uC81C \uC5D8\uB9AC\uBA3C\uD2B8 \uBC18\uD658\r\nfunction resolveAnchorEl(\r\n anchorEl: AnchorElType | undefined,\r\n): PopoverProps[\"anchorEl\"] {\r\n if (!anchorEl) return null;\r\n // RefObject\uC778 \uACBD\uC6B0 current \uBC18\uD658\r\n if (typeof anchorEl === \"object\" && \"current\" in anchorEl) {\r\n return anchorEl.current;\r\n }\r\n return anchorEl;\r\n}\r\n\r\nexport function TimePicker({\r\n anchorEl,\r\n open,\r\n onClose,\r\n value,\r\n onChange,\r\n format,\r\n minTime,\r\n maxTime,\r\n minuteStep = 1,\r\n secondStep = 1,\r\n hideDisabledTime = false,\r\n autoApply = false,\r\n // \uB85C\uCF00\uC77C \uAD00\uB828\r\n locale,\r\n texts,\r\n}: TimePickerProps) {\r\n const hasSeconds = format === \"HH:mm:ss\" || format === \"hh:mm:ss\";\r\n\r\n // \uB85C\uCF00\uC77C \uD574\uC11D \uBC0F \uBCD1\uD569 (texts\uAC00 \uC788\uC73C\uBA74 \uBD80\uBD84 \uB36E\uC5B4\uC4F0\uAE30)\r\n const resolvedLocale = resolveLocale(locale);\r\n const mergedLocale = useMemo(\r\n () => (texts ? { ...resolvedLocale, ...texts } : resolvedLocale),\r\n [resolvedLocale, texts],\r\n );\r\n\r\n // anchorEl \uD574\uC11D\r\n const resolvedAnchorEl = resolveAnchorEl(anchorEl);\r\n\r\n // \uC784\uC2DC \uC120\uD0DD\uAC12 (\uD655\uC778 \uBC84\uD2BC \uB204\uB974\uAE30 \uC804\uAE4C\uC9C0 \uBCF4\uAD00)\r\n const [tempHour, setTempHour] = useState<number>(0);\r\n const [tempMinute, setTempMinute] = useState<number>(0);\r\n const [tempSecond, setTempSecond] = useState<number>(0);\r\n\r\n // value prop \uBCC0\uACBD \uC2DC \uC784\uC2DC\uAC12 \uCD08\uAE30\uD654\r\n useEffect(() => {\r\n if (open) {\r\n const h = parseInt(value.hour, 10);\r\n const m = parseInt(value.minute, 10);\r\n const s = value.second ? parseInt(value.second, 10) : 0;\r\n\r\n const now = new Date();\r\n setTempHour(isNaN(h) ? now.getHours() : h);\r\n setTempMinute(\r\n isNaN(m)\r\n ? Math.floor(now.getMinutes() / minuteStep) * minuteStep\r\n : Math.floor(m / minuteStep) * minuteStep,\r\n );\r\n if (hasSeconds) {\r\n setTempSecond(\r\n isNaN(s)\r\n ? Math.floor(now.getSeconds() / secondStep) * secondStep\r\n : Math.floor(s / secondStep) * secondStep,\r\n );\r\n }\r\n }\r\n }, [open, value, minuteStep, secondStep, hasSeconds]);\r\n\r\n // TimeSelector\uC5D0\uC11C \uC120\uD0DD \uBCC0\uACBD \uC2DC\r\n const handleTimeChange = (\r\n hour: number,\r\n minute: number,\r\n second?: number,\r\n ) => {\r\n setTempHour(hour);\r\n setTempMinute(minute);\r\n if (second !== undefined) {\r\n setTempSecond(second);\r\n }\r\n\r\n // autoApply\uAC00 true\uBA74 \uBC14\uB85C \uC801\uC6A9\r\n if (autoApply) {\r\n const h = String(hour).padStart(2, \"0\");\r\n const m = String(minute).padStart(2, \"0\");\r\n const s = hasSeconds\r\n ? String(second ?? 0).padStart(2, \"0\")\r\n : undefined;\r\n onChange(h, m, s);\r\n onClose();\r\n }\r\n };\r\n\r\n // \uD655\uC778 \uBC84\uD2BC \uD074\uB9AD \uC2DC onChange \uD638\uCD9C\r\n const handleConfirm = () => {\r\n const h = String(tempHour).padStart(2, \"0\");\r\n const m = String(tempMinute).padStart(2, \"0\");\r\n const s = hasSeconds ? String(tempSecond).padStart(2, \"0\") : undefined;\r\n onChange(h, m, s);\r\n onClose();\r\n };\r\n\r\n return (\r\n <Popover\r\n open={open}\r\n anchorEl={resolvedAnchorEl}\r\n onClose={onClose}\r\n anchorOrigin={{\r\n vertical: \"bottom\",\r\n horizontal: \"right\",\r\n }}\r\n transformOrigin={{\r\n vertical: \"top\",\r\n horizontal: \"right\",\r\n }}\r\n slotProps={{\r\n paper: {\r\n sx: {\r\n mt: 1,\r\n borderRadius: 2,\r\n boxShadow: 3,\r\n minWidth: hasSeconds ? 165 : 110,\r\n userSelect: \"none\",\r\n },\r\n },\r\n }}\r\n >\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n height: autoApply ? 288 : 336,\r\n }}\r\n >\r\n <Box sx={{ flex: 1, minHeight: 0, overflow: \"hidden\" }}>\r\n <TimeSelector\r\n value={{\r\n hour: String(tempHour).padStart(2, \"0\"),\r\n minute: String(tempMinute).padStart(2, \"0\"),\r\n second: hasSeconds\r\n ? String(tempSecond).padStart(2, \"0\")\r\n : undefined,\r\n }}\r\n onChange={handleTimeChange}\r\n format={format}\r\n minTime={minTime}\r\n maxTime={maxTime}\r\n minuteStep={minuteStep}\r\n secondStep={secondStep}\r\n showHeader={true}\r\n hideDisabledTime={hideDisabledTime}\r\n />\r\n </Box>\r\n\r\n {/* \uD558\uB2E8 \uD655\uC778 \uBC84\uD2BC - autoApply\uAC00 false\uC77C \uB54C\uB9CC \uD45C\uC2DC */}\r\n {!autoApply && (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n justifyContent: \"center\",\r\n alignItems: \"center\",\r\n height: 48,\r\n px: 1.5,\r\n borderTop: \"1px solid\",\r\n borderColor: \"divider\",\r\n }}\r\n >\r\n <Button size=\"small\" onClick={handleConfirm} fullWidth>\r\n {mergedLocale.confirm}\r\n </Button>\r\n </Box>\r\n )}\r\n </Box>\r\n </Popover>\r\n );\r\n}\r\n", "/**\r\n * DatePicker.tsx\r\n * Popover \uAE30\uBC18 \uB0A0\uC9DC \uC120\uD0DD \uCEF4\uD3EC\uB10C\uD2B8\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { useState, useEffect } from \"react\";\r\nimport { Popover } from \"@mui/material\";\r\nimport type { PopoverProps } from \"@mui/material/Popover\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport { SimpleCalendar } from \"./SimpleCalendar\";\r\nimport type { DatePickerProps, AnchorElType } from \"./types\";\r\nimport { defaultLocale } from \"./locale\";\r\nimport { resolveFooterAndAutoApply } from \"./utils\";\r\n\r\n// anchorEl\uC774 RefObject\uC778\uC9C0 \uD655\uC778\uD558\uACE0 \uC2E4\uC81C \uC5D8\uB9AC\uBA3C\uD2B8 \uBC18\uD658\r\nfunction resolveAnchorEl(\r\n anchorEl: AnchorElType | undefined,\r\n): PopoverProps[\"anchorEl\"] {\r\n if (!anchorEl) return null;\r\n // RefObject\uC778 \uACBD\uC6B0 current \uBC18\uD658\r\n if (typeof anchorEl === \"object\" && \"current\" in anchorEl) {\r\n return anchorEl.current;\r\n }\r\n return anchorEl;\r\n}\r\n\r\n/**\r\n * DatePicker - Popover \uAE30\uBC18 \uB0A0\uC9DC \uC120\uD0DD \uCEF4\uD3EC\uB10C\uD2B8\r\n *\r\n * \uB0A0\uC9DC\uB9CC \uC120\uD0DD\uD560 \uB54C \uC0AC\uC6A9\uD569\uB2C8\uB2E4.\r\n * \uC2DC\uAC04 \uC120\uD0DD\uC774 \uD544\uC694\uD558\uBA74 DateTimePicker\uB97C \uC0AC\uC6A9\uD558\uC138\uC694.\r\n */\r\nexport function DatePicker({\r\n open,\r\n onClose,\r\n anchorEl,\r\n selectedDate,\r\n onDateChange,\r\n minDate,\r\n maxDate,\r\n holidays = [],\r\n styles,\r\n showToday = true,\r\n showFooter = true,\r\n autoApply = true,\r\n anchorOrigin = { vertical: \"bottom\", horizontal: \"left\" },\r\n transformOrigin = { vertical: \"top\", horizontal: \"left\" },\r\n slotProps,\r\n // \uB85C\uCF00\uC77C \uAD00\uB828\r\n locale = defaultLocale,\r\n texts,\r\n // \uB144\uC6D4\uB9CC \uC120\uD0DD\r\n monthOnly = false,\r\n // \uB144\uB3C4\uB9CC \uC120\uD0DD\r\n yearOnly = false,\r\n // \uB144\uC6D4/\uB144\uB3C4 \uBCC0\uACBD \uCF5C\uBC31\r\n onMonthChange,\r\n onYearChange,\r\n onWeekChange,\r\n ...popoverProps\r\n}: DatePickerProps) {\r\n const { showFooter: footerOn, autoApply: applyImmediate } =\r\n resolveFooterAndAutoApply(showFooter, autoApply);\r\n\r\n const mergedPaperProps = {\r\n ...slotProps?.paper,\r\n \"data-custom-date-picker-popper\": \"true\",\r\n tabIndex: -1,\r\n sx: {\r\n mt: 1,\r\n borderRadius: 2,\r\n boxShadow: 3,\r\n width: 300,\r\n height: footerOn ? 380 : 332,\r\n overflow: \"hidden\",\r\n userSelect: \"none\",\r\n ...((slotProps?.paper as { sx?: SxProps<Theme> })?.sx ?? {}),\r\n },\r\n } as unknown as NonNullable<PopoverProps[\"slotProps\"]>[\"paper\"];\r\n\r\n // anchorEl \uD574\uC11D\r\n const resolvedAnchorEl = resolveAnchorEl(anchorEl);\r\n\r\n // \uB0B4\uBD80 \uC784\uC2DC \uB0A0\uC9DC \uC0C1\uD0DC\r\n const [tempDate, setTempDate] = useState<Date | null>(selectedDate ?? null);\r\n\r\n // \uC774\uC804\uC5D0 \uC120\uD0DD\uB41C \uB0A0\uC9DC\uC758 \uB144/\uC6D4 \uCD94\uC801 (\uC774\uBCA4\uD2B8 \uBC1C\uC0DD \uC5EC\uBD80 \uD310\uB2E8\uC6A9)\r\n const prevYear = selectedDate?.getFullYear();\r\n const prevMonth = selectedDate?.getMonth();\r\n\r\n // open\uB420 \uB54C \uC678\uBD80 \uAC12\uC73C\uB85C \uCD08\uAE30\uD654\r\n useEffect(() => {\r\n if (open) {\r\n setTempDate(selectedDate ?? null);\r\n }\r\n }, [open, selectedDate]);\r\n\r\n // \uB0A0\uC9DC \uC120\uD0DD \uD578\uB4E4\uB7EC (SimpleCalendar\uC5D0\uC11C \uD638\uCD9C)\r\n const handleDateSelect = (date: Date) => {\r\n setTempDate(date);\r\n onDateChange?.(date);\r\n\r\n // monthOnly/yearOnly\uAC00 \uC544\uB2D0 \uB54C\uB9CC \uC5EC\uAE30\uC11C \uB144/\uC6D4 \uBCC0\uACBD \uCF5C\uBC31 \uBC1C\uC0DD\r\n // monthOnly/yearOnly\uC77C \uB54C\uB294 SimpleCalendar\uC5D0\uC11C \uC774\uBCA4\uD2B8 \uCC98\uB9AC\r\n if (!monthOnly && !yearOnly) {\r\n const newYear = date.getFullYear();\r\n const newMonth = date.getMonth();\r\n if (prevYear !== newYear) {\r\n onYearChange?.(newYear);\r\n }\r\n if (prevYear !== newYear || prevMonth !== newMonth) {\r\n onMonthChange?.(newYear, newMonth + 1);\r\n }\r\n }\r\n\r\n // \uC989\uC2DC \uC801\uC6A9\uC774\uBA74 \uB0A0\uC9DC \uC120\uD0DD \uC2DC \uBC14\uB85C \uB2EB\uAE30\r\n if (applyImmediate) {\r\n onClose();\r\n }\r\n };\r\n\r\n return (\r\n <Popover\r\n open={open}\r\n anchorEl={resolvedAnchorEl}\r\n onClose={onClose}\r\n anchorOrigin={anchorOrigin}\r\n transformOrigin={transformOrigin}\r\n {...popoverProps}\r\n slotProps={{\r\n ...slotProps,\r\n paper: mergedPaperProps,\r\n }}\r\n >\r\n <SimpleCalendar\r\n selectedDate={tempDate}\r\n onSelect={handleDateSelect}\r\n onClose={onClose}\r\n minDate={minDate}\r\n maxDate={maxDate}\r\n holidays={holidays}\r\n styles={styles}\r\n showToday={showToday}\r\n showFooter={footerOn}\r\n autoApply={applyImmediate}\r\n showTimePicker={false}\r\n locale={locale}\r\n texts={texts}\r\n monthOnly={monthOnly}\r\n yearOnly={yearOnly}\r\n // monthOnly/yearOnly \uBAA8\uB4DC\uC77C \uB54C\uB9CC SimpleCalendar\uC758 \uC774\uBCA4\uD2B8\uB97C \uC804\uB2EC\r\n // \uC77C\uBC18 \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uB0A0\uC9DC \uC120\uD0DD \uC2DC\uC5D0\uB9CC \uB144/\uC6D4 \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n onYearChange={monthOnly || yearOnly ? onYearChange : undefined}\r\n onMonthChange={\r\n monthOnly || yearOnly ? onMonthChange : undefined\r\n }\r\n onWeekChange={onWeekChange}\r\n />\r\n </Popover>\r\n );\r\n}\r\n", "/**\r\n * DateTimePicker.tsx\r\n * Popover \uAE30\uBC18 \uB0A0\uC9DC + \uC2DC\uAC04 \uC120\uD0DD \uCEF4\uD3EC\uB10C\uD2B8\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { useState, useEffect } from \"react\";\r\nimport { Popover } from \"@mui/material\";\r\nimport type { PopoverProps } from \"@mui/material/Popover\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport { SimpleCalendar } from \"./SimpleCalendar\";\r\nimport type { DateTimePickerProps, TimeValue, AnchorElType } from \"./types\";\r\nimport { defaultLocale } from \"./locale\";\r\nimport { resolveFooterAndAutoApply } from \"./utils\";\r\n\r\n// anchorEl\uC774 RefObject\uC778\uC9C0 \uD655\uC778\uD558\uACE0 \uC2E4\uC81C \uC5D8\uB9AC\uBA3C\uD2B8 \uBC18\uD658\r\nfunction resolveAnchorEl(\r\n anchorEl: AnchorElType | undefined,\r\n): PopoverProps[\"anchorEl\"] {\r\n if (!anchorEl) return null;\r\n // RefObject\uC778 \uACBD\uC6B0 current \uBC18\uD658\r\n if (typeof anchorEl === \"object\" && \"current\" in anchorEl) {\r\n return anchorEl.current;\r\n }\r\n return anchorEl;\r\n}\r\n\r\n/**\r\n * DateTimePicker - Popover \uAE30\uBC18 \uB0A0\uC9DC + \uC2DC\uAC04 \uC120\uD0DD \uCEF4\uD3EC\uB10C\uD2B8\r\n *\r\n * \uB0A0\uC9DC\uC640 \uC2DC\uAC04\uC744 \uD568\uAED8 \uC120\uD0DD\uD560 \uB54C \uC0AC\uC6A9\uD569\uB2C8\uB2E4.\r\n * \uB0A0\uC9DC\uB9CC \uC120\uD0DD\uD558\uB824\uBA74 DatePicker\uB97C, \uC2DC\uAC04\uB9CC \uC120\uD0DD\uD558\uB824\uBA74 TimePicker\uB97C \uC0AC\uC6A9\uD558\uC138\uC694.\r\n */\r\nexport function DateTimePicker({\r\n open,\r\n onClose,\r\n anchorEl,\r\n selectedDate,\r\n onDateChange,\r\n timeValue,\r\n onTimeChange,\r\n minDate,\r\n maxDate,\r\n holidays = [],\r\n styles,\r\n showToday = true,\r\n showFooter = true,\r\n autoApply = true,\r\n timeFormat = \"HH:mm\",\r\n minTime,\r\n maxTime,\r\n minuteStep = 1,\r\n secondStep = 1,\r\n hideDisabledTime = false,\r\n anchorOrigin = { vertical: \"bottom\", horizontal: \"left\" },\r\n transformOrigin = { vertical: \"top\", horizontal: \"left\" },\r\n slotProps,\r\n // \uB85C\uCF00\uC77C \uAD00\uB828\r\n locale = defaultLocale,\r\n texts,\r\n // \uB144\uC6D4/\uB144\uB3C4 \uBCC0\uACBD \uCF5C\uBC31\r\n onMonthChange,\r\n onYearChange,\r\n onWeekChange,\r\n ...popoverProps\r\n}: DateTimePickerProps) {\r\n const { showFooter: footerOn, autoApply: applyImmediate } =\r\n resolveFooterAndAutoApply(showFooter, autoApply);\r\n\r\n const hasSeconds = timeFormat === \"HH:mm:ss\" || timeFormat === \"hh:mm:ss\";\r\n\r\n // anchorEl \uD574\uC11D\r\n const resolvedAnchorEl = resolveAnchorEl(anchorEl);\r\n\r\n // \uB0B4\uBD80 \uC784\uC2DC \uB0A0\uC9DC \uC0C1\uD0DC\r\n const [tempDate, setTempDate] = useState<Date | null>(selectedDate ?? null);\r\n\r\n // \uB0B4\uBD80 \uC784\uC2DC \uC2DC\uAC04 \uC0C1\uD0DC\r\n const [tempTime, setTempTime] = useState<TimeValue>(() => {\r\n if (timeValue) return timeValue;\r\n const now = new Date();\r\n return {\r\n hour: String(now.getHours()).padStart(2, \"0\"),\r\n minute: String(\r\n Math.floor(now.getMinutes() / minuteStep) * minuteStep,\r\n ).padStart(2, \"0\"),\r\n second: hasSeconds\r\n ? String(\r\n Math.floor(now.getSeconds() / secondStep) * secondStep,\r\n ).padStart(2, \"0\")\r\n : undefined,\r\n };\r\n });\r\n\r\n // open\uB420 \uB54C \uC678\uBD80 \uAC12\uC73C\uB85C \uCD08\uAE30\uD654\r\n useEffect(() => {\r\n if (open) {\r\n setTempDate(selectedDate ?? null);\r\n if (timeValue) {\r\n setTempTime(timeValue);\r\n } else {\r\n const now = new Date();\r\n setTempTime({\r\n hour: String(now.getHours()).padStart(2, \"0\"),\r\n minute: String(\r\n Math.floor(now.getMinutes() / minuteStep) * minuteStep,\r\n ).padStart(2, \"0\"),\r\n second: hasSeconds\r\n ? String(\r\n Math.floor(now.getSeconds() / secondStep) *\r\n secondStep,\r\n ).padStart(2, \"0\")\r\n : undefined,\r\n });\r\n }\r\n }\r\n }, [open, selectedDate, timeValue, minuteStep, secondStep, hasSeconds]);\r\n\r\n // \uC774\uC804\uC5D0 \uC120\uD0DD\uB41C \uB0A0\uC9DC\uC758 \uB144/\uC6D4 \uCD94\uC801 (\uC774\uBCA4\uD2B8 \uBC1C\uC0DD \uC5EC\uBD80 \uD310\uB2E8\uC6A9)\r\n const prevYear = selectedDate?.getFullYear();\r\n const prevMonth = selectedDate?.getMonth();\r\n\r\n // \uB0A0\uC9DC \uC120\uD0DD \uD578\uB4E4\uB7EC (SimpleCalendar\uC5D0\uC11C \uD638\uCD9C)\r\n const handleDateSelect = (date: Date) => {\r\n setTempDate(date);\r\n // \uB0A0\uC9DC\uAC00 \uC120\uD0DD\uB418\uBA74 \uD56D\uC0C1 \uCF5C\uBC31 \uD638\uCD9C (\uD655\uC778 \uBC84\uD2BC\uC5D0\uC11C\uB3C4 \uD638\uCD9C\uB428)\r\n onDateChange?.(date);\r\n\r\n // \uB0A0\uC9DC \uC120\uD0DD \uC2DC \uB144/\uC6D4 \uBCC0\uACBD \uCF5C\uBC31 \uBC1C\uC0DD (\uC774\uC804 \uB0A0\uC9DC\uC640 \uBE44\uAD50)\r\n const newYear = date.getFullYear();\r\n const newMonth = date.getMonth();\r\n if (prevYear !== newYear) {\r\n onYearChange?.(newYear);\r\n }\r\n if (prevYear !== newYear || prevMonth !== newMonth) {\r\n onMonthChange?.(newYear, newMonth + 1);\r\n }\r\n };\r\n\r\n // SimpleCalendar\uC5D0\uC11C \uC2DC\uAC04 \uBCC0\uACBD\r\n const handleCalendarTimeChange = (\r\n hour: number,\r\n minute: number,\r\n second?: number,\r\n ) => {\r\n const newTime = {\r\n hour: String(hour).padStart(2, \"0\"),\r\n minute: String(minute).padStart(2, \"0\"),\r\n second:\r\n second !== undefined\r\n ? String(second).padStart(2, \"0\")\r\n : undefined,\r\n };\r\n setTempTime(newTime);\r\n\r\n // \uC2DC\uAC04\uC774 \uBCC0\uACBD\uB418\uBA74 \uD56D\uC0C1 \uCF5C\uBC31 \uD638\uCD9C (\uD655\uC778 \uBC84\uD2BC\uC5D0\uC11C\uB3C4 \uD638\uCD9C\uB428)\r\n onTimeChange?.(newTime.hour, newTime.minute, newTime.second);\r\n };\r\n\r\n // \uD31D\uC624\uBC84 \uD06C\uAE30 \uACB0\uC815 (datetime \uC804\uC6A9)\r\n const width = 300 + (hasSeconds ? 165 : 110);\r\n const height = footerOn ? 380 : 332;\r\n\r\n return (\r\n <Popover\r\n open={open}\r\n anchorEl={resolvedAnchorEl}\r\n onClose={onClose}\r\n anchorOrigin={anchorOrigin}\r\n transformOrigin={transformOrigin}\r\n {...popoverProps}\r\n slotProps={{\r\n ...slotProps,\r\n paper: {\r\n ...slotProps?.paper,\r\n sx: {\r\n mt: 1,\r\n borderRadius: 2,\r\n boxShadow: 3,\r\n width,\r\n height,\r\n overflow: \"hidden\",\r\n userSelect: \"none\",\r\n ...((slotProps?.paper as { sx?: SxProps<Theme> })?.sx ??\r\n {}),\r\n },\r\n },\r\n }}\r\n >\r\n <SimpleCalendar\r\n selectedDate={tempDate}\r\n onSelect={handleDateSelect}\r\n onClose={onClose}\r\n minDate={minDate}\r\n maxDate={maxDate}\r\n holidays={holidays}\r\n styles={styles}\r\n showToday={showToday}\r\n showFooter={footerOn}\r\n autoApply={applyImmediate}\r\n showTimePicker={true}\r\n timeValue={tempTime}\r\n onTimeChange={handleCalendarTimeChange}\r\n timeFormat={timeFormat}\r\n minTime={minTime}\r\n maxTime={maxTime}\r\n minuteStep={minuteStep}\r\n secondStep={secondStep}\r\n hideDisabledTime={hideDisabledTime}\r\n locale={locale}\r\n texts={texts}\r\n // DateTimePicker\uB294 \uC77C\uBC18 \uBAA8\uB4DC\uB9CC \uC788\uC73C\uBBC0\uB85C \uB0A0\uC9DC \uC120\uD0DD \uC2DC\uC5D0\uB9CC \uB144/\uC6D4 \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n onWeekChange={onWeekChange}\r\n />\r\n </Popover>\r\n );\r\n}\r\n", "/**\r\n * CalendarIcon.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\nexport const CalendarIcon = ({ size = 20 }: { size?: number }) => (\r\n <svg\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\r\n <line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\" />\r\n <line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\" />\r\n <line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\" />\r\n </svg>\r\n);\r\n", "/**\r\n * ChevronLeft.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\nexport const ChevronLeft = () => (\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\" />\r\n </svg>\r\n);\r\n", "/**\r\n * ChevronRight.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\nexport const ChevronRight = () => (\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M8.59 16.59L10 18l6-6-6-6-1.41 1.41L13.17 12z\" />\r\n </svg>\r\n);\r\n", "/**\r\n * ClockIcon.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\ninterface ClockIconProps {\r\n size?: number;\r\n color?: string;\r\n}\r\n\r\nexport function ClockIcon({\r\n size = 22,\r\n color = \"currentColor\",\r\n}: ClockIconProps) {\r\n return (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke={color}\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\r\n <polyline points=\"12 6 12 12 16 14\" />\r\n </svg>\r\n );\r\n}\r\n", "/**\r\n * ColonIcon.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\ninterface ColonIconProps {\r\n size?: \"small\" | \"medium\";\r\n color?: string;\r\n}\r\n\r\nexport function ColonIcon({\r\n size = \"small\",\r\n color = \"rgba(0, 0, 0, 0.87)\",\r\n}: ColonIconProps) {\r\n const height = size === \"small\" ? 14 : 18;\r\n const dotRadius = size === \"small\" ? 1.2 : 1.5;\r\n // width\uB97C dotRadius * 2 + \uC5EC\uC720\uACF5\uAC04\uC73C\uB85C \uC124\uC815\r\n const width = dotRadius * 2 + 2;\r\n const centerX = width / 2;\r\n\r\n return (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${width} ${height}`}\r\n fill={color}\r\n style={{\r\n display: \"inline-block\",\r\n visibility: \"visible\",\r\n opacity: 1,\r\n width: `${width}px`,\r\n height: `${height}px`,\r\n minWidth: `${width}px`,\r\n minHeight: `${height}px`,\r\n maxWidth: `${width}px`,\r\n maxHeight: `${height}px`,\r\n flexShrink: 0,\r\n overflow: \"visible\",\r\n margin: \"0 1px\",\r\n padding: 0,\r\n border: \"none\",\r\n background: \"transparent\",\r\n verticalAlign: \"middle\",\r\n pointerEvents: \"none\",\r\n }}\r\n >\r\n <circle\r\n cx={centerX}\r\n cy={height * 0.32}\r\n r={dotRadius}\r\n style={{\r\n fill: color,\r\n stroke: \"none\",\r\n visibility: \"visible\",\r\n opacity: 1,\r\n }}\r\n />\r\n <circle\r\n cx={centerX}\r\n cy={height * 0.68}\r\n r={dotRadius}\r\n style={{\r\n fill: color,\r\n stroke: \"none\",\r\n visibility: \"visible\",\r\n opacity: 1,\r\n }}\r\n />\r\n </svg>\r\n );\r\n}\r\n", "/**\r\n * DashIcon.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\ninterface DashIconProps {\r\n size?: \"small\" | \"medium\";\r\n}\r\n\r\nexport function DashIcon({ size = \"small\" }: DashIconProps) {\r\n const width = size === \"small\" ? 8 : 10;\r\n const height = size === \"small\" ? 1 : 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${width} ${height}`}\r\n style={{ display: \"block\" }}\r\n >\r\n <rect\r\n x=\"0\"\r\n y=\"0\"\r\n width={width}\r\n height={height}\r\n rx={height / 2}\r\n fill=\"currentColor\"\r\n />\r\n </svg>\r\n );\r\n}\r\n", "/**\r\n * CopyIcon.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\ninterface CopyIconProps {\r\n size?: \"small\" | \"medium\";\r\n}\r\n\r\nexport function CopyIcon({ size = \"small\" }: CopyIconProps) {\r\n const iconSize = size === \"small\" ? 16 : 20;\r\n\r\n return (\r\n <svg\r\n width={iconSize}\r\n height={iconSize}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n style={{ display: \"block\" }}\r\n >\r\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\r\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\r\n </svg>\r\n );\r\n}\r\n", "/**\r\n * card-icons.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\ninterface CardIconProps {\r\n size?: number;\r\n color?: string;\r\n}\r\n\r\n// \uACF5\uD1B5 \uCE74\uB4DC \uD06C\uAE30 (8:5 \uBE44\uC728, \uC2E4\uC81C \uC2E0\uC6A9\uCE74\uB4DC \uBE44\uC728\uC5D0 \uAC00\uAE4C\uC6C0)\r\nconst CARD_WIDTH = 36;\r\nconst CARD_HEIGHT = 25;\r\n\r\n// \uAE30\uBCF8 \uCE74\uB4DC \uC544\uC774\uCF58 (\uBE0C\uB79C\uB4DC \uBBF8\uD655\uC778)\r\nexport function CardIcon({ size = 24, color = \"#9e9e9e\" }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox=\"0 0 40 25\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <g transform=\"translate(8, 4)\">\r\n <rect\r\n x=\"0\"\r\n y=\"0\"\r\n width=\"24\"\r\n height=\"17\"\r\n rx=\"2\"\r\n stroke={color}\r\n strokeWidth=\"1.2\"\r\n fill=\"none\"\r\n />\r\n <line\r\n x1=\"0\"\r\n y1=\"5\"\r\n x2=\"24\"\r\n y2=\"5\"\r\n stroke={color}\r\n strokeWidth=\"2\"\r\n />\r\n <rect\r\n x=\"2\"\r\n y=\"10\"\r\n width=\"5\"\r\n height=\"2.5\"\r\n rx=\"0.5\"\r\n fill={color}\r\n />\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\n// Visa \uB85C\uACE0\r\nexport function VisaIcon({ size = 24 }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n // \uC6D0\uBCF8 viewBox: 262.3 x 85\r\n const logoWidth = 262.3;\r\n const logoHeight = 85;\r\n // \uB85C\uACE0\uB97C \uCE74\uB4DC \uB0B4\uBD80\uC5D0 \uB9DE\uCD94\uAE30 \uC704\uD55C \uC2A4\uCF00\uC77C (\uC5EC\uC720 \uC788\uAC8C)\r\n const logoScale = Math.min(\r\n (CARD_WIDTH * 0.75) / logoWidth,\r\n (CARD_HEIGHT * 0.6) / logoHeight\r\n );\r\n const offsetX = (CARD_WIDTH - logoWidth * logoScale) / 2;\r\n const offsetY = (CARD_HEIGHT - logoHeight * logoScale) / 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <g\r\n transform={`translate(${offsetX}, ${offsetY}) scale(${logoScale})`}\r\n >\r\n <path\r\n fill=\"#1434CB\"\r\n d=\"M170.9,0c-18.6,0-35.3,9.7-35.3,27.5c0,20.5,29.5,21.9,29.5,32.1c0,4.3-5,8.2-13.4,8.2c-12,0-21-5.4-21-5.4l-3.8,18c0,0,10.3,4.6,24.1,4.6c20.4,0,36.4-10.1,36.4-28.3c0-21.6-29.6-23-29.6-32.5c0-3.4,4.1-7.1,12.5-7.1c9.5,0,17.3,3.9,17.3,3.9l3.8-17.4C191.3,3.6,182.8,0,170.9,0L170.9,0z M0.5,1.3L0,3.9c0,0,7.8,1.4,14.9,4.3c9.1,3.3,9.7,5.2,11.3,11.1l16.7,64.3h22.4L99.6,1.3H77.3l-22.1,56l-9-47.5c-0.8-5.4-5-8.5-10.2-8.5C36,1.3,0.5,1.3,0.5,1.3z M108.6,1.3L91.1,83.6h21.3l17.4-82.3L108.6,1.3L108.6,1.3z M227.2,1.3c-5.1,0-7.8,2.7-9.8,7.5l-31.2,74.8h22.3l4.3-12.5H240l2.6,12.5h19.7L245.2,1.3L227.2,1.3L227.2,1.3z M230.1,23.6l6.6,30.9H219L230.1,23.6L230.1,23.6z\"\r\n />\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\n// Mastercard \uB85C\uACE0\r\nexport function MastercardIcon({ size = 24 }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n // \uC6D0\uBCF8 viewBox: 999.2 x 618 (\uC6D0 2\uAC1C)\r\n const logoWidth = 999.2;\r\n const logoHeight = 618;\r\n const logoScale = Math.min(\r\n (CARD_WIDTH * 0.75) / logoWidth,\r\n (CARD_HEIGHT * 0.75) / logoHeight\r\n );\r\n const offsetX = (CARD_WIDTH - logoWidth * logoScale) / 2;\r\n const offsetY = (CARD_HEIGHT - logoHeight * logoScale) / 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`}\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <g\r\n transform={`translate(${offsetX}, ${offsetY}) scale(${logoScale})`}\r\n >\r\n <rect\r\n x=\"364\"\r\n y=\"66.1\"\r\n fill=\"#FF5A00\"\r\n width=\"270.4\"\r\n height=\"485.8\"\r\n />\r\n <path\r\n fill=\"#EB001B\"\r\n d=\"M382,309c0-98.7,46.4-186.3,117.6-242.9C447.2,24.9,381.1,0,309,0C138.2,0,0,138.2,0,309s138.2,309,309,309c72.1,0,138.2-24.9,190.6-66.1C428.3,496.1,382,407.7,382,309z\"\r\n />\r\n <path\r\n fill=\"#F79E1B\"\r\n d=\"M999.2,309c0,170.8-138.2,309-309,309c-72.1,0-138.2-24.9-190.6-66.1c72.1-56.7,117.6-144.2,117.6-242.9S570.8,122.7,499.6,66.1C551.9,24.9,618,0,690.1,0C861,0,999.2,139.1,999.2,309z\"\r\n />\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\n// AMEX \uB85C\uACE0\r\nexport function AmexIcon({ size = 24 }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n // \uC6D0\uBCF8 viewBox: 48 x 48 (\uC815\uC0AC\uAC01\uD615) - \uCE74\uB4DC \uBC30\uACBD \uD3EC\uD568\r\n const logoWidth = 48;\r\n const logoHeight = 48;\r\n const logoScale = Math.min(\r\n (CARD_WIDTH * 1.1) / logoWidth,\r\n (CARD_HEIGHT * 1.15) / logoHeight\r\n );\r\n const offsetX = (CARD_WIDTH - logoWidth * logoScale) / 2;\r\n const offsetY = (CARD_HEIGHT - logoHeight * logoScale) / 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <g\r\n transform={`translate(${offsetX}, ${offsetY}) scale(${logoScale})`}\r\n >\r\n <path\r\n fill=\"#1976D2\"\r\n d=\"M45,35c0,2.209-1.791,4-4,4H7c-2.209,0-4-1.791-4-4V13c0-2.209,1.791-4,4-4h34c2.209,0,4,1.791,4,4V35z\"\r\n />\r\n <path\r\n fill=\"#FFF\"\r\n d=\"M22.255 20l-2.113 4.683L18.039 20h-2.695v6.726L12.341 20h-2.274L7 26.981h1.815l.671-1.558h3.432l.682 1.558h3.465v-5.185l2.299 5.185h1.563l2.351-5.095v5.095H25V20H22.255zM10.135 23.915l1.026-2.44 1.066 2.44H10.135zM37.883 23.413L41 20.018h-2.217l-1.994 2.164L34.86 20H28v6.982h6.635l2.092-2.311L38.767 27h2.21L37.883 23.413zM33.728 25.516h-4.011v-1.381h3.838v-1.323h-3.838v-1.308l4.234.012 1.693 1.897L33.728 25.516z\"\r\n />\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\n// JCB \uB85C\uACE0\r\nexport function JcbIcon({ size = 24 }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n // \uC6D0\uBCF8 viewBox: 300 x 231.511\r\n const logoWidth = 300;\r\n const logoHeight = 231.511;\r\n const logoScale = Math.min(\r\n (CARD_WIDTH * 0.85) / logoWidth,\r\n (CARD_HEIGHT * 0.85) / logoHeight\r\n );\r\n const offsetX = (CARD_WIDTH - logoWidth * logoScale) / 2;\r\n const offsetY = (CARD_HEIGHT - logoHeight * logoScale) / 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <g\r\n transform={`translate(${offsetX}, ${offsetY}) scale(${logoScale})`}\r\n >\r\n <defs>\r\n <linearGradient\r\n id=\"jcbGreen1\"\r\n x1=\"117.3856\"\r\n y1=\"81.3986\"\r\n x2=\"157.3299\"\r\n y2=\"81.3986\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n gradientTransform=\"matrix(1.125,0,0,1.125,-11.9755,-13.8615)\"\r\n >\r\n <stop offset=\"0\" stopColor=\"#007940\" />\r\n <stop offset=\"0.2285\" stopColor=\"#00873F\" />\r\n <stop offset=\"0.7433\" stopColor=\"#40A737\" />\r\n <stop offset=\"1\" stopColor=\"#5CB531\" />\r\n </linearGradient>\r\n <linearGradient\r\n id=\"jcbGreen2\"\r\n x1=\"117.3844\"\r\n y1=\"75.1714\"\r\n x2=\"157.3318\"\r\n y2=\"75.1714\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n gradientTransform=\"matrix(1.125,0,0,1.125,-11.9755,-13.8615)\"\r\n >\r\n <stop offset=\"0\" stopColor=\"#007940\" />\r\n <stop offset=\"0.2285\" stopColor=\"#00873F\" />\r\n <stop offset=\"0.7433\" stopColor=\"#40A737\" />\r\n <stop offset=\"1\" stopColor=\"#5CB531\" />\r\n </linearGradient>\r\n <linearGradient\r\n id=\"jcbGreen3\"\r\n x1=\"117.3846\"\r\n y1=\"68.3991\"\r\n x2=\"157.33051\"\r\n y2=\"68.3991\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n gradientTransform=\"matrix(1.125,0,0,1.125,-11.9755,-13.8615)\"\r\n >\r\n <stop offset=\"0\" stopColor=\"#007940\" />\r\n <stop offset=\"0.2285\" stopColor=\"#00873F\" />\r\n <stop offset=\"0.7433\" stopColor=\"#40A737\" />\r\n <stop offset=\"1\" stopColor=\"#5CB531\" />\r\n </linearGradient>\r\n <linearGradient\r\n id=\"jcbBlue\"\r\n x1=\"27.9594\"\r\n y1=\"75.1714\"\r\n x2=\"68.5221\"\r\n y2=\"75.1714\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n gradientTransform=\"matrix(1.125,0,0,1.125,-11.9755,-13.8615)\"\r\n >\r\n <stop offset=\"0\" stopColor=\"#1F286F\" />\r\n <stop offset=\"0.4751\" stopColor=\"#004E94\" />\r\n <stop offset=\"0.8261\" stopColor=\"#0066B1\" />\r\n <stop offset=\"1\" stopColor=\"#006FBC\" />\r\n </linearGradient>\r\n <linearGradient\r\n id=\"jcbRed\"\r\n x1=\"72.4595\"\r\n y1=\"75.1714\"\r\n x2=\"111.8553\"\r\n y2=\"75.1714\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n gradientTransform=\"matrix(1.125,0,0,1.125,-11.9755,-13.8615)\"\r\n >\r\n <stop offset=\"0\" stopColor=\"#6C2C2F\" />\r\n <stop offset=\"0.1735\" stopColor=\"#882730\" />\r\n <stop offset=\"0.5731\" stopColor=\"#BE1833\" />\r\n <stop offset=\"0.8585\" stopColor=\"#DC0436\" />\r\n <stop offset=\"1\" stopColor=\"#E60039\" />\r\n </linearGradient>\r\n </defs>\r\n <g transform=\"translate(-9.4,96.811)\">\r\n <g transform=\"matrix(1.8215159,0,0,1.8215159,-8.5437653,-109.83667)\">\r\n <path\r\n fill=\"#ffffff\"\r\n d=\"m 174,108.3 c 0,14 -11.4,25.4 -25.4,25.4 l -138.2,0 0,-100.6 c 0,-14 11.4,-25.4 25.4,-25.4 l 138.2,0 0,100.6 z\"\r\n />\r\n <path\r\n fill=\"url(#jcbGreen1)\"\r\n d=\"m 129,82.5 10.5,0 c 0.3,0 1,-0.1 1.3,-0.1 2,-0.4 3.7,-2.2 3.7,-4.7 0,-2.4 -1.7,-4.2 -3.7,-4.7 -0.3,-0.1 -0.9,-0.1 -1.3,-0.1 l -10.5,0 0,9.6 z\"\r\n />\r\n <path\r\n fill=\"url(#jcbGreen2)\"\r\n d=\"m 138.3,16.2 c -10,0 -18.2,8.1 -18.2,18.2 l 0,18.9 25.7,0 c 0.6,0 1.3,0 1.8,0.1 5.8,0.3 10.1,3.3 10.1,8.5 0,4.1 -2.9,7.6 -8.3,8.3 l 0,0.2 c 5.9,0.4 10.4,3.7 10.4,8.8 0,5.5 -5,9.1 -11.6,9.1 l -28.2,0 0,37 26.7,0 c 10,0 18.2,-8.1 18.2,-18.2 l 0,-90.9 -26.6,0 z\"\r\n />\r\n <path\r\n fill=\"url(#jcbGreen3)\"\r\n d=\"m 143.2,63.1 c 0,-2.4 -1.7,-4 -3.7,-4.3 -0.2,0 -0.7,-0.1 -1,-0.1 l -9.5,0 0,8.8 9.5,0 c 0.3,0 0.9,0 1,-0.1 2,-0.3 3.7,-1.9 3.7,-4.3 z\"\r\n />\r\n <path\r\n fill=\"url(#jcbBlue)\"\r\n d=\"m 37.7,16.2 c -10,0 -18.2,8.1 -18.2,18.2 l 0,44.9 c 5.1,2.5 10.4,4.1 15.7,4.1 6.3,0 9.7,-3.8 9.7,-9 l 0,-21.2 15.6,0 0,21.1 c 0,8.2 -5.1,14.9 -22.4,14.9 -10.5,0 -18.7,-2.3 -18.7,-2.3 l 0,38.3 26.7,0 c 10,0 18.2,-8.1 18.2,-18.2 l 0,-90.8 -26.6,0 z\"\r\n />\r\n <path\r\n fill=\"url(#jcbRed)\"\r\n d=\"m 88,16.2 c -10,0 -18.2,8.1 -18.2,18.2 l 0,23.8 c 4.6,-3.9 12.6,-6.4 25.5,-5.8 6.9,0.3 14.3,2.2 14.3,2.2 l 0,7.7 c -3.7,-1.9 -8.1,-3.6 -13.8,-4 -9.8,-0.7 -15.7,4.1 -15.7,12.5 0,8.5 5.9,13.3 15.7,12.5 5.7,-0.4 10.1,-2.2 13.8,-4 l 0,7.7 c 0,0 -7.3,1.9 -14.3,2.2 -12.9,0.6 -20.9,-1.9 -25.5,-5.8 l 0,42 26.7,0 c 10,0 18.2,-8.1 18.2,-18.2 l 0,-91 -26.7,0 z\"\r\n />\r\n </g>\r\n </g>\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\n// Diners Club \uB85C\uACE0\r\nexport function DinersIcon({ size = 24 }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n // \uC6D0\uBCF8 viewBox: 419.87 x 333.3\r\n const logoWidth = 419.87;\r\n const logoHeight = 333.3;\r\n const logoScale = Math.min(\r\n (CARD_WIDTH * 0.8) / logoWidth,\r\n (CARD_HEIGHT * 0.8) / logoHeight\r\n );\r\n const offsetX = (CARD_WIDTH - logoWidth * logoScale) / 2;\r\n const offsetY = (CARD_HEIGHT - logoHeight * logoScale) / 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <g\r\n transform={`translate(${offsetX}, ${offsetY}) scale(${logoScale})`}\r\n >\r\n <g transform=\"translate(-180.06, -83.35)\">\r\n <path\r\n d=\"m599.93 251.45c0-99.416-82.979-168.13-173.9-168.1h-78.241c-92.003-0.033-167.73 68.705-167.73 168.1 0 90.931 75.729 165.64 167.73 165.2h78.241c90.913 0.437 173.9-74.293 173.9-165.2z\"\r\n fill=\"#0079BE\"\r\n />\r\n <path\r\n d=\"m348.28 97.432c-84.069 0.026-152.19 68.308-152.22 152.58 0.021 84.258 68.145 152.53 152.22 152.56 84.088-0.025 152.23-68.301 152.24-152.56-0.011-84.274-68.15-152.55-152.24-152.58z\"\r\n fill=\"#ffffff\"\r\n />\r\n <path\r\n d=\"m252.07 249.6c0.08-41.18 25.747-76.296 61.94-90.25v180.48c-36.193-13.946-61.861-49.044-61.94-90.229zm131 90.275v-180.52c36.208 13.921 61.915 49.057 61.98 90.256-0.066 41.212-25.772 76.322-61.98 90.269z\"\r\n fill=\"#0079BE\"\r\n />\r\n </g>\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\n// Discover \uB85C\uACE0\r\nexport function DiscoverIcon({ size = 24 }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n // 2\uC904 \uB808\uC774\uC544\uC6C3: Disc + \uB3D9\uADF8\uB77C\uBBF8 / ver\r\n const logoWidth = 700;\r\n const logoHeight = 450;\r\n const logoScale = Math.min(\r\n (CARD_WIDTH * 0.95) / logoWidth,\r\n (CARD_HEIGHT * 0.95) / logoHeight\r\n );\r\n const offsetX = (CARD_WIDTH - logoWidth * logoScale) / 2;\r\n const offsetY = (CARD_HEIGHT - logoHeight * logoScale) / 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n xmlnsXlink=\"http://www.w3.org/1999/xlink\"\r\n >\r\n <defs>\r\n <radialGradient\r\n id=\"discoverGradient\"\r\n cx=\"141.25\"\r\n cy=\"77.588577\"\r\n r=\"77.916664\"\r\n fx=\"141.25\"\r\n fy=\"77.588577\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n >\r\n <stop offset=\"0\" stopColor=\"#f0f0f0\" />\r\n <stop offset=\"1\" stopColor=\"#ff8330\" />\r\n </radialGradient>\r\n </defs>\r\n <g\r\n transform={`translate(${offsetX}, ${offsetY}) scale(${logoScale})`}\r\n >\r\n {/* \uCCAB\uBC88\uC9F8 \uC904: Disc + \uC8FC\uD669\uC0C9 \uB3D9\uADF8\uB77C\uBBF8 */}\r\n <text\r\n x=\"-9.8425188\"\r\n y=\"193.30708\"\r\n fontFamily=\"Verdana, sans-serif\"\r\n fontWeight=\"700\"\r\n fontSize=\"220\"\r\n fill=\"#000000\"\r\n >\r\n Disc\r\n </text>\r\n <g transform=\"matrix(0.94947156 0 0 0.949483 496.94722 33.627248)\">\r\n <path\r\n d=\"m 199.16666,97.588577 a 77.916664,77.916664 0 1 1 -155.833324,0 77.916664,77.916664 0 1 1 155.833324,0 z\"\r\n transform=\"translate(-25.8333 3.33333)\"\r\n fill=\"url(#discoverGradient)\"\r\n />\r\n </g>\r\n {/* \uB450\uBC88\uC9F8 \uC904: ver */}\r\n <text\r\n x=\"200\"\r\n y=\"420\"\r\n fontFamily=\"Verdana, sans-serif\"\r\n fontWeight=\"700\"\r\n fontSize=\"220\"\r\n fill=\"#000000\"\r\n >\r\n ver\r\n </text>\r\n <text\r\n x=\"580\"\r\n y=\"310\"\r\n fontFamily=\"Bitstream Vera Sans, sans-serif\"\r\n fontSize=\"40\"\r\n fill=\"#000000\"\r\n >\r\n \u00AE\r\n </text>\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\n// UnionPay \uB85C\uACE0\r\nexport function UnionPayIcon({ size = 24 }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n // \uC6D0\uBCF8 viewBox: 256 x 160\r\n const logoWidth = 256;\r\n const logoHeight = 160;\r\n const logoScale = Math.min(\r\n (CARD_WIDTH * 0.8) / logoWidth,\r\n (CARD_HEIGHT * 0.85) / logoHeight\r\n );\r\n const offsetX = (CARD_WIDTH - logoWidth * logoScale) / 2;\r\n const offsetY = (CARD_HEIGHT - logoHeight * logoScale) / 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <g\r\n transform={`translate(${offsetX}, ${offsetY}) scale(${logoScale})`}\r\n >\r\n <path\r\n d=\"M50.041631,0.000667563305 L113.820211,0.000667563305 C122.723127,0.000667563305 128.260438,7.25731345 126.183558,16.1897657 L96.4900715,143.675416 C94.3945365,152.576777 85.480739,159.839641 76.571605,159.839641 L12.7992433,159.839641 C3.908764,159.839641 -1.64098444,152.576777 0.435896208,143.675416 L30.1418186,16.1897657 C32.2186993,7.25731345 41.1278333,0.000667563305 50.041631,0.000667563305\"\r\n fill=\"#E21836\"\r\n />\r\n <path\r\n d=\"M108.513283,0.000667563305 L181.857018,0.000667563305 C190.758378,0.000667563305 186.744527,7.25731345 184.650546,16.1897657 L154.961724,143.675416 C152.878625,152.576777 153.528427,159.839641 144.608411,159.839641 L71.2646775,159.839641 C62.3446615,159.839641 56.8244495,152.576777 58.919985,143.675416 L88.6072525,16.1897657 C90.715224,7.25731345 99.6057035,0.000667563305 108.513283,0.000667563305\"\r\n fill=\"#00447C\"\r\n />\r\n <path\r\n d=\"M178.94783,0.000667563305 L242.726409,0.000667563305 C251.641762,0.000667563305 257.179074,7.25731345 255.085093,16.1897657 L225.396271,143.675416 C223.300736,152.576777 214.380719,159.839641 205.466922,159.839641 L141.717879,159.839641 C132.797863,159.839641 127.265215,152.576777 129.354532,143.675416 L159.048017,16.1897657 C161.124899,7.25731345 170.027814,0.000667563305 178.94783,0.000667563305\"\r\n fill=\"#007B84\"\r\n />\r\n <path\r\n d=\"M66.698338,40.8561434 C60.139686,40.9229891 58.202715,40.8561434 57.5840035,40.7100156 C57.346157,41.8401744 52.920349,62.256098 52.9079125,62.273198 C51.9549725,66.403641 51.261643,69.347961 48.9064975,71.2491775 C47.5695833,72.3544635 46.0088137,72.8876745 44.1993159,72.8876745 C41.2907503,72.8876745 39.5962892,71.4434965 39.3118063,68.704377 L39.2573971,67.7638735 C39.2573971,67.7638735 40.1434913,62.231225 40.1434913,62.200134 C40.1434913,62.200134 44.7884909,43.5952629 45.6201759,41.1359627 C45.6637033,40.9960531 45.6761397,40.9229891 45.6870215,40.8561434 C36.6457507,40.9354255 35.0430082,40.8561434 34.9326351,40.7100156 C34.8720075,40.9105527 34.6481522,42.0640298 34.6481522,42.0640298 L29.9052159,63.0333735 L29.4979234,64.8117805 L28.7097659,70.6289115 C28.7097659,72.3544635 29.0486581,73.762887 29.7233334,74.9536735 C31.8841598,78.729679 38.0479561,79.2955355 41.5348148,79.2955355 C46.0274683,79.2955355 50.241857,78.341041 53.089795,76.598389 C58.0332685,73.677387 59.3266555,69.1116695 60.4801325,65.0542905 L61.014898,62.972746 C61.014898,62.972746 65.7998075,43.6496723 66.6128375,41.1359627 C66.643929,40.9960531 66.656365,40.9229891 66.698338,40.8561434 Z M82.9786885,56.444252 C81.825211,56.444252 79.7172395,56.724071 77.823796,57.6521385 C77.1366845,58.0050215 76.486882,58.412314 75.8013245,58.818052 L76.420036,56.5841615 L76.081144,56.20796 C72.0657375,57.0209905 71.167207,57.129809 67.4580475,57.6521385 L67.147137,57.8588935 C66.7165265,61.4296985 66.3341065,64.1144085 64.7375825,71.133208 C64.129753,73.7199815 63.498605,76.331628 62.8659025,78.912183 L63.036903,79.2401935 C66.8377815,79.0396565 67.9912585,79.0396565 71.29468,79.0940655 L71.562063,78.8033645 C71.981792,76.65342 72.036201,76.1497455 72.965823,71.795447 C73.402652,69.7310025 74.313619,65.1948215 74.7628845,63.579643 C75.588351,63.197223 76.402936,62.8210215 77.1802115,62.8210215 C79.0316825,62.8210215 78.8062725,64.4362005 78.734763,65.079785 C78.655481,66.160198 77.9808055,69.68903 77.2890305,72.7188505 L76.8273285,74.674476 C76.5055365,76.1186545 76.152653,77.522414 75.830861,78.954156 L75.9707705,79.2401935 C79.7172395,79.0396565 80.859835,79.0396565 84.0591015,79.0940655 L84.435303,78.8033645 C85.013596,75.4455335 85.183042,74.547003 86.209046,69.6579385 L86.725157,67.411612 C87.727843,63.0153405 88.2315175,60.786114 87.4728965,58.970398 C86.670748,56.93549 84.7462135,56.444252 82.9786885,56.444252 Z M101.165696,61.047123 C99.1743155,61.429543 97.904247,61.684489 96.6419515,61.8492715 C95.3905375,62.049809 94.1702145,62.2316915 92.24568,62.499074 L92.093334,62.637429 L91.9534245,62.7478025 C91.7528875,64.181099 91.6129775,65.420076 91.3471495,66.876691 C91.1217395,68.383051 90.7750745,70.094612 90.2107725,72.5539125 C89.7739435,74.436474 89.5485335,75.092495 89.299805,75.754734 C89.057295,76.4169725 88.7899125,77.060557 88.298674,78.9120275 L88.413711,79.0830285 L88.510093,79.240038 C90.308709,79.1545375 91.4855045,79.09391 92.6949455,79.0830285 C93.902832,79.039501 95.1542455,79.0830285 97.0912165,79.09391 L97.260663,78.955555 L97.4425455,78.803209 C97.7223645,77.133621 97.7643375,76.6843555 97.935338,75.8697705 C98.104784,74.9961125 98.39704,73.786672 99.113688,70.556314 C99.4525805,69.039072 99.8303365,67.5264935 100.181665,65.97816 C100.546985,64.436045 100.929404,62.9172485 101.293169,61.4000065 L101.23876,61.2165695 L101.165696,61.047123 Z M101.208135,54.841043 C99.3986375,53.7730665 96.222689,54.1119585 94.0851805,55.587228 C91.953891,57.0329605 91.711381,59.0849685 93.5146605,60.166936 C95.293067,61.2053765 98.481452,60.896021 100.600305,59.408315 C102.726932,57.9314915 102.99276,55.898138 101.208135,54.841043 Z M112.151399,79.574733 C115.812368,79.574733 119.565055,78.565829 122.389675,75.571763 C124.562938,73.143554 125.559405,69.5307765 125.904516,68.043071 C127.028457,63.112034 126.153244,60.809743 125.054176,59.407538 C123.384588,57.2700295 120.43405,56.5844725 117.373138,56.5844725 C115.532549,56.5844725 111.148714,56.766355 107.724038,59.923649 C105.264737,62.2010665 104.12836,65.291515 103.442803,68.2544895 C102.751028,71.2734285 101.955097,76.70814 106.95298,78.7306115 C108.495095,79.3928505 110.718104,79.574733 112.151399,79.574733 Z M111.865362,68.4798995 C112.709484,64.7458675 113.705951,61.6118915 116.249197,61.6118915 C118.242132,61.6118915 118.386705,63.943719 117.500611,67.6901875 C117.342047,68.5218725 116.614517,71.6138755 115.630486,72.9305805 C114.943374,73.902175 114.130344,74.49135 113.231813,74.49135 C112.96443,74.49135 111.374124,74.49135 111.349251,72.1299865 C111.336815,70.964073 111.574661,69.7732865 111.865362,68.4798995 Z M135.05616,79.094532 L135.342197,78.803831 C135.747935,76.6538865 135.814781,76.148657 136.713312,71.7959135 C137.162577,69.731469 138.092198,65.195288 138.529028,63.580109 C139.356049,63.196135 140.156643,62.8199335 140.958791,62.8199335 C142.797825,62.8199335 142.57397,64.4351125 142.500907,65.0786965 C142.43406,66.1606645 141.759386,69.6879415 141.055173,72.717762 L140.618345,74.673388 C140.284116,76.1191205 139.920351,77.521326 139.598559,78.9546225 L139.738469,79.24066 C143.497374,79.0401225 144.596441,79.0401225 147.814363,79.094532 L148.203001,78.803831 C148.767303,75.4444455 148.919649,74.5459145 149.976744,69.658405 L150.480419,67.410524 C151.487768,63.0142525 151.99766,60.7865805 151.251476,58.9708645 C150.426009,56.9359565 148.489038,56.4447185 146.746386,56.4447185 C145.591354,56.4447185 143.472501,56.722983 141.589939,57.652605 C140.916819,58.005488 140.242143,58.411226 139.579904,58.8185185 L140.156643,56.584628 L139.847287,56.206872 C135.833436,57.021457 134.91625,57.1302755 131.211754,57.652605 L130.927271,57.85936 C130.478006,61.4301645 130.112686,64.1133205 128.516162,71.1336745 C127.908333,73.720448 127.277185,76.332094 126.646037,78.9126495 L126.815483,79.24066 C130.622579,79.0401225 131.758957,79.0401225 135.05616,79.094532 Z M162.673542,79.2398825 C162.909834,78.0864055 164.313594,71.2494885 164.32603,71.2494885 C164.32603,71.2494885 165.52148,66.232951 165.594545,66.0510685 C165.594545,66.0510685 165.970746,65.5287395 166.346947,65.321984 L166.900367,65.321984 C172.122106,65.321984 178.018519,65.321984 182.6402,61.92218 C185.785058,59.590353 187.935002,56.1470215 188.89416,51.9621695 C189.142889,50.9361655 189.326326,49.7158426 189.326326,48.4955199 C189.326326,46.8927774 189.004534,45.3071349 188.074912,44.0681575 C185.718212,40.770954 181.025022,40.7103265 175.60741,40.6854536 C175.59031,40.6854536 172.93669,40.7103265 172.93669,40.7103265 C166.001837,40.7958268 163.220744,40.770954 162.078149,40.6310444 C161.981767,41.1362735 161.799884,42.0348043 161.799884,42.0348043 C161.799884,42.0348043 159.315711,53.547812 159.315711,53.5664665 C159.315711,53.5664665 153.371107,78.0444325 153.091287,79.1979095 C159.146265,79.124846 161.628884,79.124846 162.673542,79.2398825 Z M167.276569,58.7882045 C167.276569,58.7882045 169.917752,47.2985153 169.905316,47.3420427 L169.990815,46.7528678 L170.028125,46.3036024 L171.083665,46.4124209 C171.083665,46.4124209 176.530813,46.8803409 176.658287,46.8927774 C178.808231,47.7244624 179.694325,49.8681887 179.075614,52.666381 C178.511312,55.223618 176.852606,57.373563 174.721316,58.412003 C172.966227,59.291879 170.816282,59.364943 168.601047,59.364943 L167.167751,59.364943 L167.276569,58.7882045 Z M183.721236,68.692718 C183.023242,71.668129 182.221093,77.102841 187.194103,79.039812 C188.779745,79.714487 190.200605,79.915024 191.644784,79.8419605 C193.169799,79.759569 194.582886,78.99473 195.891818,77.8941075 C195.773673,78.346482 195.655527,78.7988565 195.537381,79.2527855 L195.76279,79.5434865 C199.339813,79.392695 200.449763,79.392695 204.325259,79.4222315 L204.676588,79.1548485 C205.242445,75.8281085 205.775656,72.597751 207.246262,66.2334175 C207.962909,63.184942 208.678003,60.1660035 209.413306,57.1299645 L209.29827,56.795736 C205.296854,57.537257 204.227323,57.6958215 200.378253,58.241469 L200.085998,58.479315 C200.047134,58.788671 200.006716,59.08559 199.969406,59.3825095 C199.370904,58.4155785 198.503465,57.590112 197.164996,57.0755555 C195.453434,56.4024345 191.433365,57.269874 187.977597,60.416286 C185.549388,62.662613 184.383475,65.7406245 183.721236,68.692718 Z M192.12514,68.8746005 C192.981698,65.2074135 193.965729,62.104529 196.515194,62.104529 C198.127263,62.104529 198.976048,63.5922345 198.803493,66.1292625 C198.666693,66.761965 198.51901,67.4288675 198.343345,68.182825 C198.0884,69.2725655 197.811689,70.3529785 197.542752,71.4349465 C197.26915,72.174913 196.950468,72.8729065 196.600694,73.3377175 C195.944673,74.267339 194.383904,74.8440775 193.485373,74.8440775 C193.230426,74.8440775 191.65722,74.8440775 191.602811,72.524687 C191.590374,71.3696555 191.828221,70.1804235 192.12514,68.8746005 Z M236.010903,56.766044 L235.701548,56.413161 C231.742105,57.2153095 231.025456,57.3427825 227.387807,57.834021 L227.120423,58.1014035 C227.107988,58.144931 227.097105,58.211777 227.078451,58.2724045 L227.066014,58.211777 C224.357986,64.459519 224.437268,63.111723 222.232914,68.0303235 C222.220477,67.806468 222.220477,67.6665585 222.208042,67.428712 L221.656175,56.766044 L221.30951,56.413161 C217.161968,57.2153095 217.064031,57.3427825 213.233616,57.834021 L212.935143,58.1014035 C212.893169,58.228877 212.893169,58.3687865 212.868297,58.5211325 L212.893169,58.575542 C213.371971,61.022406 213.256934,60.4767585 213.737291,64.338264 C213.961146,66.233262 214.25962,68.139142 214.483475,70.010822 C214.861232,73.143243 215.072651,74.685358 215.534352,79.4656035 C212.947578,83.7344015 212.335085,85.3495805 209.844694,89.0960495 L209.861794,89.1333585 L208.10826,91.906678 C207.907723,92.198934 207.725841,92.399471 207.470894,92.4849715 C207.191075,92.6233265 206.82731,92.648199 206.32208,92.648199 L205.350486,92.648199 L203.906308,97.451763 L208.860663,97.5372635 C211.769228,97.524827 213.597381,96.1645945 214.581412,94.336442 L217.696733,88.9981125 L217.646987,88.9981125 L217.974998,88.621911 C220.070533,84.110603 236.010903,56.766044 236.010903,56.766044 Z M183.72108,119.853625 L181.619326,119.853625 L189.398302,94.1242455 L191.978857,94.1242455 L192.798105,91.4737355 L192.877387,94.421165 C192.781005,96.243099 194.214302,97.858278 197.979425,97.5908955 L202.333723,97.5908955 L203.832311,92.63654 L202.193814,92.63654 C201.251756,92.63654 200.814927,92.3986935 200.869337,91.888801 L200.790054,88.890071 L192.726596,88.890071 L192.726596,88.9056165 C190.119614,88.960026 182.33442,89.1558995 180.758105,89.5756285 C178.850671,90.0668665 176.840635,91.5125995 176.840635,91.5125995 L177.630347,88.85898 L170.087664,88.85898 L168.516013,94.1242455 L160.632883,120.246927 L159.103204,120.246927 L157.603062,125.165528 L172.626247,125.165528 L172.122572,126.805579 L179.525345,126.805579 L180.016584,125.165528 L182.093465,125.165528 L183.72108,119.853625 Z M177.557284,99.352202 C176.349398,99.6864305 174.101516,100.699998 174.101516,100.699998 L176.100669,94.1242455 L182.093465,94.1242455 L180.647732,98.915373 C180.647732,98.915373 178.796261,99.0241915 177.557284,99.352202 Z M177.672321,108.746356 C177.672321,108.746356 175.789759,108.982648 174.550781,109.262467 C173.330458,109.632451 171.042159,110.798364 171.042159,110.798364 L173.106603,103.955229 L179.13049,103.955229 L177.672321,108.746356 Z M174.31449,119.914253 L168.30304,119.914253 L170.045692,114.139095 L176.038487,114.139095 L174.31449,119.914253 Z M188.791404,103.955229 L197.456474,103.955229 L196.211278,107.987735 L187.431173,107.987735 L186.112912,112.396443 L193.795505,112.396443 L187.978375,120.587374 C187.571082,121.188986 187.205762,121.401959 186.800025,121.571405 C186.392732,121.77816 185.857967,122.02067 185.239255,122.02067 L183.107965,122.02067 L181.643577,126.849107 L187.218198,126.849107 C190.115882,126.849107 191.827443,125.530847 193.091294,123.800631 L197.080273,118.341047 L197.936831,123.884578 C198.118713,124.923017 198.864898,125.530847 199.370127,125.767139 C199.928211,126.046958 200.50495,126.527315 201.319535,126.598824 C202.193192,126.636133 202.82434,126.66567 203.244069,126.66567 L205.983189,126.66567 L207.627904,121.262049 L206.547491,121.262049 C205.927224,121.262049 204.859248,121.157894 204.677366,120.963575 C204.495483,120.727283 204.495483,120.363518 204.397546,119.810098 L203.528552,114.254131 L199.970183,114.254131 L201.530954,112.396443 L210.293959,112.396443 L211.641755,107.987735 L203.528552,107.987735 L204.792402,103.955229 L212.880733,103.955229 L214.380875,98.982219 L190.266674,98.982219 L188.791404,103.955229 Z M115.605924,121.037106 L117.628395,114.309008 L125.940582,114.309008 L127.459378,109.304907 L119.139419,109.304907 L120.409488,105.163582 L128.539791,105.163582 L130.046152,100.318045 L109.703292,100.318045 L108.228023,105.163582 L112.849704,105.163582 L111.616945,109.304907 L106.982827,109.304907 L105.446931,114.394508 L110.067057,114.394508 L107.371465,123.295869 C107.0077,124.474219 107.542466,124.923484 107.881358,125.470686 C108.228023,126.003897 108.579352,126.35678 109.369064,126.557317 C110.183649,126.7392 110.741733,126.848018 111.500354,126.848018 L120.87119,126.848018 L122.540778,121.304488 L118.387016,121.875009 C117.584868,121.875009 115.363414,121.778627 115.605924,121.037106 Z M116.55933,88.8286665 L114.452913,92.635763 C114.002093,93.4674475 113.596355,93.983559 113.231036,94.221405 C112.909244,94.4219425 112.271878,94.505888 111.348474,94.505888 L110.249406,94.505888 L108.780355,99.3762975 L112.430442,99.3762975 C114.18553,99.3762975 115.533326,98.7327135 116.176911,98.410921 C116.868686,98.040938 117.050568,98.252357 117.585334,97.736246 L118.818094,96.668269 L130.216064,96.668269 L131.728643,91.5973225 L123.385365,91.5973225 L124.84198,88.8286665 L116.55933,88.8286665 Z M133.386416,121.134887 C133.192097,120.855067 133.332007,120.362275 133.628926,119.336271 L136.744247,109.024932 L147.826644,109.024932 C149.441823,109.001614 150.607736,108.982959 151.366357,108.92855 C152.180942,108.843049 153.067037,108.552348 154.032413,108.030019 C155.028881,107.482817 155.538773,106.906078 155.969384,106.243839 C156.44974,105.583155 157.220798,104.137422 157.883037,101.908196 L161.798952,88.859291 L150.298381,88.926137 C150.298381,88.926137 146.757113,89.448466 145.197898,90.0252045 C143.624692,90.668789 141.37681,92.4658505 141.37681,92.4658505 L142.415251,88.8888275 L135.31095,88.8888275 L125.364931,121.874854 C125.012048,123.155803 124.775756,124.085425 124.721347,124.643509 C124.702692,125.245121 125.479968,125.840514 125.983643,126.289779 C126.579036,126.739045 127.458911,126.665981 128.303033,126.739045 C129.190682,126.805891 130.452978,126.847863 132.195629,126.847863 L137.655214,126.847863 L139.33102,121.189296 L134.443511,121.650998 C133.921182,121.650998 133.543426,121.371178 133.386416,121.134887 Z M138.754282,102.060541 L150.394763,102.060541 L149.654797,104.379932 C149.550642,104.434341 149.301913,104.264895 148.117345,104.404805 L138.037634,104.404805 L138.754282,102.060541 Z M141.086109,94.2815665 L152.824526,94.2815665 L151.980405,97.075095 C151.980405,97.075095 146.447757,97.020686 145.561663,97.1839135 C141.662847,97.858589 139.38543,99.941688 139.38543,99.941688 L141.086109,94.2815665 Z M149.915339,112.146937 C149.818957,112.493602 149.666611,112.705021 149.453638,112.863585 C149.217345,113.015931 148.834926,113.07034 148.264406,113.07034 L146.605699,113.07034 L146.703636,110.245721 L139.804537,110.245721 L139.524718,124.054801 C139.513836,125.051268 139.610218,125.628007 140.339303,126.089709 C141.068387,126.666447 143.314714,126.739511 146.338316,126.739511 L150.661524,126.739511 L152.222294,121.570628 L148.458724,121.777383 L147.207311,121.850447 C147.03631,121.777383 146.873082,121.710537 146.6912,121.528655 C146.532635,121.371645 146.265253,121.468028 146.30878,120.47156 L146.338316,116.931847 L150.285323,116.768619 C152.416613,116.768619 153.32758,116.075288 154.104855,115.414604 C154.846376,114.781902 155.088886,114.054372 155.368706,113.07034 L156.030945,109.936365 L150.607114,109.936365 L149.915339,112.146937 Z\"\r\n fill=\"#FEFEFE\"\r\n />\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\n// BC\uCE74\uB4DC \uB85C\uACE0\r\nexport function BcIcon({ size = 24 }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n // \uC6D0\uBCF8 viewBox: 160.11 x 160.09 (\uC815\uC0AC\uAC01\uD615)\r\n const logoSize = Math.min(CARD_WIDTH, CARD_HEIGHT) * 0.75;\r\n const offsetX = (CARD_WIDTH - logoSize) / 2;\r\n const offsetY = (CARD_HEIGHT - logoSize) / 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`}\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <svg\r\n x={offsetX}\r\n y={offsetY}\r\n width={logoSize}\r\n height={logoSize}\r\n viewBox=\"0 0 160.11065 160.09067\"\r\n >\r\n <g transform=\"matrix(1.3333333,0,0,-1.3333333,-218.97066,649.46545)\">\r\n <g>\r\n <g>\r\n <g transform=\"translate(284.311,427.0571)\">\r\n <path\r\n d=\"m 0,0 c 0,-33.144 -26.904,-60.026 -60.042,-60.026 -33.158,0 -60.041,26.882 -60.041,60.026 0,33.164 26.883,60.042 60.041,60.042 C -26.904,60.042 0,33.164 0,0\"\r\n fill=\"#e83e44\"\r\n />\r\n </g>\r\n </g>\r\n </g>\r\n <g>\r\n <g>\r\n <g transform=\"translate(174.2358,433.7524)\">\r\n <path\r\n d=\"M 0,0 C 0,-0.041 0.112,-1.324 0.112,-1.324 0.092,-1.62 0.255,-1.901 0.521,-2.003 0.756,-2.111 1.022,-2.06 1.257,-1.861 3.495,0.02 6.889,1.702 9.618,0.762 11.754,0.02 13.206,-2.183 13.962,-5.796 15.516,-13.37 10.323,-17.02 7.083,-18.506 L 6.971,-18.557 2.82,-20.592 c 0,0 -0.234,-0.101 -0.49,0.021 -0.255,0.133 -0.327,0.297 -0.501,0.746 -2.821,10.411 -3.782,21.348 -2.729,31.559 0.112,0.767 0.46,1.697 1.053,2.454 l 3.485,3.715 0.389,0.424 c 1.891,1.84 3.669,2.76 4.631,2.361 C 9.455,20.351 9.649,19.073 9.659,18.071 9.822,12.644 6.787,7.098 0.429,1.125 0.429,1.125 -0.062,0.726 0,0 m 19.104,7.528 c -1.892,1.13 -4.027,1.451 -6.184,1.139 3.934,4.192 6.072,8.75 6.072,13.35 0,0.419 -0.011,0.838 -0.062,1.268 -0.204,2.861 -1.523,5.008 -3.567,5.734 -2.045,0.766 -5.797,0.378 -11.756,-5.714 L 0.03,19.298 C -0.961,18.092 -4.723,12.399 -5.418,6.47 c -1.165,-10.078 -0.419,-20.136 2.147,-29.054 0.296,-1.042 1.257,-3.558 3.567,-4.489 2.454,-1.001 4.784,0.205 6.849,1.269 l 0.551,0.275 2.126,0.951 2.065,0.91 2.515,1.104 c 1.808,0.736 3.506,1.421 5.161,2.811 2.198,1.876 3.813,4.328 4.641,7.119 0.43,1.441 0.726,3.015 0.879,4.804 0.133,1.39 0.276,4.089 -0.245,6.46 -1.134,5.223 -3.731,7.718 -5.734,8.898\"\r\n fill=\"#ffffff\"\r\n />\r\n </g>\r\n <g transform=\"translate(240.4609,472.9214)\">\r\n <path\r\n d=\"M 0,0 C -1.166,3.996 -3.067,4.834 -3.619,5.019 -8.606,6.613 -13.79,6.94 -18.818,6.062 -26.372,4.671 -32.903,0.706 -37.237,-5.101 c -4.549,-6.107 -6.307,-13.727 -4.958,-21.434 1.37,-7.738 5.275,-14.004 11.346,-18.103 7.114,-4.794 16.579,-6.255 26.699,-4.129 5.979,1.298 10.917,3.623 14.739,6.92 1.707,1.482 2.034,3.368 2.034,4.692 0,0 0.092,1.068 -0.736,4.436 -0.224,0.817 -0.582,1.063 -1.155,1.063 -0.419,0 -0.858,-0.481 -0.94,-0.583 -2.852,-3.302 -7.196,-5.601 -12.624,-6.669 -13.932,-2.678 -24.644,3.827 -27.301,16.584 -1.135,5.525 -0.195,10.824 2.688,14.924 2.893,4.17 7.635,6.93 13.349,7.788 4.354,0.634 8.78,0.098 12.756,-1.564 0,0 1.708,-0.495 1.34,1.176\"\r\n fill=\"#ffffff\"\r\n />\r\n </g>\r\n </g>\r\n </g>\r\n </g>\r\n </svg>\r\n </svg>\r\n );\r\n}\r\n", "/**\r\n * Slider.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback } from \"react\";\r\nimport {\r\n Box,\r\n FormControl,\r\n FormLabel,\r\n Slider as MuiSlider,\r\n} from \"@mui/material\";\r\nimport type { SliderProps } from \"./types\";\r\n\r\nconst SliderBase = forwardRef<HTMLSpanElement, SliderProps>(function SliderBase(\r\n { label, name, value, onChange, readonly, disabled, ...props },\r\n ref,\r\n) {\r\n return (\r\n <FormControl disabled={disabled} sx={{ width: \"100%\" }}>\r\n {label && <FormLabel>{label}</FormLabel>}\r\n <Box sx={{ px: 1 }}>\r\n <MuiSlider\r\n {...props}\r\n ref={ref}\r\n name={name}\r\n value={value ?? 0}\r\n onChange={onChange}\r\n disabled={disabled || readonly}\r\n />\r\n </Box>\r\n </FormControl>\r\n );\r\n});\r\n\r\nconst SliderWithForm = forwardRef<HTMLSpanElement, SliderProps>(\r\n function SliderWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"Slider form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"Slider requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const resolvedValue =\r\n formValue !== undefined && formValue !== null\r\n ? (formValue as number | number[])\r\n : (rest.value ?? 0);\r\n\r\n const handleFormChange = useCallback(\r\n (_event: Event, nextValue: number | number[]) => {\r\n const syntheticEvent = {\r\n target: {\r\n name,\r\n value: nextValue,\r\n },\r\n } as unknown as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n onChange?.(_event, nextValue);\r\n },\r\n [form, name, onChange],\r\n );\r\n\r\n return (\r\n <SliderBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={resolvedValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const Slider = forwardRef<HTMLSpanElement, SliderProps>(\r\n function Slider(props, ref) {\r\n if (props.form) {\r\n return <SliderWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <SliderBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * Stepper.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \u0010a8ud10a8uc601uc9c4 (Kim Young Jin)\r\n * @author \u0010a8ud10a8uc601uc9c4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { forwardRef, useCallback, useEffect } from \"react\";\r\nimport { Stepper as MuiStepper } from \"@mui/material\";\r\nimport type { StepperProps } from \"./types\";\r\n\r\nconst parseStepValue = (value: unknown): number | undefined => {\r\n if (typeof value === \"number\" && Number.isFinite(value)) {\r\n return value;\r\n }\r\n if (typeof value === \"string\" && value.trim() !== \"\") {\r\n const parsed = Number(value);\r\n return Number.isFinite(parsed) ? parsed : undefined;\r\n }\r\n return undefined;\r\n};\r\n\r\nexport const Stepper = forwardRef<HTMLDivElement, StepperProps>(function Stepper(\r\n { form, name, activeStep: activeStepProp, defaultActiveStep = 0, onStepChange, ...props },\r\n ref\r\n) {\r\n if (form && !name) {\r\n throw new Error(\"Stepper requires a name when form prop is provided.\");\r\n }\r\n\r\n const shouldUseForm = Boolean(form && name);\r\n const formValue = shouldUseForm ? form!.useFormValue(name!) : undefined;\r\n const parsedFormValue = parseStepValue(formValue);\r\n\r\n const emitStepChange = useCallback(\r\n (step: number) => {\r\n if (!form || !name) {\r\n onStepChange?.(step);\r\n return;\r\n }\r\n\r\n const eventTarget = {\r\n name,\r\n value: String(step),\r\n } as HTMLInputElement;\r\n const fakeEvent = {\r\n target: eventTarget,\r\n currentTarget: eventTarget,\r\n } as unknown as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(fakeEvent);\r\n onStepChange?.(step);\r\n },\r\n [form, name, onStepChange]\r\n );\r\n\r\n useEffect(() => {\r\n if (!shouldUseForm || activeStepProp === undefined) {\r\n return;\r\n }\r\n\r\n if (activeStepProp !== parsedFormValue) {\r\n emitStepChange(activeStepProp);\r\n }\r\n }, [shouldUseForm, activeStepProp, parsedFormValue, emitStepChange]);\r\n\r\n useEffect(() => {\r\n if (!shouldUseForm || activeStepProp !== undefined) {\r\n return;\r\n }\r\n\r\n if (parsedFormValue === undefined) {\r\n emitStepChange(defaultActiveStep);\r\n }\r\n }, [shouldUseForm, activeStepProp, parsedFormValue, defaultActiveStep, emitStepChange]);\r\n\r\n const resolvedActiveStep = activeStepProp ?? parsedFormValue ?? defaultActiveStep;\r\n\r\n return <MuiStepper ref={ref} activeStep={resolvedActiveStep} {...props} />;\r\n});\r\n", "import * as React from \"react\";\r\nimport { NumberField as BaseNumberField } from \"@base-ui/react/number-field\";\r\nimport type { NumberFieldRoot } from \"@base-ui/react/number-field\";\r\nimport IconButton from \"@mui/material/IconButton\";\r\nimport FormControl from \"@mui/material/FormControl\";\r\nimport FormHelperText from \"@mui/material/FormHelperText\";\r\nimport OutlinedInput from \"@mui/material/OutlinedInput\";\r\nimport InputAdornment from \"@mui/material/InputAdornment\";\r\nimport InputLabel from \"@mui/material/InputLabel\";\r\nimport KeyboardArrowUpIcon from \"@mui/icons-material/KeyboardArrowUp\";\r\nimport KeyboardArrowDownIcon from \"@mui/icons-material/KeyboardArrowDown\";\r\nimport type { FormLike } from \"../types\";\r\n\r\nexport type NumberFieldProps = BaseNumberField.Root.Props & {\r\n label?: React.ReactNode;\r\n size?: \"small\" | \"medium\";\r\n error?: boolean;\r\n fullWidth?: boolean;\r\n form?: FormLike | null;\r\n};\r\n\r\n/**\r\n * This component is a placeholder for FormControl to correctly set the shrink label state on SSR.\r\n */\r\nfunction SSRInitialFilled(_: BaseNumberField.Root.Props) {\r\n return null;\r\n}\r\nSSRInitialFilled.muiName = \"Input\";\r\n\r\nfunction NumberFieldBase({\r\n id: idProp,\r\n label,\r\n error,\r\n size = \"medium\",\r\n step = 1,\r\n fullWidth = true,\r\n form: _form,\r\n ...other\r\n}: NumberFieldProps) {\r\n let id = React.useId();\r\n if (idProp) {\r\n id = idProp;\r\n }\r\n return (\r\n <BaseNumberField.Root\r\n step={step}\r\n {...other}\r\n render={(props, state) => (\r\n <FormControl\r\n size={size}\r\n fullWidth={fullWidth}\r\n sx={fullWidth ? { display: \"flex\" } : undefined}\r\n ref={props.ref}\r\n disabled={state.disabled}\r\n required={state.required}\r\n error={error}\r\n variant=\"outlined\"\r\n >\r\n {props.children}\r\n </FormControl>\r\n )}\r\n >\r\n <SSRInitialFilled {...other} />\r\n <InputLabel htmlFor={id}>{label}</InputLabel>\r\n <BaseNumberField.Input\r\n id={id}\r\n render={(props, state) => (\r\n <OutlinedInput\r\n label={label}\r\n fullWidth={fullWidth}\r\n inputRef={props.ref}\r\n value={state.inputValue}\r\n onBlur={props.onBlur}\r\n onChange={props.onChange}\r\n onKeyUp={props.onKeyUp}\r\n onKeyDown={props.onKeyDown}\r\n onFocus={props.onFocus}\r\n slotProps={{\r\n input: props,\r\n }}\r\n endAdornment={\r\n <InputAdornment\r\n position=\"end\"\r\n sx={{\r\n flexDirection: \"column\",\r\n maxHeight: \"unset\",\r\n alignSelf: \"stretch\",\r\n borderLeft: \"1px solid\",\r\n borderColor: \"divider\",\r\n ml: 0,\r\n \"& button\": {\r\n py: 0,\r\n flex: 1,\r\n borderRadius: 0.5,\r\n },\r\n }}\r\n >\r\n <BaseNumberField.Increment\r\n render={\r\n <IconButton\r\n size={size}\r\n aria-label=\"Increase\"\r\n />\r\n }\r\n >\r\n <KeyboardArrowUpIcon\r\n fontSize={size}\r\n sx={{ transform: \"translateY(2px)\" }}\r\n />\r\n </BaseNumberField.Increment>\r\n\r\n <BaseNumberField.Decrement\r\n render={\r\n <IconButton\r\n size={size}\r\n aria-label=\"Decrease\"\r\n />\r\n }\r\n >\r\n <KeyboardArrowDownIcon\r\n fontSize={size}\r\n sx={{ transform: \"translateY(-2px)\" }}\r\n />\r\n </BaseNumberField.Decrement>\r\n </InputAdornment>\r\n }\r\n sx={{ pr: 0 }}\r\n />\r\n )}\r\n />\r\n </BaseNumberField.Root>\r\n );\r\n}\r\n\r\nfunction NumberFieldWithForm({\r\n form,\r\n name,\r\n onValueChange,\r\n ...rest\r\n}: NumberFieldProps) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"NumberField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"NumberField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormValueChange = React.useCallback(\r\n (\r\n value: number | null,\r\n eventDetails: NumberFieldRoot.ChangeEventDetails,\r\n ) => {\r\n const syntheticEvent = {\r\n target: {\r\n name,\r\n value: value !== null ? String(value) : \"\",\r\n },\r\n currentTarget: {\r\n name,\r\n value: value !== null ? String(value) : \"\",\r\n },\r\n } as unknown as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n onValueChange?.(value, eventDetails);\r\n },\r\n [form, name, onValueChange],\r\n );\r\n\r\n return (\r\n <NumberFieldBase\r\n {...rest}\r\n name={name}\r\n value={formValue as number | null}\r\n onValueChange={handleFormValueChange}\r\n />\r\n );\r\n}\r\n\r\nexport default function NumberField(props: NumberFieldProps) {\r\n if (props.form) {\r\n return <NumberFieldWithForm {...props} />;\r\n }\r\n return <NumberFieldBase {...props} />;\r\n}\r\n", "import * as React from \"react\";\r\nimport { NumberField as BaseNumberField } from \"@base-ui/react/number-field\";\r\nimport Box from \"@mui/material/Box\";\r\nimport Button from \"@mui/material/Button\";\r\nimport FormControl from \"@mui/material/FormControl\";\r\nimport FormLabel from \"@mui/material/FormLabel\";\r\nimport AddIcon from \"@mui/icons-material/Add\";\r\nimport RemoveIcon from \"@mui/icons-material/Remove\";\r\nimport OutlinedInput from \"@mui/material/OutlinedInput\";\r\nimport OpenInFullIcon from \"@mui/icons-material/OpenInFull\";\r\n\r\nexport default function NumberSpinner({\r\n id: idProp,\r\n label,\r\n error,\r\n size = \"medium\",\r\n ...other\r\n}: BaseNumberField.Root.Props & {\r\n label?: React.ReactNode;\r\n size?: \"small\" | \"medium\";\r\n error?: boolean;\r\n}) {\r\n let id = React.useId();\r\n if (idProp) {\r\n id = idProp;\r\n }\r\n return (\r\n <BaseNumberField.Root\r\n {...other}\r\n render={(props, state) => (\r\n <FormControl\r\n size={size}\r\n ref={props.ref}\r\n disabled={state.disabled}\r\n required={state.required}\r\n error={error}\r\n variant=\"outlined\"\r\n sx={{\r\n \"& .MuiButton-root\": {\r\n borderColor: \"divider\",\r\n minWidth: 0,\r\n bgcolor: \"action.hover\",\r\n \"&:not(.Mui-disabled)\": {\r\n color: \"text.primary\",\r\n },\r\n },\r\n }}\r\n >\r\n {props.children}\r\n </FormControl>\r\n )}\r\n >\r\n <BaseNumberField.ScrubArea\r\n render={<Box component=\"span\" sx={{ userSelect: \"none\", width: \"max-content\" }} />}\r\n >\r\n <FormLabel\r\n htmlFor={id}\r\n sx={{\r\n display: \"inline-block\",\r\n cursor: \"ew-resize\",\r\n fontSize: \"0.875rem\",\r\n color: \"text.primary\",\r\n fontWeight: 500,\r\n lineHeight: 1.5,\r\n mb: 0.5,\r\n }}\r\n >\r\n {label}\r\n </FormLabel>\r\n <BaseNumberField.ScrubAreaCursor>\r\n <OpenInFullIcon fontSize=\"small\" sx={{ transform: \"translateY(12.5%) rotate(45deg)\" }} />\r\n </BaseNumberField.ScrubAreaCursor>\r\n </BaseNumberField.ScrubArea>\r\n <Box sx={{ display: \"flex\" }}>\r\n <BaseNumberField.Decrement\r\n render={\r\n <Button\r\n variant=\"outlined\"\r\n aria-label=\"Decrease\"\r\n size={size}\r\n sx={{\r\n borderTopRightRadius: 0,\r\n borderBottomRightRadius: 0,\r\n borderRight: \"0px\",\r\n \"&.Mui-disabled\": {\r\n borderRight: \"0px\",\r\n },\r\n }}\r\n />\r\n }\r\n >\r\n <RemoveIcon fontSize={size} />\r\n </BaseNumberField.Decrement>\r\n\r\n <BaseNumberField.Input\r\n id={id}\r\n render={(props, state) => (\r\n <OutlinedInput\r\n inputRef={props.ref}\r\n value={state.inputValue}\r\n onBlur={props.onBlur}\r\n onChange={props.onChange}\r\n onKeyUp={props.onKeyUp}\r\n onKeyDown={props.onKeyDown}\r\n onFocus={props.onFocus}\r\n slotProps={{\r\n input: {\r\n ...props,\r\n size:\r\n Math.max((other.min?.toString() || \"\").length, state.inputValue.length || 1) +\r\n 1,\r\n sx: {\r\n textAlign: \"center\",\r\n },\r\n },\r\n }}\r\n sx={{ pr: 0, borderRadius: 0, flex: 1 }}\r\n />\r\n )}\r\n />\r\n\r\n <BaseNumberField.Increment\r\n render={\r\n <Button\r\n variant=\"outlined\"\r\n aria-label=\"Increase\"\r\n size={size}\r\n sx={{\r\n borderTopLeftRadius: 0,\r\n borderBottomLeftRadius: 0,\r\n borderLeft: \"0px\",\r\n \"&.Mui-disabled\": {\r\n borderLeft: \"0px\",\r\n },\r\n }}\r\n />\r\n }\r\n >\r\n <AddIcon fontSize={size} />\r\n </BaseNumberField.Increment>\r\n </Box>\r\n </BaseNumberField.Root>\r\n );\r\n}\r\n", "/**\r\n * Autocomplete.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback } from \"react\";\r\nimport { Autocomplete as MuiAutocomplete, TextField } from \"@mui/material\";\r\nimport type { AutocompleteProps, AutocompleteOption } from \"./types\";\r\n\r\nconst AutocompleteBase = forwardRef<HTMLDivElement, AutocompleteProps>(\r\n function AutocompleteBase(\r\n {\r\n name,\r\n label,\r\n options,\r\n value,\r\n onChange,\r\n fullWidth = true,\r\n size,\r\n readonly,\r\n disabled,\r\n textFieldProps,\r\n renderOption,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const selectedOption =\r\n value === null || value === undefined\r\n ? null\r\n : (options.find((option) => option.value === value) ?? null);\r\n\r\n const handleChange = useCallback(\r\n (\r\n _event: React.SyntheticEvent,\r\n option: AutocompleteOption | null,\r\n ) => {\r\n onChange?.(option ? option.value : null);\r\n },\r\n [onChange],\r\n );\r\n\r\n return (\r\n <MuiAutocomplete\r\n {...props}\r\n ref={ref}\r\n options={options}\r\n value={selectedOption}\r\n onChange={handleChange}\r\n fullWidth={fullWidth}\r\n disabled={disabled}\r\n getOptionLabel={(option) => option.label}\r\n isOptionEqualToValue={(option, selected) =>\r\n option.value === selected.value\r\n }\r\n renderOption={\r\n renderOption ??\r\n ((optionProps, option, state) => {\r\n const labelText = option.label;\r\n const query = state.inputValue.trim();\r\n const lowerLabel = labelText.toLowerCase();\r\n const lowerQuery = query.toLowerCase();\r\n const matchIndex = lowerQuery\r\n ? lowerLabel.indexOf(lowerQuery)\r\n : -1;\r\n\r\n if (matchIndex === -1) {\r\n return <li {...optionProps}>{labelText}</li>;\r\n }\r\n\r\n const before = labelText.slice(0, matchIndex);\r\n const match = labelText.slice(\r\n matchIndex,\r\n matchIndex + query.length,\r\n );\r\n const after = labelText.slice(\r\n matchIndex + query.length,\r\n );\r\n\r\n return (\r\n <li {...optionProps}>\r\n {before}\r\n <span style={{ color: \"#1976d2\" }}>\r\n {match}\r\n </span>\r\n {after}\r\n </li>\r\n );\r\n })\r\n }\r\n renderInput={(params) => (\r\n <TextField\r\n {...params}\r\n {...textFieldProps}\r\n name={name}\r\n label={label}\r\n size={size}\r\n InputProps={{\r\n ...params.InputProps,\r\n ...textFieldProps?.InputProps,\r\n readOnly: readonly,\r\n }}\r\n />\r\n )}\r\n />\r\n );\r\n },\r\n);\r\n\r\nconst AutocompleteWithForm = forwardRef<HTMLDivElement, AutocompleteProps>(\r\n function AutocompleteWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"Autocomplete form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"Autocomplete requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name) as string | number | null;\r\n const handleFormChange = useCallback(\r\n (nextValue: string | number | null) => {\r\n const syntheticEvent = {\r\n target: {\r\n name,\r\n value: nextValue ?? \"\",\r\n },\r\n } as unknown as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n onChange?.(nextValue);\r\n },\r\n [form, name, onChange],\r\n );\r\n\r\n return (\r\n <AutocompleteBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const Autocomplete = forwardRef<HTMLDivElement, AutocompleteProps>(\r\n function Autocomplete(props, ref) {\r\n if (props.form) {\r\n return <AutocompleteWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <AutocompleteBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * Select.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 Kim Young Jin\r\n * @author Kim Young Jin (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback, useId } from \"react\";\r\nimport {\r\n FormControl,\r\n MenuItem,\r\n Select as MuiSelect,\r\n SelectChangeEvent,\r\n} from \"@mui/material\";\r\nimport type { SelectProps } from \"./types\";\r\n\r\nconst SelectBase = forwardRef<HTMLDivElement, SelectProps>(function SelectBase(\r\n {\r\n value = \"\",\r\n onChange,\r\n options,\r\n inputProps,\r\n enableWheel = false,\r\n emptyLabel = \"\",\r\n readOnly = false,\r\n showEmptyOption = emptyLabel !== \"\",\r\n fullWidth = true,\r\n size,\r\n formControlProps,\r\n form,\r\n ...selectProps\r\n },\r\n ref,\r\n) {\r\n const generatedId = useId();\r\n const selectId = selectProps.id ?? `select-${generatedId}`;\r\n\r\n const hasValue = value !== undefined && value !== null && value !== \"\";\r\n const safeValue =\r\n hasValue && options.some((option) => option.value === value)\r\n ? value\r\n : \"\";\r\n\r\n const handleSelectWheel = useCallback(\r\n (event: React.WheelEvent) => {\r\n if (!enableWheel || readOnly) return;\r\n event.stopPropagation();\r\n\r\n const optionValues = [\"\", ...options.map((option) => option.value)];\r\n const currentIndex = optionValues.indexOf(safeValue);\r\n if (currentIndex === -1) return;\r\n\r\n const nextIndex =\r\n event.deltaY > 0\r\n ? Math.min(currentIndex + 1, optionValues.length - 1)\r\n : Math.max(currentIndex - 1, 0);\r\n\r\n if (nextIndex !== currentIndex && onChange) {\r\n const nextValue = optionValues[nextIndex];\r\n const syntheticEvent = {\r\n target: {\r\n value: nextValue,\r\n name: selectProps.name ?? \"\",\r\n },\r\n } as SelectChangeEvent<string | number>;\r\n onChange(syntheticEvent);\r\n }\r\n },\r\n [enableWheel, readOnly, options, safeValue, onChange, selectProps],\r\n );\r\n\r\n return (\r\n <FormControl\r\n ref={ref}\r\n fullWidth={fullWidth}\r\n size={size}\r\n {...formControlProps}\r\n sx={{\r\n minWidth: 0,\r\n width: fullWidth ? \"100%\" : undefined,\r\n ...formControlProps?.sx,\r\n }}\r\n >\r\n <MuiSelect\r\n {...selectProps}\r\n id={selectId}\r\n value={safeValue}\r\n onChange={onChange}\r\n fullWidth={fullWidth}\r\n size={size}\r\n inputProps={{\r\n ...inputProps,\r\n readOnly,\r\n }}\r\n onWheel={handleSelectWheel}\r\n displayEmpty={showEmptyOption}\r\n sx={{\r\n width: fullWidth ? \"100%\" : undefined,\r\n minWidth: 0,\r\n \"& .MuiSelect-select\": {\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n },\r\n ...(readOnly && {\r\n pointerEvents: \"none\",\r\n \"&.Mui-focused .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiSelect-icon\": {\r\n display: \"none\",\r\n },\r\n }),\r\n ...selectProps.sx,\r\n }}\r\n renderValue={(selected) => {\r\n if (selected === \"\") {\r\n return (\r\n <span style={{ color: \"#999\" }}>{emptyLabel}</span>\r\n );\r\n }\r\n const option = options.find(\r\n (opt) => opt.value === selected,\r\n );\r\n return (\r\n <span\r\n style={{\r\n display: \"block\",\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n }}\r\n >\r\n {option ? option.label : selected}\r\n </span>\r\n );\r\n }}\r\n >\r\n {showEmptyOption && <MenuItem value=\"\">{emptyLabel}</MenuItem>}\r\n {options.map((option) => (\r\n <MenuItem\r\n key={String(option.value)}\r\n value={option.value as string | number}\r\n >\r\n {option.label}\r\n </MenuItem>\r\n ))}\r\n </MuiSelect>\r\n </FormControl>\r\n );\r\n});\r\n\r\nconst SelectWithForm = forwardRef<HTMLDivElement, SelectProps>(\r\n function SelectWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"Select form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"Select requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name) as\r\n | string\r\n | number\r\n | undefined;\r\n const handleFormChange = useCallback(\r\n (event: SelectChangeEvent<string | number>) => {\r\n form.handleFormChange(\r\n event as React.ChangeEvent<HTMLInputElement>,\r\n );\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <SelectBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const Select = forwardRef<HTMLDivElement, SelectProps>(\r\n function Select(props, ref) {\r\n if (props.form) {\r\n return <SelectWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <SelectBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * LabelSelect.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 Kim Young Jin\r\n * @author Kim Young Jin (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback, useId, useState } from \"react\";\r\nimport {\r\n FormControl,\r\n InputLabel,\r\n MenuItem,\r\n Select,\r\n SelectChangeEvent,\r\n} from \"@mui/material\";\r\nimport type { LabelSelectProps } from \"./types\";\r\n\r\nconst LabelSelectBase = forwardRef<HTMLDivElement, LabelSelectProps>(\r\n function LabelSelectBase(\r\n {\r\n label,\r\n value = \"\",\r\n onChange,\r\n options,\r\n inputProps,\r\n enableWheel = false,\r\n showLabel = true,\r\n emptyLabel = \"\uC120\uD0DD\uC548\uD568\",\r\n readOnly = false,\r\n showEmptyOption = true,\r\n fullWidth = true,\r\n size,\r\n formControlProps,\r\n form,\r\n ...selectProps\r\n },\r\n ref,\r\n ) {\r\n const generatedId = useId();\r\n const selectId = selectProps.id ?? `label-select-${generatedId}`;\r\n const labelId = showLabel ? `${selectId}-label` : undefined;\r\n\r\n const hasValue = value !== undefined && value !== null && value !== \"\";\r\n const safeValue =\r\n hasValue && options.some((option) => option.value === value)\r\n ? value\r\n : \"\";\r\n const [isFocused, setIsFocused] = useState(false);\r\n const shouldNotch = showLabel && (safeValue !== \"\" || isFocused);\r\n const displayEmptyValue = showEmptyOption && !showLabel;\r\n\r\n const handleFocus = useCallback(\r\n (event: React.FocusEvent<HTMLInputElement>) => {\r\n setIsFocused(true);\r\n selectProps.onFocus?.(event);\r\n },\r\n [selectProps],\r\n );\r\n\r\n const handleBlur = useCallback(\r\n (event: React.FocusEvent<HTMLInputElement>) => {\r\n setIsFocused(false);\r\n selectProps.onBlur?.(event);\r\n },\r\n [selectProps],\r\n );\r\n\r\n const handleSelectWheel = useCallback(\r\n (event: React.WheelEvent) => {\r\n if (!enableWheel || readOnly) return;\r\n event.stopPropagation();\r\n\r\n const optionValues = [\r\n \"\",\r\n ...options.map((option) => option.value),\r\n ];\r\n const currentIndex = optionValues.indexOf(safeValue);\r\n if (currentIndex === -1) return;\r\n\r\n const nextIndex =\r\n event.deltaY > 0\r\n ? Math.min(currentIndex + 1, optionValues.length - 1)\r\n : Math.max(currentIndex - 1, 0);\r\n\r\n if (nextIndex !== currentIndex && onChange) {\r\n const nextValue = optionValues[nextIndex];\r\n const syntheticEvent = {\r\n target: {\r\n value: nextValue,\r\n name: selectProps.name ?? \"\",\r\n },\r\n } as SelectChangeEvent<string | number>;\r\n onChange(syntheticEvent);\r\n }\r\n },\r\n [enableWheel, readOnly, options, safeValue, onChange, selectProps],\r\n );\r\n\r\n return (\r\n <FormControl\r\n ref={ref}\r\n fullWidth={fullWidth}\r\n size={size}\r\n {...formControlProps}\r\n sx={{\r\n flex: fullWidth ? 1 : undefined,\r\n minWidth: 0,\r\n width: fullWidth ? \"100%\" : undefined,\r\n ...formControlProps?.sx,\r\n }}\r\n >\r\n {showLabel && (\r\n <InputLabel id={labelId} size={size}>\r\n {label}\r\n </InputLabel>\r\n )}\r\n <Select\r\n {...selectProps}\r\n id={selectId}\r\n labelId={labelId}\r\n value={safeValue}\r\n onChange={onChange}\r\n fullWidth={fullWidth}\r\n size={size}\r\n label={showLabel ? label : undefined}\r\n notched={shouldNotch}\r\n inputProps={{\r\n ...inputProps,\r\n readOnly,\r\n }}\r\n onWheel={handleSelectWheel}\r\n onFocus={handleFocus}\r\n onBlur={handleBlur}\r\n displayEmpty={displayEmptyValue}\r\n sx={{\r\n width: fullWidth ? \"100%\" : undefined,\r\n minWidth: 0,\r\n \"& .MuiSelect-select\": {\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n },\r\n ...(readOnly && {\r\n pointerEvents: \"none\",\r\n \"&.Mui-focused .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiSelect-icon\": {\r\n display: \"none\",\r\n },\r\n }),\r\n ...selectProps.sx,\r\n }}\r\n renderValue={(selected) => {\r\n if (selected === \"\") {\r\n return \"\";\r\n }\r\n const option = options.find(\r\n (opt) => opt.value === selected,\r\n );\r\n return (\r\n <span\r\n style={{\r\n display: \"block\",\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n }}\r\n >\r\n {option ? option.label : selected}\r\n </span>\r\n );\r\n }}\r\n >\r\n {showEmptyOption && (\r\n <MenuItem value=\"\">{emptyLabel}</MenuItem>\r\n )}\r\n {options.map((option) => (\r\n <MenuItem\r\n key={String(option.value)}\r\n value={option.value as string | number}\r\n >\r\n {option.label}\r\n </MenuItem>\r\n ))}\r\n </Select>\r\n </FormControl>\r\n );\r\n },\r\n);\r\n\r\nconst LabelSelectWithForm = forwardRef<HTMLDivElement, LabelSelectProps>(\r\n function LabelSelectWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"LabelSelect form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"LabelSelect requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name) as\r\n | string\r\n | number\r\n | undefined;\r\n const handleFormChange = useCallback(\r\n (event: SelectChangeEvent<string | number>) => {\r\n form.handleFormChange(\r\n event as React.ChangeEvent<HTMLInputElement>,\r\n );\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <LabelSelectBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const LabelSelect = forwardRef<HTMLDivElement, LabelSelectProps>(\r\n function LabelSelect(props, ref) {\r\n if (props.form) {\r\n return <LabelSelectWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <LabelSelectBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * PhoneTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n useRef,\r\n ChangeEvent,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport type { PhoneTextFieldProps } from \"./types\";\r\nimport { useDebouncedEmit } from \"./hooks\";\r\nimport { formatPhoneNumber, getPhoneMaxLength } from \"./utils\";\r\n\r\nconst PhoneTextFieldBase = forwardRef<HTMLDivElement, PhoneTextFieldProps>(\r\n function PhoneTextFieldBase(\r\n {\r\n label,\r\n autoFormat = true,\r\n includeDash = false,\r\n prefix,\r\n format,\r\n onValidationChange,\r\n invalidBorderColor,\r\n debounce,\r\n readonly,\r\n slotProps,\r\n sx,\r\n value,\r\n onChange,\r\n onBlur,\r\n inputRef: externalInputRef,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n const [displayValue, setDisplayValue] = useState(\"\");\r\n const [prevNumbers, setPrevNumbers] = useState(\"\");\r\n const [currentMaxLength, setCurrentMaxLength] = useState(13);\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n const cursorPositionRef = useRef<number | null>(null);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLInputElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange, flushOnBlur, lastEmittedValue } = useDebouncedEmit({\r\n name: props.name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n // prefix \uD3EC\uB9F7\uD305 (\uC608: \"010\" -> \"010-\")\r\n const prefixFormatted = prefix ? `${prefix}-` : \"\";\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uC218\uD589\r\n const performValidation = useCallback(\r\n (inputValue: string) => {\r\n const numbers = inputValue.replace(/\\D/g, \"\");\r\n // \uCD5C\uC18C \uAE38\uC774 \uD310\uB2E8\r\n let minLength = 10;\r\n if (/^1[0-9]{3}/.test(numbers)) {\r\n minLength = 8; // \uC804\uAD6D\uB300\uD45C\uBC88\uD638\r\n } else if (numbers.startsWith(\"02\")) {\r\n minLength = 9; // \uC11C\uC6B8\r\n }\r\n\r\n const isComplete = numbers.length >= minLength;\r\n setIsInvalid(isComplete && numbers.length < minLength);\r\n\r\n if (onValidationChange) {\r\n onValidationChange(isComplete);\r\n }\r\n },\r\n [onValidationChange],\r\n );\r\n\r\n // value \uBCC0\uACBD \uC2DC \uC720\uD6A8\uC131 \uAC80\uC0AC \uBC0F displayValue \uC5C5\uB370\uC774\uD2B8 (\uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uACBD\uC6B0\uB9CC)\r\n useEffect(() => {\r\n if (value !== undefined && value !== null) {\r\n const strValue = String(value);\r\n\r\n if (prefix && strValue === \"\") {\r\n if (lastEmittedValue.current !== prefix) {\r\n setDisplayValue(prefixFormatted);\r\n setPrevNumbers(prefix);\r\n lastEmittedValue.current = prefix;\r\n setCurrentMaxLength(getPhoneMaxLength(prefix));\r\n performValidation(prefixFormatted);\r\n }\r\n return;\r\n }\r\n\r\n // \uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uAC12\uC774 \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uD55C \uAC12\uACFC \uB2E4\uB97C \uB54C\uB9CC \uB3D9\uAE30\uD654\r\n if (strValue === lastEmittedValue.current) {\r\n return;\r\n }\r\n\r\n // format\uC774 \uC9C0\uC815\uB418\uC5B4 \uC788\uC73C\uBA74 \uD574\uB2F9 format \uC0AC\uC6A9\r\n let formattedValue = autoFormat\r\n ? formatPhoneNumber(strValue, format)\r\n : strValue;\r\n\r\n // prefix\uAC00 \uC788\uACE0 \uAC12\uC774 \uBE44\uC5B4\uC788\uC73C\uBA74 prefix\uB85C \uCD08\uAE30\uD654\r\n if (prefix && !formattedValue) {\r\n formattedValue = prefixFormatted;\r\n }\r\n // prefix\uAC00 \uC788\uC73C\uBA74 \uD56D\uC0C1 prefix\uB85C \uC2DC\uC791\uD558\uB3C4\uB85D\r\n if (\r\n prefix &&\r\n formattedValue &&\r\n !formattedValue.startsWith(prefixFormatted)\r\n ) {\r\n formattedValue =\r\n prefixFormatted +\r\n formattedValue.replace(/^\\d{3}-?/, \"\");\r\n }\r\n\r\n setDisplayValue(formattedValue);\r\n setPrevNumbers(strValue.replace(/\\D/g, \"\"));\r\n lastEmittedValue.current = strValue;\r\n\r\n // maxLength \uC5C5\uB370\uC774\uD2B8\r\n const numbers = strValue.replace(/\\D/g, \"\");\r\n setCurrentMaxLength(getPhoneMaxLength(numbers));\r\n\r\n performValidation(formattedValue);\r\n } else if (prefix) {\r\n // value\uAC00 \uC5C6\uC73C\uBA74 prefix\uB85C \uCD08\uAE30\uD654\r\n if (lastEmittedValue.current !== prefix) {\r\n setDisplayValue(prefixFormatted);\r\n setPrevNumbers(prefix);\r\n lastEmittedValue.current = prefix;\r\n }\r\n } else {\r\n if (lastEmittedValue.current !== \"\") {\r\n setDisplayValue(\"\");\r\n setPrevNumbers(\"\");\r\n lastEmittedValue.current = \"\";\r\n }\r\n }\r\n }, [\r\n value,\r\n autoFormat,\r\n prefix,\r\n prefixFormatted,\r\n performValidation,\r\n format,\r\n lastEmittedValue,\r\n ]);\r\n\r\n // \uCEE4\uC11C \uC704\uCE58 \uBCF5\uC6D0 effect\r\n useEffect(() => {\r\n if (\r\n cursorPositionRef.current !== null &&\r\n internalInputRef.current\r\n ) {\r\n const pos = cursorPositionRef.current;\r\n internalInputRef.current.setSelectionRange(pos, pos);\r\n cursorPositionRef.current = null;\r\n }\r\n }, [displayValue]);\r\n\r\n // \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\r\n const newValue = e.target.value;\r\n const newNumbers = newValue.replace(/\\D/g, \"\");\r\n const cursorPos = e.target.selectionStart ?? newValue.length;\r\n\r\n // prefix\uAC00 \uC788\uC744 \uB54C prefix \uC0AD\uC81C \uBC29\uC9C0\r\n if (prefix) {\r\n const prefixNumbers = prefix.replace(/\\D/g, \"\");\r\n // prefix\uBCF4\uB2E4 \uC9E7\uC544\uC9C0\uB824\uACE0 \uD558\uBA74 \uBB34\uC2DC (prefix \uC22B\uC790\uB97C \uC9C0\uC6B0\uB824\uACE0 \uD560 \uB54C)\r\n if (newNumbers.length < prefixNumbers.length) {\r\n // \uCEE4\uC11C \uC704\uCE58 \uC720\uC9C0 - \uBC31\uC2A4\uD398\uC774\uC2A4 \uC804 \uC704\uCE58\uB85C \uBCF5\uC6D0\r\n requestAnimationFrame(() => {\r\n const originalPos = cursorPos + 1;\r\n internalInputRef.current?.setSelectionRange(\r\n originalPos,\r\n originalPos,\r\n );\r\n });\r\n return;\r\n }\r\n // prefix\uAC00 \uC544\uB2CC \uB2E4\uB978 \uBC88\uD638\uB85C \uC2DC\uC791\uD558\uBA74 prefix \uC720\uC9C0\r\n if (!newNumbers.startsWith(prefixNumbers)) {\r\n // \uCEE4\uC11C \uC704\uCE58 \uC720\uC9C0 - \uBC31\uC2A4\uD398\uC774\uC2A4 \uC804 \uC704\uCE58\uB85C \uBCF5\uC6D0\r\n requestAnimationFrame(() => {\r\n const originalPos = cursorPos + 1;\r\n internalInputRef.current?.setSelectionRange(\r\n originalPos,\r\n originalPos,\r\n );\r\n });\r\n return;\r\n }\r\n // prefix + dash \uC0AD\uC81C \uBC29\uC9C0: \"010-\" \uC0C1\uD0DC\uC5D0\uC11C \uBC31\uC2A4\uD398\uC774\uC2A4 \uC2DC \uBB34\uC2DC\r\n if (\r\n newNumbers.length === prefixNumbers.length &&\r\n !newValue.endsWith(\"-\")\r\n ) {\r\n // dash\uAC00 \uC9C0\uC6CC\uC84C\uC73C\uBA74 \uB2E4\uC2DC \uCD94\uAC00, \uCEE4\uC11C\uB294 \uBC31\uC2A4\uD398\uC774\uC2A4 \uC804 \uC704\uCE58 (dash \uB4A4 = prefixFormatted.length)\r\n setDisplayValue(prefixFormatted);\r\n requestAnimationFrame(() => {\r\n const originalPos = prefixFormatted.length;\r\n internalInputRef.current?.setSelectionRange(\r\n originalPos,\r\n originalPos,\r\n );\r\n });\r\n return;\r\n }\r\n }\r\n\r\n // \uBC31\uC2A4\uD398\uC774\uC2A4 \uAC10\uC9C0\r\n const isBackspace =\r\n newNumbers.length <= prevNumbers.length &&\r\n newValue.length < displayValue.length;\r\n\r\n let formattedValue: string;\r\n let deletedDigitIndex = -1;\r\n let prefixProtected = false; // prefix \uC601\uC5ED \uBCF4\uD638 \uC5EC\uBD80\r\n\r\n if (autoFormat) {\r\n if (isBackspace && newNumbers.length === prevNumbers.length) {\r\n // dash\uB9CC \uC0AD\uC81C\uB41C \uACBD\uC6B0: \uC22B\uC790\uB3C4 \uD558\uB098 \uC0AD\uC81C\r\n // \uCEE4\uC11C \uC704\uCE58 \uAE30\uC900\uC73C\uB85C \uC0AD\uC81C\uD560 \uC22B\uC790 \uC704\uCE58 \uACC4\uC0B0\r\n const numbersBeforeCursor = newValue\r\n .slice(0, cursorPos)\r\n .replace(/\\D/g, \"\").length;\r\n deletedDigitIndex =\r\n numbersBeforeCursor > 0 ? numbersBeforeCursor - 1 : 0;\r\n\r\n let trimmedNumbers: string;\r\n if (prefix) {\r\n const prefixNumbers = prefix.replace(/\\D/g, \"\");\r\n if (deletedDigitIndex < prefixNumbers.length) {\r\n // prefix \uC601\uC5ED\uC774\uBA74 \uC0AD\uC81C\uD558\uC9C0 \uC54A\uC74C\r\n trimmedNumbers = newNumbers;\r\n prefixProtected = true; // prefix \uBCF4\uD638\uB428\r\n } else {\r\n // \uD574\uB2F9 \uC704\uCE58\uC758 \uC22B\uC790 \uC0AD\uC81C\r\n trimmedNumbers =\r\n newNumbers.slice(0, deletedDigitIndex) +\r\n newNumbers.slice(deletedDigitIndex + 1);\r\n if (trimmedNumbers.length < prefixNumbers.length) {\r\n trimmedNumbers = prefix;\r\n }\r\n }\r\n } else {\r\n // prefix \uC5C6\uB294 \uACBD\uC6B0\r\n trimmedNumbers =\r\n newNumbers.slice(0, deletedDigitIndex) +\r\n newNumbers.slice(deletedDigitIndex + 1);\r\n }\r\n formattedValue = formatPhoneNumber(trimmedNumbers, format);\r\n } else {\r\n formattedValue = formatPhoneNumber(newValue, format);\r\n }\r\n } else {\r\n formattedValue = newValue;\r\n }\r\n\r\n // \uCEE4\uC11C \uC704\uCE58 \uACC4\uC0B0\r\n if (prefixProtected) {\r\n // prefix \uC601\uC5ED\uC774 \uBCF4\uD638\uB41C \uACBD\uC6B0: \uCEE4\uC11C\uB97C prefix \uBC14\uB85C \uB4A4\uB85C (dash \uB4A4)\r\n // formattedValue\uAC00 displayValue\uC640 \uAC19\uC73C\uBA74 useEffect\uAC00 \uD2B8\uB9AC\uAC70\uB418\uC9C0 \uC54A\uC73C\uBBC0\uB85C \uC9C1\uC811 \uC124\uC815\r\n if (formattedValue === displayValue) {\r\n requestAnimationFrame(() => {\r\n internalInputRef.current?.setSelectionRange(\r\n prefixFormatted.length,\r\n prefixFormatted.length,\r\n );\r\n });\r\n } else {\r\n cursorPositionRef.current = prefixFormatted.length;\r\n }\r\n } else if (isBackspace) {\r\n // \uBC31\uC2A4\uD398\uC774\uC2A4\uC778 \uACBD\uC6B0: \uC0AD\uC81C\uB41C \uC22B\uC790 \uC704\uCE58 \uAE30\uC900\uC73C\uB85C \uCEE4\uC11C \uC704\uCE58 \uACC4\uC0B0\r\n if (deletedDigitIndex >= 0) {\r\n // \uC0AD\uC81C\uB41C \uC22B\uC790 \uC55E\uC758 \uC22B\uC790 \uAC1C\uC218\uB97C \uAE30\uC900\uC73C\uB85C \uD3EC\uB9F7\uB41C \uBB38\uC790\uC5F4\uC5D0\uC11C \uC704\uCE58 \uCC3E\uAE30\r\n let targetPos = 0;\r\n let digitCount = 0;\r\n for (let i = 0; i < formattedValue.length; i++) {\r\n if (digitCount === deletedDigitIndex) {\r\n targetPos = i;\r\n break;\r\n }\r\n if (/\\d/.test(formattedValue[i])) {\r\n digitCount++;\r\n }\r\n targetPos = i + 1;\r\n }\r\n cursorPositionRef.current = targetPos;\r\n } else {\r\n // \uC77C\uBC18 \uBC31\uC2A4\uD398\uC774\uC2A4: \uCEE4\uC11C \uC704\uCE58 \uAE30\uC900\uC73C\uB85C \uACC4\uC0B0\r\n const numbersBeforeCursor = newValue\r\n .slice(0, cursorPos)\r\n .replace(/\\D/g, \"\").length;\r\n let targetPos = 0;\r\n let digitCount = 0;\r\n for (\r\n let i = 0;\r\n i < formattedValue.length &&\r\n digitCount < numbersBeforeCursor;\r\n i++\r\n ) {\r\n if (/\\d/.test(formattedValue[i])) {\r\n digitCount++;\r\n }\r\n targetPos = i + 1;\r\n }\r\n // \uC785\uB825 \uB05D\uC5D0\uC11C \uBC31\uC2A4\uD398\uC774\uC2A4: \uC22B\uC790 \uAC1C\uC218\uB9CC \uB9DE\uCD94\uBA74 \uB300\uC2DC(-) \uC55E(targetPos\uAC00 \uAD6C\uBD84\uC790 \uC778\uB371\uC2A4)\uC5D0\r\n // \uCEE4\uC11C\uAC00 \uC11C\uB294 \uACBD\uC6B0\uAC00 \uC788\uC5B4, \uB05D\uC774\uBA74 \uD3EC\uB9F7 \uBB38\uC790\uC5F4 \uB05D\uC73C\uB85C \uB9DE\uCDA4 (\uC608: \"010-\" \u2192 4)\r\n if (cursorPos === newValue.length) {\r\n targetPos = formattedValue.length;\r\n }\r\n cursorPositionRef.current = targetPos;\r\n }\r\n } else {\r\n // \uC785\uB825\uC778 \uACBD\uC6B0: \uCEE4\uC11C \uC704\uCE58 \uC55E\uC758 \uC22B\uC790 \uAC1C\uC218 \uAE30\uC900\uC73C\uB85C \uACC4\uC0B0\r\n const numbersBeforeCursor = newValue\r\n .slice(0, cursorPos)\r\n .replace(/\\D/g, \"\").length;\r\n let targetPos = 0;\r\n let digitCount = 0;\r\n for (let i = 0; i < formattedValue.length; i++) {\r\n if (/\\d/.test(formattedValue[i])) {\r\n digitCount++;\r\n }\r\n if (digitCount === numbersBeforeCursor) {\r\n targetPos = i + 1;\r\n break;\r\n }\r\n }\r\n cursorPositionRef.current = targetPos;\r\n }\r\n\r\n setDisplayValue(formattedValue);\r\n const currentNumbers = formattedValue.replace(/\\D/g, \"\");\r\n setPrevNumbers(currentNumbers);\r\n\r\n // maxLength \uB3D9\uC801 \uC5C5\uB370\uC774\uD2B8\r\n setCurrentMaxLength(getPhoneMaxLength(currentNumbers));\r\n\r\n // onChange\uB85C \uC804\uB2EC\uD560 \uAC12\r\n const outputValue = includeDash\r\n ? formattedValue\r\n : formattedValue.replace(/-/g, \"\");\r\n\r\n // \uB514\uBC14\uC6B4\uC2A4 \uC801\uC6A9\r\n emitChange(e, outputValue);\r\n };\r\n\r\n // blur \uC2DC \uB300\uAE30 \uC911\uC778 \uB514\uBC14\uC6B4\uC2A4 \uC989\uC2DC \uC2E4\uD589\r\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\r\n const outputValue = includeDash\r\n ? displayValue\r\n : displayValue.replace(/-/g, \"\");\r\n flushOnBlur(e, outputValue);\r\n if (onBlur) {\r\n onBlur(e);\r\n }\r\n };\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uC2E4\uD328 \uC2DC \uD14C\uB450\uB9AC \uC2A4\uD0C0\uC77C (invalidBorderColor\uAC00 \uC124\uC815\uB41C \uACBD\uC6B0\uC5D0\uB9CC)\r\n const invalidStyles: SxProps<Theme> =\r\n isInvalid && invalidBorderColor\r\n ? {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n \"&:hover fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n \"&.Mui-focused fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n },\r\n \"& .MuiFilledInput-root\": {\r\n \"&:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:hover:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:after\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n },\r\n \"& .MuiInput-root\": {\r\n \"&:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:hover:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:after\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n },\r\n }\r\n : {};\r\n\r\n // readonly\uC77C \uB54C \uD3EC\uCEE4\uC2A4 \uC2A4\uD0C0\uC77C \uC81C\uAC70\r\n const readonlyStyles = readonly\r\n ? {\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n return (\r\n <TextField\r\n {...props}\r\n ref={ref}\r\n inputRef={internalInputRef}\r\n value={displayValue}\r\n label={label}\r\n type=\"tel\"\r\n onChange={handleChange}\r\n onBlur={handleBlur}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n sx={{\r\n ...invalidStyles,\r\n ...readonlyStyles,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...sx,\r\n }}\r\n slotProps={{\r\n ...slotProps,\r\n input: {\r\n ...slotProps?.input,\r\n readOnly: readonly,\r\n },\r\n htmlInput: {\r\n ...slotProps?.htmlInput,\r\n maxLength: currentMaxLength,\r\n },\r\n }}\r\n />\r\n );\r\n },\r\n);\r\n\r\nconst PhoneTextFieldWithForm = forwardRef<HTMLDivElement, PhoneTextFieldProps>(\r\n function PhoneTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"PhoneTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"PhoneTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <PhoneTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const PhoneTextField = forwardRef<HTMLDivElement, PhoneTextFieldProps>(\r\n function PhoneTextField(props, ref) {\r\n if (props.form) {\r\n return <PhoneTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <PhoneTextFieldBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * AddressTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport {\r\n IconButton,\r\n InputAdornment,\r\n TextField,\r\n Dialog,\r\n DialogContent,\r\n DialogTitle,\r\n} from \"@mui/material\";\r\nimport SearchIcon from \"@mui/icons-material/Search\";\r\nimport CloseIcon from \"@mui/icons-material/Close\";\r\nimport {\r\n useState,\r\n useEffect,\r\n type ChangeEvent,\r\n useCallback,\r\n forwardRef,\r\n useRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport DaumPostcode from \"react-daum-postcode\";\r\nimport type { AddressTextFieldProps, DaumPostcodeData } from \"./types\";\r\nimport { useDebouncedEmit } from \"./hooks\";\r\n\r\nconst AddressTextFieldBase = forwardRef<HTMLDivElement, AddressTextFieldProps>(\r\n function AddressTextFieldBase(\r\n {\r\n value,\r\n onChange,\r\n readonly,\r\n debounce,\r\n onBlur,\r\n size,\r\n spellCheck = false,\r\n inputRef: externalInputRef,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLInputElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n const [address, setAddress] = useState<string>(\r\n typeof value === \"string\" ? value : \"\",\r\n );\r\n const [isPostcodeOpen, setIsPostcodeOpen] = useState(false);\r\n\r\n // size\uC5D0 \uB530\uB978 \uC544\uC774\uCF58 \uD06C\uAE30\r\n const iconSize = size === \"small\" ? 20 : 24;\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange, flushOnBlur, lastEmittedValue } = useDebouncedEmit({\r\n name: props.name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n // value prop\uC774 \uBCC0\uACBD\uB420 \uB54C \uB0B4\uBD80 state \uC5C5\uB370\uC774\uD2B8 (\uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uACBD\uC6B0\uB9CC)\r\n useEffect(() => {\r\n if (value !== undefined && value !== null) {\r\n const strValue = String(value);\r\n // \uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uAC12\uC774 \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uD55C \uAC12\uACFC \uB2E4\uB97C \uB54C\uB9CC \uB3D9\uAE30\uD654\r\n if (strValue !== lastEmittedValue.current) {\r\n setAddress(strValue);\r\n lastEmittedValue.current = strValue;\r\n }\r\n } else if (lastEmittedValue.current !== \"\") {\r\n setAddress(\"\");\r\n lastEmittedValue.current = \"\";\r\n }\r\n }, [value, lastEmittedValue]);\r\n\r\n const handlePostcodeComplete = (data: DaumPostcodeData) => {\r\n let fullAddress = data.address;\r\n let extraAddress = \"\";\r\n\r\n // \uC0AC\uC6A9\uC790\uAC00 \uC120\uD0DD\uD55C \uC8FC\uC18C \uD0C0\uC785\uC5D0 \uB530\uB77C \uD574\uB2F9 \uC8FC\uC18C \uAC12\uC744 \uAC00\uC838\uC628\uB2E4.\r\n if (data.addressType === \"R\") {\r\n // \uB3C4\uB85C\uBA85 \uC8FC\uC18C\uB97C \uC120\uD0DD\uD588\uC744 \uACBD\uC6B0\r\n if (data.bname !== \"\" && /[\uB3D9|\uB85C|\uAC00]$/g.test(data.bname)) {\r\n extraAddress += data.bname;\r\n }\r\n if (data.buildingName !== \"\" && data.apartment === \"Y\") {\r\n extraAddress +=\r\n extraAddress !== \"\"\r\n ? \", \" + data.buildingName\r\n : data.buildingName;\r\n }\r\n if (extraAddress !== \"\") {\r\n extraAddress = \" (\" + extraAddress + \")\";\r\n }\r\n fullAddress += extraAddress;\r\n }\r\n\r\n // \uC8FC\uC18C \uC124\uC815\r\n setAddress(fullAddress);\r\n\r\n // \uC8FC\uC18C \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uBC1C\uC0DD (\uD31D\uC5C5 \uC120\uD0DD\uC740 \uC989\uC2DC \uD638\uCD9C)\r\n emitChange(null, fullAddress, true);\r\n\r\n // \uD31D\uC5C5 \uB2EB\uAE30\r\n setIsPostcodeOpen(false);\r\n };\r\n\r\n const handleSearchButtonClick = () => {\r\n setIsPostcodeOpen(true);\r\n };\r\n\r\n const handleKeyDown = (\r\n event: React.KeyboardEvent<HTMLInputElement>,\r\n ) => {\r\n if (event.key === \"Enter\") {\r\n event.preventDefault();\r\n handleSearchButtonClick();\r\n }\r\n };\r\n\r\n const handlePostcodeClose = () => {\r\n setIsPostcodeOpen(false);\r\n };\r\n\r\n const onClose = () => {\r\n setIsPostcodeOpen(false);\r\n emitChange(null, address as string, true);\r\n };\r\n\r\n // blur \uC2DC \uB300\uAE30 \uC911\uC778 \uB514\uBC14\uC6B4\uC2A4 \uC989\uC2DC \uC2E4\uD589\r\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\r\n flushOnBlur(e, address as string);\r\n if (onBlur) {\r\n onBlur(e);\r\n }\r\n };\r\n\r\n // readonly\uC77C \uB54C \uD3EC\uCEE4\uC2A4 \uC2A4\uD0C0\uC77C \uC81C\uAC70\r\n const readonlyStyles = readonly\r\n ? {\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n return (\r\n <>\r\n <TextField\r\n {...props}\r\n ref={ref}\r\n inputRef={internalInputRef}\r\n size={size}\r\n value={address}\r\n onChange={\r\n readonly\r\n ? undefined\r\n : (e) => {\r\n const newValue = e.target.value;\r\n setAddress(newValue);\r\n emitChange(\r\n e as ChangeEvent<HTMLInputElement>,\r\n newValue,\r\n );\r\n }\r\n }\r\n autoComplete=\"off\"\r\n spellCheck={spellCheck}\r\n onKeyDown={readonly ? undefined : handleKeyDown}\r\n onBlur={readonly ? undefined : handleBlur}\r\n sx={{\r\n ...readonlyStyles,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n }}\r\n slotProps={{\r\n ...props.slotProps,\r\n input: {\r\n ...props.slotProps?.input,\r\n readOnly: readonly,\r\n endAdornment: readonly ? undefined : (\r\n <InputAdornment\r\n position=\"end\"\r\n sx={{ mr: size === \"small\" ? -0.5 : 0.5 }}\r\n >\r\n <IconButton\r\n onClick={handleSearchButtonClick}\r\n edge=\"end\"\r\n aria-label=\"\uC8FC\uC18C \uCC3E\uAE30\"\r\n size={size}\r\n >\r\n <SearchIcon\r\n sx={{ fontSize: iconSize }}\r\n />\r\n </IconButton>\r\n </InputAdornment>\r\n ),\r\n },\r\n }}\r\n />\r\n\r\n <Dialog\r\n open={isPostcodeOpen}\r\n onClose={handlePostcodeClose}\r\n maxWidth=\"sm\"\r\n fullWidth\r\n slotProps={{\r\n paper: {\r\n sx: { height: \"550px\" },\r\n },\r\n }}\r\n >\r\n <DialogTitle\r\n sx={{\r\n display: \"flex\",\r\n justifyContent: \"space-between\",\r\n alignItems: \"center\",\r\n pr: 2,\r\n }}\r\n >\r\n \uC8FC\uC18C \uAC80\uC0C9\r\n <IconButton onClick={onClose} size=\"small\">\r\n <CloseIcon />\r\n </IconButton>\r\n </DialogTitle>\r\n <DialogContent style={{ padding: 0 }} dividers>\r\n <DaumPostcode\r\n onComplete={handlePostcodeComplete}\r\n onClose={handlePostcodeClose}\r\n defaultQuery={address as string}\r\n style={{\r\n width: \"100%\",\r\n height: \"100%\",\r\n }}\r\n />\r\n </DialogContent>\r\n </Dialog>\r\n </>\r\n );\r\n },\r\n);\r\n\r\nconst AddressTextFieldWithForm = forwardRef<\r\n HTMLDivElement,\r\n AddressTextFieldProps\r\n>(function AddressTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"AddressTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"AddressTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <AddressTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const AddressTextField = forwardRef<\r\n HTMLDivElement,\r\n AddressTextFieldProps\r\n>(function AddressTextField(props, ref) {\r\n if (props.form) {\r\n return <AddressTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <AddressTextFieldBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * NumberTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n ChangeEvent,\r\n forwardRef,\r\n useRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField, InputAdornment } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport type { NumberTextFieldProps } from \"./types\";\r\nimport { useDebouncedEmit } from \"./hooks\";\r\nimport { formatNumber, parseNumber } from \"./utils\";\r\n\r\nconst NumberTextFieldBase = forwardRef<HTMLDivElement, NumberTextFieldProps>(\r\n function NumberTextFieldBase(\r\n {\r\n label,\r\n thousandSeparator = true,\r\n decimalLength,\r\n decimalFixed = false,\r\n textAlign = \"right\",\r\n min = -2000000000,\r\n max = 2000000000,\r\n negative = false,\r\n negativeStyles,\r\n prefix,\r\n suffix,\r\n showSuffix = \"always\",\r\n selectOnFocus = true,\r\n debounce,\r\n readonly,\r\n slotProps,\r\n sx,\r\n value,\r\n onChange,\r\n onBlur,\r\n onFocus,\r\n inputRef: externalInputRef,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLInputElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n const [displayValue, setDisplayValue] = useState(\"\");\r\n const [isNegative, setIsNegative] = useState(false);\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange, flushOnBlur, lastEmittedValue } = useDebouncedEmit({\r\n name: props.name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n // value \uBCC0\uACBD \uC2DC displayValue \uC5C5\uB370\uC774\uD2B8 (\uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uACBD\uC6B0\uB9CC)\r\n useEffect(() => {\r\n if (value !== undefined && value !== null) {\r\n const strValue = String(value);\r\n\r\n // \uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uAC12\uC774 \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uD55C \uAC12\uACFC \uB2E4\uB97C \uB54C\uB9CC \uB3D9\uAE30\uD654\r\n if (strValue === lastEmittedValue.current) {\r\n return;\r\n }\r\n\r\n const formattedValue = formatNumber(\r\n strValue,\r\n thousandSeparator,\r\n decimalLength,\r\n );\r\n setDisplayValue(formattedValue);\r\n setIsNegative(\r\n strValue.startsWith(\"-\") || formattedValue.startsWith(\"-\"),\r\n );\r\n lastEmittedValue.current = strValue;\r\n } else {\r\n if (lastEmittedValue.current !== \"\") {\r\n setDisplayValue(\"\");\r\n setIsNegative(false);\r\n lastEmittedValue.current = \"\";\r\n }\r\n }\r\n }, [value, thousandSeparator, decimalLength, lastEmittedValue]);\r\n\r\n // \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleChange = useCallback(\r\n (e: ChangeEvent<HTMLInputElement>) => {\r\n let newValue = e.target.value;\r\n\r\n // \uC74C\uC218 \uD5C8\uC6A9 \uC5EC\uBD80\r\n if (!negative) {\r\n newValue = newValue.replace(/-/g, \"\");\r\n }\r\n\r\n // \uCF64\uB9C8 \uC81C\uAC70 \uD6C4 \uC22B\uC790, \uC18C\uC218\uC810, \uB9C8\uC774\uB108\uC2A4\uB9CC \uD5C8\uC6A9\r\n const withoutComma = newValue.replace(/,/g, \"\");\r\n if (!/^-?\\d*\\.?\\d*$/.test(withoutComma)) {\r\n return; // \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uBB38\uC790\uAC00 \uD3EC\uD568\uB41C \uACBD\uC6B0 \uBB34\uC2DC\r\n }\r\n\r\n // \uC810\uC73C\uB85C \uC2DC\uC791\uD558\uBA74 0. \uC73C\uB85C \uBCC0\uD658\r\n if (withoutComma === \".\") {\r\n newValue = \"0.\";\r\n } else if (withoutComma === \"-.\") {\r\n newValue = \"-0.\";\r\n } else if (withoutComma.startsWith(\".\")) {\r\n newValue = \"0\" + withoutComma;\r\n } else if (withoutComma.startsWith(\"-.\")) {\r\n newValue = \"-0\" + withoutComma.slice(1);\r\n }\r\n\r\n // max \uCD08\uACFC \uAC80\uC99D (\uC785\uB825 \uC911) - max\uB85C \uBCC0\uD658\r\n const numValue = parseFloat(withoutComma);\r\n if (!isNaN(numValue) && max !== undefined && numValue > max) {\r\n const maxFormatted = formatNumber(\r\n String(max),\r\n thousandSeparator,\r\n decimalLength,\r\n );\r\n setDisplayValue(maxFormatted);\r\n setIsNegative(false);\r\n\r\n const emitValue = String(max);\r\n emitChange(e, emitValue);\r\n return;\r\n }\r\n\r\n // min \uBBF8\uB9CC \uAC80\uC99D (\uC785\uB825 \uC911, \uC74C\uC218 \uD5C8\uC6A9 \uC2DC) - min\uC73C\uB85C \uBCC0\uD658\r\n if (!isNaN(numValue) && min !== undefined && numValue < min) {\r\n const minFormatted = formatNumber(\r\n String(min),\r\n thousandSeparator,\r\n decimalLength,\r\n );\r\n setDisplayValue(minFormatted);\r\n setIsNegative(min < 0);\r\n\r\n const emitValue = String(min);\r\n emitChange(e, emitValue);\r\n return;\r\n }\r\n\r\n const formattedValue = formatNumber(\r\n newValue,\r\n thousandSeparator,\r\n decimalLength,\r\n );\r\n setDisplayValue(formattedValue);\r\n setIsNegative(formattedValue.startsWith(\"-\"));\r\n\r\n // onChange\uB85C \uC804\uB2EC\uD560 \uAC12\uC740 \uCF64\uB9C8 \uC81C\uAC70\uB41C \uC2E4\uC81C \uC22B\uC790\r\n const numericValue = parseNumber(formattedValue);\r\n\r\n emitChange(e, numericValue);\r\n },\r\n [thousandSeparator, decimalLength, negative, max, min, emitChange],\r\n );\r\n\r\n // blur \uC2DC min/max \uAC80\uC99D \uBC0F decimalFixed \uC801\uC6A9\r\n const handleBlur = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>) => {\r\n // \uB514\uBC14\uC6B4\uC2A4 \uC989\uC2DC \uC2E4\uD589\r\n const numericValue = parseNumber(displayValue);\r\n flushOnBlur(e, numericValue);\r\n\r\n let num = parseFloat(numericValue);\r\n\r\n // \uAC12\uC774 \uC5C6\uC73C\uBA74 decimalFixed \uC801\uC6A9 \uC548\uD568\r\n if (displayValue === \"\" || displayValue === \"-\") {\r\n if (onBlur) {\r\n onBlur(e);\r\n }\r\n return;\r\n }\r\n\r\n if (!isNaN(num)) {\r\n // min/max \uAC80\uC99D\r\n if (min !== undefined && num < min) {\r\n num = min;\r\n }\r\n if (max !== undefined && num > max) {\r\n num = max;\r\n }\r\n\r\n // \uC18C\uC218\uC810 \uAE38\uC774 \uB9DE\uCD94\uAE30 (decimalFixed \uB610\uB294 decimalLength)\r\n let finalValue: string;\r\n if (decimalFixed && decimalLength !== undefined) {\r\n finalValue = num.toFixed(decimalLength);\r\n } else if (decimalLength !== undefined) {\r\n // decimalLength\uB9CC \uC788\uC744 \uB54C\uB294 \uCD08\uACFC\uBD84\uB9CC \uC790\uB974\uACE0 \uACE0\uC815\uD558\uC9C0 \uC54A\uC74C\r\n finalValue = String(num);\r\n } else {\r\n finalValue = String(num);\r\n }\r\n\r\n const formattedValue = formatNumber(\r\n finalValue,\r\n thousandSeparator,\r\n decimalLength,\r\n );\r\n setDisplayValue(formattedValue);\r\n\r\n // onChange \uD638\uCD9C (\uAC12\uC774 \uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC)\r\n if (finalValue !== lastEmittedValue.current) {\r\n emitChange(e, finalValue, true);\r\n }\r\n }\r\n\r\n if (onBlur) {\r\n onBlur(e);\r\n }\r\n },\r\n [\r\n displayValue,\r\n min,\r\n max,\r\n decimalLength,\r\n decimalFixed,\r\n thousandSeparator,\r\n flushOnBlur,\r\n emitChange,\r\n lastEmittedValue,\r\n onBlur,\r\n ],\r\n );\r\n\r\n // \uD14D\uC2A4\uD2B8 \uC815\uB82C \uBC0F \uC74C\uC218 \uC2A4\uD0C0\uC77C\r\n const inputStyles: SxProps<Theme> = {\r\n \"& .MuiInputBase-input\": {\r\n textAlign: textAlign,\r\n ...(isNegative && negativeStyles ? negativeStyles : {}),\r\n },\r\n };\r\n\r\n // \uD3EC\uCEE4\uC2A4 \uD578\uB4E4\uB7EC (selectOnFocus)\r\n const handleFocus = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>) => {\r\n if (selectOnFocus) {\r\n e.target.select();\r\n }\r\n if (onFocus) {\r\n onFocus(e);\r\n }\r\n },\r\n [selectOnFocus, onFocus],\r\n );\r\n\r\n // readonly\uC77C \uB54C \uD3EC\uCEE4\uC2A4 \uC2A4\uD0C0\uC77C \uC81C\uAC70\r\n const readonlyStyles = readonly\r\n ? {\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n return (\r\n <TextField\r\n {...props}\r\n ref={ref}\r\n inputRef={internalInputRef}\r\n value={displayValue}\r\n label={label}\r\n onChange={handleChange}\r\n onBlur={handleBlur}\r\n onFocus={handleFocus}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n sx={{\r\n ...inputStyles,\r\n ...readonlyStyles,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...(props.fullWidth && { minWidth: 0 }),\r\n ...sx,\r\n }}\r\n slotProps={{\r\n ...slotProps,\r\n input: {\r\n ...slotProps?.input,\r\n readOnly: readonly,\r\n startAdornment: prefix ? (\r\n <InputAdornment position=\"start\">\r\n {prefix}\r\n </InputAdornment>\r\n ) : undefined,\r\n endAdornment:\r\n suffix &&\r\n (showSuffix === \"always\" || displayValue) ? (\r\n <InputAdornment position=\"end\">\r\n {suffix}\r\n </InputAdornment>\r\n ) : undefined,\r\n },\r\n htmlInput: {\r\n ...slotProps?.htmlInput,\r\n inputMode: \"decimal\",\r\n },\r\n }}\r\n />\r\n );\r\n },\r\n);\r\n\r\nconst NumberTextFieldWithForm = forwardRef<\r\n HTMLDivElement,\r\n NumberTextFieldProps\r\n>(function NumberTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"NumberTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"NumberTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <NumberTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const NumberTextField = forwardRef<HTMLDivElement, NumberTextFieldProps>(\r\n function NumberTextField(props, ref) {\r\n if (props.form) {\r\n return <NumberTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <NumberTextFieldBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * JuminTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n useRef,\r\n useMemo,\r\n ChangeEvent,\r\n KeyboardEvent,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField, Box } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport { GroupedInputWrapper } from \"./components\";\r\nimport type { JuminInfo, JuminTextFieldProps } from \"./types\";\r\nimport { DashIcon } from \"./icons\";\r\nimport {\r\n extractJuminInfo,\r\n validateJuminChecksum,\r\n validateJuminBirthDate,\r\n} from \"./utils\";\r\n\r\nconst JuminTextFieldBase = forwardRef<HTMLDivElement, JuminTextFieldProps>(\r\n function JuminTextFieldBase(\r\n {\r\n label,\r\n mask = true,\r\n maskColor = \"rgba(0, 0, 0, 0.7)\",\r\n validateChecksum = true,\r\n fontSize,\r\n fontColor,\r\n fontFamily,\r\n onChange,\r\n onValidationChange,\r\n invalidBorderColor,\r\n debounce,\r\n readonly,\r\n sx,\r\n value,\r\n size,\r\n disabled,\r\n fullWidth = false,\r\n className,\r\n id,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const [frontValue, setFrontValue] = useState(\"\"); // \uC55E 6\uC790\uB9AC\r\n const [backValue, setBackValue] = useState(\"\"); // \uB4A4 7\uC790\uB9AC (\uC2E4\uC81C \uAC12)\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n const [isInternalChange, setIsInternalChange] = useState(false); // \uB0B4\uBD80 \uBCC0\uACBD \uD50C\uB798\uADF8\r\n const [focusedField, setFocusedField] = useState<\r\n \"front\" | \"back\" | null\r\n >(null);\r\n const [cursorVisible, setCursorVisible] = useState(false); // \uCEE4\uC11C \uD45C\uC2DC \uC5EC\uBD80\r\n const [renderTrigger, setRenderTrigger] = useState(0); // \uB80C\uB354\uB9C1 \uD2B8\uB9AC\uAC70\r\n const [backComplete, setBackComplete] = useState(false); // \uB4B7\uC790\uB9AC \uC785\uB825 \uC644\uB8CC (\uCEE4\uC11C \uC228\uAE40\uC6A9)\r\n\r\n const frontRef = useRef<HTMLInputElement>(null);\r\n const backRef = useRef<HTMLInputElement>(null);\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const isClickFocusRef = useRef(false); // \uD074\uB9AD\uC73C\uB85C \uC778\uD55C \uD3EC\uCEE4\uC2A4\uC778\uC9C0 \uAD6C\uBD84\r\n const cursorPosRef = useRef(0); // \uCEE4\uC11C \uC704\uCE58 (ref\uB85C \uC989\uC2DC \uBC18\uC601)\r\n\r\n // \uC678\uBD80 ref\uC640 \uB0B4\uBD80 containerRef \uBCD1\uD569\r\n useImperativeHandle(ref, () => containerRef.current!, []);\r\n\r\n // \uB514\uBC14\uC6B4\uC2A4 \uD0C0\uC774\uBA38\r\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(\r\n null,\r\n );\r\n\r\n // \uD0C0\uC774\uBA38 \uC815\uB9AC\r\n useEffect(() => {\r\n return () => {\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n }\r\n };\r\n }, []);\r\n\r\n // value prop \uBCC0\uACBD \uC2DC \uB0B4\uBD80 \uC0C1\uD0DC \uB3D9\uAE30\uD654 (\uC678\uBD80 \uBCC0\uACBD\uC77C \uB54C\uB9CC)\r\n useEffect(() => {\r\n // \uB0B4\uBD80 \uBCC0\uACBD\uC774\uBA74 \uB3D9\uAE30\uD654 \uC2A4\uD0B5\r\n if (isInternalChange) {\r\n setIsInternalChange(false);\r\n return;\r\n }\r\n\r\n if (value !== undefined && value !== null) {\r\n const numbers = String(value).replace(/\\D/g, \"\");\r\n setFrontValue(numbers.slice(0, 6));\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uB4B7\uC790\uB9AC 1\uAE00\uC790\uB9CC \uC800\uC7A5\r\n if (mask) {\r\n setBackValue(numbers.slice(6, 7));\r\n } else {\r\n setBackValue(numbers.slice(6, 13));\r\n }\r\n } else {\r\n setFrontValue(\"\");\r\n setBackValue(\"\");\r\n }\r\n }, [value, mask]);\r\n\r\n // \uB9C8\uC2A4\uD0B9\uB41C \uB4B7\uC790\uB9AC \uD45C\uC2DC\uAC12\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: 1\uAE00\uC790\uB9CC \uD45C\uC2DC\r\n // \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uC804\uCCB4 \uD45C\uC2DC\r\n const displayBackValue = mask ? backValue.slice(0, 1) : backValue;\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uBC0F onChange \uD638\uCD9C\r\n const emitChange = useCallback(\r\n (front: string, back: string) => {\r\n const fullValue = front + back;\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: 7\uC790\uB9AC(6+1) \uC644\uC131, \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: 13\uC790\uB9AC \uC644\uC131\r\n const completeLength = mask ? 7 : 13;\r\n const isLengthComplete = fullValue.length === completeLength;\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC:\r\n // - \uC0DD\uB144\uC6D4\uC77C \uC720\uD6A8\uC131\uC740 \uD56D\uC0C1 \uAC80\uC0AC\r\n // - \uCCB4\uD06C\uC12C \uAC80\uC99D\uC740 \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC + validateChecksum=true\uC77C \uB54C\uB9CC\r\n let isValid = false;\r\n if (mask) {\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: 7\uC790\uB9AC \uC644\uC131 + \uC0DD\uB144\uC6D4\uC77C \uC720\uD6A8\uC131\r\n isValid =\r\n isLengthComplete && validateJuminBirthDate(fullValue);\r\n } else {\r\n // \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: 13\uC790\uB9AC \uC644\uC131 + \uC0DD\uB144\uC6D4\uC77C \uC720\uD6A8\uC131 + (\uC635\uC158) \uCCB4\uD06C\uC12C \uAC80\uC99D\r\n isValid =\r\n isLengthComplete &&\r\n validateJuminBirthDate(fullValue) &&\r\n (validateChecksum\r\n ? validateJuminChecksum(fullValue)\r\n : true);\r\n }\r\n\r\n setIsInvalid(fullValue.length > 0 && !isValid);\r\n\r\n if (onValidationChange) {\r\n onValidationChange(isValid);\r\n }\r\n\r\n const doEmit = () => {\r\n if (onChange) {\r\n setIsInternalChange(true); // \uB0B4\uBD80 \uBCC0\uACBD \uD50C\uB798\uADF8 \uC124\uC815\r\n const info = extractJuminInfo(fullValue);\r\n onChange({ ...info, isValid });\r\n }\r\n };\r\n\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n }\r\n\r\n if (debounce === undefined || debounce === 0) {\r\n doEmit();\r\n } else {\r\n debounceTimer.current = setTimeout(doEmit, debounce);\r\n }\r\n },\r\n [onChange, onValidationChange, mask, validateChecksum, debounce],\r\n );\r\n\r\n // \uC55E\uC790\uB9AC \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleFrontChange = useCallback(\r\n (e: ChangeEvent<HTMLInputElement>) => {\r\n const numbers = e.target.value.replace(/\\D/g, \"\").slice(0, 6);\r\n setFrontValue(numbers);\r\n cursorPosRef.current = numbers.length;\r\n setCursorVisible(true); // \uC785\uB825 \uC2DC \uCEE4\uC11C \uD45C\uC2DC\r\n setRenderTrigger((r) => r + 1);\r\n\r\n // 6\uC790\uB9AC \uC785\uB825 \uC644\uB8CC \uC2DC \uB4B7\uC790\uB9AC\uB85C \uD3EC\uCEE4\uC2A4 \uC774\uB3D9\r\n if (numbers.length === 6) {\r\n setTimeout(() => {\r\n const input = backRef.current;\r\n if (input) {\r\n input.focus();\r\n const len = mask ? 0 : input.value.length;\r\n input.setSelectionRange(len, len);\r\n cursorPosRef.current = len;\r\n setFocusedField(\"back\");\r\n setCursorVisible(true);\r\n }\r\n }, 0);\r\n }\r\n\r\n emitChange(numbers, backValue);\r\n },\r\n [backValue, emitChange, mask],\r\n );\r\n\r\n // \uC55E\uC790\uB9AC \uD3EC\uCEE4\uC2A4 \uD578\uB4E4\uB7EC\r\n const handleFrontFocus = useCallback(() => {\r\n // \uD074\uB9AD\uC73C\uB85C \uC778\uD55C \uD3EC\uCEE4\uC2A4\uBA74 \uD074\uB9AD \uD578\uB4E4\uB7EC\uC5D0\uC11C \uC804\uCCB4 \uC120\uD0DD \uCC98\uB9AC\r\n if (isClickFocusRef.current) {\r\n isClickFocusRef.current = false;\r\n setFocusedField(\"front\");\r\n // \uAC12\uC774 \uC788\uC73C\uBA74 \uC804\uCCB4 \uC120\uD0DD\r\n if (frontRef.current && frontValue.length > 0) {\r\n setTimeout(() => {\r\n frontRef.current?.setSelectionRange(\r\n 0,\r\n frontValue.length,\r\n );\r\n }, 0);\r\n setCursorVisible(false);\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n return;\r\n }\r\n // \uD0ED \uB4F1 \uC77C\uBC18 \uD3EC\uCEE4\uC2A4\uB3C4 \uC804\uCCB4 \uC120\uD0DD\r\n setFocusedField(\"front\");\r\n if (frontRef.current && frontValue.length > 0) {\r\n setTimeout(() => {\r\n frontRef.current?.setSelectionRange(0, frontValue.length);\r\n }, 0);\r\n setCursorVisible(false);\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n }, [frontValue.length]);\r\n\r\n // \uC55E\uC790\uB9AC \uBE14\uB7EC \uD578\uB4E4\uB7EC\r\n const handleFrontBlur = useCallback(() => {\r\n setCursorVisible(false);\r\n setTimeout(() => {\r\n const activeElement = document.activeElement;\r\n if (\r\n activeElement !== frontRef.current &&\r\n activeElement !== backRef.current\r\n ) {\r\n setFocusedField(null);\r\n }\r\n }, 0);\r\n }, []);\r\n\r\n // \uC55E\uC790\uB9AC \uD0A4\uBCF4\uB4DC \uD578\uB4E4\uB7EC\r\n const handleFrontKeyDown = useCallback(\r\n (e: KeyboardEvent<HTMLInputElement>) => {\r\n const input = frontRef.current;\r\n const pos = input?.selectionStart ?? 0;\r\n\r\n if (e.key === \"ArrowLeft\") {\r\n if (pos > 0) {\r\n e.preventDefault();\r\n const newPos = pos - 1;\r\n input?.setSelectionRange(newPos, newPos);\r\n cursorPosRef.current = newPos;\r\n setRenderTrigger((r) => r + 1);\r\n }\r\n } else if (e.key === \"ArrowRight\") {\r\n // 6\uC790\uB9AC \uC644\uC131 \uD6C4 \uB9C8\uC9C0\uB9C9 \uAE00\uC790\uC5D0\uC11C \uC624\uB978\uCABD \uB204\uB974\uBA74 \uBC14\uB85C \uB4B7\uC790\uB9AC\uB85C \uC774\uB3D9\r\n if (\r\n frontValue.length === 6 &&\r\n pos >= frontValue.length - 1\r\n ) {\r\n e.preventDefault();\r\n cursorPosRef.current = 0;\r\n setFocusedField(\"back\");\r\n backRef.current?.focus();\r\n backRef.current?.setSelectionRange(0, 0);\r\n } else if (pos < frontValue.length) {\r\n e.preventDefault();\r\n const newPos = pos + 1;\r\n input?.setSelectionRange(newPos, newPos);\r\n cursorPosRef.current = newPos;\r\n setRenderTrigger((r) => r + 1);\r\n }\r\n } else if (e.key === \"Backspace\") {\r\n if (pos > 0) {\r\n e.preventDefault();\r\n // \uD604\uC7AC \uC704\uCE58 \uC55E\uC758 \uBB38\uC790\uB97C \uC0AD\uC81C\r\n const newValue =\r\n frontValue.slice(0, pos - 1) +\r\n frontValue.slice(pos);\r\n setFrontValue(newValue);\r\n const newPos = pos - 1;\r\n cursorPosRef.current = newPos;\r\n setRenderTrigger((r) => r + 1);\r\n setTimeout(() => {\r\n input?.setSelectionRange(newPos, newPos);\r\n }, 0);\r\n emitChange(newValue, backValue);\r\n }\r\n }\r\n },\r\n [frontValue, backValue, emitChange],\r\n );\r\n\r\n // \uB4B7\uC790\uB9AC \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleBackChange = useCallback(\r\n (e: ChangeEvent<HTMLInputElement>) => {\r\n if (mask) {\r\n const inputVal = e.target.value.replace(/[\u25CF]/g, \"\");\r\n const numbers = inputVal.replace(/\\D/g, \"\").slice(0, 1);\r\n setBackValue(numbers);\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: 1\uAE00\uC790 \uC785\uB825 \uC644\uB8CC \uC2DC \uCEE4\uC11C\uB97C \uC67C\uCABD(0)\uC5D0 \uC704\uCE58\uD558\uACE0 \uCEE4\uC11C \uC228\uAE40\r\n cursorPosRef.current = 0;\r\n if (numbers.length === 1) {\r\n setBackComplete(true); // \uC785\uB825 \uC644\uB8CC \uC2DC \uCEE4\uC11C \uC228\uAE40\r\n } else {\r\n setCursorVisible(true); // \uC785\uB825 \uC911 \uCEE4\uC11C \uD45C\uC2DC\r\n }\r\n setTimeout(() => {\r\n backRef.current?.setSelectionRange(0, 0);\r\n }, 0);\r\n emitChange(frontValue, numbers);\r\n } else {\r\n const numbers = e.target.value\r\n .replace(/\\D/g, \"\")\r\n .slice(0, 7);\r\n setBackValue(numbers);\r\n cursorPosRef.current = numbers.length;\r\n setCursorVisible(true); // \uC785\uB825 \uC2DC \uCEE4\uC11C \uD45C\uC2DC\r\n if (numbers.length === 7) {\r\n setBackComplete(true); // 7\uC790\uB9AC \uC644\uB8CC \uC2DC \uCEE4\uC11C \uC228\uAE40\r\n } else {\r\n setBackComplete(false);\r\n }\r\n setRenderTrigger((r) => r + 1);\r\n emitChange(frontValue, numbers);\r\n }\r\n },\r\n [frontValue, emitChange, mask],\r\n );\r\n\r\n // \uB4B7\uC790\uB9AC \uD0A4\uBCF4\uB4DC \uD578\uB4E4\uB7EC\r\n const handleBackKeyDown = useCallback(\r\n (e: KeyboardEvent<HTMLInputElement>) => {\r\n const input = backRef.current;\r\n const pos = input?.selectionStart ?? 0;\r\n const valLen = mask\r\n ? displayBackValue.length\r\n : backValue.length;\r\n\r\n if (e.key === \"ArrowLeft\") {\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uBC14\uB85C \uC55E\uC790\uB9AC\uB85C \uC774\uB3D9\r\n if (mask || pos === 0) {\r\n e.preventDefault();\r\n frontRef.current?.focus();\r\n // \uC55E\uC790\uB9AC \uB9C8\uC9C0\uB9C9 \uAE00\uC790 '\uC544\uB798'\uB85C \uCEE4\uC11C \uC704\uCE58 (len - 1)\r\n const len = frontValue.length;\r\n const newPos = len > 0 ? len - 1 : 0;\r\n frontRef.current?.setSelectionRange(newPos, newPos);\r\n cursorPosRef.current = newPos;\r\n setRenderTrigger((r) => r + 1);\r\n } else if (pos > 0) {\r\n e.preventDefault();\r\n const newPos = pos - 1;\r\n input?.setSelectionRange(newPos, newPos);\r\n cursorPosRef.current = newPos;\r\n setRenderTrigger((r) => r + 1);\r\n }\r\n } else if (e.key === \"ArrowRight\") {\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC\uC5D0\uC11C\uB294 1\uAE00\uC790 \uC774\uC0C1 \uC624\uB978\uCABD\uC73C\uB85C \uAC00\uBA74 \uC548 \uB428\r\n if (pos < valLen) {\r\n e.preventDefault();\r\n const newPos = pos + 1;\r\n input?.setSelectionRange(newPos, newPos);\r\n cursorPosRef.current = newPos;\r\n setRenderTrigger((r) => r + 1);\r\n }\r\n // pos >= valLen\uC774\uBA74 \uC544\uBB34\uAC83\uB3C4 \uC548 \uD568 (\uB354 \uC774\uC0C1 \uC624\uB978\uCABD\uC73C\uB85C \uAC08 \uC218 \uC5C6\uC74C)\r\n } else if (e.key === \"Backspace\") {\r\n if (mask) {\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uB4B7\uC790\uB9AC \uAC12\uC774 \uC788\uC73C\uBA74 \uC0AD\uC81C, \uC5C6\uC73C\uBA74 \uC55E\uC790\uB9AC\uB85C \uC774\uB3D9\r\n e.preventDefault();\r\n if (backValue.length > 0) {\r\n setBackValue(\"\");\r\n setBackComplete(false);\r\n cursorPosRef.current = 0;\r\n setRenderTrigger((r) => r + 1);\r\n emitChange(frontValue, \"\");\r\n } else if (frontValue.length > 0) {\r\n const newFrontValue = frontValue.slice(0, -1);\r\n setFrontValue(newFrontValue);\r\n cursorPosRef.current = newFrontValue.length;\r\n setRenderTrigger((r) => r + 1);\r\n emitChange(newFrontValue, \"\");\r\n frontRef.current?.focus();\r\n setTimeout(() => {\r\n const len = frontRef.current?.value.length || 0;\r\n frontRef.current?.setSelectionRange(len, len);\r\n }, 0);\r\n }\r\n } else if (pos === 0 && backValue === \"\") {\r\n e.preventDefault();\r\n if (frontValue.length > 0) {\r\n const newFrontValue = frontValue.slice(0, -1);\r\n setFrontValue(newFrontValue);\r\n cursorPosRef.current = newFrontValue.length;\r\n emitChange(newFrontValue, backValue);\r\n }\r\n frontRef.current?.focus();\r\n setTimeout(() => {\r\n const len = frontRef.current?.value.length || 0;\r\n frontRef.current?.setSelectionRange(len, len);\r\n cursorPosRef.current = len;\r\n setRenderTrigger((r) => r + 1);\r\n }, 0);\r\n } else if (!mask && pos > 0) {\r\n // \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uC911\uAC04\uC5D0\uC11C Backspace \uCC98\uB9AC\r\n e.preventDefault();\r\n const newBackValue =\r\n backValue.slice(0, pos - 1) + backValue.slice(pos);\r\n setBackValue(newBackValue);\r\n const newPos = pos - 1;\r\n cursorPosRef.current = newPos;\r\n setRenderTrigger((r) => r + 1);\r\n emitChange(frontValue, newBackValue);\r\n setTimeout(() => {\r\n input?.setSelectionRange(newPos, newPos);\r\n }, 0);\r\n } else if (!mask && pos === 0 && backValue.length > 0) {\r\n // \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uB9E8 \uC55E\uC5D0\uC11C Backspace - \uC55E\uC790\uB9AC\uB85C \uC774\uB3D9\r\n e.preventDefault();\r\n frontRef.current?.focus();\r\n const len = frontValue.length;\r\n const newPos = len > 0 ? len - 1 : 0;\r\n frontRef.current?.setSelectionRange(newPos, newPos);\r\n cursorPosRef.current = newPos;\r\n setRenderTrigger((r) => r + 1);\r\n }\r\n }\r\n },\r\n [backValue, frontValue, displayBackValue, mask, emitChange],\r\n );\r\n\r\n // \uB4B7\uC790\uB9AC \uD3EC\uCEE4\uC2A4 \uD578\uB4E4\uB7EC\r\n const handleBackFocus = useCallback(() => {\r\n // \uD074\uB9AD \uB610\uB294 \uD0ED\uC73C\uB85C \uD3EC\uCEE4\uC2A4 - \uC804\uCCB4 \uC120\uD0DD\r\n isClickFocusRef.current = false;\r\n setFocusedField(\"back\");\r\n setCursorVisible(false); // \uC804\uCCB4 \uC120\uD0DD \uC2DC \uCEE4\uC11C \uC228\uAE40\r\n\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uAC12\uC774 \uC788\uC73C\uBA74 \uC804\uCCB4 \uC120\uD0DD\r\n if (mask) {\r\n if (backValue.length > 0) {\r\n // \uC0C1\uD0DC \uBCC0\uACBD \uD6C4 \uB9AC\uB80C\uB354\uB9C1\uC774 \uC644\uB8CC\uB41C \uB2E4\uC74C\uC5D0 \uC120\uD0DD \uC801\uC6A9\r\n requestAnimationFrame(() => {\r\n backRef.current?.setSelectionRange(0, 1);\r\n });\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n } else {\r\n // \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uAC12\uC774 \uC788\uC73C\uBA74 \uC804\uCCB4 \uC120\uD0DD\r\n if (backValue.length > 0) {\r\n requestAnimationFrame(() => {\r\n backRef.current?.setSelectionRange(0, backValue.length);\r\n });\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n }\r\n }, [backValue.length, mask]);\r\n\r\n // \uB4B7\uC790\uB9AC \uBE14\uB7EC \uD578\uB4E4\uB7EC\r\n const handleBackBlur = useCallback(() => {\r\n setCursorVisible(false);\r\n setTimeout(() => {\r\n const activeElement = document.activeElement;\r\n if (\r\n activeElement !== frontRef.current &&\r\n activeElement !== backRef.current\r\n ) {\r\n setFocusedField(null);\r\n }\r\n }, 0);\r\n }, []);\r\n\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC\uC5D0\uC11C placeholder \uB3D9\uADF8\uB77C\uBBF8 \uAC1C\uC218 (\uCCAB\uBC88\uC9F8 \uC785\uB825\uCE78 + 6\uAC1C = 7\uAC1C \uACE0\uC815)\r\n const placeholderDots = mask ? 7 : 0;\r\n\r\n // \uD3F0\uD2B8 \uD06C\uAE30 \uACC4\uC0B0 (\uAE30\uBCF8\uAC12: small=16px, medium=18px)\r\n const defaultFontSize = size === \"small\" ? 16 : 18;\r\n const computedFontSize = fontSize\r\n ? typeof fontSize === \"number\"\r\n ? fontSize\r\n : parseFloat(fontSize) *\r\n (fontSize.toString().includes(\"rem\") ? 16 : 1)\r\n : defaultFontSize;\r\n\r\n // \uD14D\uC2A4\uD2B8 \uB108\uBE44 \uCE21\uC815 \uD568\uC218\r\n const measureTextWidth = useCallback(\r\n (text: string): number => {\r\n if (typeof document === \"undefined\")\r\n return text.length * computedFontSize * 0.6;\r\n const canvas = document.createElement(\"canvas\");\r\n const ctx = canvas.getContext(\"2d\");\r\n if (!ctx) return text.length * computedFontSize * 0.6;\r\n ctx.font = `${computedFontSize}px ${\r\n fontFamily || \"Roboto, sans-serif\"\r\n }`;\r\n return ctx.measureText(text).width;\r\n },\r\n [computedFontSize, fontFamily],\r\n );\r\n\r\n // \uB3D9\uADF8\uB77C\uBBF8 \uD06C\uAE30: \uD3F0\uD2B8 \uD06C\uAE30\uC5D0 \uBE44\uB840\r\n const dotSize = Math.round(computedFontSize * 0.5); // \uCCAB \uBC88\uC9F8 \uB3D9\uADF8\uB77C\uBBF8 (\uC785\uB825 \uC704\uCE58)\r\n const smallDotSize = Math.round(computedFontSize * 0.35); // \uB4A4 6\uAC1C \uB3D9\uADF8\uB77C\uBBF8\r\n\r\n // \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C \uD06C\uAE30\r\n const cursorHeight = \"1px\";\r\n\r\n // \uCEE4\uC11C \uC704\uCE58 \uACC4\uC0B0 \uACF5\uC6A9 \uD568\uC218\r\n const getCursorLeft = useCallback(\r\n (field: \"front\" | \"back\") => {\r\n if (field === \"front\") {\r\n const textBeforeCursor = frontValue.slice(\r\n 0,\r\n cursorPosRef.current,\r\n );\r\n return measureTextWidth(textBeforeCursor);\r\n } else {\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC\uC5D0\uC11C \uAC12\uC774 \uC5C6\uC744 \uB54C\uB294 \uCCAB \uBC88\uC9F8 \uB3D9\uADF8\uB77C\uBBF8 \uC544\uB798\uC5D0 \uCEE4\uC11C \uC704\uCE58\r\n if (mask && displayBackValue.length === 0) {\r\n return dotSize / 2 - (computedFontSize * 0.55) / 2;\r\n }\r\n const textBeforeCursor = displayBackValue.slice(\r\n 0,\r\n cursorPosRef.current,\r\n );\r\n return measureTextWidth(textBeforeCursor);\r\n }\r\n },\r\n [\r\n frontValue,\r\n displayBackValue,\r\n mask,\r\n dotSize,\r\n computedFontSize,\r\n measureTextWidth,\r\n ],\r\n );\r\n\r\n // \uCEE4\uC11C \uC704\uCE58 (\uB80C\uB354\uB9C1 \uC2DC\uC810\uC5D0 \uACC4\uC0B0)\r\n const cursorLeft = useMemo(() => {\r\n if (!focusedField) return 0;\r\n return getCursorLeft(focusedField);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [focusedField, cursorVisible, renderTrigger, getCursorLeft]);\r\n\r\n // \uD544\uB4DC \uB108\uBE44: ch \uB2E8\uC704 \uC0AC\uC6A9 (\uD3F0\uD2B8 \uD06C\uAE30\uC5D0 \uC790\uB3D9 \uBE44\uB840)\r\n const frontFieldCh = \"6.2ch\"; // 6\uC790\uB9AC + \uCD5C\uC18C \uC5EC\uC720\r\n const backFieldCh = mask ? \"8.5ch\" : \"7.5ch\"; // \uB9C8\uC2A4\uD0B9: \uC801\uC808\uD55C \uAC04\uACA9, \uBE44\uB9C8\uC2A4\uD0B9: 7\uC790\uB9AC\r\n\r\n // \uAC1C\uBCC4 TextField\uC5D0\uC11C border \uC81C\uAC70\uD558\uB294 \uC2A4\uD0C0\uC77C\r\n const noBorderStyle: SxProps<Theme> = {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": {\r\n border: \"none\",\r\n },\r\n \"&:hover fieldset\": {\r\n border: \"none\",\r\n },\r\n \"&.Mui-focused fieldset\": {\r\n border: \"none\",\r\n },\r\n },\r\n };\r\n\r\n // \uC804\uCCB4 \uC8FC\uBBFC\uBC88\uD638 \uAC12 \uAC00\uC838\uC624\uAE30\r\n const getFullNumber = () => frontValue + backValue;\r\n\r\n // \uADF8\uB8F9 \uC785\uB825 \uB0B4\uBD80 \uCEF4\uD3EC\uB10C\uD2B8 \uB80C\uB354\uB9C1\r\n const renderGroupedInput = () => (\r\n <>\r\n <Box\r\n onClick={() => {\r\n if (disabled || readonly) return;\r\n isClickFocusRef.current = true;\r\n setBackComplete(false);\r\n\r\n // \uCCAB \uBC88\uC9F8 \uBE48 \uCE78 \uCC3E\uAE30, \uC5C6\uC73C\uBA74 \uB9C8\uC9C0\uB9C9 \uCE78 \uC120\uD0DD\r\n const hasFrontValue = frontValue.length > 0;\r\n const hasBackValue = backValue.length > 0;\r\n\r\n if (!hasFrontValue) {\r\n // \uC55E\uCE78\uC774 \uBE44\uC5B4\uC788\uC73C\uBA74 \uC55E\uCE78 \uD3EC\uCEE4\uC2A4\r\n setFocusedField(\"front\");\r\n frontRef.current?.focus();\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n } else if (!hasBackValue) {\r\n // \uC55E\uCE78\uC740 \uC788\uACE0 \uB4B7\uCE78\uC774 \uBE44\uC5B4\uC788\uC73C\uBA74 \uB4B7\uCE78 \uD3EC\uCEE4\uC2A4\r\n setFocusedField(\"back\");\r\n backRef.current?.focus();\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n } else {\r\n // \uB458 \uB2E4 \uAC12\uC774 \uC788\uC73C\uBA74 \uB4B7\uCE78 \uC804\uCCB4 \uC120\uD0DD\r\n setFocusedField(\"back\");\r\n backRef.current?.focus();\r\n if (mask) {\r\n setCursorVisible(false);\r\n setTimeout(() => {\r\n backRef.current?.setSelectionRange(0, 1);\r\n }, 0);\r\n } else {\r\n setCursorVisible(false);\r\n setTimeout(() => {\r\n backRef.current?.setSelectionRange(\r\n 0,\r\n backValue.length,\r\n );\r\n }, 0);\r\n }\r\n }\r\n }}\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: 0.2,\r\n width: \"100%\",\r\n height: \"100%\",\r\n cursor: disabled ? \"default\" : \"text\",\r\n }}\r\n >\r\n <Box\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n if (disabled || readonly) return;\r\n // \uD074\uB9AD \uC2DC \uC804\uCCB4 \uC120\uD0DD\r\n isClickFocusRef.current = true;\r\n setFocusedField(\"front\");\r\n frontRef.current?.focus();\r\n if (frontValue.length > 0) {\r\n setCursorVisible(false);\r\n setTimeout(() => {\r\n frontRef.current?.setSelectionRange(\r\n 0,\r\n frontValue.length,\r\n );\r\n }, 0);\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n }}\r\n sx={{\r\n position: \"relative\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n }}\r\n >\r\n <TextField\r\n {...props}\r\n inputRef={frontRef}\r\n value={frontValue}\r\n onChange={handleFrontChange}\r\n onKeyDown={handleFrontKeyDown}\r\n onFocus={handleFrontFocus}\r\n onBlur={handleFrontBlur}\r\n disabled={disabled}\r\n size={size}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n placeholder=\"000000\"\r\n variant=\"outlined\"\r\n sx={{\r\n width: \"auto\",\r\n minWidth: 0,\r\n ...noBorderStyle,\r\n \"& .MuiInputBase-root\": {\r\n width: \"auto\",\r\n },\r\n \"& .MuiInputBase-input\": {\r\n width: frontFieldCh,\r\n caretColor: \"transparent\",\r\n ...(fontSize && { fontSize }),\r\n ...(fontColor && { color: fontColor }),\r\n ...(fontFamily && { fontFamily }),\r\n },\r\n \"& .MuiInputBase-input::placeholder\": {\r\n color: \"rgba(0, 0, 0, 0.2)\",\r\n opacity: 1,\r\n },\r\n }}\r\n slotProps={{\r\n input: {\r\n readOnly: readonly,\r\n },\r\n htmlInput: {\r\n maxLength: 6,\r\n inputMode: \"numeric\",\r\n style: {\r\n textAlign: \"left\",\r\n padding: \"0 4px\",\r\n },\r\n },\r\n }}\r\n />\r\n {/* \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C - \uC55E\uC790\uB9AC */}\r\n {cursorVisible && focusedField === \"front\" && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n bottom: size === \"small\" ? 1 : 3,\r\n left: `calc(4px + ${cursorLeft}px)`,\r\n width: `${computedFontSize * 0.55}px`,\r\n height: cursorHeight,\r\n backgroundColor:\r\n fontColor || \"text.primary\",\r\n animation: \"blink 1s step-end infinite\",\r\n \"@keyframes blink\": {\r\n \"0%, 100%\": { opacity: 1 },\r\n \"50%\": { opacity: 0 },\r\n },\r\n pointerEvents: \"none\",\r\n }}\r\n />\r\n )}\r\n </Box>\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n color: \"text.secondary\",\r\n mx: size === \"small\" ? 0.5 : 0.75,\r\n userSelect: \"none\",\r\n height: \"100%\",\r\n flexShrink: 0,\r\n }}\r\n >\r\n <DashIcon size={size} />\r\n </Box>\r\n <Box\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n if (disabled || readonly) return;\r\n // \uD074\uB9AD \uC2DC \uC804\uCCB4 \uC120\uD0DD\r\n isClickFocusRef.current = true;\r\n setFocusedField(\"back\");\r\n setBackComplete(false);\r\n backRef.current?.focus();\r\n const len = mask\r\n ? backValue.length > 0\r\n ? 1\r\n : 0\r\n : backValue.length;\r\n if (len > 0) {\r\n setCursorVisible(false);\r\n setTimeout(() => {\r\n backRef.current?.setSelectionRange(0, len);\r\n }, 0);\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n }}\r\n sx={{\r\n position: \"relative\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n }}\r\n >\r\n <TextField\r\n {...props}\r\n inputRef={backRef}\r\n value={displayBackValue}\r\n onChange={handleBackChange}\r\n onKeyDown={handleBackKeyDown}\r\n onFocus={handleBackFocus}\r\n onBlur={handleBackBlur}\r\n onClick={(e) => {\r\n if (disabled || readonly) return;\r\n e.stopPropagation();\r\n\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uD074\uB9AD \uC2DC \uC804\uCCB4 \uC120\uD0DD\r\n if (mask) {\r\n setFocusedField(\"back\");\r\n setBackComplete(false);\r\n if (backValue.length > 0) {\r\n setCursorVisible(false);\r\n requestAnimationFrame(() => {\r\n backRef.current?.setSelectionRange(\r\n 0,\r\n 1,\r\n );\r\n });\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n return;\r\n }\r\n\r\n // \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uB4DC\uB798\uADF8 \uC120\uD0DD \uD655\uC778\r\n const input = backRef.current;\r\n const selStart = input?.selectionStart ?? 0;\r\n const selEnd = input?.selectionEnd ?? 0;\r\n\r\n // \uC120\uD0DD \uBC94\uC704\uAC00 \uC788\uC73C\uBA74 \uADF8\uB300\uB85C \uC720\uC9C0\r\n if (selStart !== selEnd) {\r\n setCursorVisible(false);\r\n setFocusedField(\"back\");\r\n return;\r\n }\r\n\r\n // \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uD074\uB9AD \uC2DC \uC804\uCCB4 \uC120\uD0DD\r\n setFocusedField(\"back\");\r\n setBackComplete(false);\r\n if (backValue.length > 0) {\r\n setCursorVisible(false);\r\n requestAnimationFrame(() => {\r\n backRef.current?.setSelectionRange(\r\n 0,\r\n backValue.length,\r\n );\r\n });\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n }}\r\n disabled={disabled}\r\n size={size}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n placeholder={mask ? \"\" : \"0000000\"}\r\n variant=\"outlined\"\r\n sx={{\r\n width: \"auto\",\r\n minWidth: 0,\r\n ...noBorderStyle,\r\n \"& .MuiInputBase-root\": {\r\n width: \"auto\",\r\n },\r\n \"& .MuiInputBase-input\": {\r\n width: backFieldCh,\r\n caretColor: \"transparent\",\r\n ...(fontSize && { fontSize }),\r\n ...(fontColor && { color: fontColor }),\r\n ...(fontFamily && { fontFamily }),\r\n background: \"transparent\",\r\n position: \"relative\",\r\n zIndex: 1,\r\n },\r\n \"& .MuiInputBase-input::placeholder\": {\r\n color: \"rgba(0, 0, 0, 0.2)\",\r\n opacity: 1,\r\n },\r\n }}\r\n slotProps={{\r\n input: {\r\n readOnly: readonly,\r\n },\r\n htmlInput: {\r\n maxLength: mask ? 1 : 7,\r\n inputMode: \"numeric\",\r\n style: {\r\n textAlign: \"left\",\r\n padding: \"0 4px\",\r\n },\r\n },\r\n }}\r\n />\r\n {/* \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C - \uB4B7\uC790\uB9AC (\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC\uC5D0\uC11C \uC785\uB825 \uC644\uB8CC \uC2DC \uC228\uAE40) */}\r\n {/* \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C - \uB4B7\uC790\uB9AC (\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC\uC5D0\uC11C \uC785\uB825 \uC644\uB8CC \uD6C4 \uC790\uB3D9 \uC228\uAE40, \uD074\uB9AD \uC2DC \uB2E4\uC2DC \uBCF4\uC784) */}\r\n {cursorVisible &&\r\n focusedField === \"back\" &&\r\n !backComplete && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n bottom: size === \"small\" ? 1 : 3,\r\n left: `calc(4px + ${cursorLeft}px)`,\r\n width: `${computedFontSize * 0.55}px`,\r\n height: cursorHeight,\r\n backgroundColor:\r\n fontColor || \"text.primary\",\r\n animation: \"blink 1s step-end infinite\",\r\n \"@keyframes blink\": {\r\n \"0%, 100%\": { opacity: 1 },\r\n \"50%\": { opacity: 0 },\r\n },\r\n pointerEvents: \"none\",\r\n zIndex: 2,\r\n }}\r\n />\r\n )}\r\n {/* \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC\uC77C \uB54C \uB4B7\uC790\uB9AC placeholder \u25CF \uD45C\uC2DC */}\r\n {mask && placeholderDots > 0 && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n left: 0,\r\n width: backFieldCh,\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n pointerEvents: \"none\",\r\n fontSize:\r\n fontSize ||\r\n (size === \"small\" ? \"16px\" : \"18px\"),\r\n fontFamily: fontFamily || \"inherit\",\r\n }}\r\n >\r\n {/* \uCCAB \uBC88\uC9F8 \uB3D9\uADF8\uB77C\uBBF8 (\uC785\uB825 \uC704\uCE58) */}\r\n <span\r\n style={{\r\n width: `${dotSize}px`,\r\n height: `${dotSize}px`,\r\n borderRadius: \"50%\",\r\n backgroundColor:\r\n displayBackValue.length > 0\r\n ? \"transparent\"\r\n : maskColor,\r\n opacity: 0.2,\r\n display: \"inline-block\",\r\n flexShrink: 0,\r\n }}\r\n />\r\n {/* \uB4A4 6\uAC1C \uB3D9\uADF8\uB77C\uBBF8 (7ch \uAC04\uACA9) */}\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n justifyContent: \"space-between\",\r\n width: \"7ch\",\r\n marginLeft: \"auto\",\r\n }}\r\n >\r\n {Array.from({ length: 6 }).map((_, i) => (\r\n <span\r\n key={i}\r\n style={{\r\n width: `${smallDotSize}px`,\r\n height: `${smallDotSize}px`,\r\n borderRadius: \"50%\",\r\n backgroundColor: maskColor,\r\n display: \"inline-block\",\r\n flexShrink: 0,\r\n }}\r\n />\r\n ))}\r\n </Box>\r\n </Box>\r\n )}\r\n </Box>\r\n </Box>\r\n </>\r\n );\r\n\r\n // \uD074\uB9AD \uC2DC \uD3EC\uCEE4\uC2A4\uD560 ref \uACB0\uC815\r\n const getTargetRefOnClick = useCallback(() => {\r\n if (frontValue.length === 0) {\r\n return { ref: frontRef, groupIndex: 0 };\r\n } else if (backValue.length === 0) {\r\n return { ref: backRef, groupIndex: 1 };\r\n }\r\n return { ref: backRef, groupIndex: 1 };\r\n }, [frontValue.length, backValue.length]);\r\n\r\n // focusedGroup\uC744 focusedField\uB85C \uB9E4\uD551 (GroupedInputWrapper \uD638\uD658)\r\n const focusedGroup =\r\n focusedField === \"front\" ? 0 : focusedField === \"back\" ? 1 : null;\r\n const setFocusedGroupWrapper = useCallback((group: number | null) => {\r\n if (group === null) {\r\n setFocusedField(null);\r\n setCursorVisible(false);\r\n } else if (group === 0) {\r\n setFocusedField(\"front\");\r\n setCursorVisible(true);\r\n } else if (group === 1) {\r\n setFocusedField(\"back\");\r\n setCursorVisible(true);\r\n }\r\n }, []);\r\n\r\n return (\r\n <GroupedInputWrapper\r\n label={label}\r\n size={size}\r\n disabled={disabled}\r\n readonly={readonly}\r\n focusedGroup={focusedGroup}\r\n setFocusedGroup={setFocusedGroupWrapper}\r\n hasValue={getFullNumber().length > 0}\r\n isInvalid={isInvalid}\r\n invalidBorderColor={invalidBorderColor}\r\n inputRefs={[frontRef, backRef]}\r\n getTargetRefOnClick={getTargetRefOnClick}\r\n fullWidth={fullWidth}\r\n sx={sx}\r\n className={className}\r\n id={id}\r\n >\r\n {renderGroupedInput()}\r\n </GroupedInputWrapper>\r\n );\r\n },\r\n);\r\n\r\nconst JuminTextFieldWithForm = forwardRef<HTMLDivElement, JuminTextFieldProps>(\r\n function JuminTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"JuminTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"JuminTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name) as string | undefined;\r\n const handleFormChange = useCallback(\r\n (info: JuminInfo) => {\r\n const syntheticEvent = {\r\n target: { name, value: info.value },\r\n currentTarget: { name, value: info.value },\r\n } as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n onChange?.(info);\r\n },\r\n [form, name, onChange],\r\n );\r\n\r\n return (\r\n <JuminTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const JuminTextField = forwardRef<HTMLDivElement, JuminTextFieldProps>(\r\n function JuminTextField(props, ref) {\r\n if (props.form) {\r\n return <JuminTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <JuminTextFieldBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * GroupedInputWrapper.tsx\r\n *\r\n * \uADF8\uB8F9\uD654\uB41C \uC785\uB825 \uCEF4\uD3EC\uB10C\uD2B8(\uC0AC\uC5C5\uC790\uBC88\uD638, \uC8FC\uBBFC\uBC88\uD638, \uCE74\uB4DC\uBC88\uD638, \uC2DC\uAC04 \uB4F1)\uB97C \uC704\uD55C\r\n * FormControl + OutlinedInput \uB798\uD37C \uCEF4\uD3EC\uB10C\uD2B8\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useCallback,\r\n useRef,\r\n useEffect,\r\n RefObject,\r\n forwardRef,\r\n} from \"react\";\r\nimport { FormControl, InputLabel, OutlinedInput, Box } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\n\r\nexport interface GroupedInputWrapperProps {\r\n label?: React.ReactNode; // \uB77C\uBCA8\r\n size?: \"small\" | \"medium\"; // \uC0AC\uC774\uC988\r\n disabled?: boolean; // \uBE44\uD65C\uC131\uD654\r\n readonly?: boolean; // \uC77D\uAE30 \uC804\uC6A9\r\n focusedGroup: number | null; // \uD3EC\uCEE4\uC2A4\uB41C \uADF8\uB8F9 \uC778\uB371\uC2A4 (null\uC774\uBA74 \uD3EC\uCEE4\uC2A4 \uC5C6\uC74C)\r\n setFocusedGroup: (group: number | null) => void; // \uD3EC\uCEE4\uC2A4 \uADF8\uB8F9 \uC124\uC815 \uD568\uC218\r\n hasValue: boolean; // \uAC12\uC774 \uC788\uB294\uC9C0 \uC5EC\uBD80\r\n isInvalid?: boolean; // \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uC0C1\uD0DC\r\n invalidBorderColor?: string; // \uC720\uD6A8\uD558\uC9C0 \uC54A\uC744 \uB54C \uD14C\uB450\uB9AC \uC0C9\uC0C1\r\n inputRefs: RefObject<HTMLInputElement | null>[]; // \uB0B4\uBD80 \uC785\uB825 \uD544\uB4DC\uB4E4\uC758 ref \uBC30\uC5F4\r\n getTargetRefOnClick: () => {\r\n ref: RefObject<HTMLInputElement | null>;\r\n groupIndex: number;\r\n }; // \uD074\uB9AD \uC2DC \uD3EC\uCEE4\uC2A4\uD560 ref\uC640 \uADF8\uB8F9 \uC778\uB371\uC2A4 \uACB0\uC815 \uD568\uC218\r\n sx?: SxProps<Theme>; // \uCEE8\uD14C\uC774\uB108 sx\r\n className?: string; // className\r\n id?: string; // id\r\n fullWidth?: boolean; // \uC804\uCCB4 \uB108\uBE44 \uC0AC\uC6A9 \uC5EC\uBD80\r\n children: React.ReactNode; // \uB0B4\uBD80 \uCEE8\uD150\uCE20 \uB80C\uB354\uB9C1\r\n contentSx?: SxProps<Theme>; // \uB0B4\uBD80 Box\uC758 \uCD94\uAC00 sx\r\n endAdornment?: React.ReactNode; // \uC624\uB978\uCABD \uB05D\uC5D0 \uD56D\uC0C1 \uBCF4\uC774\uB294 \uC694\uC18C (\uC544\uC774\uCF58 \uB4F1)\r\n}\r\n\r\n// inputComponent\uB97C \uCEF4\uD3EC\uB10C\uD2B8 \uC678\uBD80\uC5D0\uC11C \uC815\uC758\uD558\uC5EC \uB9AC\uB80C\uB354\uB9C1 \uBC29\uC9C0\r\ninterface CustomInputProps {\r\n showContent: boolean;\r\n inputSize: \"small\" | \"medium\";\r\n contentSx?: SxProps<Theme>;\r\n children: React.ReactNode;\r\n endAdornment?: React.ReactNode;\r\n}\r\n\r\nconst CustomInput = forwardRef<HTMLDivElement, CustomInputProps>(\r\n function CustomInput(\r\n { showContent, inputSize, contentSx, children, endAdornment },\r\n ref,\r\n ) {\r\n return (\r\n <Box\r\n ref={ref}\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n width: \"100%\",\r\n height: \"100%\",\r\n px: inputSize === \"small\" ? 1 : 1.25,\r\n ...contentSx,\r\n }}\r\n >\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n flex: 1,\r\n visibility: showContent ? \"visible\" : \"hidden\",\r\n }}\r\n >\r\n {children}\r\n </Box>\r\n {endAdornment}\r\n </Box>\r\n );\r\n },\r\n);\r\n\r\nexport function GroupedInputWrapper({\r\n label,\r\n size = \"medium\",\r\n disabled,\r\n readonly,\r\n focusedGroup,\r\n setFocusedGroup,\r\n hasValue,\r\n isInvalid,\r\n invalidBorderColor,\r\n inputRefs,\r\n getTargetRefOnClick,\r\n sx,\r\n className,\r\n id,\r\n fullWidth = false,\r\n children,\r\n contentSx,\r\n endAdornment,\r\n}: GroupedInputWrapperProps) {\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n // label\uC774 \uC788\uACE0 focus/\uAC12\uC774 \uC5C6\uC744 \uB54C \uB0B4\uBD80 \uC785\uB825 \uC694\uC18C \uC228\uAE40\r\n const showContent = !label || focusedGroup !== null || hasValue;\r\n const isLabelShrunk = focusedGroup !== null || hasValue;\r\n\r\n // \uD074\uB9AD \uD578\uB4E4\uB7EC - onMouseDown\uC5D0\uC11C \uCC98\uB9AC\uD558\uC5EC OutlinedInput\uC758 \uAE30\uBCF8 \uD3EC\uCEE4\uC2A4 \uB3D9\uC791 \uBC29\uC9C0\r\n const handleMouseDown = useCallback(\r\n (e: React.MouseEvent) => {\r\n if (disabled || readonly) {\r\n return;\r\n }\r\n\r\n // \uC774\uBBF8 input\uC5D0\uC11C \uCC98\uB9AC\uB41C \uD074\uB9AD\uC774\uBA74 \uBB34\uC2DC\r\n const target = e.target as HTMLElement;\r\n if (target.tagName === \"INPUT\") {\r\n return;\r\n }\r\n\r\n // \uAE30\uBCF8 \uD3EC\uCEE4\uC2A4 \uB3D9\uC791 \uBC29\uC9C0\r\n e.preventDefault();\r\n\r\n const { ref: targetRef, groupIndex } = getTargetRefOnClick();\r\n const inputEl = targetRef.current;\r\n\r\n if (inputEl) {\r\n // \uBA3C\uC800 focusedGroup\uC744 \uC124\uC815\uD558\uC5EC visibility\uB97C visible\uB85C \uBCC0\uACBD\r\n setFocusedGroup(groupIndex);\r\n\r\n // \uB2E4\uC74C \uB80C\uB354 \uC0AC\uC774\uD074\uC5D0\uC11C \uD3EC\uCEE4\uC2A4 \uBC0F \uC804\uCCB4 \uC120\uD0DD (visibility\uAC00 visible\uC774 \uB41C \uD6C4)\r\n setTimeout(() => {\r\n inputEl.focus();\r\n inputEl.select(); // \uC804\uCCB4 \uC120\uD0DD\r\n }, 0);\r\n }\r\n },\r\n [disabled, readonly, getTargetRefOnClick, setFocusedGroup],\r\n );\r\n\r\n // blur \uD578\uB4E4\uB7EC - \uC678\uBD80 \uD074\uB9AD \uAC10\uC9C0\r\n useEffect(() => {\r\n if (focusedGroup === null) return;\r\n\r\n const handleDocumentClick = (e: MouseEvent) => {\r\n const target = e.target as Node;\r\n\r\n // \uCEE8\uD14C\uC774\uB108 \uB0B4\uBD80 \uD074\uB9AD\uC774\uBA74 \uBB34\uC2DC\r\n if (containerRef.current?.contains(target)) {\r\n return;\r\n }\r\n\r\n // \uB0B4\uBD80 input \uC911 \uD558\uB098\uAC00 \uD3EC\uCEE4\uC2A4\uB418\uC5B4 \uC788\uB294\uC9C0 \uD655\uC778\r\n const isAnyInputFocused = inputRefs.some(\r\n (ref) => ref.current === document.activeElement,\r\n );\r\n\r\n if (!isAnyInputFocused) {\r\n setFocusedGroup(null);\r\n }\r\n };\r\n\r\n // mousedown\uC73C\uB85C \uCC98\uB9AC (click\uBCF4\uB2E4 \uBA3C\uC800 \uBC1C\uC0DD)\r\n document.addEventListener(\"mousedown\", handleDocumentClick);\r\n return () => {\r\n document.removeEventListener(\"mousedown\", handleDocumentClick);\r\n };\r\n }, [focusedGroup, inputRefs, setFocusedGroup]);\r\n\r\n // \uB0B4\uBD80 input blur \uC2DC \uCC98\uB9AC\r\n const handleBlur = useCallback(() => {\r\n // setTimeout\uC73C\uB85C \uB2E4\uB978 \uB0B4\uBD80 input\uC73C\uB85C \uC774\uB3D9\uD588\uB294\uC9C0 \uD655\uC778\r\n setTimeout(() => {\r\n const activeEl = document.activeElement;\r\n const isStillFocused = inputRefs.some(\r\n (ref) => ref.current === activeEl,\r\n );\r\n if (!isStillFocused) {\r\n setFocusedGroup(null);\r\n }\r\n }, 0);\r\n }, [inputRefs, setFocusedGroup]);\r\n\r\n return (\r\n <FormControl\r\n ref={containerRef}\r\n size={size}\r\n disabled={disabled}\r\n error={isInvalid}\r\n focused={readonly ? false : focusedGroup !== null}\r\n fullWidth={fullWidth}\r\n sx={{\r\n ...(fullWidth && {\r\n width: \"100%\",\r\n flex: 1,\r\n minWidth: 0,\r\n display: \"flex\",\r\n }),\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...sx,\r\n }}\r\n className={className}\r\n >\r\n {label && (\r\n <InputLabel\r\n shrink={isLabelShrunk}\r\n sx={{\r\n ...(isInvalid &&\r\n invalidBorderColor && {\r\n color: invalidBorderColor,\r\n \"&.Mui-focused\": { color: invalidBorderColor },\r\n }),\r\n }}\r\n >\r\n {label}\r\n </InputLabel>\r\n )}\r\n <OutlinedInput\r\n id={id}\r\n label={label}\r\n notched={isLabelShrunk}\r\n fullWidth={fullWidth}\r\n onMouseDown={handleMouseDown}\r\n onBlur={handleBlur}\r\n sx={{\r\n height: size === \"small\" ? 40 : 56,\r\n cursor: disabled ? \"default\" : \"text\",\r\n ...(isInvalid &&\r\n invalidBorderColor && {\r\n \"& .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n \"&:hover .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n \"&.Mui-focused .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n }),\r\n ...(readonly && {\r\n \"&:hover .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n }),\r\n }}\r\n slots={{ input: CustomInput }}\r\n slotProps={{\r\n input: {\r\n showContent,\r\n inputSize: size,\r\n contentSx,\r\n children,\r\n endAdornment,\r\n } as CustomInputProps,\r\n }}\r\n />\r\n </FormControl>\r\n );\r\n}\r\n", "/**\r\n * ColonBox.tsx - \uC2DC\uAC04 \uD544\uB4DC \uC0AC\uC774\uC758 \uCF5C\uB860 \uC544\uC774\uCF58 \uCEF4\uD3EC\uB10C\uD2B8\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { Box } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport { ColonIcon as ColonSvg } from \"../icons\";\r\n\r\nexport interface ColonBoxProps {\r\n /** \uD06C\uAE30 (small | medium) */\r\n size?: \"small\" | \"medium\";\r\n /** \uAC00\uB85C \uB9C8\uC9C4 */\r\n mx?: number;\r\n /** \uCF5C\uB860 \uD45C\uC2DC \uC5EC\uBD80 */\r\n visible?: boolean;\r\n /** \uCD94\uAC00 \uC2A4\uD0C0\uC77C */\r\n sx?: SxProps<Theme>;\r\n}\r\n\r\n/**\r\n * \uCF5C\uB860 \uC544\uC774\uCF58\uC744 \uAC10\uC2F8\uB294 \uBC15\uC2A4 \uCEF4\uD3EC\uB10C\uD2B8\r\n * TimeTextField\uC640 DateTimeTextField\uC5D0\uC11C \uACF5\uD1B5\uC73C\uB85C \uC0AC\uC6A9\r\n */\r\nexport function ColonBox({ size, mx, visible = true, sx }: ColonBoxProps) {\r\n return (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n userSelect: \"none\",\r\n minWidth: \"6px\",\r\n padding: 0,\r\n flexShrink: 0,\r\n position: \"relative\",\r\n zIndex: 1,\r\n opacity: visible ? 0.8 : 0,\r\n visibility: visible ? \"visible\" : \"hidden\",\r\n mx,\r\n ...sx,\r\n }}\r\n >\r\n <ColonSvg size={size} />\r\n </Box>\r\n );\r\n}\r\n", "/**\r\n * VerificationCodeTextField.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n useRef,\r\n ChangeEvent,\r\n KeyboardEvent,\r\n ClipboardEvent,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { Box, FormControl, InputLabel, OutlinedInput } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport type { VerificationCodeTextFieldProps } from \"./types\";\r\nimport { useDebouncedEmit } from \"./hooks\";\r\n\r\nconst VerificationCodeTextFieldBase = forwardRef<\r\n HTMLDivElement,\r\n VerificationCodeTextFieldProps\r\n>(function VerificationCodeTextFieldBase(\r\n {\r\n label,\r\n length = 6,\r\n type = \"numeric\",\r\n value,\r\n onChange,\r\n onComplete,\r\n debounce,\r\n readonly,\r\n disabled,\r\n size,\r\n name = \"\",\r\n fontSize: fontSizeProp,\r\n fontColor = \"text.primary\",\r\n fontFamily = \"monospace\",\r\n dotSize: dotSizeProp,\r\n caretColor = \"text.primary\",\r\n sx,\r\n invalidBorderColor,\r\n inputRef: externalInputRef,\r\n ...restProps\r\n },\r\n ref,\r\n) {\r\n const [internalValue, setInternalValue] = useState(\"\");\r\n const [isFocused, setIsFocused] = useState(false);\r\n const [isAllSelected, setIsAllSelected] = useState(false);\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLInputElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange, flushOnBlur, lastEmittedValue } = useDebouncedEmit({\r\n name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n // value prop \uB3D9\uAE30\uD654 (\uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uACBD\uC6B0\uB9CC)\r\n useEffect(() => {\r\n if (value !== undefined && value !== null) {\r\n const strValue = String(value).slice(0, length);\r\n // \uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uAC12\uC774 \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uD55C \uAC12\uACFC \uB2E4\uB97C \uB54C\uB9CC \uB3D9\uAE30\uD654\r\n if (strValue !== lastEmittedValue.current) {\r\n setInternalValue(strValue);\r\n lastEmittedValue.current = strValue;\r\n }\r\n } else if (lastEmittedValue.current !== \"\") {\r\n setInternalValue(\"\");\r\n lastEmittedValue.current = \"\";\r\n }\r\n }, [value, length, lastEmittedValue]);\r\n\r\n // \uC785\uB825 \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n const isValidChar = useCallback(\r\n (char: string): boolean => {\r\n if (type === \"numeric\") {\r\n return /^\\d$/.test(char);\r\n } else if (type === \"alpha\") {\r\n return /^[a-zA-Z]$/.test(char);\r\n } else {\r\n // alphanumeric\r\n return /^[a-zA-Z0-9]$/.test(char);\r\n }\r\n },\r\n [type],\r\n );\r\n\r\n // \uBB38\uC790\uC5F4 \uD544\uD130\uB9C1\r\n const filterValue = useCallback(\r\n (val: string): string => {\r\n let filtered = \"\";\r\n for (const char of val) {\r\n if (isValidChar(char)) {\r\n filtered += type === \"alpha\" ? char.toUpperCase() : char;\r\n }\r\n }\r\n return filtered.slice(0, length);\r\n },\r\n [isValidChar, length, type],\r\n );\r\n\r\n // \uBCC0\uACBD \uD578\uB4E4\uB7EC\r\n const handleChange = useCallback(\r\n (e: ChangeEvent<HTMLInputElement>) => {\r\n const filtered = filterValue(e.target.value);\r\n setInternalValue(filtered);\r\n setIsAllSelected(false); // \uC785\uB825 \uC2DC \uC804\uCCB4 \uC120\uD0DD \uD574\uC81C\r\n\r\n // \uB514\uBC14\uC6B4\uC2A4 \uC801\uC6A9\r\n emitChange(e, filtered);\r\n\r\n // \uC644\uB8CC \uC2DC \uCF5C\uBC31\r\n if (filtered.length === length && onComplete) {\r\n onComplete(filtered);\r\n }\r\n },\r\n [filterValue, length, onComplete, emitChange],\r\n );\r\n\r\n // \uBD99\uC5EC\uB123\uAE30 \uCC98\uB9AC\r\n const handlePaste = useCallback(\r\n (e: ClipboardEvent<HTMLInputElement>) => {\r\n e.preventDefault();\r\n const pastedText = e.clipboardData.getData(\"text\");\r\n const filtered = filterValue(pastedText);\r\n setInternalValue(filtered);\r\n\r\n // \uBD99\uC5EC\uB123\uAE30 \uC2DC \uC989\uC2DC emit\r\n emitChange(null, filtered, true);\r\n\r\n if (filtered.length === length && onComplete) {\r\n onComplete(filtered);\r\n }\r\n },\r\n [filterValue, length, onComplete, emitChange],\r\n );\r\n\r\n // \uD0A4 \uC785\uB825 \uCC98\uB9AC (\uBC31\uC2A4\uD398\uC774\uC2A4 \uB4F1)\r\n const handleKeyDown = useCallback((e: KeyboardEvent<HTMLInputElement>) => {\r\n // \uD2B9\uC218 \uD0A4\uB294 \uD5C8\uC6A9\r\n if (\r\n [\r\n \"Backspace\",\r\n \"Delete\",\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"Tab\",\r\n \"Home\",\r\n \"End\",\r\n ].includes(e.key)\r\n ) {\r\n return;\r\n }\r\n\r\n // Ctrl+A, Ctrl+C, Ctrl+V \uB4F1 \uD5C8\uC6A9\r\n if (e.ctrlKey || e.metaKey) {\r\n return;\r\n }\r\n }, []);\r\n\r\n // \uD074\uB9AD \uC2DC \uC804\uCCB4 \uC120\uD0DD\r\n const handleFocus = useCallback(() => {\r\n setIsFocused(true);\r\n setTimeout(() => {\r\n const input = internalInputRef.current;\r\n if (input && input.value.length > 0) {\r\n input.setSelectionRange(0, input.value.length);\r\n setIsAllSelected(true);\r\n }\r\n }, 0);\r\n }, []);\r\n\r\n // \uC774\uBBF8 \uD3EC\uCEE4\uC2A4\uB41C \uC0C1\uD0DC\uC5D0\uC11C \uD074\uB9AD\uD574\uB3C4 \uC804\uCCB4 \uC120\uD0DD\r\n const handleClick = useCallback(() => {\r\n const input = internalInputRef.current;\r\n if (input && input.value.length > 0) {\r\n input.setSelectionRange(0, input.value.length);\r\n setIsAllSelected(true);\r\n }\r\n }, []);\r\n\r\n // \uD3EC\uCEE4\uC2A4 \uD574\uC81C\r\n const handleBlur = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>) => {\r\n setIsFocused(false);\r\n setIsAllSelected(false);\r\n // blur \uC2DC \uB300\uAE30 \uC911\uC778 \uB514\uBC14\uC6B4\uC2A4 \uC989\uC2DC \uC2E4\uD589\r\n flushOnBlur(e, internalValue);\r\n },\r\n [internalValue, flushOnBlur],\r\n );\r\n\r\n // \uC0AC\uC774\uC988\uBCC4 \uC124\uC815\r\n const defaultFontSize = size === \"small\" ? 18 : 24;\r\n const defaultDotSize = size === \"small\" ? 10 : 14;\r\n const fontSize = fontSizeProp ?? defaultFontSize;\r\n const dotSize = dotSizeProp ?? defaultDotSize;\r\n const charWidth = Math.max(fontSize, size === \"small\" ? 18 : 22); // \uAE00\uC790 \uD558\uB098\uC758 \uB108\uBE44\r\n const gap = size === \"small\" ? 6 : 8; // \uAE00\uC790/dot \uAC04 \uAC04\uACA9\r\n const totalContentWidth = length * charWidth + (length - 1) * gap;\r\n const containerHeight = Math.max(size === \"small\" ? 40 : 56, fontSize + 16);\r\n const containerPadding = size === \"small\" ? 16 : 20;\r\n\r\n // inputMode \uC124\uC815\r\n const inputMode = type === \"numeric\" ? \"numeric\" : \"text\";\r\n\r\n // sx\uC5D0\uC11C width\uAC00 \uC9C0\uC815\uB418\uC5C8\uB294\uC9C0 \uD655\uC778\r\n const hasCustomWidth =\r\n sx &&\r\n typeof sx === \"object\" &&\r\n !Array.isArray(sx) &&\r\n (\"width\" in sx || \"minWidth\" in sx || \"maxWidth\" in sx);\r\n\r\n // showContent: label\uC774 \uC5C6\uAC70\uB098, \uD3EC\uCEE4\uC2A4/\uAC12\uC774 \uC788\uC744 \uB54C\r\n const showContent = !label || isFocused || internalValue.length > 0;\r\n\r\n // FormControl sx \uACC4\uC0B0\r\n const formControlWidth = hasCustomWidth\r\n ? ((sx as Record<string, unknown>)?.width as\r\n | string\r\n | number\r\n | undefined) ||\r\n ((sx as Record<string, unknown>)?.minWidth as\r\n | string\r\n | number\r\n | undefined) ||\r\n ((sx as Record<string, unknown>)?.maxWidth as\r\n | string\r\n | number\r\n | undefined)\r\n : totalContentWidth + containerPadding * 2;\r\n\r\n const formControlSx: SxProps<Theme> = {\r\n display: \"inline-flex\",\r\n width: formControlWidth,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...(sx as Record<string, unknown>),\r\n };\r\n\r\n return (\r\n <FormControl\r\n ref={ref}\r\n variant=\"outlined\"\r\n size={size}\r\n disabled={disabled}\r\n focused={readonly ? false : isFocused}\r\n sx={formControlSx}\r\n >\r\n {label && (\r\n <InputLabel\r\n shrink={isFocused || internalValue.length > 0}\r\n sx={{\r\n backgroundColor: \"background.paper\",\r\n px: 0.5,\r\n ...(readonly && {\r\n \"&.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }),\r\n }}\r\n >\r\n {label}\r\n </InputLabel>\r\n )}\r\n <OutlinedInput\r\n label={label}\r\n notched={\r\n label ? isFocused || internalValue.length > 0 : undefined\r\n }\r\n readOnly={readonly}\r\n onMouseDown={(e) => {\r\n e.preventDefault();\r\n internalInputRef.current?.focus();\r\n }}\r\n sx={{\r\n height: containerHeight,\r\n cursor: disabled ? \"default\" : \"text\",\r\n \"& .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: invalidBorderColor || undefined,\r\n },\r\n \"& .MuiOutlinedInput-input\": {\r\n padding: 0,\r\n height: \"100%\",\r\n },\r\n ...(readonly && {\r\n \"&:hover .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n }),\r\n }}\r\n inputProps={{\r\n style: { display: \"none\" },\r\n }}\r\n />\r\n {/* \uCEE4\uC2A4\uD140 \uB0B4\uC6A9\uBB3C \uB80C\uB354\uB9C1 */}\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n top: 0,\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n width: \"100%\",\r\n height: \"100%\",\r\n px: 1.75,\r\n pointerEvents: \"none\",\r\n }}\r\n >\r\n {/* \uB0B4\uC6A9\uBB3C \uCEE8\uD14C\uC774\uB108 */}\r\n <Box\r\n sx={{\r\n width: hasCustomWidth ? \"100%\" : totalContentWidth,\r\n height: \"100%\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n visibility: showContent ? \"visible\" : \"hidden\",\r\n }}\r\n >\r\n {/* Placeholder dots + \uC785\uB825\uB41C \uAE00\uC790 \uD45C\uC2DC */}\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n gap: hasCustomWidth ? 0 : `${gap}px`,\r\n width: hasCustomWidth ? \"100%\" : undefined,\r\n }}\r\n >\r\n {Array.from({ length }).map((_, i) => (\r\n <Box\r\n key={i}\r\n sx={{\r\n flex: hasCustomWidth ? 1 : undefined,\r\n width: hasCustomWidth\r\n ? undefined\r\n : charWidth,\r\n minWidth: charWidth,\r\n height: charWidth,\r\n display: \"flex\",\r\n justifyContent: \"center\",\r\n alignItems: \"center\",\r\n position: \"relative\",\r\n borderRadius: 0.5,\r\n backgroundColor:\r\n isAllSelected &&\r\n i < internalValue.length\r\n ? \"primary.main\"\r\n : \"transparent\",\r\n transition: \"background-color 0.1s\",\r\n }}\r\n >\r\n {i < internalValue.length ? (\r\n <Box\r\n component=\"span\"\r\n sx={{\r\n fontSize,\r\n fontFamily,\r\n fontWeight: 600,\r\n lineHeight: 1,\r\n color: isAllSelected\r\n ? \"white\"\r\n : fontColor,\r\n transition: \"color 0.1s\",\r\n }}\r\n >\r\n {internalValue[i]}\r\n </Box>\r\n ) : (\r\n <Box\r\n sx={{\r\n width: dotSize,\r\n height: dotSize,\r\n borderRadius: \"50%\",\r\n backgroundColor:\r\n \"rgba(0, 0, 0, 0.08)\",\r\n }}\r\n />\r\n )}\r\n {/* \uAE5C\uBE61\uC774\uB294 \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C */}\r\n {isFocused &&\r\n i === internalValue.length &&\r\n internalValue.length < length && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n bottom: -2,\r\n left: \"50%\",\r\n transform: \"translateX(-50%)\",\r\n width: \"0.6em\",\r\n height: \"1px\",\r\n backgroundColor: caretColor,\r\n animation:\r\n \"blink 1s step-end infinite\",\r\n \"@keyframes blink\": {\r\n \"0%, 100%\": {\r\n opacity: 1,\r\n },\r\n \"50%\": { opacity: 0 },\r\n },\r\n }}\r\n />\r\n )}\r\n </Box>\r\n ))}\r\n </Box>\r\n </Box>\r\n </Box>\r\n {/* \uC228\uACA8\uC9C4 \uC785\uB825 \uD544\uB4DC */}\r\n <input\r\n ref={internalInputRef}\r\n value={internalValue}\r\n onChange={handleChange}\r\n onKeyDown={handleKeyDown}\r\n onPaste={handlePaste}\r\n onFocus={handleFocus}\r\n onClick={handleClick}\r\n onBlur={handleBlur}\r\n disabled={disabled}\r\n readOnly={readonly}\r\n autoComplete=\"one-time-code\"\r\n spellCheck={false}\r\n maxLength={length}\r\n inputMode={inputMode}\r\n style={{\r\n position: \"absolute\",\r\n opacity: 0,\r\n width: 1,\r\n height: 1,\r\n pointerEvents: \"none\",\r\n textTransform:\r\n type === \"alpha\" || type === \"alphanumeric\"\r\n ? \"uppercase\"\r\n : \"none\",\r\n }}\r\n />\r\n </FormControl>\r\n );\r\n});\r\n\r\nconst VerificationCodeTextFieldWithForm = forwardRef<\r\n HTMLDivElement,\r\n VerificationCodeTextFieldProps\r\n>(function VerificationCodeTextFieldWithForm(\r\n { form, name, onChange, ...rest },\r\n ref,\r\n) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"VerificationCodeTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"VerificationCodeTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <VerificationCodeTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const VerificationCodeTextField = forwardRef<\r\n HTMLDivElement,\r\n VerificationCodeTextFieldProps\r\n>(function VerificationCodeTextField(props, ref) {\r\n if (props.form) {\r\n return <VerificationCodeTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <VerificationCodeTextFieldBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * EmailTextField.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n useRef,\r\n ChangeEvent,\r\n KeyboardEvent,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport {\r\n TextField,\r\n Box,\r\n Popper,\r\n Paper,\r\n List,\r\n ListItemButton,\r\n ListItemText,\r\n ListItemIcon,\r\n ClickAwayListener,\r\n} from \"@mui/material\";\r\nimport type { EmailTextFieldProps } from \"./types\";\r\nimport { getEmailIcon } from \"./icons/email-icons\";\r\nimport { useDebouncedEmit } from \"./hooks\";\r\nimport { DEFAULT_EMAIL_DOMAINS, validateEmail } from \"./utils\";\r\n\r\nconst EmailTextFieldBase = forwardRef<HTMLDivElement, EmailTextFieldProps>(function EmailTextFieldBase(\r\n {\r\n value,\r\n onChange,\r\n onValidationChange,\r\n domains = DEFAULT_EMAIL_DOMAINS,\r\n extraDomains,\r\n suggestions = true,\r\n showLogos = true,\r\n invalidBorderColor,\r\n debounce,\r\n readonly,\r\n sx,\r\n size,\r\n disabled,\r\n name = \"\",\r\n onBlur,\r\n fullWidth,\r\n inputRef: externalInputRef,\r\n ...props\r\n },\r\n ref\r\n) {\r\n // extraDomains\uAC00 \uC788\uC73C\uBA74 \uC55E\uC5D0 \uCD94\uAC00, \uC911\uBCF5 \uC81C\uAC70\r\n // customIcons: \uCEE4\uC2A4\uD140 \uC544\uC774\uCF58 \uB9E4\uD551 (domain -> ReactNode)\r\n const { allDomains, customIcons } = React.useMemo(() => {\r\n const icons: Record<string, React.ReactNode> = {};\r\n\r\n // extraDomains \uCC98\uB9AC (\uBB38\uC790\uC5F4 \uB610\uB294 CustomDomain \uAC1D\uCCB4)\r\n const extraDomainStrings: string[] = [];\r\n if (extraDomains && extraDomains.length > 0) {\r\n extraDomains.forEach((item) => {\r\n if (typeof item === \"string\") {\r\n extraDomainStrings.push(item);\r\n } else {\r\n // CustomDomain \uAC1D\uCCB4\r\n extraDomainStrings.push(item.domain);\r\n if (item.icon) {\r\n icons[item.domain.toLowerCase()] = item.icon;\r\n }\r\n }\r\n });\r\n }\r\n\r\n const combined = [...extraDomainStrings, ...domains];\r\n // \uC911\uBCF5 \uC81C\uAC70 (\uB300\uC18C\uBB38\uC790 \uBB34\uC2DC)\r\n const seen = new Set<string>();\r\n const uniqueDomains = combined.filter((domain) => {\r\n const lower = domain.toLowerCase();\r\n if (seen.has(lower)) return false;\r\n seen.add(lower);\r\n return true;\r\n });\r\n\r\n return { allDomains: uniqueDomains, customIcons: icons };\r\n }, [domains, extraDomains]);\r\n\r\n // \uB3C4\uBA54\uC778\uC5D0 \uD574\uB2F9\uD558\uB294 \uC544\uC774\uCF58 \uAC00\uC838\uC624\uAE30 (\uCEE4\uC2A4\uD140 \uC544\uC774\uCF58 \uC6B0\uC120)\r\n const getDomainIcon = useCallback(\r\n (domain: string, size: number): React.ReactNode => {\r\n const lowerDomain = domain.toLowerCase();\r\n if (customIcons[lowerDomain]) {\r\n return customIcons[lowerDomain];\r\n }\r\n return getEmailIcon(domain, size);\r\n },\r\n [customIcons]\r\n );\r\n\r\n const [inputValue, setInputValue] = useState(\"\");\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n const [localSuggestions, setLocalSuggestions] = useState<string[]>([]);\r\n const [showPopper, setShowPopper] = useState(false);\r\n const [selectedIndex, setSelectedIndex] = useState(-1);\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n const anchorRef = useRef<HTMLDivElement>(null);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(externalInputRef as React.Ref<HTMLInputElement>, () => internalInputRef.current!, []);\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange, flushOnBlur, lastEmittedValue } = useDebouncedEmit({\r\n name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n // value prop \uB3D9\uAE30\uD654 (\uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uACBD\uC6B0\uB9CC)\r\n useEffect(() => {\r\n if (value !== undefined && value !== null) {\r\n const strValue = String(value);\r\n // \uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uAC12\uC774 \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uD55C \uAC12\uACFC \uB2E4\uB97C \uB54C\uB9CC \uB3D9\uAE30\uD654\r\n if (strValue !== lastEmittedValue.current) {\r\n setInputValue(strValue);\r\n lastEmittedValue.current = strValue;\r\n }\r\n } else if (lastEmittedValue.current !== \"\") {\r\n setInputValue(\"\");\r\n lastEmittedValue.current = \"\";\r\n }\r\n }, [value, lastEmittedValue]);\r\n\r\n // \uB3C4\uBA54\uC778 \uC81C\uC548 \uC0DD\uC131\r\n const generateSuggestions = useCallback(\r\n (input: string) => {\r\n if (!suggestions || !input || disabled || readonly) {\r\n setLocalSuggestions([]);\r\n return;\r\n }\r\n\r\n const atIndex = input.indexOf(\"@\");\r\n if (atIndex === -1) {\r\n // @ \uC5C6\uC73C\uBA74 \uC81C\uC548 \uC548 \uD568\r\n setLocalSuggestions([]);\r\n return;\r\n }\r\n\r\n const localPart = input.slice(0, atIndex);\r\n const domainPart = input.slice(atIndex + 1).toLowerCase();\r\n\r\n if (!localPart) {\r\n setLocalSuggestions([]);\r\n return;\r\n }\r\n\r\n // \uB3C4\uBA54\uC778 \uBD80\uBD84\uC774 \uBE44\uC5B4\uC788\uAC70\uB098 \uBD80\uBD84 \uC785\uB825\uB41C \uACBD\uC6B0\r\n const filteredDomains = allDomains.filter((domain) => domain.toLowerCase().startsWith(domainPart));\r\n\r\n // \uC774\uBBF8 \uC644\uC804\uD788 \uC77C\uCE58\uD558\uB294 \uB3C4\uBA54\uC778\uC774 \uC788\uC73C\uBA74 \uC81C\uC548 \uC548 \uD568\r\n if (filteredDomains.length === 1 && filteredDomains[0].toLowerCase() === domainPart) {\r\n setLocalSuggestions([]);\r\n return;\r\n }\r\n\r\n const newSuggestions = filteredDomains.slice(0, 10).map((domain) => `${localPart}@${domain}`);\r\n\r\n setLocalSuggestions(newSuggestions);\r\n setShowPopper(newSuggestions.length > 0);\r\n // \uCCAB \uBC88\uC9F8 \uD56D\uBAA9 \uC790\uB3D9 \uC120\uD0DD\r\n setSelectedIndex(newSuggestions.length > 0 ? 0 : -1);\r\n },\r\n [allDomains, suggestions, disabled]\r\n );\r\n\r\n // \uC785\uB825 \uBCC0\uACBD \uD578\uB4E4\uB7EC\r\n const handleChange = useCallback(\r\n (e: ChangeEvent<HTMLInputElement>) => {\r\n const newValue = e.target.value;\r\n setInputValue(newValue);\r\n generateSuggestions(newValue);\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n const isValid = validateEmail(newValue);\r\n const hasContent = newValue.length > 0;\r\n setIsInvalid(hasContent && !isValid);\r\n\r\n if (onValidationChange) {\r\n onValidationChange(isValid);\r\n }\r\n\r\n // \uB514\uBC14\uC6B4\uC2A4 \uC801\uC6A9\r\n emitChange(e, newValue);\r\n },\r\n [onValidationChange, generateSuggestions, emitChange]\r\n );\r\n\r\n // \uC81C\uC548 \uC120\uD0DD \uD578\uB4E4\uB7EC\r\n const handleSelectSuggestion = useCallback(\r\n (suggestion: string) => {\r\n setInputValue(suggestion);\r\n setLocalSuggestions([]);\r\n setShowPopper(false);\r\n setSelectedIndex(-1);\r\n\r\n const isValid = validateEmail(suggestion);\r\n setIsInvalid(!isValid);\r\n\r\n if (onValidationChange) {\r\n onValidationChange(isValid);\r\n }\r\n\r\n // \uC81C\uC548 \uC120\uD0DD \uC2DC \uC989\uC2DC emit\r\n emitChange(null, suggestion, true);\r\n\r\n // \uD3EC\uCEE4\uC2A4 \uC720\uC9C0\r\n internalInputRef.current?.focus();\r\n },\r\n [onValidationChange, emitChange]\r\n );\r\n\r\n // \uD0A4\uBCF4\uB4DC \uB124\uBE44\uAC8C\uC774\uC158\r\n const handleKeyDown = useCallback(\r\n (e: KeyboardEvent<HTMLInputElement>) => {\r\n if (!showPopper || localSuggestions.length === 0) return;\r\n\r\n switch (e.key) {\r\n case \"ArrowDown\":\r\n e.preventDefault();\r\n setSelectedIndex((prev) => (prev < localSuggestions.length - 1 ? prev + 1 : 0));\r\n break;\r\n case \"ArrowUp\":\r\n e.preventDefault();\r\n setSelectedIndex((prev) => (prev > 0 ? prev - 1 : localSuggestions.length - 1));\r\n break;\r\n case \"Enter\":\r\n // \uC120\uD0DD\uB41C \uD56D\uBAA9\uC774 \uC788\uC73C\uBA74 \uD574\uB2F9 \uD56D\uBAA9, \uC5C6\uC73C\uBA74 \uCCAB \uBC88\uC9F8 \uD56D\uBAA9 \uC120\uD0DD\r\n e.preventDefault();\r\n if (selectedIndex >= 0) {\r\n handleSelectSuggestion(localSuggestions[selectedIndex]);\r\n } else if (localSuggestions.length > 0) {\r\n handleSelectSuggestion(localSuggestions[0]);\r\n }\r\n break;\r\n case \"Escape\":\r\n e.preventDefault();\r\n setShowPopper(false);\r\n setSelectedIndex(-1);\r\n break;\r\n case \"Tab\":\r\n if (selectedIndex >= 0) {\r\n e.preventDefault();\r\n handleSelectSuggestion(localSuggestions[selectedIndex]);\r\n } else if (localSuggestions.length > 0) {\r\n e.preventDefault();\r\n handleSelectSuggestion(localSuggestions[0]);\r\n }\r\n break;\r\n }\r\n },\r\n [showPopper, localSuggestions, selectedIndex, handleSelectSuggestion]\r\n );\r\n\r\n // \uD074\uB9AD \uC678\uBD80 \uCC98\uB9AC\r\n const handleClickAway = useCallback(() => {\r\n setShowPopper(false);\r\n setSelectedIndex(-1);\r\n }, []);\r\n\r\n // blur \uC2DC \uB300\uAE30 \uC911\uC778 \uB514\uBC14\uC6B4\uC2A4 \uC989\uC2DC \uC2E4\uD589\r\n const handleBlur = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>) => {\r\n flushOnBlur(e, inputValue);\r\n if (onBlur) {\r\n onBlur(e);\r\n }\r\n },\r\n [inputValue, flushOnBlur, onBlur]\r\n );\r\n\r\n // \uD3EC\uCEE4\uC2A4 \uC2DC \uC81C\uC548 \uB2E4\uC2DC \uD45C\uC2DC\r\n const handleFocus = useCallback(() => {\r\n if (localSuggestions.length > 0) {\r\n setShowPopper(true);\r\n } else {\r\n generateSuggestions(inputValue);\r\n }\r\n }, [localSuggestions, inputValue, generateSuggestions]);\r\n\r\n // \uD14C\uB450\uB9AC \uC0C9\uC0C1\r\n const borderColor = isInvalid && invalidBorderColor ? invalidBorderColor : undefined;\r\n\r\n // anchorRef\uC640 \uC678\uBD80 ref\uB97C \uB3D9\uAE30\uD654\r\n const setRefs = useCallback(\r\n (node: HTMLDivElement | null) => {\r\n anchorRef.current = node;\r\n if (typeof ref === \"function\") {\r\n ref(node);\r\n } else if (ref) {\r\n (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\r\n }\r\n },\r\n [ref]\r\n );\r\n\r\n return (\r\n <ClickAwayListener onClickAway={handleClickAway}>\r\n <Box\r\n ref={setRefs}\r\n sx={{\r\n position: \"relative\",\r\n ...(fullWidth && { width: \"100%\" }),\r\n ...sx,\r\n }}\r\n >\r\n <TextField\r\n {...props}\r\n inputRef={internalInputRef}\r\n name={name}\r\n value={inputValue}\r\n onChange={handleChange}\r\n onKeyDown={handleKeyDown}\r\n onFocus={handleFocus}\r\n onBlur={handleBlur}\r\n disabled={disabled}\r\n size={size}\r\n fullWidth={fullWidth}\r\n type=\"email\"\r\n autoComplete=\"email\"\r\n autoCapitalize=\"off\"\r\n autoCorrect=\"off\"\r\n spellCheck=\"false\"\r\n sx={{\r\n width: \"100%\",\r\n ...(borderColor && {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": {\r\n borderColor: borderColor,\r\n },\r\n \"&:hover fieldset\": {\r\n borderColor: borderColor,\r\n },\r\n \"&.Mui-focused fieldset\": {\r\n borderColor: borderColor,\r\n },\r\n },\r\n }),\r\n ...(readonly && {\r\n pointerEvents: \"none\",\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }),\r\n }}\r\n slotProps={{\r\n ...props.slotProps,\r\n input: {\r\n ...props.slotProps?.input,\r\n readOnly: readonly,\r\n },\r\n htmlInput: {\r\n ...props.slotProps?.htmlInput,\r\n inputMode: \"email\",\r\n },\r\n }}\r\n />\r\n <Popper\r\n open={showPopper && localSuggestions.length > 0}\r\n anchorEl={anchorRef.current}\r\n placement=\"bottom-start\"\r\n style={{\r\n zIndex: 1300,\r\n width: anchorRef.current?.offsetWidth,\r\n }}\r\n >\r\n <Paper elevation={3} sx={{ mt: 0.5 }}>\r\n <List dense disablePadding>\r\n {localSuggestions.map((suggestion, index) => {\r\n const domain = suggestion.split(\"@\")[1];\r\n const iconSize = size === \"small\" ? 16 : 20;\r\n return (\r\n <ListItemButton\r\n key={suggestion}\r\n selected={index === selectedIndex}\r\n onClick={() => handleSelectSuggestion(suggestion)}\r\n sx={{\r\n py: 0.5,\r\n \"&.Mui-selected\": {\r\n backgroundColor: \"action.selected\",\r\n },\r\n }}\r\n >\r\n {showLogos && (\r\n <ListItemIcon sx={{ minWidth: 32 }}>\r\n {getDomainIcon(domain, iconSize)}\r\n </ListItemIcon>\r\n )}\r\n <ListItemText\r\n primary={suggestion}\r\n primaryTypographyProps={{\r\n fontSize: size === \"small\" ? 14 : 16,\r\n }}\r\n />\r\n </ListItemButton>\r\n );\r\n })}\r\n </List>\r\n </Paper>\r\n </Popper>\r\n </Box>\r\n </ClickAwayListener>\r\n );\r\n});\r\n\r\nconst EmailTextFieldWithForm = forwardRef<HTMLDivElement, EmailTextFieldProps>(function EmailTextFieldWithForm(\r\n { form, name, onChange, ...rest },\r\n ref\r\n) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\"EmailTextField form prop is missing. Provide a form from useForm or useGlobalForm.\");\r\n }\r\n if (!name) {\r\n throw new Error(\"EmailTextField requires a name when form prop is provided.\");\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange]\r\n );\r\n\r\n return <EmailTextFieldBase {...rest} ref={ref} name={name} value={formValue} onChange={handleFormChange} />;\r\n});\r\n\r\nexport const EmailTextField = forwardRef<HTMLDivElement, EmailTextFieldProps>(function EmailTextField(props, ref) {\r\n if (props.form) {\r\n return <EmailTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <EmailTextFieldBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * email-icons.tsx\r\n *\r\n * \uC774\uBA54\uC77C \uB3C4\uBA54\uC778 \uC544\uC774\uCF58 \uCEF4\uD3EC\uB10C\uD2B8\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\ninterface IconProps {\r\n size?: number;\r\n}\r\n\r\n// Gmail - \uACF5\uC2DD Gmail \uB85C\uACE0\r\nexport const GmailIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"52 42 88 66\" fill=\"none\">\r\n <path fill=\"#4285f4\" d=\"M58 108h14V74L52 59v43c0 3.32 2.69 6 6 6\" />\r\n <path fill=\"#34a853\" d=\"M120 108h14c3.32 0 6-2.69 6-6V59l-20 15\" />\r\n <path\r\n fill=\"#fbbc04\"\r\n d=\"M120 48v26l20-15v-8c0-7.42-8.47-11.65-14.4-7.2\"\r\n />\r\n <path fill=\"#ea4335\" d=\"M72 74V48l24 18 24-18v26L96 92\" />\r\n <path\r\n fill=\"#c5221f\"\r\n d=\"M52 51v8l20 15V48l-5.6-4.2c-5.94-4.45-14.4-.22-14.4 7.2\"\r\n />\r\n </svg>\r\n);\r\n\r\n// Naver\r\nexport const NaverIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\">\r\n <rect width=\"24\" height=\"24\" rx=\"4\" fill=\"#03C75A\" />\r\n <path\r\n d=\"M14.4 12.6L9.3 5.4H6v13.2h3.6v-7.2l5.1 7.2H18V5.4h-3.6v7.2z\"\r\n fill=\"white\"\r\n />\r\n </svg>\r\n);\r\n\r\n// Daum / Hanmail - \uB2E4\uC74C \uACF5\uC2DD \uB85C\uACE0 (\uBC30\uACBD + \uD770\uC0C9 D)\r\nexport const DaumIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 52 52\" fill=\"none\">\r\n {/* \uB124\uC774\uBE44 \uBC30\uACBD */}\r\n <rect width=\"52\" height=\"52\" rx=\"8\" fill=\"#273552\" />\r\n {/* \uD770\uC0C9 D \uAE00\uC790 */}\r\n <path\r\n d=\"m 25.52,20.36 c 3.1152,0 5.6352,2.712 5.5152,5.8536 -0.1128,2.988 -2.6616,5.4264 -5.652,5.4264 h -3.9456 c -0.264,0 -0.48,-0.216 -0.48,-0.48 V 20.84 c 0,-0.264 0.216,-0.48 0.48,-0.48 h 4.08 M 25.52,14 h -9.6 c -0.7944,0 -1.44,0.6456 -1.44,1.44 v 21.12 c 0,0.7944 0.6456,1.44 1.44,1.44 H 25.52 C 32.1464,38 37.52,32.6264 37.52,26 37.52,19.3736 32.1464,14 25.52,14 Z\"\r\n fill=\"white\"\r\n />\r\n </svg>\r\n);\r\n\r\n// Kakao\r\nexport const KakaoIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\">\r\n <rect width=\"24\" height=\"24\" rx=\"4\" fill=\"#FEE500\" />\r\n <path\r\n d=\"M12 5C7.58 5 4 7.79 4 11.15c0 2.13 1.42 4.01 3.58 5.08-.16.57-.57 2.07-.65 2.39-.1.4.15.39.31.28.13-.08 2.04-1.38 2.87-1.94.6.09 1.23.14 1.89.14 4.42 0 8-2.79 8-6.15S16.42 5 12 5z\"\r\n fill=\"#3C1E1E\"\r\n />\r\n </svg>\r\n);\r\n\r\n// Nate\r\n// Nate - \uB124\uC774\uD2B8 \uB85C\uACE0 (\uBE68\uAC04\uC0C9 \uBC30\uACBD + \uD770\uC0C9 n)\r\nexport const NateIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\">\r\n {/* \uBE68\uAC04\uC0C9 \uB465\uADFC \uBC30\uACBD */}\r\n <rect width=\"24\" height=\"24\" rx=\"4\" fill=\"#FF2F1A\" />\r\n {/* \uD770\uC0C9 n \uAE00\uC790 */}\r\n <path\r\n d=\"M6 8V18H9V13C9 11.5 10 10.5 12 10.5C14 10.5 15 11.5 15 13V18H18V12C18 9 15.5 7 12 7C10 7 8 7.8 6 8Z\"\r\n fill=\"white\"\r\n />\r\n </svg>\r\n);\r\n\r\n// Hotmail / Outlook - Microsoft \uB85C\uACE0\r\nexport const OutlookIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 48 48\" fill=\"none\">\r\n <path fill=\"#ff5722\" d=\"M6 6H22V22H6z\" transform=\"rotate(-180 14 14)\" />\r\n <path\r\n fill=\"#4caf50\"\r\n d=\"M26 6H42V22H26z\"\r\n transform=\"rotate(-180 34 14)\"\r\n />\r\n <path\r\n fill=\"#ffc107\"\r\n d=\"M26 26H42V42H26z\"\r\n transform=\"rotate(-180 34 34)\"\r\n />\r\n <path\r\n fill=\"#03a9f4\"\r\n d=\"M6 26H22V42H6z\"\r\n transform=\"rotate(-180 14 34)\"\r\n />\r\n </svg>\r\n);\r\n\r\n// Yahoo - \uACF5\uC2DD \uB85C\uACE0\r\nexport const YahooIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 48 48\" fill=\"none\">\r\n <polygon\r\n fill=\"#5e35b1\"\r\n points=\"4.209,14.881 11.632,14.881 16.189,26.715 20.966,14.881 28.315,14.881 17.07,42 9.501,42 12.587,34.96\"\r\n />\r\n <circle cx=\"29.276\" cy=\"30.522\" r=\"4.697\" fill=\"#5e35b1\" />\r\n <polygon\r\n fill=\"#5e35b1\"\r\n points=\"34.693,6 27.213,24.042 35.444,24.042 42.925,6\"\r\n />\r\n </svg>\r\n);\r\n\r\n// iCloud - Apple \uAD6C\uB984 \uB85C\uACE0\r\nexport const ICloudIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 48 48\" fill=\"none\">\r\n {/* \uD558\uB298\uC0C9 \uADF8\uB77C\uB370\uC774\uC158 \uAD6C\uB984 - \uD06C\uAC8C, \uC911\uC559 \uC815\uB82C */}\r\n <path\r\n d=\"M44 26c0-4.42-3.58-8-8-8-.43 0-.85.04-1.27.1C33.57 11.77 28.03 7 21.5 7 13.49 7 7 13.49 7 21.5c0 .42.01.83.05 1.23-.04 0-.07-.01-.11-.01C3.63 22.72 1 25.35 1 28.66 1 32.16 3.84 35 7.34 35H36c4.42 0 8-3.58 8-8v-1z\"\r\n fill=\"url(#icloud_gradient)\"\r\n />\r\n <defs>\r\n <linearGradient\r\n id=\"icloud_gradient\"\r\n x1=\"24\"\r\n y1=\"7\"\r\n x2=\"24\"\r\n y2=\"35\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n >\r\n <stop stopColor=\"#6AC4F7\" />\r\n <stop offset=\"1\" stopColor=\"#3693F3\" />\r\n </linearGradient>\r\n </defs>\r\n </svg>\r\n);\r\n\r\n// \uAE30\uBCF8 \uC774\uBA54\uC77C \uC544\uC774\uCF58 (\uC54C \uC218 \uC5C6\uB294 \uB3C4\uBA54\uC778\uC6A9) - \uC9C4\uD68C\uC0C9 \uC544\uC6C3\uB77C\uC778\r\nexport const DefaultEmailIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\">\r\n {/* \uBD09\uD22C \uBCF8\uCCB4 */}\r\n <rect\r\n x=\"2\"\r\n y=\"4\"\r\n width=\"20\"\r\n height=\"16\"\r\n rx=\"2\"\r\n stroke=\"#666666\"\r\n strokeWidth=\"2\"\r\n fill=\"none\"\r\n />\r\n {/* \uBD09\uD22C \uB36E\uAC1C */}\r\n <path\r\n d=\"M2 6l10 7 10-7\"\r\n stroke=\"#666666\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n fill=\"none\"\r\n />\r\n </svg>\r\n);\r\n\r\n/**\r\n * \uB3C4\uBA54\uC778\uC5D0 \uD574\uB2F9\uD558\uB294 \uC544\uC774\uCF58 \uCEF4\uD3EC\uB10C\uD2B8 \uBC18\uD658\r\n */\r\nexport function getEmailIcon(\r\n domain: string,\r\n size: number = 16\r\n): React.ReactNode {\r\n const lowerDomain = domain.toLowerCase();\r\n\r\n switch (lowerDomain) {\r\n case \"gmail.com\":\r\n return <GmailIcon size={size} />;\r\n case \"naver.com\":\r\n return <NaverIcon size={size} />;\r\n case \"daum.net\":\r\n case \"hanmail.net\":\r\n return <DaumIcon size={size} />;\r\n case \"kakao.com\":\r\n return <KakaoIcon size={size} />;\r\n case \"nate.com\":\r\n return <NateIcon size={size} />;\r\n case \"hotmail.com\":\r\n case \"outlook.com\":\r\n return <OutlookIcon size={size} />;\r\n case \"yahoo.com\":\r\n return <YahooIcon size={size} />;\r\n case \"icloud.com\":\r\n return <ICloudIcon size={size} />;\r\n default:\r\n return <DefaultEmailIcon size={size} />;\r\n }\r\n}\r\n", "/**\r\n * TimeTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n useRef,\r\n useMemo,\r\n ChangeEvent,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField, Box } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport type { TimeTextFieldProps } from \"./types\";\r\nimport { ClockIcon } from \"./icons\";\r\nimport { ColonBox, GroupedInputWrapper } from \"./components\";\r\nimport { useGroupedInput, GroupConfig } from \"./hooks/useGroupedInput\";\r\nimport { TimePicker } from \"@ehfuse/mui-datetime-picker\";\r\nimport { getTimeFieldCount, validateTime } from \"./utils\";\r\n\r\nconst TimeTextFieldBase = forwardRef<HTMLDivElement, TimeTextFieldProps>(function TimeTextFieldBase(\r\n {\r\n label,\r\n format = \"HH:mm\",\r\n minTime,\r\n maxTime,\r\n clockIcon = true,\r\n minuteStep = 1,\r\n secondStep = 1,\r\n hideDisabledTime = false,\r\n invalidBorderColor,\r\n debounce,\r\n sx,\r\n value,\r\n onChange,\r\n onBlur,\r\n name = \"\",\r\n disabled,\r\n readonly = false,\r\n size,\r\n fullWidth = false,\r\n className,\r\n id,\r\n fontSize,\r\n fontColor,\r\n fontFamily,\r\n },\r\n ref\r\n) {\r\n const [hourValue, setHourValue] = useState(\"\");\r\n const [minuteValue, setMinuteValue] = useState(\"\");\r\n const [secondValue, setSecondValue] = useState(\"\");\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n const [isInternalChange, setIsInternalChange] = useState(false);\r\n const [pickerOpen, setPickerOpen] = useState(false);\r\n\r\n const hourRef = useRef<HTMLInputElement>(null);\r\n const minuteRef = useRef<HTMLInputElement>(null);\r\n const secondRef = useRef<HTMLInputElement>(null);\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n // \uC678\uBD80 ref\uC640 \uB0B4\uBD80 containerRef \uBCD1\uD569\r\n useImperativeHandle(ref, () => containerRef.current!, []);\r\n\r\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n const fieldCount = getTimeFieldCount(format);\r\n const hasSecond = fieldCount === 3;\r\n\r\n // \uD3F0\uD2B8 \uD06C\uAE30 \uACC4\uC0B0\r\n const defaultFontSize = size === \"small\" ? 16 : 18;\r\n const computedFontSize = fontSize\r\n ? typeof fontSize === \"number\"\r\n ? fontSize\r\n : parseFloat(fontSize) * (fontSize.toString().includes(\"rem\") ? 16 : 1)\r\n : defaultFontSize;\r\n const cursorHeight = \"1px\";\r\n const cursorWidth = `${computedFontSize * 0.55}px`;\r\n\r\n // useGroupedInput \uD6C5 \uC0AC\uC6A9\r\n const groups: GroupConfig[] = useMemo(\r\n () =>\r\n hasSecond\r\n ? [\r\n {\r\n maxLength: 2,\r\n ref: hourRef,\r\n value: hourValue,\r\n setValue: setHourValue,\r\n },\r\n {\r\n maxLength: 2,\r\n ref: minuteRef,\r\n value: minuteValue,\r\n setValue: setMinuteValue,\r\n },\r\n {\r\n maxLength: 2,\r\n ref: secondRef,\r\n value: secondValue,\r\n setValue: setSecondValue,\r\n },\r\n ]\r\n : [\r\n {\r\n maxLength: 2,\r\n ref: hourRef,\r\n value: hourValue,\r\n setValue: setHourValue,\r\n },\r\n {\r\n maxLength: 2,\r\n ref: minuteRef,\r\n value: minuteValue,\r\n setValue: setMinuteValue,\r\n },\r\n ],\r\n [hourValue, minuteValue, secondValue, hasSecond]\r\n );\r\n\r\n const {\r\n focusedGroup,\r\n setFocusedGroup,\r\n cursorVisible,\r\n inputComplete,\r\n getCursorLeft,\r\n createMouseDownHandler,\r\n createClickHandler,\r\n createFocusHandler,\r\n createBlurHandler,\r\n createKeyDownHandler,\r\n createChangeHandler: createGroupChangeHandler,\r\n } = useGroupedInput({\r\n groups,\r\n fontSize: computedFontSize,\r\n disabled,\r\n readonly,\r\n });\r\n\r\n useEffect(() => {\r\n return () => {\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n }\r\n };\r\n }, []);\r\n\r\n // value prop \uBCC0\uACBD \uC2DC \uB0B4\uBD80 \uC0C1\uD0DC \uB3D9\uAE30\uD654\r\n useEffect(() => {\r\n if (isInternalChange) {\r\n setIsInternalChange(false);\r\n return;\r\n }\r\n\r\n if (value !== undefined && value !== null) {\r\n const strValue = String(value).replace(/[^\\d:]/g, \"\");\r\n const parts = strValue.split(\":\");\r\n\r\n if (parts.length >= 2) {\r\n setHourValue(parts[0].slice(0, 2));\r\n setMinuteValue(parts[1].slice(0, 2));\r\n if (hasSecond && parts[2]) {\r\n setSecondValue(parts[2].slice(0, 2));\r\n }\r\n } else {\r\n const numbers = strValue.replace(/\\D/g, \"\");\r\n setHourValue(numbers.slice(0, 2));\r\n setMinuteValue(numbers.slice(2, 4));\r\n if (hasSecond) {\r\n setSecondValue(numbers.slice(4, 6));\r\n }\r\n }\r\n } else {\r\n setHourValue(\"\");\r\n setMinuteValue(\"\");\r\n setSecondValue(\"\");\r\n }\r\n }, [value, hasSecond, isInternalChange]);\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uBC0F onChange \uD638\uCD9C\r\n const emitChange = useCallback(\r\n (hour: string, minute: string, second: string) => {\r\n const isComplete = hasSecond\r\n ? hour.length === 2 && minute.length === 2 && second.length === 2\r\n : hour.length === 2 && minute.length === 2;\r\n\r\n const isValid = isComplete ? validateTime(hour, minute, second, format, minTime, maxTime) : true;\r\n\r\n setIsInvalid(isComplete && !isValid);\r\n\r\n const doEmit = () => {\r\n if (onChange) {\r\n setIsInternalChange(true);\r\n const timeString = hasSecond ? `${hour}:${minute}:${second}` : `${hour}:${minute}`;\r\n\r\n const event = {\r\n target: { name, value: timeString },\r\n } as ChangeEvent<HTMLInputElement>;\r\n onChange(event);\r\n }\r\n };\r\n\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n }\r\n\r\n if (debounce === undefined || debounce === 0) {\r\n doEmit();\r\n } else {\r\n debounceTimer.current = setTimeout(doEmit, debounce);\r\n }\r\n },\r\n [onChange, name, hasSecond, format, minTime, maxTime, debounce]\r\n );\r\n\r\n // \uC2DC\uAC04 \uAC12 \uC81C\uD55C (\uC2DC: 0-23 \uB610\uB294 0-12, \uBD84/\uCD08: 0-59)\r\n // 24\uC2DC\uAC04 \uD615\uC2DD\uC5D0\uC11C 24 \uC774\uC0C1\uC744 \uC785\uB825\uD558\uBA74 24\uB97C \uBE7C\uC11C \uBCC0\uD658 (24\u219200, 25\u219201, ...)\r\n const clampTimeValue = useCallback(\r\n (value: string, type: \"hour\" | \"minute\" | \"second\"): string => {\r\n if (value.length === 0) return value;\r\n\r\n // \uCCAB \uBC88\uC9F8 \uC790\uB9AC \uC785\uB825 \uC2DC: \uC720\uD6A8 \uBC94\uC704 \uCD08\uACFC\uD558\uBA74 \uC55E\uC5D0 0\uC744 \uBD99\uC5EC\uC11C \uB450 \uC790\uB9AC\uB85C\r\n if (value.length === 1) {\r\n const digit = parseInt(value, 10);\r\n if (type === \"hour\") {\r\n // \uC2DC: 12\uC2DC\uAC04 \uD615\uC2DD\uC774\uBA74 1\uAE4C\uC9C0, 24\uC2DC\uAC04 \uD615\uC2DD\uC774\uBA74 2\uAE4C\uC9C0\r\n const maxFirstDigit = format.startsWith(\"hh\") ? 1 : 2;\r\n // \uCCAB \uC790\uB9AC\uAC00 \uBC94\uC704 \uCD08\uACFC\uD558\uBA74 \uC55E\uC5D0 0\uC744 \uBD99\uC5EC\uC11C \uB450 \uC790\uB9AC\uB85C \uB9CC\uB4E6\r\n if (digit > maxFirstDigit) return `0${digit}`;\r\n } else {\r\n // \uBD84/\uCD08: \uCCAB \uC790\uB9AC\uB294 0-5\uB9CC \uAC00\uB2A5, 6-9\uBA74 \uC55E\uC5D0 0 \uBD99\uC784\r\n if (digit > 5) return `0${digit}`;\r\n }\r\n return value;\r\n }\r\n\r\n // \uB450 \uBC88\uC9F8 \uC790\uB9AC\uAE4C\uC9C0 \uC785\uB825 \uC644\uB8CC \uC2DC \uC81C\uD55C\r\n const num = parseInt(value, 10);\r\n if (isNaN(num)) return value;\r\n\r\n if (type === \"hour\") {\r\n const is12Hour = format.startsWith(\"hh\");\r\n // 24\uC2DC\uAC04 \uD615\uC2DD\uC5D0\uC11C 24 \uC774\uC0C1\uC744 \uC785\uB825\uD558\uBA74 24\uB97C \uBE7C\uC11C \uBCC0\uD658\r\n if (!is12Hour && num >= 24) {\r\n return String(num - 24).padStart(2, \"0\");\r\n }\r\n const maxHour = is12Hour ? 12 : 23;\r\n if (num > maxHour) return String(maxHour).padStart(2, \"0\");\r\n } else {\r\n // minute or second\r\n if (num > 59) return \"59\";\r\n }\r\n return value;\r\n },\r\n [format]\r\n );\r\n\r\n // \uC785\uB825 \uD578\uB4E4\uB7EC (\uD6C5\uC758 \uD578\uB4E4\uB7EC + \uCEE4\uC2A4\uD140 \uB85C\uC9C1)\r\n const handleChange = (groupIndex: number) => {\r\n return createGroupChangeHandler(groupIndex, (newValue, idx) => {\r\n // \uAC12 \uC81C\uD55C \uC801\uC6A9\r\n let clampedValue = newValue;\r\n if (idx === 0) {\r\n clampedValue = clampTimeValue(newValue, \"hour\");\r\n } else if (idx === 1) {\r\n clampedValue = clampTimeValue(newValue, \"minute\");\r\n } else if (idx === 2) {\r\n clampedValue = clampTimeValue(newValue, \"second\");\r\n }\r\n\r\n // \uAC12\uC774 \uBCC0\uACBD\uB418\uC5C8\uC73C\uBA74 \uC0C1\uD0DC \uC5C5\uB370\uC774\uD2B8\r\n if (clampedValue !== newValue) {\r\n groups[idx].setValue(clampedValue);\r\n\r\n // clamp\uB85C \uC778\uD574 2\uC790\uB9AC\uAC00 \uB418\uC5C8\uC73C\uBA74 \uB2E4\uC74C \uD544\uB4DC\uB85C \uC774\uB3D9\r\n if (clampedValue.length === 2 && newValue.length === 1 && idx < groups.length - 1) {\r\n const refs = [hourRef, minuteRef, secondRef];\r\n setTimeout(() => {\r\n refs[idx + 1].current?.focus();\r\n refs[idx + 1].current?.setSelectionRange(0, 0);\r\n }, 0);\r\n }\r\n }\r\n\r\n const newValues = [hourValue, minuteValue, secondValue];\r\n newValues[idx] = clampedValue;\r\n emitChange(newValues[0], newValues[1], newValues[2] || \"\");\r\n });\r\n };\r\n\r\n // \uD0A4 \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleKeyDown = (groupIndex: number) => {\r\n return createKeyDownHandler(groupIndex, (newValue, idx) => {\r\n const newValues = [hourValue, minuteValue, secondValue];\r\n newValues[idx] = newValue;\r\n emitChange(newValues[0], newValues[1], newValues[2] || \"\");\r\n });\r\n };\r\n\r\n // blur \uD578\uB4E4\uB7EC\r\n const handleBlur = useCallback(() => {\r\n const blurHandler = createBlurHandler();\r\n blurHandler();\r\n\r\n // \uC2DC\uAC04 \uADF8\uB8F9 \uB0B4 \uB2E4\uB978 \uD544\uB4DC\uB85C \uD3EC\uCEE4\uC2A4 \uC774\uB3D9 \uC2DC \uD328\uB529\uD558\uC9C0 \uC54A\uC74C\r\n setTimeout(() => {\r\n const activeElement = document.activeElement;\r\n const isStillInTimeGroup =\r\n activeElement === hourRef.current ||\r\n activeElement === minuteRef.current ||\r\n activeElement === secondRef.current;\r\n\r\n if (!isStillInTimeGroup) {\r\n // 1\uC790\uB9AC \uC2DC\uAC04 \uAC12\uC744 2\uC790\uB9AC\uB85C \uD328\uB529\r\n if (hourValue.length === 1) {\r\n setHourValue(hourValue.padStart(2, \"0\"));\r\n }\r\n if (minuteValue.length === 1) {\r\n setMinuteValue(minuteValue.padStart(2, \"0\"));\r\n }\r\n if (secondValue.length === 1) {\r\n setSecondValue(secondValue.padStart(2, \"0\"));\r\n }\r\n }\r\n }, 0);\r\n\r\n if (onBlur) {\r\n const paddedHour = hourValue.length === 1 ? hourValue.padStart(2, \"0\") : hourValue;\r\n const paddedMinute = minuteValue.length === 1 ? minuteValue.padStart(2, \"0\") : minuteValue;\r\n const paddedSecond = secondValue.length === 1 ? secondValue.padStart(2, \"0\") : secondValue;\r\n const timeString = hasSecond\r\n ? `${paddedHour}:${paddedMinute}:${paddedSecond}`\r\n : `${paddedHour}:${paddedMinute}`;\r\n const event = {\r\n target: { name, value: timeString },\r\n } as React.FocusEvent<HTMLInputElement>;\r\n onBlur(event);\r\n }\r\n }, [createBlurHandler, onBlur, hasSecond, hourValue, minuteValue, secondValue, name]);\r\n\r\n // \uD074\uB9AD \uC2DC \uD3EC\uCEE4\uC2A4\uD560 ref \uACB0\uC815\r\n const getTargetRefOnClick = useCallback(() => {\r\n const values = hasSecond ? [hourValue, minuteValue, secondValue] : [hourValue, minuteValue];\r\n const refs = hasSecond ? [hourRef, minuteRef, secondRef] : [hourRef, minuteRef];\r\n\r\n // \uB9C8\uC9C0\uB9C9\uC73C\uB85C \uAC12\uC774 \uC788\uB294 \uADF8\uB8F9 \uCC3E\uAE30\r\n let lastFilledIndex = -1;\r\n for (let i = values.length - 1; i >= 0; i--) {\r\n if (values[i].length > 0) {\r\n lastFilledIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n if (lastFilledIndex >= 0) {\r\n return {\r\n ref: refs[lastFilledIndex],\r\n groupIndex: lastFilledIndex,\r\n };\r\n }\r\n // \uBAA8\uB450 \uBE44\uC5B4\uC788\uC73C\uBA74 \uCCAB \uBC88\uC9F8 \uCE78\r\n return { ref: hourRef, groupIndex: 0 };\r\n }, [hourValue, minuteValue, secondValue, hasSecond]);\r\n\r\n // useGroupedInput \uD6C5\uC5D0\uC11C \uBC18\uD658\uB41C setFocusedGroup \uC0AC\uC6A9\r\n // (GroupedInputWrapper\uAC00 \uD638\uCD9C\uD560 \uB54C \uD6C5 \uB0B4\uBD80 \uC0C1\uD0DC\uB3C4 \uC5C5\uB370\uC774\uD2B8\uB428)\r\n\r\n // \uC2DC\uACC4 \uC544\uC774\uCF58 \uD074\uB9AD \uD578\uB4E4\uB7EC\r\n const handleClockIconClick = useCallback(\r\n (e: React.MouseEvent<HTMLElement>) => {\r\n e.stopPropagation();\r\n if (disabled || readonly) return;\r\n\r\n // \uD604\uC7AC \uD3EC\uCEE4\uC2A4\uB41C \uC694\uC18C blur \uCC98\uB9AC\r\n const activeElement = document.activeElement as HTMLElement;\r\n if (activeElement && typeof activeElement.blur === \"function\") {\r\n activeElement.blur();\r\n }\r\n setFocusedGroup(null);\r\n\r\n setPickerOpen(true);\r\n },\r\n [disabled, readonly, setFocusedGroup]\r\n );\r\n\r\n // TimePicker\uC5D0\uC11C \uC2DC\uAC04 \uC120\uD0DD \uC2DC\r\n const handlePickerChange = useCallback(\r\n (hour: string, minute: string, second?: string) => {\r\n setHourValue(hour);\r\n setMinuteValue(minute);\r\n if (hasSecond && second) {\r\n setSecondValue(second);\r\n }\r\n emitChange(hour, minute, second || \"\");\r\n\r\n // \uD3EC\uCEE4\uC2A4\uAC00 \uB2E4\uC2DC \uB4E4\uC5B4\uAC00\uC9C0 \uC54A\uB3C4\uB85D\r\n setFocusedGroup(null);\r\n },\r\n [hasSecond, emitChange, setFocusedGroup]\r\n );\r\n\r\n // TimePicker \uB2EB\uAE30\r\n const handlePickerClose = useCallback(() => {\r\n setPickerOpen(false);\r\n }, []);\r\n\r\n const noBorderStyle: SxProps<Theme> = {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": { border: \"none\" },\r\n \"&:hover fieldset\": { border: \"none\" },\r\n \"&.Mui-focused fieldset\": { border: \"none\" },\r\n },\r\n };\r\n\r\n // \uCEE4\uC2A4\uD140 \uD3F0\uD2B8 \uD06C\uAE30\uC5D0 \uB530\uB978 fieldWidth \uACC4\uC0B0\r\n // ch \uB2E8\uC704\uB294 \uD3F0\uD2B8\uB9C8\uB2E4 \uB2E4\uB974\uBBC0\uB85C, fontSize \uAE30\uC900\uC73C\uB85C px \uACC4\uC0B0\r\n const fieldWidth = fontSize ? `${computedFontSize * 1.25}px` : \"2.5ch\";\r\n\r\n // \uADF8\uB8F9 \uB80C\uB354\uB9C1\r\n const renderGroup = (groupIndex: number, groupValue: string, placeholder: string) => {\r\n const isFocused = focusedGroup === groupIndex;\r\n const showCursor = cursorVisible && isFocused && !inputComplete;\r\n const refs = [hourRef, minuteRef, secondRef];\r\n\r\n return (\r\n <Box\r\n onMouseDown={createMouseDownHandler(groupIndex)}\r\n onClick={createClickHandler(groupIndex)}\r\n sx={{\r\n position: \"relative\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n }}\r\n >\r\n <TextField\r\n inputRef={refs[groupIndex]}\r\n value={groupValue}\r\n onChange={handleChange(groupIndex)}\r\n onKeyDown={handleKeyDown(groupIndex)}\r\n onFocus={createFocusHandler(groupIndex)}\r\n onBlur={handleBlur}\r\n disabled={disabled}\r\n size={size}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n placeholder={placeholder}\r\n variant=\"outlined\"\r\n sx={{\r\n width: fieldWidth,\r\n maxWidth: fieldWidth,\r\n minWidth: fieldWidth,\r\n ...noBorderStyle,\r\n \"& .MuiInputBase-root\": {\r\n width: fieldWidth,\r\n maxWidth: fieldWidth,\r\n minWidth: fieldWidth,\r\n },\r\n \"& .MuiInputBase-input\": {\r\n width: fieldWidth,\r\n minWidth: fieldWidth,\r\n maxWidth: fieldWidth,\r\n textAlign: \"left\",\r\n caretColor: \"transparent\",\r\n ...(fontSize && { fontSize }),\r\n ...(fontColor && { color: fontColor }),\r\n ...(fontFamily && { fontFamily }),\r\n },\r\n \"& .MuiInputBase-input::placeholder\": {\r\n color: \"rgba(0, 0, 0, 0.3)\",\r\n opacity: 1,\r\n },\r\n }}\r\n slotProps={{\r\n input: { readOnly: readonly },\r\n htmlInput: {\r\n maxLength: 2,\r\n inputMode: \"numeric\",\r\n style: { padding: \"0 2px\", textAlign: \"left\" },\r\n },\r\n }}\r\n />\r\n {showCursor && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n bottom: size === \"small\" ? 1 : 3,\r\n left: `calc(2px + ${getCursorLeft(groupIndex)}px)`,\r\n width: cursorWidth,\r\n height: cursorHeight,\r\n backgroundColor: \"text.primary\",\r\n animation: \"blink 1s step-end infinite\",\r\n \"@keyframes blink\": {\r\n \"0%, 100%\": { opacity: 1 },\r\n \"50%\": { opacity: 0 },\r\n },\r\n pointerEvents: \"none\",\r\n }}\r\n />\r\n )}\r\n </Box>\r\n );\r\n };\r\n\r\n // \uC804\uCCB4 \uC2DC\uAC04 \uAC12 \uD655\uC778\r\n const getFullTime = useCallback(() => {\r\n return hourValue + minuteValue + (hasSecond ? secondValue : \"\");\r\n }, [hourValue, minuteValue, secondValue, hasSecond]);\r\n\r\n // \uCF5C\uB860 \uD45C\uC2DC \uC5EC\uBD80 (\uAC12\uC774 \uC788\uAC70\uB098 \uD3EC\uCEE4\uC2A4\uAC00 \uC788\uC744 \uB54C)\r\n const showColon = getFullTime().length > 0 || focusedGroup !== null;\r\n\r\n // \uB0B4\uBD80 \uADF8\uB8F9 \uB80C\uB354\uB9C1\r\n const renderGroupedInput = () => (\r\n <>\r\n {/* \uC2DC\uAC04 \uD544\uB4DC */}\r\n {renderGroup(0, hourValue, \"00\")}\r\n\r\n <ColonBox size={size} visible={showColon} />\r\n\r\n {/* \uBD84 \uD544\uB4DC */}\r\n {renderGroup(1, minuteValue, \"00\")}\r\n\r\n {/* \uCD08 \uD544\uB4DC */}\r\n {hasSecond && (\r\n <>\r\n <ColonBox size={size} visible={showColon} />\r\n\r\n {renderGroup(2, secondValue, \"00\")}\r\n </>\r\n )}\r\n\r\n {/* Spacer - flex \uD655\uC7A5\uC744 \uC704\uD55C \uBE48 \uACF5\uAC04 */}\r\n <Box sx={{ flex: 1 }} />\r\n </>\r\n );\r\n\r\n // \uC2DC\uACC4 \uC544\uC774\uCF58 (endAdornment)\r\n const clockIconElement =\r\n clockIcon && !readonly ? (\r\n <Box\r\n onMouseDown={(e) => {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n }}\r\n onClick={handleClockIconClick}\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n ml: size === \"small\" ? 0.5 : 1,\r\n mr: size === \"small\" ? -0.5 : 0,\r\n color: \"text.secondary\",\r\n opacity: 0.5,\r\n cursor: disabled ? \"default\" : \"pointer\",\r\n borderRadius: \"50%\",\r\n p: 0.5,\r\n transition: \"opacity 0.2s, color 0.2s, background-color 0.2s\",\r\n \"&:hover\": {\r\n opacity: disabled ? 0.5 : 1,\r\n color: disabled ? \"text.secondary\" : \"text.primary\",\r\n backgroundColor: disabled ? \"transparent\" : \"action.hover\",\r\n },\r\n }}\r\n >\r\n <ClockIcon size={size === \"small\" ? 18 : 22} />\r\n </Box>\r\n ) : null;\r\n\r\n return (\r\n <Box\r\n ref={containerRef}\r\n sx={{\r\n ...(fullWidth && { width: \"100%\" }),\r\n ...sx,\r\n }}\r\n className={className}\r\n >\r\n <GroupedInputWrapper\r\n label={label}\r\n size={size}\r\n disabled={disabled}\r\n readonly={readonly}\r\n focusedGroup={focusedGroup}\r\n setFocusedGroup={setFocusedGroup}\r\n hasValue={getFullTime().length > 0}\r\n isInvalid={isInvalid}\r\n invalidBorderColor={invalidBorderColor}\r\n inputRefs={hasSecond ? [hourRef, minuteRef, secondRef] : [hourRef, minuteRef]}\r\n getTargetRefOnClick={getTargetRefOnClick}\r\n fullWidth={fullWidth}\r\n id={id}\r\n endAdornment={clockIconElement}\r\n contentSx={{ pl: 1.75 }}\r\n >\r\n {renderGroupedInput()}\r\n </GroupedInputWrapper>\r\n\r\n {/* TimePicker Popover */}\r\n <TimePicker\r\n anchorEl={containerRef}\r\n open={pickerOpen}\r\n onClose={handlePickerClose}\r\n value={{\r\n hour: hourValue,\r\n minute: minuteValue,\r\n second: hasSecond ? secondValue : undefined,\r\n }}\r\n onChange={handlePickerChange}\r\n format={format}\r\n minTime={minTime}\r\n maxTime={maxTime}\r\n minuteStep={minuteStep}\r\n secondStep={secondStep}\r\n hideDisabledTime={hideDisabledTime}\r\n />\r\n </Box>\r\n );\r\n});\r\n\r\nconst TimeTextFieldWithForm = forwardRef<HTMLDivElement, TimeTextFieldProps>(function TimeTextFieldWithForm(\r\n { form, name, onChange, ...rest },\r\n ref\r\n) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\"TimeTextField form prop is missing. Provide a form from useForm or useGlobalForm.\");\r\n }\r\n if (!name) {\r\n throw new Error(\"TimeTextField requires a name when form prop is provided.\");\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange]\r\n );\r\n\r\n return <TimeTextFieldBase {...rest} ref={ref} name={name} value={formValue} onChange={handleFormChange} />;\r\n});\r\n\r\nexport const TimeTextField = forwardRef<HTMLDivElement, TimeTextFieldProps>(function TimeTextField(props, ref) {\r\n if (props.form) {\r\n return <TimeTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <TimeTextFieldBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * DateTimeTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n ChangeEvent,\r\n useMemo,\r\n useRef,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField, InputAdornment, IconButton, Box } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport type { DateTimeTextFieldProps } from \"./types\";\r\nimport { DateTimePicker } from \"@ehfuse/mui-datetime-picker\";\r\nimport { ColonBox } from \"./components\";\r\nimport { CalendarIcon } from \"./icons\";\r\nimport { useDebouncedEmit, useGroupedInput, GroupConfig } from \"./hooks\";\r\nimport {\r\n getSeparator,\r\n getMaxLength,\r\n getCompleteLength,\r\n validateDate,\r\n validateTime,\r\n clampTimeValue,\r\n is12HourFormat,\r\n extractDateFormat,\r\n hasSecondField,\r\n formatDateValue,\r\n formatToPlaceholder,\r\n getSegmentRange,\r\n hasYearInFormat,\r\n parseDateWithInternalYear,\r\n buildDateOutputValue,\r\n dateToNumbers,\r\n} from \"./utils\";\r\n\r\nconst DateTimeTextFieldBase = forwardRef<\r\n HTMLDivElement,\r\n DateTimeTextFieldProps\r\n>(function DateTimeTextFieldBase(\r\n {\r\n label,\r\n format = \"YYYY-MM-DD HH:mm\",\r\n dateSeparator = \"-\",\r\n minDateTime,\r\n maxDateTime,\r\n minTime,\r\n maxTime,\r\n holidays = [],\r\n holidayColor = \"red\",\r\n calendarIcon = true,\r\n selectedColor,\r\n showToday = true,\r\n minuteStep = 1,\r\n secondStep = 1,\r\n hideDisabledTime = false,\r\n invalidBorderColor,\r\n debounce,\r\n sx,\r\n value,\r\n onChange,\r\n onBlur,\r\n name = \"\",\r\n disabled,\r\n readonly = false,\r\n size,\r\n fullWidth = false,\r\n className,\r\n id,\r\n },\r\n ref,\r\n) {\r\n // \uB0A0\uC9DC \uD544\uB4DC \uC0C1\uD0DC\r\n const [dateDisplayValue, setDateDisplayValue] = useState(\"\");\r\n const [prevDateNumbers, setPrevDateNumbers] = useState(\"\");\r\n const [internalYear, setInternalYear] = useState<number | null>(null); // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC6A9\r\n\r\n // \uC2DC\uAC04 \uD544\uB4DC \uC0C1\uD0DC\r\n const [hourValue, setHourValue] = useState(\"\");\r\n const [minuteValue, setMinuteValue] = useState(\"\");\r\n const [secondValue, setSecondValue] = useState(\"\");\r\n\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n const [isDateFocused, setIsDateFocused] = useState(false);\r\n\r\n // \uD31D\uC624\uBC84 \uC0C1\uD0DC\r\n const [calendarOpen, setCalendarOpen] = useState(false);\r\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);\r\n\r\n // refs\r\n const dateInputRef = useRef<HTMLInputElement>(null);\r\n const hourRef = useRef<HTMLInputElement>(null);\r\n const minuteRef = useRef<HTMLInputElement>(null);\r\n const secondRef = useRef<HTMLInputElement>(null);\r\n const selectionRangeRef = useRef<{ start: number; end: number } | null>(\r\n null,\r\n );\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n // \uC678\uBD80 ref\uC640 \uB0B4\uBD80 containerRef \uBCD1\uD569\r\n useImperativeHandle(ref, () => containerRef.current!, []);\r\n\r\n const hasSecond = hasSecondField(format);\r\n const is12Hour = is12HourFormat(format);\r\n const dateFormat = extractDateFormat(format);\r\n const displayDateSeparator = getSeparator(dateFormat);\r\n const dateMaxLength = getMaxLength(dateFormat);\r\n const dateCompleteLength = getCompleteLength(dateFormat);\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC778\uC9C0 \uD655\uC778 (YYYY, YY\uAC00 \uC5C6\uB294 \uD3EC\uB9F7)\r\n const isYearlessFormat = !hasYearInFormat(dateFormat);\r\n\r\n // \uD3F0\uD2B8 \uD06C\uAE30 \uACC4\uC0B0 (\uC2DC\uAC04 \uD544\uB4DC\uC6A9)\r\n const computedFontSize = size === \"small\" ? 16 : 18;\r\n const cursorHeight = \"1px\";\r\n const cursorWidth = `${computedFontSize * 0.55}px`;\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange, flushOnBlur, lastEmittedValue } = useDebouncedEmit({\r\n name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n // \uC2DC\uAC04 \uADF8\uB8F9 \uC124\uC815\r\n const timeGroups: GroupConfig[] = useMemo(() => {\r\n const baseGroups: GroupConfig[] = [\r\n {\r\n maxLength: 2,\r\n ref: hourRef,\r\n value: hourValue,\r\n setValue: setHourValue,\r\n },\r\n {\r\n maxLength: 2,\r\n ref: minuteRef,\r\n value: minuteValue,\r\n setValue: setMinuteValue,\r\n },\r\n ];\r\n\r\n if (hasSecond) {\r\n baseGroups.push({\r\n maxLength: 2,\r\n ref: secondRef,\r\n value: secondValue,\r\n setValue: setSecondValue,\r\n });\r\n }\r\n\r\n return baseGroups;\r\n }, [hourValue, minuteValue, secondValue, hasSecond]);\r\n\r\n const {\r\n focusedGroup,\r\n cursorVisible,\r\n inputComplete,\r\n getCursorLeft,\r\n createMouseDownHandler,\r\n createClickHandler,\r\n createFocusHandler,\r\n createBlurHandler,\r\n createKeyDownHandler,\r\n createChangeHandler: createGroupChangeHandler,\r\n } = useGroupedInput({\r\n groups: timeGroups,\r\n fontSize: computedFontSize,\r\n disabled,\r\n readonly,\r\n });\r\n\r\n // \uC804\uCCB4 \uB0A0\uC9DC\uC2DC\uAC04 \uBB38\uC790\uC5F4 \uC0DD\uC131 (\uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC774\uC5B4\uB3C4 \uC5F0\uB3C4 \uD3EC\uD568)\r\n const buildDateTimeString = useCallback(\r\n (\r\n dateStr: string,\r\n hour: string,\r\n minute: string,\r\n second: string,\r\n yearOverride?: number,\r\n ) => {\r\n // \uB0A0\uC9DC \uBD80\uBD84 \uCD9C\uB825\uAC12 \uC0DD\uC131 (yearless \uD3EC\uB9F7 \uC9C0\uC6D0)\r\n const outputDateStr = buildDateOutputValue(\r\n dateStr,\r\n dateFormat,\r\n dateSeparator,\r\n yearOverride ?? internalYear,\r\n );\r\n const timeStr = hasSecond\r\n ? `${hour}:${minute}:${second}`\r\n : `${hour}:${minute}`;\r\n return `${outputDateStr} ${timeStr}`;\r\n },\r\n [dateFormat, dateSeparator, hasSecond, internalYear],\r\n );\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n const performValidation = useCallback(\r\n (dateStr: string, hour: string, minute: string, second: string) => {\r\n const dateNumbers = dateStr.replace(/\\D/g, \"\");\r\n const dateComplete = dateNumbers.length === dateCompleteLength;\r\n const timeComplete = hasSecond\r\n ? hour.length === 2 &&\r\n minute.length === 2 &&\r\n second.length === 2\r\n : hour.length === 2 && minute.length === 2;\r\n\r\n if (dateComplete && timeComplete) {\r\n const dateValid = validateDate(\r\n dateStr,\r\n dateFormat,\r\n minDateTime,\r\n maxDateTime,\r\n );\r\n const timeValid = validateTime(\r\n hour,\r\n minute,\r\n second,\r\n is12Hour,\r\n minTime,\r\n maxTime,\r\n );\r\n setIsInvalid(!dateValid || !timeValid);\r\n } else {\r\n setIsInvalid(false);\r\n }\r\n },\r\n [\r\n dateCompleteLength,\r\n hasSecond,\r\n dateFormat,\r\n minDateTime,\r\n maxDateTime,\r\n is12Hour,\r\n minTime,\r\n maxTime,\r\n ],\r\n );\r\n\r\n // value prop \uBCC0\uACBD \uC2DC \uB3D9\uAE30\uD654\r\n useEffect(() => {\r\n if (value !== undefined && value !== null) {\r\n const strValue = String(value);\r\n const [datePart, timePart] = strValue.split(\" \");\r\n\r\n if (strValue !== lastEmittedValue.current) {\r\n if (datePart) {\r\n const formatted = formatDateValue(datePart, dateFormat);\r\n setDateDisplayValue(formatted);\r\n setPrevDateNumbers(formatted.replace(/\\D/g, \"\"));\r\n }\r\n\r\n if (timePart) {\r\n const timeParts = timePart.split(\":\");\r\n setHourValue(timeParts[0]?.slice(0, 2) || \"\");\r\n setMinuteValue(timeParts[1]?.slice(0, 2) || \"\");\r\n if (hasSecond && timeParts[2]) {\r\n setSecondValue(timeParts[2].slice(0, 2));\r\n }\r\n }\r\n\r\n lastEmittedValue.current = strValue;\r\n }\r\n } else {\r\n if (lastEmittedValue.current !== \"\") {\r\n setDateDisplayValue(\"\");\r\n setPrevDateNumbers(\"\");\r\n setHourValue(\"\");\r\n setMinuteValue(\"\");\r\n setSecondValue(\"\");\r\n lastEmittedValue.current = \"\";\r\n }\r\n }\r\n }, [value, hasSecond, dateFormat, lastEmittedValue]);\r\n\r\n // \uB0A0\uC9DC \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleDateChange = useCallback(\r\n (e: ChangeEvent<HTMLInputElement>) => {\r\n const input = e.target;\r\n const newValue = input.value;\r\n const newNumbers = newValue.replace(/\\D/g, \"\");\r\n const selection = selectionRangeRef.current;\r\n\r\n // \uC601\uC5ED \uC120\uD0DD \uC0C1\uD0DC\uC5D0\uC11C \uC785\uB825\uD55C \uACBD\uC6B0\r\n if (\r\n selection &&\r\n selection.start !== selection.end &&\r\n selection.start >= 0 &&\r\n selection.end <= dateDisplayValue.length &&\r\n dateDisplayValue.length > 0 &&\r\n selection.start < selection.end\r\n ) {\r\n const beforeSelection = dateDisplayValue.slice(\r\n 0,\r\n selection.start,\r\n );\r\n const afterSelection = dateDisplayValue.slice(selection.end);\r\n const beforeNumbers = beforeSelection.replace(/\\D/g, \"\");\r\n const afterNumbers = afterSelection.replace(/\\D/g, \"\");\r\n const inputChar = newValue\r\n .slice(selection.start, selection.start + 1)\r\n .replace(/\\D/g, \"\");\r\n\r\n if (inputChar) {\r\n const combinedNumbers =\r\n beforeNumbers + inputChar + afterNumbers;\r\n const formattedValue = formatDateValue(\r\n combinedNumbers,\r\n dateFormat,\r\n );\r\n\r\n setDateDisplayValue(formattedValue);\r\n setPrevDateNumbers(formattedValue.replace(/\\D/g, \"\"));\r\n performValidation(\r\n formattedValue,\r\n hourValue,\r\n minuteValue,\r\n secondValue,\r\n );\r\n\r\n const newCursorPos = selection.start + 1;\r\n let adjustedPos = newCursorPos;\r\n if (formattedValue[adjustedPos] === displayDateSeparator) {\r\n adjustedPos++;\r\n }\r\n\r\n requestAnimationFrame(() => {\r\n input.setSelectionRange(adjustedPos, adjustedPos);\r\n });\r\n\r\n const outputValue = buildDateTimeString(\r\n formattedValue,\r\n hourValue,\r\n minuteValue,\r\n secondValue,\r\n );\r\n emitChange(e, outputValue);\r\n\r\n selectionRangeRef.current = null;\r\n return;\r\n }\r\n }\r\n\r\n selectionRangeRef.current = null;\r\n\r\n // \uBC31\uC2A4\uD398\uC774\uC2A4 \uAC10\uC9C0\r\n const isBackspace =\r\n newNumbers.length <= prevDateNumbers.length &&\r\n newValue.length < dateDisplayValue.length;\r\n\r\n let formattedValue: string;\r\n\r\n if (isBackspace && newNumbers.length === prevDateNumbers.length) {\r\n const trimmedNumbers = newNumbers.slice(0, -1);\r\n formattedValue = formatDateValue(trimmedNumbers, dateFormat);\r\n } else {\r\n formattedValue = formatDateValue(newValue, dateFormat);\r\n }\r\n\r\n setDateDisplayValue(formattedValue);\r\n setPrevDateNumbers(formattedValue.replace(/\\D/g, \"\"));\r\n performValidation(\r\n formattedValue,\r\n hourValue,\r\n minuteValue,\r\n secondValue,\r\n );\r\n\r\n const outputValue = buildDateTimeString(\r\n formattedValue,\r\n hourValue,\r\n minuteValue,\r\n secondValue,\r\n );\r\n emitChange(e, outputValue);\r\n\r\n // \uB0A0\uC9DC \uC785\uB825 \uC644\uB8CC \uC2DC \uC2DC\uAC04 \uD544\uB4DC\uB85C \uD3EC\uCEE4\uC2A4 \uC774\uB3D9\r\n const numbers = formattedValue.replace(/\\D/g, \"\");\r\n if (numbers.length === dateCompleteLength) {\r\n setTimeout(() => {\r\n hourRef.current?.focus();\r\n }, 0);\r\n }\r\n },\r\n [\r\n dateDisplayValue,\r\n prevDateNumbers,\r\n dateFormat,\r\n displayDateSeparator,\r\n dateCompleteLength,\r\n hourValue,\r\n minuteValue,\r\n secondValue,\r\n performValidation,\r\n buildDateTimeString,\r\n emitChange,\r\n ],\r\n );\r\n\r\n // \uD14D\uC2A4\uD2B8 \uB108\uBE44 \uCE21\uC815\r\n const measureTextWidth = useCallback(\r\n (text: string, input: HTMLInputElement): number => {\r\n const style = window.getComputedStyle(input);\r\n const canvas = document.createElement(\"canvas\");\r\n const ctx = canvas.getContext(\"2d\");\r\n if (!ctx) return text.length * 10;\r\n ctx.font = `${style.fontSize} ${style.fontFamily}`;\r\n return ctx.measureText(text).width;\r\n },\r\n [],\r\n );\r\n\r\n // \uB0A0\uC9DC \uD074\uB9AD \uD578\uB4E4\uB7EC (\uC601\uC5ED \uC120\uD0DD)\r\n const handleDateClick = useCallback(\r\n (e: React.MouseEvent<HTMLInputElement>) => {\r\n if (disabled || readonly) return;\r\n\r\n // dateInputRef\uB97C \uC0AC\uC6A9\uD558\uC5EC \uC2E4\uC81C input \uC694\uC18C \uCC38\uC870\r\n const input = dateInputRef.current;\r\n if (!input) return;\r\n\r\n const cursorPos = input.selectionStart || 0;\r\n\r\n if (dateDisplayValue.length > 0) {\r\n // \uD074\uB9AD\uD55C X \uC88C\uD45C\uAC00 \uD14D\uC2A4\uD2B8 \uB108\uBE44\uBCF4\uB2E4 \uD070\uC9C0 \uD655\uC778 (\uC678\uACFD \uD074\uB9AD)\r\n const rect = input.getBoundingClientRect();\r\n const clickX = e.clientX - rect.left;\r\n const paddingLeft = parseFloat(\r\n window.getComputedStyle(input).paddingLeft,\r\n );\r\n const textWidth = measureTextWidth(dateDisplayValue, input);\r\n const isOutsideText = clickX > paddingLeft + textWidth;\r\n\r\n // \uC678\uACFD \uD074\uB9AD\uC774\uAC70\uB098 \uCEE4\uC11C\uAC00 \uAC12 \uAE38\uC774 \uB05D\uC774\uBA74 \uC804\uCCB4 \uC120\uD0DD\r\n if (isOutsideText || cursorPos >= dateDisplayValue.length) {\r\n selectionRangeRef.current = {\r\n start: 0,\r\n end: dateDisplayValue.length,\r\n };\r\n requestAnimationFrame(() => {\r\n input?.setSelectionRange?.(0, dateDisplayValue.length);\r\n });\r\n } else {\r\n // \uB144/\uC6D4/\uC77C \uAC01 \uCE78 \uD074\uB9AD\uC2DC \uD574\uB2F9 \uCE78\uB9CC \uC120\uD0DD\r\n const { start, end } = getSegmentRange(\r\n cursorPos,\r\n dateFormat,\r\n );\r\n const actualEnd = Math.min(end, dateDisplayValue.length);\r\n const actualStart = Math.min(\r\n start,\r\n dateDisplayValue.length,\r\n );\r\n\r\n selectionRangeRef.current = {\r\n start: actualStart,\r\n end: actualEnd,\r\n };\r\n\r\n requestAnimationFrame(() => {\r\n input?.setSelectionRange?.(actualStart, actualEnd);\r\n });\r\n }\r\n } else {\r\n selectionRangeRef.current = null;\r\n }\r\n },\r\n [disabled, readonly, dateDisplayValue, dateFormat, measureTextWidth],\r\n );\r\n\r\n // \uB0A0\uC9DC \uD0A4 \uC785\uB825 \uC81C\uD55C (\uC5F0\uB3C4 \uCCAB \uC790\uB9AC)\r\n const handleDateKeyDown = useCallback(\r\n (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n if (!/^\\d$/.test(e.key)) return;\r\n\r\n const currentNumbers = dateDisplayValue.replace(/\\D/g, \"\");\r\n const numLen = currentNumbers.length;\r\n\r\n if (dateFormat.startsWith(\"YYYY\") && numLen === 0) {\r\n if (e.key !== \"1\" && e.key !== \"2\") {\r\n e.preventDefault();\r\n return;\r\n }\r\n }\r\n },\r\n [dateDisplayValue, dateFormat],\r\n );\r\n\r\n // \uC2DC\uAC04 \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleTimeChange = (groupIndex: number) => {\r\n return createGroupChangeHandler(groupIndex, (newValue, idx) => {\r\n let clampedValue = clampTimeValue(\r\n newValue,\r\n idx === 0 ? \"hour\" : idx === 1 ? \"minute\" : \"second\",\r\n is12Hour,\r\n );\r\n\r\n if (clampedValue !== newValue) {\r\n timeGroups[idx].setValue(clampedValue);\r\n\r\n // clamp\uB85C \uC778\uD574 2\uC790\uB9AC\uAC00 \uB418\uC5C8\uC73C\uBA74 \uB2E4\uC74C \uD544\uB4DC\uB85C \uC774\uB3D9\r\n if (\r\n clampedValue.length === 2 &&\r\n newValue.length === 1 &&\r\n idx < timeGroups.length - 1\r\n ) {\r\n const refs = [hourRef, minuteRef, secondRef];\r\n setTimeout(() => {\r\n refs[idx + 1].current?.focus();\r\n refs[idx + 1].current?.setSelectionRange(0, 0);\r\n }, 0);\r\n }\r\n }\r\n\r\n const newHour = idx === 0 ? clampedValue : hourValue;\r\n const newMinute = idx === 1 ? clampedValue : minuteValue;\r\n const newSecond = idx === 2 ? clampedValue : secondValue;\r\n\r\n performValidation(dateDisplayValue, newHour, newMinute, newSecond);\r\n\r\n const outputValue = buildDateTimeString(\r\n dateDisplayValue,\r\n newHour,\r\n newMinute,\r\n newSecond,\r\n );\r\n emitChange(null, outputValue);\r\n });\r\n };\r\n\r\n // \uC2DC\uAC04 \uD0A4 \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleTimeKeyDown = (groupIndex: number) => {\r\n return createKeyDownHandler(groupIndex, (newValue, idx) => {\r\n const newHour = idx === 0 ? newValue : hourValue;\r\n const newMinute = idx === 1 ? newValue : minuteValue;\r\n const newSecond = idx === 2 ? newValue : secondValue;\r\n\r\n const outputValue = buildDateTimeString(\r\n dateDisplayValue,\r\n newHour,\r\n newMinute,\r\n newSecond,\r\n );\r\n emitChange(null, outputValue);\r\n });\r\n };\r\n\r\n // blur \uD578\uB4E4\uB7EC\r\n const handleBlur = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>) => {\r\n setIsDateFocused(false);\r\n\r\n // 1\uC790\uB9AC \uC2DC\uAC04 \uAC12\uC744 2\uC790\uB9AC\uB85C \uD328\uB529\r\n const paddedHour =\r\n hourValue.length === 1 ? hourValue.padStart(2, \"0\") : hourValue;\r\n const paddedMinute =\r\n minuteValue.length === 1\r\n ? minuteValue.padStart(2, \"0\")\r\n : minuteValue;\r\n const paddedSecond =\r\n secondValue.length === 1\r\n ? secondValue.padStart(2, \"0\")\r\n : secondValue;\r\n\r\n // \uD328\uB529\uB41C \uAC12\uC73C\uB85C \uC0C1\uD0DC \uC5C5\uB370\uC774\uD2B8\r\n if (hourValue.length === 1) setHourValue(paddedHour);\r\n if (minuteValue.length === 1) setMinuteValue(paddedMinute);\r\n if (secondValue.length === 1) setSecondValue(paddedSecond);\r\n\r\n const outputValue = buildDateTimeString(\r\n dateDisplayValue,\r\n paddedHour,\r\n paddedMinute,\r\n paddedSecond,\r\n );\r\n flushOnBlur(e, outputValue);\r\n if (onBlur) {\r\n onBlur(e);\r\n }\r\n },\r\n [\r\n dateDisplayValue,\r\n hourValue,\r\n minuteValue,\r\n secondValue,\r\n buildDateTimeString,\r\n flushOnBlur,\r\n onBlur,\r\n ],\r\n );\r\n\r\n // \uC2DC\uAC04 \uD544\uB4DC blur \uD578\uB4E4\uB7EC (\uD328\uB529 \uCC98\uB9AC \uD3EC\uD568)\r\n const handleTimeBlur = useCallback(() => {\r\n // \uAE30\uC874 createBlurHandler \uB85C\uC9C1 \uC2E4\uD589\r\n const baseBlurHandler = createBlurHandler();\r\n baseBlurHandler();\r\n\r\n // \uC2DC\uAC04 \uADF8\uB8F9 \uB0B4 \uB2E4\uB978 \uD544\uB4DC\uB85C \uD3EC\uCEE4\uC2A4 \uC774\uB3D9 \uC2DC \uD328\uB529\uD558\uC9C0 \uC54A\uC74C\r\n setTimeout(() => {\r\n const activeElement = document.activeElement;\r\n const isStillInTimeGroup =\r\n activeElement === hourRef.current ||\r\n activeElement === minuteRef.current ||\r\n activeElement === secondRef.current;\r\n\r\n if (!isStillInTimeGroup) {\r\n // 1\uC790\uB9AC \uC2DC\uAC04 \uAC12\uC744 2\uC790\uB9AC\uB85C \uD328\uB529\r\n if (hourValue.length === 1) {\r\n setHourValue(hourValue.padStart(2, \"0\"));\r\n }\r\n if (minuteValue.length === 1) {\r\n setMinuteValue(minuteValue.padStart(2, \"0\"));\r\n }\r\n if (secondValue.length === 1) {\r\n setSecondValue(secondValue.padStart(2, \"0\"));\r\n }\r\n }\r\n }, 0);\r\n }, [createBlurHandler, hourValue, minuteValue, secondValue]);\r\n\r\n // focus \uD578\uB4E4\uB7EC\r\n const handleDateFocus = useCallback(() => {\r\n setIsDateFocused(true);\r\n }, []);\r\n\r\n // \uB2EC\uB825\uC5D0\uC11C \uB0A0\uC9DC \uC120\uD0DD\r\n const handleCalendarSelect = useCallback(\r\n (date: Date) => {\r\n const year = date.getFullYear();\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC758 \uACBD\uC6B0 internalYear\uC5D0 \uC800\uC7A5\r\n if (isYearlessFormat) {\r\n setInternalYear(year);\r\n }\r\n\r\n // \uD3EC\uB9F7\uC5D0 \uB9DE\uAC8C \uC22B\uC790 \uBB38\uC790\uC5F4 \uC0DD\uC131\r\n const numbers = dateToNumbers(date, dateFormat);\r\n\r\n const formatted = formatDateValue(numbers, dateFormat);\r\n\r\n setDateDisplayValue(formatted);\r\n setPrevDateNumbers(numbers);\r\n performValidation(formatted, hourValue, minuteValue, secondValue);\r\n\r\n const outputValue = buildDateTimeString(\r\n formatted,\r\n hourValue,\r\n minuteValue,\r\n secondValue,\r\n year,\r\n );\r\n emitChange(null, outputValue, true);\r\n setCalendarOpen(false);\r\n setAnchorEl(null);\r\n\r\n // \uD3EC\uCEE4\uC2A4 \uD574\uC81C (blur)\r\n setTimeout(() => {\r\n dateInputRef.current?.blur();\r\n hourRef.current?.blur();\r\n minuteRef.current?.blur();\r\n secondRef.current?.blur();\r\n }, 0);\r\n },\r\n [\r\n dateFormat,\r\n isYearlessFormat,\r\n hourValue,\r\n minuteValue,\r\n secondValue,\r\n performValidation,\r\n buildDateTimeString,\r\n emitChange,\r\n ],\r\n );\r\n\r\n // \uB2EC\uB825 \uD31D\uC624\uBC84 \uB0B4 \uC2DC\uAC04 \uC120\uD0DD \uD578\uB4E4\uB7EC\r\n const handleCalendarTimeChange = useCallback(\r\n (hour: number, minute: number, second?: number) => {\r\n const h = String(hour).padStart(2, \"0\");\r\n const m = String(minute).padStart(2, \"0\");\r\n const s =\r\n second !== undefined ? String(second).padStart(2, \"0\") : \"\";\r\n\r\n setHourValue(h);\r\n setMinuteValue(m);\r\n if (hasSecond && s) {\r\n setSecondValue(s);\r\n }\r\n\r\n performValidation(dateDisplayValue, h, m, s);\r\n\r\n const outputValue = buildDateTimeString(dateDisplayValue, h, m, s);\r\n emitChange(null, outputValue, true);\r\n },\r\n [\r\n hasSecond,\r\n dateDisplayValue,\r\n performValidation,\r\n buildDateTimeString,\r\n emitChange,\r\n ],\r\n );\r\n\r\n // \uC120\uD0DD\uB41C \uB0A0\uC9DC \uACC4\uC0B0 (\uB2EC\uB825\uC6A9)\r\n const selectedDate = useMemo((): Date | null => {\r\n const parsed = parseDateWithInternalYear(\r\n dateDisplayValue,\r\n dateFormat,\r\n internalYear,\r\n );\r\n if (!parsed) return null;\r\n return new Date(parsed.year, parsed.month - 1, parsed.day);\r\n }, [dateDisplayValue, dateFormat, internalYear]);\r\n\r\n // \uB2EC\uB825\uC5D0 \uC804\uB2EC\uD560 \uB0A0\uC9DC \uACC4\uC0B0\r\n const calendarSelectedDate = useMemo((): Date => {\r\n // \uC120\uD0DD\uB41C \uB0A0\uC9DC\uAC00 \uC788\uC73C\uBA74 \uADF8\uB300\uB85C \uC0AC\uC6A9\r\n if (selectedDate) return selectedDate;\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC758 \uACBD\uC6B0 internalYear \uB610\uB294 \uD604\uC7AC \uC5F0\uB3C4 \uC0AC\uC6A9\r\n if (isYearlessFormat) {\r\n const yearToUse = internalYear || new Date().getFullYear();\r\n const parsed = parseDateWithInternalYear(\r\n dateDisplayValue,\r\n dateFormat,\r\n yearToUse,\r\n );\r\n if (\r\n parsed &&\r\n parsed.month >= 1 &&\r\n parsed.month <= 12 &&\r\n parsed.day >= 1 &&\r\n parsed.day <= 31\r\n ) {\r\n return new Date(yearToUse, parsed.month - 1, parsed.day);\r\n }\r\n return new Date(\r\n yearToUse,\r\n new Date().getMonth(),\r\n new Date().getDate(),\r\n );\r\n }\r\n\r\n return new Date();\r\n }, [\r\n selectedDate,\r\n dateDisplayValue,\r\n dateFormat,\r\n isYearlessFormat,\r\n internalYear,\r\n ]);\r\n\r\n // \uC2A4\uD0C0\uC77C\r\n const invalidStyles: SxProps<Theme> =\r\n isInvalid && invalidBorderColor\r\n ? {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": { borderColor: invalidBorderColor },\r\n \"&:hover fieldset\": { borderColor: invalidBorderColor },\r\n \"&.Mui-focused fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n },\r\n }\r\n : {};\r\n\r\n const readonlyStyles: SxProps<Theme> = readonly\r\n ? {\r\n pointerEvents: \"none\",\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n const noBorderStyle: SxProps<Theme> = {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": { border: \"none\" },\r\n \"&:hover fieldset\": { border: \"none\" },\r\n \"&.Mui-focused fieldset\": { border: \"none\" },\r\n },\r\n };\r\n\r\n // \uB0A0\uC9DC \uD544\uB4DC width \uACC4\uC0B0\r\n // placeholder '____-__-__' \uC5D0\uC11C \uBC11\uC904\uC740 \uC22B\uC790\uC640 \uBE44\uC2B7\uD55C \uB108\uBE44\r\n const dateFieldWidth = useMemo(() => {\r\n // dateMaxLength = 10 (YYYY-MM-DD)\r\n return `${dateMaxLength}ch`;\r\n }, [dateMaxLength]);\r\n\r\n // \uB0A0\uC9DC placeholder (____-__-__)\r\n const datePlaceholder = useMemo(() => {\r\n return formatToPlaceholder(dateFormat);\r\n }, [dateFormat]);\r\n\r\n // \uC2DC\uAC04 \uD544\uB4DC width (TimeTextField\uC640 \uB3D9\uC77C\uD558\uAC8C)\r\n const timeFieldWidth = \"2.5ch\";\r\n\r\n // \uC2DC\uAC04 \uADF8\uB8F9 \uB80C\uB354\uB9C1\r\n const renderTimeGroup = (\r\n groupIndex: number,\r\n groupValue: string,\r\n placeholder: string,\r\n ) => {\r\n const isFocusedGroup = focusedGroup === groupIndex;\r\n const showCursor = cursorVisible && isFocusedGroup && !inputComplete;\r\n const refs = [hourRef, minuteRef, secondRef];\r\n\r\n return (\r\n <Box\r\n key={groupIndex}\r\n onMouseDown={createMouseDownHandler(groupIndex)}\r\n onClick={createClickHandler(groupIndex)}\r\n sx={{\r\n position: \"relative\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n }}\r\n >\r\n <TextField\r\n inputRef={refs[groupIndex]}\r\n value={groupValue}\r\n onChange={handleTimeChange(groupIndex)}\r\n onKeyDown={handleTimeKeyDown(groupIndex)}\r\n onFocus={createFocusHandler(groupIndex)}\r\n onBlur={handleTimeBlur}\r\n disabled={disabled}\r\n size={size}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n placeholder={placeholder}\r\n variant=\"outlined\"\r\n sx={{\r\n width: timeFieldWidth,\r\n maxWidth: timeFieldWidth,\r\n minWidth: timeFieldWidth,\r\n ...noBorderStyle,\r\n \"& .MuiInputBase-root\": {\r\n width: timeFieldWidth,\r\n maxWidth: timeFieldWidth,\r\n minWidth: timeFieldWidth,\r\n },\r\n \"& .MuiInputBase-input\": {\r\n width: timeFieldWidth,\r\n minWidth: timeFieldWidth,\r\n maxWidth: timeFieldWidth,\r\n textAlign: \"left\",\r\n caretColor: \"transparent\",\r\n },\r\n \"& .MuiInputBase-input::placeholder\": {\r\n color: \"rgba(0, 0, 0, 0.3)\",\r\n opacity: 1,\r\n },\r\n }}\r\n slotProps={{\r\n input: { readOnly: readonly },\r\n htmlInput: {\r\n maxLength: 2,\r\n inputMode: \"numeric\",\r\n style: { padding: \"0 2px\", textAlign: \"left\" },\r\n },\r\n }}\r\n />\r\n {showCursor && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n bottom: size === \"small\" ? 1 : 3,\r\n left: `calc(2px + ${getCursorLeft(groupIndex)}px)`,\r\n width: cursorWidth,\r\n height: cursorHeight,\r\n backgroundColor: \"text.primary\",\r\n animation: \"blink 1s step-end infinite\",\r\n \"@keyframes blink\": {\r\n \"0%, 100%\": { opacity: 1 },\r\n \"50%\": { opacity: 0 },\r\n },\r\n pointerEvents: \"none\",\r\n }}\r\n />\r\n )}\r\n </Box>\r\n );\r\n };\r\n\r\n // \uC2DC\uAC04 \uD544\uB4DC \uD45C\uC2DC \uC5EC\uBD80 (\uAC12\uC774 \uC788\uAC70\uB098 \uD3EC\uCEE4\uC2A4\uAC00 \uC788\uC744 \uB54C\uB9CC)\r\n const hasAnyValue =\r\n dateDisplayValue.length > 0 ||\r\n hourValue.length > 0 ||\r\n minuteValue.length > 0 ||\r\n secondValue.length > 0;\r\n const showTimeFields =\r\n hasAnyValue || isDateFocused || focusedGroup !== null;\r\n\r\n // endAdornment (\uC2DC\uAC04 \uD544\uB4DC + \uC544\uC774\uCF58)\r\n const endAdornmentElement = (\r\n <InputAdornment\r\n position=\"end\"\r\n sx={{ ml: 0, mr: size === \"small\" ? -0.5 : 0, flexGrow: 1 }}\r\n >\r\n <Box sx={{ display: \"flex\", alignItems: \"center\", width: \"100%\" }}>\r\n {/* \uC2DC\uAC04 \uD544\uB4DC\uB4E4 - \uAC12\uC774 \uC788\uAC70\uB098 \uD3EC\uCEE4\uC2A4\uAC00 \uC788\uC744 \uB54C\uB9CC \uD45C\uC2DC */}\r\n {showTimeFields && (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n flexShrink: 0,\r\n }}\r\n >\r\n {renderTimeGroup(0, hourValue, \"00\")}\r\n <ColonBox size={size} />\r\n {renderTimeGroup(1, minuteValue, \"00\")}\r\n {hasSecond && (\r\n <>\r\n <ColonBox size={size} />\r\n {renderTimeGroup(2, secondValue, \"00\")}\r\n </>\r\n )}\r\n </Box>\r\n )}\r\n\r\n {/* Spacer - \uC544\uC774\uCF58\uC744 \uC624\uB978\uCABD \uB05D\uC73C\uB85C \uBC00\uAE30, \uD074\uB9AD \uC2DC \uB0A0\uC9DC \uD544\uB4DC \uD3EC\uCEE4\uC2A4 */}\r\n <Box\r\n sx={{ flexGrow: 1, height: \"100%\", minHeight: 24 }}\r\n onClick={() => {\r\n if (!disabled && !readonly) {\r\n dateInputRef.current?.focus();\r\n }\r\n }}\r\n />\r\n\r\n {/* \uC544\uC774\uCF58 \uB610\uB294 \uB3D9\uC77C \uD06C\uAE30 \uBE48 \uACF5\uAC04 */}\r\n {calendarIcon &&\r\n (readonly ? (\r\n // readonly\uC77C \uB54C \uC544\uC774\uCF58\uACFC \uB3D9\uC77C\uD55C \uD06C\uAE30\uC758 \uBE48 \uACF5\uAC04\r\n <Box\r\n sx={{\r\n width: size === \"small\" ? 28 : 32,\r\n height: size === \"small\" ? 28 : 32,\r\n ml: 0.5,\r\n }}\r\n />\r\n ) : (\r\n <IconButton\r\n onClick={(e) => {\r\n setAnchorEl(e.currentTarget);\r\n setCalendarOpen(true);\r\n }}\r\n edge=\"end\"\r\n size=\"small\"\r\n disabled={disabled}\r\n sx={{\r\n ml: 0.5,\r\n color: \"text.secondary\",\r\n opacity: 0.5,\r\n transition: \"opacity 0.2s, color 0.2s\",\r\n \"&:hover\": {\r\n opacity: 1,\r\n color: \"text.primary\",\r\n },\r\n }}\r\n >\r\n <CalendarIcon size={size === \"small\" ? 16 : 18} />\r\n </IconButton>\r\n ))}\r\n </Box>\r\n </InputAdornment>\r\n );\r\n\r\n return (\r\n <>\r\n <TextField\r\n inputRef={dateInputRef}\r\n value={dateDisplayValue}\r\n onChange={handleDateChange}\r\n onClick={handleDateClick}\r\n onKeyDown={handleDateKeyDown}\r\n onFocus={handleDateFocus}\r\n onBlur={handleBlur}\r\n label={label}\r\n placeholder={datePlaceholder}\r\n disabled={disabled}\r\n size={size}\r\n fullWidth={fullWidth}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n className={className}\r\n id={id}\r\n sx={{\r\n ...invalidStyles,\r\n ...readonlyStyles,\r\n ...sx,\r\n \"& .MuiInputBase-input\": {\r\n width: dateFieldWidth,\r\n minWidth: dateFieldWidth,\r\n },\r\n }}\r\n slotProps={{\r\n input: {\r\n readOnly: readonly,\r\n endAdornment: endAdornmentElement,\r\n },\r\n htmlInput: {\r\n maxLength: dateMaxLength,\r\n inputMode: \"numeric\",\r\n },\r\n }}\r\n />\r\n\r\n {/* Calendar Popup */}\r\n <DateTimePicker\r\n open={calendarOpen}\r\n anchorEl={anchorEl}\r\n onClose={() => {\r\n setCalendarOpen(false);\r\n setAnchorEl(null);\r\n }}\r\n anchorOrigin={{\r\n vertical: \"bottom\",\r\n horizontal: \"right\",\r\n }}\r\n transformOrigin={{\r\n vertical: \"top\",\r\n horizontal: \"right\",\r\n }}\r\n selectedDate={calendarSelectedDate}\r\n onDateChange={handleCalendarSelect}\r\n timeValue={{\r\n hour: hourValue,\r\n minute: minuteValue,\r\n second: hasSecond ? secondValue : undefined,\r\n }}\r\n onTimeChange={(hour, minute, second) => {\r\n handleCalendarTimeChange(\r\n parseInt(hour, 10),\r\n parseInt(minute, 10),\r\n second ? parseInt(second, 10) : undefined,\r\n );\r\n }}\r\n minDate={minDateTime}\r\n maxDate={maxDateTime}\r\n holidays={holidays}\r\n styles={{ selectedColor, holidayColor }}\r\n showToday={showToday}\r\n timeFormat={\r\n hasSecond\r\n ? is12Hour\r\n ? \"hh:mm:ss\"\r\n : \"HH:mm:ss\"\r\n : is12Hour\r\n ? \"hh:mm\"\r\n : \"HH:mm\"\r\n }\r\n minTime={minTime}\r\n maxTime={maxTime}\r\n minuteStep={minuteStep}\r\n secondStep={secondStep}\r\n hideDisabledTime={hideDisabledTime}\r\n />\r\n </>\r\n );\r\n});\r\n\r\nconst DateTimeTextFieldWithForm = forwardRef<\r\n HTMLDivElement,\r\n DateTimeTextFieldProps\r\n>(function DateTimeTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"DateTimeTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"DateTimeTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <DateTimeTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const DateTimeTextField = forwardRef<\r\n HTMLDivElement,\r\n DateTimeTextFieldProps\r\n>(function DateTimeTextField(props, ref) {\r\n if (props.form) {\r\n return <DateTimeTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <DateTimeTextFieldBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * BizNumTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n useRef,\r\n useMemo,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField, Box, IconButton } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport { InfoAlert } from \"@ehfuse/alerts\";\r\nimport type { BizNumTextFieldProps } from \"./types\";\r\nimport { DashIcon, CopyIcon } from \"./icons\";\r\nimport { useGroupedInput, GroupConfig } from \"./hooks/useGroupedInput\";\r\nimport { useDebouncedEmit } from \"./hooks\";\r\nimport { GroupedInputWrapper } from \"./components\";\r\nimport { validateBusinessNumber } from \"./utils\";\r\n\r\nconst BizNumTextFieldBase = forwardRef<HTMLDivElement, BizNumTextFieldProps>(\r\n function BizNumTextFieldBase(\r\n {\r\n label,\r\n includeDash = false,\r\n validate = false,\r\n copyIcon = true,\r\n fontSize,\r\n fontColor,\r\n fontFamily,\r\n onValidationChange,\r\n invalidBorderColor,\r\n debounce,\r\n readonly,\r\n sx,\r\n value,\r\n onChange,\r\n size,\r\n disabled,\r\n className,\r\n id,\r\n autoFocus,\r\n name,\r\n fullWidth = false,\r\n },\r\n ref,\r\n ) {\r\n // 3\uAC1C \uADF8\uB8F9: 000-00-00000\r\n const [group1, setGroup1] = useState(\"\"); // 3\uC790\uB9AC\r\n const [group2, setGroup2] = useState(\"\"); // 2\uC790\uB9AC\r\n const [group3, setGroup3] = useState(\"\"); // 5\uC790\uB9AC\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n const [isInternalChange, setIsInternalChange] = useState(false);\r\n\r\n const ref1 = useRef<HTMLInputElement>(null);\r\n const ref2 = useRef<HTMLInputElement>(null);\r\n const ref3 = useRef<HTMLInputElement>(null);\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n // \uC678\uBD80 ref\uC640 \uB0B4\uBD80 containerRef \uBCD1\uD569\r\n useImperativeHandle(ref, () => containerRef.current!, []);\r\n\r\n // \uADF8\uB8F9\uBCC4 \uCD5C\uB300 \uAE38\uC774\r\n const maxLengths = [3, 2, 5];\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange: debouncedEmit, flushOnBlur } = useDebouncedEmit({\r\n name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n // \uD3F0\uD2B8 \uD06C\uAE30 \uACC4\uC0B0\r\n const defaultFontSize = size === \"small\" ? 16 : 18;\r\n const computedFontSize = fontSize\r\n ? typeof fontSize === \"number\"\r\n ? fontSize\r\n : parseFloat(fontSize) *\r\n (fontSize.toString().includes(\"rem\") ? 16 : 1)\r\n : defaultFontSize;\r\n\r\n // useGroupedInput \uD6C5 \uC0AC\uC6A9\r\n const groups: GroupConfig[] = useMemo(\r\n () => [\r\n { maxLength: 3, ref: ref1, value: group1, setValue: setGroup1 },\r\n { maxLength: 2, ref: ref2, value: group2, setValue: setGroup2 },\r\n { maxLength: 5, ref: ref3, value: group3, setValue: setGroup3 },\r\n ],\r\n [group1, group2, group3],\r\n );\r\n\r\n const {\r\n focusedGroup,\r\n setFocusedGroup,\r\n cursorVisible,\r\n inputComplete,\r\n getCursorLeft,\r\n createMouseDownHandler,\r\n createClickHandler,\r\n createFocusHandler,\r\n createBlurHandler,\r\n createKeyDownHandler,\r\n createChangeHandler: createGroupChangeHandler,\r\n } = useGroupedInput({\r\n groups,\r\n fontFamily,\r\n fontSize: computedFontSize,\r\n disabled,\r\n readonly,\r\n });\r\n\r\n // value prop \uBCC0\uACBD \uC2DC \uB0B4\uBD80 \uC0C1\uD0DC \uB3D9\uAE30\uD654\r\n useEffect(() => {\r\n if (isInternalChange) {\r\n setIsInternalChange(false);\r\n return;\r\n }\r\n\r\n if (value !== undefined && value !== null) {\r\n const numbers = String(value).replace(/\\D/g, \"\").slice(0, 10);\r\n setGroup1(numbers.slice(0, 3));\r\n setGroup2(numbers.slice(3, 5));\r\n setGroup3(numbers.slice(5, 10));\r\n } else {\r\n setGroup1(\"\");\r\n setGroup2(\"\");\r\n setGroup3(\"\");\r\n }\r\n }, [value, isInternalChange]);\r\n\r\n // \uC804\uCCB4 \uBC88\uD638 \uAC00\uC838\uC624\uAE30\r\n const getFullNumber = useCallback(() => {\r\n return group1 + group2 + group3;\r\n }, [group1, group2, group3]);\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uBC0F onChange \uD638\uCD9C\r\n const emitChange = useCallback(\r\n (g1: string, g2: string, g3: string) => {\r\n const fullNumber = g1 + g2 + g3;\r\n const isComplete = fullNumber.length === 10;\r\n let isValid = isComplete;\r\n\r\n if (validate && isComplete) {\r\n isValid = validateBusinessNumber(fullNumber);\r\n }\r\n\r\n setIsInvalid(isComplete && !isValid);\r\n\r\n if (onValidationChange) {\r\n onValidationChange(isValid);\r\n }\r\n\r\n setIsInternalChange(true);\r\n const outputValue = includeDash\r\n ? `${g1}-${g2}-${g3}`\r\n : fullNumber;\r\n debouncedEmit(null, outputValue);\r\n },\r\n [validate, onValidationChange, includeDash, debouncedEmit],\r\n );\r\n\r\n // \uC785\uB825 \uD578\uB4E4\uB7EC (\uD6C5\uC758 \uD578\uB4E4\uB7EC + \uCEE4\uC2A4\uD140 \uB85C\uC9C1)\r\n const handleChange = (groupIndex: number) => {\r\n return createGroupChangeHandler(groupIndex, (newValue, idx) => {\r\n const newValues = [group1, group2, group3];\r\n newValues[idx] = newValue;\r\n emitChange(newValues[0], newValues[1], newValues[2]);\r\n });\r\n };\r\n\r\n // \uD0A4 \uC785\uB825 \uD578\uB4E4\uB7EC (\uD6C5\uC758 \uD578\uB4E4\uB7EC + \uCEE4\uC2A4\uD140 \uB85C\uC9C1)\r\n const handleKeyDown = (groupIndex: number) => {\r\n return createKeyDownHandler(groupIndex, (newValue, idx) => {\r\n const newValues = [group1, group2, group3];\r\n newValues[idx] = newValue;\r\n emitChange(newValues[0], newValues[1], newValues[2]);\r\n });\r\n };\r\n\r\n // blur \uD578\uB4E4\uB7EC\r\n const handleBlur = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>) => {\r\n const blurHandler = createBlurHandler();\r\n blurHandler();\r\n\r\n const fullNumber = getFullNumber();\r\n const outputValue = includeDash\r\n ? `${group1}-${group2}-${group3}`\r\n : fullNumber;\r\n setIsInternalChange(true);\r\n flushOnBlur(e, outputValue);\r\n },\r\n [\r\n createBlurHandler,\r\n getFullNumber,\r\n includeDash,\r\n group1,\r\n group2,\r\n group3,\r\n flushOnBlur,\r\n ],\r\n );\r\n\r\n // \uBCF5\uC0AC \uD578\uB4E4\uB7EC\r\n const handleCopy = useCallback(() => {\r\n const fullNumber = getFullNumber();\r\n const copyValue = includeDash\r\n ? `${group1}-${group2}-${group3}`\r\n : fullNumber;\r\n navigator.clipboard.writeText(copyValue);\r\n InfoAlert(\"\uC0AC\uC5C5\uC790\uBC88\uD638\uAC00 \uBCF5\uC0AC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\");\r\n }, [getFullNumber, includeDash, group1, group2, group3]);\r\n\r\n // \uD544\uB4DC \uB108\uBE44\r\n const fieldWidths = [\"3ch\", \"2ch\", \"5.5ch\"];\r\n\r\n // \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C \uD06C\uAE30\r\n const cursorWidth = \"0.6em\";\r\n const cursorHeight = \"1px\";\r\n\r\n // TextField border \uC81C\uAC70 \uC2A4\uD0C0\uC77C\r\n const noBorderStyle: SxProps<Theme> = {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": { border: \"none\" },\r\n \"&:hover fieldset\": { border: \"none\" },\r\n \"&.Mui-focused fieldset\": { border: \"none\" },\r\n },\r\n };\r\n\r\n // \uADF8\uB8F9 \uB80C\uB354\uB9C1\r\n const renderGroup = (\r\n groupIndex: number,\r\n groupValue: string,\r\n placeholder: string,\r\n ) => {\r\n const isFocused = focusedGroup === groupIndex;\r\n const showCursor = cursorVisible && isFocused && !inputComplete;\r\n const refs = [ref1, ref2, ref3];\r\n\r\n return (\r\n <Box\r\n onMouseDown={createMouseDownHandler(groupIndex)}\r\n onClick={createClickHandler(groupIndex)}\r\n sx={{\r\n position: \"relative\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n }}\r\n >\r\n <TextField\r\n inputRef={refs[groupIndex]}\r\n value={groupValue}\r\n onChange={handleChange(groupIndex)}\r\n onKeyDown={handleKeyDown(groupIndex)}\r\n onFocus={createFocusHandler(groupIndex)}\r\n onBlur={handleBlur}\r\n disabled={disabled}\r\n size={size}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n placeholder={placeholder}\r\n variant=\"outlined\"\r\n autoFocus={groupIndex === 0 && autoFocus}\r\n sx={{\r\n width: \"auto\",\r\n minWidth: 0,\r\n ...noBorderStyle,\r\n \"& .MuiInputBase-root\": { width: \"auto\" },\r\n \"& .MuiInputBase-input\": {\r\n width: fieldWidths[groupIndex],\r\n userSelect: \"none\",\r\n ...(fontSize && { fontSize }),\r\n ...(fontColor && { color: fontColor }),\r\n ...(fontFamily && { fontFamily }),\r\n },\r\n \"& .MuiInputBase-input::placeholder\": {\r\n color: \"rgba(0, 0, 0, 0.2)\",\r\n opacity: 1,\r\n },\r\n }}\r\n slotProps={{\r\n input: {\r\n readOnly: readonly,\r\n },\r\n htmlInput: {\r\n maxLength: maxLengths[groupIndex],\r\n inputMode: \"numeric\",\r\n style: { textAlign: \"left\", padding: \"0 4px\" },\r\n },\r\n }}\r\n />\r\n {/* \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C */}\r\n {showCursor && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n bottom: size === \"small\" ? 0 : -2,\r\n left: `calc(4px + ${getCursorLeft(\r\n groupIndex,\r\n )}px)`,\r\n width: cursorWidth,\r\n height: cursorHeight,\r\n backgroundColor: fontColor || \"text.primary\",\r\n animation: \"blink 1s step-end infinite\",\r\n \"@keyframes blink\": {\r\n \"0%, 100%\": { opacity: 1 },\r\n \"50%\": { opacity: 0 },\r\n },\r\n pointerEvents: \"none\",\r\n }}\r\n />\r\n )}\r\n </Box>\r\n );\r\n };\r\n\r\n // Dash \uB798\uD37C \uCEF4\uD3EC\uB10C\uD2B8\r\n const Dash = () => (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n color: \"text.secondary\",\r\n mx: size === \"small\" ? 0.25 : 0.5,\r\n userSelect: \"none\",\r\n }}\r\n >\r\n <DashIcon size={size} />\r\n </Box>\r\n );\r\n\r\n // \uD074\uB9AD \uC2DC \uD3EC\uCEE4\uC2A4\uD560 ref \uACB0\uC815 (\uC678\uACFD \uD074\uB9AD \uC2DC \uCCAB \uBC88\uC9F8 \uCE78\uC73C\uB85C)\r\n const getTargetRefOnClick = useCallback(() => {\r\n return { ref: ref1, groupIndex: 0 };\r\n }, []);\r\n\r\n return (\r\n <Box\r\n ref={containerRef}\r\n sx={{\r\n ...(fullWidth && { width: \"100%\" }),\r\n ...sx,\r\n }}\r\n className={className}\r\n >\r\n <GroupedInputWrapper\r\n label={label}\r\n size={size}\r\n disabled={disabled}\r\n readonly={readonly}\r\n focusedGroup={focusedGroup}\r\n setFocusedGroup={setFocusedGroup}\r\n hasValue={getFullNumber().length > 0}\r\n isInvalid={isInvalid}\r\n invalidBorderColor={invalidBorderColor}\r\n inputRefs={[ref1, ref2, ref3]}\r\n getTargetRefOnClick={getTargetRefOnClick}\r\n fullWidth={fullWidth}\r\n id={id}\r\n contentSx={{\r\n pr:\r\n copyIcon && getFullNumber().length === 10\r\n ? 0.5\r\n : 1.5,\r\n }}\r\n >\r\n {renderGroup(0, group1, \"000\")}\r\n <Dash />\r\n {renderGroup(1, group2, \"00\")}\r\n <Dash />\r\n {renderGroup(2, group3, \"00000\")}\r\n {copyIcon && getFullNumber().length === 10 && (\r\n <>\r\n <Box sx={{ flexGrow: 1 }} />\r\n <IconButton\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n handleCopy();\r\n }}\r\n onMouseDown={(e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n }}\r\n disabled={disabled}\r\n size={size}\r\n sx={{\r\n p: size === \"small\" ? 0.5 : 1,\r\n mr: 0.5,\r\n color: \"text.secondary\",\r\n \"&:hover\": {\r\n color: \"text.primary\",\r\n },\r\n }}\r\n >\r\n <CopyIcon size={size} />\r\n </IconButton>\r\n </>\r\n )}\r\n </GroupedInputWrapper>\r\n </Box>\r\n );\r\n },\r\n);\r\n\r\nconst BizNumTextFieldWithForm = forwardRef<\r\n HTMLDivElement,\r\n BizNumTextFieldProps\r\n>(function BizNumTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"BizNumTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"BizNumTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name) as string | undefined;\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <BizNumTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const BizNumTextField = forwardRef<HTMLDivElement, BizNumTextFieldProps>(\r\n function BizNumTextField(props, ref) {\r\n if (props.form) {\r\n return <BizNumTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <BizNumTextFieldBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * CardNumTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n useRef,\r\n useMemo,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField, Box } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport type { CardNumTextFieldProps } from \"./types\";\r\nimport { useDebouncedEmit } from \"./hooks\";\r\nimport { useGroupedInput, GroupConfig } from \"./hooks/useGroupedInput\";\r\nimport { GroupedInputWrapper } from \"./components\";\r\nimport {\r\n DashIcon,\r\n CardIcon,\r\n VisaIcon,\r\n MastercardIcon,\r\n AmexIcon,\r\n JcbIcon,\r\n DinersIcon,\r\n DiscoverIcon,\r\n UnionPayIcon,\r\n BcIcon,\r\n} from \"./icons\";\r\nimport { CardBrand, validateCardNumber, detectCardBrand } from \"./utils\";\r\n\r\nconst CardNumTextFieldBase = forwardRef<HTMLDivElement, CardNumTextFieldProps>(\r\n function CardNumTextFieldBase(\r\n {\r\n label,\r\n maskColor = \"rgba(0, 0, 0, 0.7)\",\r\n fontSize,\r\n fontColor,\r\n fontFamily,\r\n onChange,\r\n onValidationChange,\r\n onCardBrandChange,\r\n invalidBorderColor,\r\n validate = false,\r\n debounce,\r\n readonly,\r\n sx,\r\n value,\r\n size,\r\n disabled,\r\n logoIcon = true,\r\n name = \"\",\r\n className,\r\n id,\r\n fullWidth = false,\r\n },\r\n ref,\r\n ) {\r\n // 4\uAC1C \uADF8\uB8F9 \uAC01\uAC01\uC758 \uAC12\r\n const [group1, setGroup1] = useState(\"\"); // \uCCAB 4\uC790\uB9AC (\uBCF4\uC784)\r\n const [group2, setGroup2] = useState(\"\"); // \uB458\uC9F8 4\uC790\uB9AC (\uB9C8\uC2A4\uD0B9)\r\n const [group3, setGroup3] = useState(\"\"); // \uC14B\uC9F8 4\uC790\uB9AC (\uB9C8\uC2A4\uD0B9)\r\n const [group4, setGroup4] = useState(\"\"); // \uB137\uC9F8 4\uC790\uB9AC (\uBCF4\uC784)\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n const [isInternalChange, setIsInternalChange] = useState(false);\r\n const [cardBrand, setCardBrand] = useState<CardBrand>(null);\r\n // \uB9C8\uC9C0\uB9C9 \uC785\uB825\uB41C \uADF8\uB8F9\uACFC \uC778\uB371\uC2A4 \uCD94\uC801 (\uB9C8\uC2A4\uD0B9 \uADF8\uB8F9\uC5D0\uC11C \uB9C8\uC9C0\uB9C9 \uC22B\uC790 \uD45C\uC2DC\uC6A9)\r\n const [lastInputInfo, setLastInputInfo] = useState<{\r\n groupIndex: number;\r\n charIndex: number;\r\n } | null>(null);\r\n\r\n const ref1 = useRef<HTMLInputElement>(null);\r\n const ref2 = useRef<HTMLInputElement>(null);\r\n const ref3 = useRef<HTMLInputElement>(null);\r\n const ref4 = useRef<HTMLInputElement>(null);\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n // \uC678\uBD80 ref\uC640 \uB0B4\uBD80 containerRef \uBCD1\uD569\r\n useImperativeHandle(ref, () => containerRef.current!, []);\r\n\r\n // \uD3F0\uD2B8 \uD06C\uAE30 \uACC4\uC0B0\r\n const defaultFontSize = size === \"small\" ? 16 : 18;\r\n const computedFontSize = fontSize\r\n ? typeof fontSize === \"number\"\r\n ? fontSize\r\n : parseFloat(fontSize) *\r\n (fontSize.toString().includes(\"rem\") ? 16 : 1)\r\n : defaultFontSize;\r\n\r\n // useGroupedInput \uD6C5 \uC0AC\uC6A9\r\n const groups: GroupConfig[] = useMemo(\r\n () => [\r\n { maxLength: 4, ref: ref1, value: group1, setValue: setGroup1 },\r\n { maxLength: 4, ref: ref2, value: group2, setValue: setGroup2 },\r\n { maxLength: 4, ref: ref3, value: group3, setValue: setGroup3 },\r\n { maxLength: 4, ref: ref4, value: group4, setValue: setGroup4 },\r\n ],\r\n [group1, group2, group3, group4],\r\n );\r\n\r\n const {\r\n focusedGroup,\r\n setFocusedGroup,\r\n cursorVisible,\r\n cursorPosRef,\r\n inputComplete,\r\n renderTrigger,\r\n getCursorLeft,\r\n createMouseDownHandler,\r\n createClickHandler,\r\n createFocusHandler,\r\n createBlurHandler,\r\n createKeyDownHandler,\r\n createChangeHandler: createGroupChangeHandler,\r\n } = useGroupedInput({\r\n groups,\r\n fontSize: computedFontSize,\r\n disabled,\r\n readonly,\r\n });\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange, flushOnBlur } = useDebouncedEmit({\r\n name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n // \uC804\uCCB4 \uCE74\uB4DC\uBC88\uD638 \uC870\uD569\r\n const getFullNumber = useCallback(() => {\r\n return group1 + group2 + group3 + group4;\r\n }, [group1, group2, group3, group4]);\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uBC0F onChange \uD638\uCD9C\r\n const emitCardChange = useCallback(\r\n (g1: string, g2: string, g3: string, g4: string) => {\r\n const fullValue = g1 + g2 + g3 + g4;\r\n const isComplete = fullValue.length === 16;\r\n let isValid = isComplete;\r\n\r\n // validate\uAC00 true\uC77C \uB54C\uB9CC Luhn \uC54C\uACE0\uB9AC\uC998 \uC801\uC6A9\r\n if (validate && isComplete) {\r\n isValid = validateCardNumber(fullValue);\r\n }\r\n\r\n setIsInvalid(isComplete && !isValid);\r\n\r\n if (onValidationChange) {\r\n onValidationChange(isValid);\r\n }\r\n\r\n // \uCE74\uB4DC \uBE0C\uB79C\uB4DC \uAC10\uC9C0\r\n const brand = detectCardBrand(fullValue);\r\n setCardBrand(brand);\r\n if (onCardBrandChange) {\r\n onCardBrandChange(brand);\r\n }\r\n\r\n setIsInternalChange(true);\r\n emitChange(null, fullValue, true);\r\n },\r\n [validate, onValidationChange, onCardBrandChange, emitChange],\r\n );\r\n\r\n // value prop \uBCC0\uACBD \uC2DC \uB0B4\uBD80 \uC0C1\uD0DC \uB3D9\uAE30\uD654\r\n useEffect(() => {\r\n if (isInternalChange) {\r\n setIsInternalChange(false);\r\n return;\r\n }\r\n\r\n // uncontrolled \uC0AC\uC6A9 \uC2DC \uB3D9\uAE30\uD654 \uC2A4\uD0B5\r\n if (value === undefined) {\r\n return;\r\n }\r\n\r\n if (value !== null) {\r\n const numbers = String(value).replace(/\\D/g, \"\").slice(0, 16);\r\n setGroup1(numbers.slice(0, 4));\r\n setGroup2(numbers.slice(4, 8));\r\n setGroup3(numbers.slice(8, 12));\r\n setGroup4(numbers.slice(12, 16));\r\n } else {\r\n setGroup1(\"\");\r\n setGroup2(\"\");\r\n setGroup3(\"\");\r\n setGroup4(\"\");\r\n }\r\n }, [value, isInternalChange]);\r\n\r\n // \uC785\uB825 \uD578\uB4E4\uB7EC (\uD6C5\uC758 \uD578\uB4E4\uB7EC + \uCEE4\uC2A4\uD140 \uB85C\uC9C1)\r\n const handleChange = (groupIndex: number) => {\r\n return createGroupChangeHandler(groupIndex, (newValue, idx) => {\r\n const newValues = [group1, group2, group3, group4];\r\n newValues[idx] = newValue;\r\n\r\n // \uB9C8\uC2A4\uD0B9 \uADF8\uB8F9(1, 2)\uC5D0\uC11C \uC785\uB825 \uC2DC \uB9C8\uC9C0\uB9C9 \uC785\uB825 \uBB38\uC790 \uCD94\uC801\r\n if ((idx === 1 || idx === 2) && newValue.length > 0) {\r\n setLastInputInfo({\r\n groupIndex: idx,\r\n charIndex: newValue.length - 1,\r\n });\r\n // \uC7A0\uC2DC \uD6C4 \uC228\uAE40 (500ms)\r\n setTimeout(() => {\r\n setLastInputInfo(null);\r\n }, 500);\r\n }\r\n\r\n emitCardChange(\r\n newValues[0],\r\n newValues[1],\r\n newValues[2],\r\n newValues[3],\r\n );\r\n });\r\n };\r\n\r\n // \uD0A4 \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleKeyDown = (groupIndex: number) => {\r\n return createKeyDownHandler(groupIndex, (newValue, idx) => {\r\n const newValues = [group1, group2, group3, group4];\r\n newValues[idx] = newValue;\r\n emitCardChange(\r\n newValues[0],\r\n newValues[1],\r\n newValues[2],\r\n newValues[3],\r\n );\r\n });\r\n };\r\n\r\n // blur \uD578\uB4E4\uB7EC\r\n const handleBlur = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>) => {\r\n const blurHandler = createBlurHandler();\r\n blurHandler();\r\n\r\n const fullValue = getFullNumber();\r\n flushOnBlur(e, fullValue);\r\n },\r\n [createBlurHandler, getFullNumber, flushOnBlur],\r\n );\r\n\r\n // 2-2. \uC678\uACFD \uC601\uC5ED \uD074\uB9AD \uC2DC \uB9C8\uC9C0\uB9C9 \uAC12\uC774 \uC788\uB294 \uCE78\uC758 \uB9C8\uC9C0\uB9C9\uC73C\uB85C \uCEE4\uC11C \uC774\uB3D9\r\n const handleContainerClick = useCallback(\r\n (e: React.MouseEvent) => {\r\n if (disabled || readonly) return;\r\n\r\n // \uC774\uBBF8 input\uC5D0\uC11C \uCC98\uB9AC\uB41C \uD074\uB9AD\uC774\uBA74 \uBB34\uC2DC\r\n const target = e.target as HTMLElement;\r\n if (target.tagName === \"INPUT\") return;\r\n\r\n const values = [group1, group2, group3, group4];\r\n const refs = [ref1, ref2, ref3, ref4];\r\n\r\n // \uB9C8\uC9C0\uB9C9\uC73C\uB85C \uAC12\uC774 \uC788\uB294 \uADF8\uB8F9 \uCC3E\uAE30\r\n let lastFilledIndex = -1;\r\n for (let i = values.length - 1; i >= 0; i--) {\r\n if (values[i].length > 0) {\r\n lastFilledIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n if (lastFilledIndex >= 0) {\r\n // \uB9C8\uC9C0\uB9C9 \uAC12\uC774 \uC788\uB294 \uCE78\uC758 \uB9C8\uC9C0\uB9C9\uC73C\uB85C \uC774\uB3D9\r\n const targetRef = refs[lastFilledIndex];\r\n const targetValue = values[lastFilledIndex];\r\n const newPos = targetValue.length;\r\n cursorPosRef.current = newPos;\r\n targetRef.current?.focus();\r\n targetRef.current?.setSelectionRange(newPos, newPos);\r\n } else {\r\n // \uBAA8\uB450 \uBE44\uC5B4\uC788\uC73C\uBA74 \uCCAB \uBC88\uC9F8 \uCE78\uC73C\uB85C\r\n cursorPosRef.current = 0;\r\n ref1.current?.focus();\r\n ref1.current?.setSelectionRange(0, 0);\r\n }\r\n },\r\n [disabled, readonly, group1, group2, group3, group4, cursorPosRef],\r\n );\r\n\r\n // \uB3D9\uADF8\uB77C\uBBF8 \uD06C\uAE30 (\uB9C8\uC2A4\uD0B9\uC6A9)\r\n const dotSize = Math.round(computedFontSize * 0.5);\r\n\r\n // \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C \uD06C\uAE30\r\n const cursorWidthPx = `${computedFontSize * 0.55}px`;\r\n const cursorHeightPx = \"1px\";\r\n\r\n // \uD544\uB4DC \uB108\uBE44 - \uC77C\uBC18 \uADF8\uB8F9\uC6A9 (\uC22B\uC790 4\uC790\uB9AC)\r\n const normalFieldWidth = \"4ch\";\r\n // \uD544\uB4DC \uB108\uBE44 - \uB9C8\uC2A4\uD0B9 \uADF8\uB8F9\uC6A9 (\uB3D9\uADF8\uB77C\uBBF8 \uAC04\uACA9 \uACE0\uB824)\r\n const maskedFieldWidth = \"5.5ch\";\r\n\r\n // \uB9C8\uC2A4\uD0B9 \uADF8\uB8F9\uC758 \uB3D9\uADF8\uB77C\uBBF8 \uAC04\uACA9 \uACC4\uC0B0 (px \uB2E8\uC704)\r\n // maskedFieldWidth = 5.5ch, padding px: 0.25 * 8 = 2px \uC591\uCABD\r\n // \uB3D9\uADF8\uB77C\uBBF8 4\uAC1C\uAC00 space-between\uC73C\uB85C \uBC30\uCE58\uB428\r\n const getMaskedCursorLeft = (cursorPos: number): number => {\r\n // 5.5ch\uB97C px\uB85C \uBCC0\uD658 (1ch \u2248 0.45em)\r\n const chToPx = computedFontSize * 0.45;\r\n const fieldWidthPx = 5.5 * chToPx;\r\n const paddingPx = 2; // px: 0.25 * 8\r\n const contentWidth = fieldWidthPx - paddingPx * 2;\r\n // space-between: \uCCAB \uBC88\uC9F8 \uC694\uC18C\uB294 \uC2DC\uC791, \uB9C8\uC9C0\uB9C9 \uC694\uC18C\uB294 \uB05D, \uB098\uBA38\uC9C0\uB294 \uADE0\uB4F1 \uBD84\uBC30\r\n // 4\uAC1C \uC694\uC18C\uC758 \uACBD\uC6B0: 0, 1/3, 2/3, 1 \uC704\uCE58\uC5D0 \uBC30\uCE58\r\n const gap = contentWidth / 3; // 4\uAC1C \uB3D9\uADF8\uB77C\uBBF8 \uC0AC\uC774 3\uAC1C \uAC04\uACA9\r\n return paddingPx + cursorPos * gap;\r\n };\r\n\r\n // TextField border \uC81C\uAC70 \uC2A4\uD0C0\uC77C\r\n const noBorderStyle: SxProps<Theme> = {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": { border: \"none\" },\r\n \"&:hover fieldset\": { border: \"none\" },\r\n \"&.Mui-focused fieldset\": { border: \"none\" },\r\n },\r\n };\r\n\r\n // \uB9C8\uC2A4\uD0B9\uB41C \uADF8\uB8F9 \uB80C\uB354\uB9C1 (2, 3\uBC88\uC9F8 \uADF8\uB8F9)\r\n // renderTrigger\uB97C \uC758\uC874\uC131\uC73C\uB85C \uC0AC\uC6A9\uD558\uC5EC \uCEE4\uC11C \uC704\uCE58 \uBCC0\uACBD \uC2DC \uB9AC\uB80C\uB354\uB9C1\r\n const renderMaskedGroup = (groupIndex: number, groupValue: string) => {\r\n const isFocused = focusedGroup === groupIndex;\r\n const showCursor = cursorVisible && isFocused && !inputComplete;\r\n const refs = [ref1, ref2, ref3, ref4];\r\n // renderTrigger \uBCC0\uACBD \uC2DC \uCEE4\uC11C \uC704\uCE58 \uC5C5\uB370\uC774\uD2B8\uB97C \uC704\uD574 \uCC38\uC870\r\n void renderTrigger;\r\n\r\n return (\r\n <Box\r\n onMouseDown={createMouseDownHandler(groupIndex)}\r\n onClick={createClickHandler(groupIndex)}\r\n sx={{\r\n position: \"relative\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n userSelect: \"none\",\r\n }}\r\n >\r\n <TextField\r\n inputRef={refs[groupIndex]}\r\n value={groupValue}\r\n onChange={handleChange(groupIndex)}\r\n onKeyDown={handleKeyDown(groupIndex)}\r\n onFocus={createFocusHandler(groupIndex)}\r\n onBlur={handleBlur}\r\n disabled={disabled}\r\n size={size}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n variant=\"outlined\"\r\n sx={{\r\n width: \"auto\",\r\n minWidth: 0,\r\n ...noBorderStyle,\r\n \"& .MuiInputBase-root\": { width: \"auto\" },\r\n \"& .MuiInputBase-input\": {\r\n width: maskedFieldWidth,\r\n color: \"transparent\",\r\n caretColor: \"transparent\",\r\n userSelect: \"none\",\r\n ...(fontSize && { fontSize }),\r\n ...(fontFamily && { fontFamily }),\r\n },\r\n }}\r\n slotProps={{\r\n input: {\r\n readOnly: readonly,\r\n },\r\n htmlInput: {\r\n maxLength: 4,\r\n inputMode: \"numeric\",\r\n style: { textAlign: \"left\", padding: 0 },\r\n },\r\n }}\r\n />\r\n {/* \uB9C8\uC2A4\uD0B9 \uC624\uBC84\uB808\uC774 - \uB3D9\uADF8\uB77C\uBBF8 + \uB9C8\uC9C0\uB9C9 \uC785\uB825 \uC22B\uC790 */}\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n left: 0,\r\n width: maskedFieldWidth,\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"space-between\",\r\n pointerEvents: \"none\",\r\n userSelect: \"none\",\r\n px: 0.25,\r\n }}\r\n >\r\n {Array.from({ length: 4 }).map((_, i) => {\r\n const isEntered = i < groupValue.length;\r\n // \uD3EC\uCEE4\uC2A4 \uC911\uC77C \uB54C \uCEE4\uC11C \uC704\uCE58\uC758 \uBB38\uC790 \uD45C\uC2DC (\uBC29\uD5A5\uD0A4 \uC774\uB3D9 \uC9C0\uC6D0)\r\n const cursorPos = cursorPosRef.current;\r\n const isAtCursor =\r\n isFocused &&\r\n i === cursorPos &&\r\n i < groupValue.length;\r\n\r\n // \uB9C8\uC9C0\uB9C9 \uC785\uB825\uB41C \uBB38\uC790 \uD45C\uC2DC (\uC785\uB825 \uC9C1\uD6C4 \uC7A0\uAE50)\r\n const isLastInput =\r\n lastInputInfo !== null &&\r\n lastInputInfo.groupIndex === groupIndex &&\r\n lastInputInfo.charIndex === i;\r\n\r\n if (isAtCursor || isLastInput) {\r\n // \uD3EC\uCEE4\uC2A4 \uC911\uC774\uACE0 \uCEE4\uC11C \uC704\uCE58\uC758 \uBB38\uC790\uAC70\uB098, \uB9C8\uC9C0\uB9C9 \uC785\uB825\uB41C \uBB38\uC790\uBA74 \uC22B\uC790 \uD45C\uC2DC\r\n return (\r\n <span\r\n key={i}\r\n style={{\r\n fontSize:\r\n fontSize ||\r\n (size === \"small\" ? 16 : 18),\r\n fontFamily: fontFamily || \"inherit\",\r\n color: fontColor || \"inherit\",\r\n display: \"inline-block\",\r\n width: `${dotSize}px`,\r\n textAlign: \"center\",\r\n }}\r\n >\r\n {groupValue[i]}\r\n </span>\r\n );\r\n }\r\n\r\n // \uB3D9\uADF8\uB77C\uBBF8 \uD45C\uC2DC (\uC785\uB825\uB428: \uC9C4\uD558\uAC8C, \uBBF8\uC785\uB825: \uD750\uB9AC\uAC8C)\r\n return (\r\n <span\r\n key={i}\r\n style={{\r\n width: `${dotSize}px`,\r\n height: `${dotSize}px`,\r\n borderRadius: \"50%\",\r\n backgroundColor: maskColor,\r\n opacity: isEntered ? 1 : 0.15,\r\n display: \"inline-block\",\r\n }}\r\n />\r\n );\r\n })}\r\n </Box>\r\n {/* \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C */}\r\n {showCursor && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n bottom: size === \"small\" ? 1 : 3,\r\n left: `${getMaskedCursorLeft(\r\n cursorPosRef.current,\r\n )}px`,\r\n width: cursorWidthPx,\r\n height: cursorHeightPx,\r\n backgroundColor: fontColor || \"text.primary\",\r\n animation: \"blink 1s step-end infinite\",\r\n \"@keyframes blink\": {\r\n \"0%, 100%\": { opacity: 1 },\r\n \"50%\": { opacity: 0 },\r\n },\r\n pointerEvents: \"none\",\r\n }}\r\n />\r\n )}\r\n </Box>\r\n );\r\n };\r\n\r\n // \uC77C\uBC18 \uADF8\uB8F9 \uB80C\uB354\uB9C1 (1, 4\uBC88\uC9F8 \uADF8\uB8F9)\r\n const renderNormalGroup = (groupIndex: number, groupValue: string) => {\r\n const isFocused = focusedGroup === groupIndex;\r\n const showCursor = cursorVisible && isFocused && !inputComplete;\r\n const refs = [ref1, ref2, ref3, ref4];\r\n\r\n return (\r\n <Box\r\n onMouseDown={createMouseDownHandler(groupIndex)}\r\n onClick={createClickHandler(groupIndex)}\r\n sx={{\r\n position: \"relative\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n }}\r\n >\r\n <TextField\r\n inputRef={refs[groupIndex]}\r\n value={groupValue}\r\n onChange={handleChange(groupIndex)}\r\n onKeyDown={handleKeyDown(groupIndex)}\r\n onFocus={createFocusHandler(groupIndex)}\r\n onBlur={handleBlur}\r\n disabled={disabled}\r\n size={size}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n placeholder=\"0000\"\r\n variant=\"outlined\"\r\n sx={{\r\n width: \"auto\",\r\n minWidth: 0,\r\n ...noBorderStyle,\r\n \"& .MuiInputBase-root\": { width: \"auto\" },\r\n \"& .MuiInputBase-input\": {\r\n width: normalFieldWidth,\r\n userSelect: \"none\",\r\n caretColor: \"transparent\",\r\n ...(fontSize && { fontSize }),\r\n ...(fontColor && { color: fontColor }),\r\n ...(fontFamily && { fontFamily }),\r\n },\r\n \"& .MuiInputBase-input::placeholder\": {\r\n color: \"rgba(0, 0, 0, 0.2)\",\r\n opacity: 1,\r\n },\r\n }}\r\n slotProps={{\r\n input: {\r\n readOnly: readonly,\r\n },\r\n htmlInput: {\r\n maxLength: 4,\r\n inputMode: \"numeric\",\r\n style: { textAlign: \"left\", padding: \"0 4px\" },\r\n },\r\n }}\r\n />\r\n {/* \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C */}\r\n {showCursor && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n bottom: size === \"small\" ? 1 : 3,\r\n left: `${getCursorLeft(groupIndex) + 4}px`,\r\n width: cursorWidthPx,\r\n height: cursorHeightPx,\r\n backgroundColor: fontColor || \"text.primary\",\r\n animation: \"blink 1s step-end infinite\",\r\n \"@keyframes blink\": {\r\n \"0%, 100%\": { opacity: 1 },\r\n \"50%\": { opacity: 0 },\r\n },\r\n pointerEvents: \"none\",\r\n }}\r\n />\r\n )}\r\n </Box>\r\n );\r\n };\r\n\r\n // Dash \uB798\uD37C \uCEF4\uD3EC\uB10C\uD2B8\r\n const Dash = () => (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n color: \"text.secondary\",\r\n mx: size === \"small\" ? 0.5 : 0.75,\r\n userSelect: \"none\",\r\n }}\r\n >\r\n <DashIcon size={size} />\r\n </Box>\r\n );\r\n\r\n // \uCE74\uB4DC \uBE0C\uB79C\uB4DC \uC544\uC774\uCF58 \uB80C\uB354\uB9C1\r\n const renderCardIcon = () => {\r\n const iconSize = size === \"small\" ? 22 : 26;\r\n\r\n switch (cardBrand) {\r\n case \"visa\":\r\n return <VisaIcon size={iconSize} />;\r\n case \"mastercard\":\r\n return <MastercardIcon size={iconSize} />;\r\n case \"amex\":\r\n return <AmexIcon size={iconSize} />;\r\n case \"jcb\":\r\n return <JcbIcon size={iconSize} />;\r\n case \"diners\":\r\n return <DinersIcon size={iconSize} />;\r\n case \"discover\":\r\n return <DiscoverIcon size={iconSize} />;\r\n case \"unionpay\":\r\n return <UnionPayIcon size={iconSize} />;\r\n case \"bc\":\r\n return <BcIcon size={iconSize} />;\r\n default:\r\n return <CardIcon size={iconSize} />;\r\n }\r\n };\r\n\r\n // \uADF8\uB8F9 \uC785\uB825 \uB0B4\uBD80 \uCEF4\uD3EC\uB10C\uD2B8 \uB80C\uB354\uB9C1\r\n const renderGroupedInput = () => (\r\n <Box\r\n onClick={handleContainerClick}\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n width: \"100%\",\r\n height: \"100%\",\r\n cursor: disabled ? \"default\" : \"text\",\r\n ...(logoIcon && { pl: 1 }),\r\n }}\r\n >\r\n {/* \uCE74\uB4DC \uBE0C\uB79C\uB4DC \uC544\uC774\uCF58 */}\r\n {logoIcon && (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n mr: 0,\r\n flexShrink: 0,\r\n }}\r\n >\r\n {renderCardIcon()}\r\n </Box>\r\n )}\r\n {/* \uADF8\uB8F9 1: \uC77C\uBC18 */}\r\n {renderNormalGroup(0, group1)}\r\n <Dash />\r\n {/* \uADF8\uB8F9 2: \uB9C8\uC2A4\uD0B9 */}\r\n {renderMaskedGroup(1, group2)}\r\n <Dash />\r\n {/* \uADF8\uB8F9 3: \uB9C8\uC2A4\uD0B9 */}\r\n {renderMaskedGroup(2, group3)}\r\n <Dash />\r\n {/* \uADF8\uB8F9 4: \uC77C\uBC18 */}\r\n {renderNormalGroup(3, group4)}\r\n </Box>\r\n );\r\n\r\n // \uD074\uB9AD \uC2DC \uD3EC\uCEE4\uC2A4\uD560 ref \uACB0\uC815\r\n const getTargetRefOnClick = useCallback(() => {\r\n const values = [group1, group2, group3, group4];\r\n const refs = [ref1, ref2, ref3, ref4];\r\n\r\n // \uB9C8\uC9C0\uB9C9\uC73C\uB85C \uAC12\uC774 \uC788\uB294 \uADF8\uB8F9 \uCC3E\uAE30\r\n let lastFilledIndex = -1;\r\n for (let i = values.length - 1; i >= 0; i--) {\r\n if (values[i].length > 0) {\r\n lastFilledIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n if (lastFilledIndex >= 0) {\r\n return {\r\n ref: refs[lastFilledIndex],\r\n groupIndex: lastFilledIndex,\r\n };\r\n }\r\n // \uBAA8\uB450 \uBE44\uC5B4\uC788\uC73C\uBA74 \uCCAB \uBC88\uC9F8 \uCE78\r\n return { ref: ref1, groupIndex: 0 };\r\n }, [group1, group2, group3, group4]);\r\n\r\n return (\r\n <GroupedInputWrapper\r\n label={label}\r\n size={size}\r\n disabled={disabled}\r\n readonly={readonly}\r\n focusedGroup={focusedGroup}\r\n setFocusedGroup={setFocusedGroup}\r\n hasValue={getFullNumber().length > 0}\r\n isInvalid={isInvalid}\r\n invalidBorderColor={invalidBorderColor}\r\n inputRefs={[ref1, ref2, ref3, ref4]}\r\n getTargetRefOnClick={getTargetRefOnClick}\r\n fullWidth={fullWidth}\r\n sx={sx}\r\n className={className}\r\n id={id}\r\n contentSx={logoIcon ? { pl: 0 } : undefined}\r\n >\r\n {renderGroupedInput()}\r\n </GroupedInputWrapper>\r\n );\r\n },\r\n);\r\n\r\nconst CardNumTextFieldWithForm = forwardRef<\r\n HTMLDivElement,\r\n CardNumTextFieldProps\r\n>(function CardNumTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"CardNumTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"CardNumTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name) as string | undefined;\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <CardNumTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const CardNumTextField = forwardRef<\r\n HTMLDivElement,\r\n CardNumTextFieldProps\r\n>(function CardNumTextField(props, ref) {\r\n if (props.form) {\r\n return <CardNumTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <CardNumTextFieldBase {...props} ref={ref} />;\r\n});\r\n"],
5
- "mappings": "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AW,EACA,sBAAAnC,EACA,YAAAc,CACJ,CACJ,CC7gBA,IAAM2B,GAA2B,CAC7B,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,GACJ,EAEMC,GAA4B,CAC9B,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,KACA,KACA,KACA,IACA,IACA,KACA,KACA,KACA,IACA,IACA,KACA,GACJ,EAEMC,GAA4B,CAC9B,GACA,IACA,IACA,KACA,IACA,KACA,KACA,IACA,IACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,IACA,IACA,KACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,GACJ,EAEMC,GAA6D,CAC/D,OAAG,IACH,OAAG,IACH,OAAG,KACH,OAAG,IACH,OAAG,KACH,OAAG,KACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,KACH,OAAG,KACH,OAAG,KACH,OAAG,KACH,OAAG,KACH,OAAG,KACH,OAAG,KACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,KACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,KACH,OAAG,KACH,OAAG,KACH,OAAG,IACH,OAAG,IACH,OAAG,KACH,OAAG,KACH,OAAG,KACH,OAAG,IACH,OAAG,IACH,OAAG,KACH,OAAG,GACP,EAEMC,GAA0D,CAC5D,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,GACP,EAEMC,GAA2D,CAC7D,OAAG,IA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",
4
+ "sourcesContent": ["/**\r\n * SearchTextField.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n forwardRef,\r\n useCallback,\r\n useEffect,\r\n useRef,\r\n useImperativeHandle,\r\n useState,\r\n} from \"react\";\r\nimport {\r\n TextField,\r\n IconButton,\r\n InputAdornment,\r\n CircularProgress,\r\n} from \"@mui/material\";\r\nimport ClearIcon from \"@mui/icons-material/Clear\";\r\nimport SearchIcon from \"@mui/icons-material/Search\";\r\nimport type { SearchTextFieldProps } from \"./types\";\r\nimport { useTextFieldBase } from \"./hooks\";\r\nimport type { BaseTextFieldProps as MuiBaseTextFieldProps } from \"@mui/material/TextField\";\r\nimport {\r\n convertMistypedKoreanImeToEnglish,\r\n shouldAutoConvertKoreanImeQuery,\r\n} from \"./utils/koreanIme\";\r\n\r\nconst SearchTextFieldBase = forwardRef<HTMLDivElement, SearchTextFieldProps>(\r\n function SearchTextFieldBase(\r\n {\r\n value,\r\n form,\r\n loading = false,\r\n searchIcon = true,\r\n searchIconColor = \"#666\",\r\n clearIcon = true,\r\n clearIconColor = \"#666\",\r\n debounce = 300,\r\n readonly,\r\n spellCheck = false,\r\n autoConvertKoreanImeToEnglish = false,\r\n autoConvertKoreanImeDelay = 500,\r\n minLength,\r\n onChange,\r\n onBlur,\r\n onFocus,\r\n onCompositionStart,\r\n onCompositionEnd,\r\n onClear,\r\n onSearch,\r\n slotProps,\r\n size,\r\n inputRef: externalInputRef,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const {\r\n internalValue,\r\n setInternalValue,\r\n handleChange,\r\n handleBlur,\r\n emitChange,\r\n } = useTextFieldBase({\r\n value: (value as string) ?? \"\",\r\n name: props.name,\r\n debounce,\r\n onChange,\r\n onBlur,\r\n });\r\n\r\n const [isFocused, setIsFocused] = useState(false);\r\n const [forceShrink, setForceShrink] = useState(false);\r\n const [internalLoading, setInternalLoading] = useState(false);\r\n const isClearingRef = useRef(false);\r\n const onSearchTimer = useRef<ReturnType<typeof setTimeout> | null>(\r\n null,\r\n );\r\n const autoConvertTimer = useRef<ReturnType<typeof setTimeout> | null>(\r\n null,\r\n );\r\n const lastSearchValueRef = useRef<string | null>(null);\r\n const restoreFocusAfterAutoConvertRef = useRef(false);\r\n const isComposingRef = useRef(false);\r\n const compositionTaskIdRef = useRef(0);\r\n const forcedAutoConvertTaskRef = useRef<number | null>(null);\r\n const suppressBlurRef = useRef(false);\r\n\r\n // input ref for focus after clear\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n\r\n useEffect(() => {\r\n return () => {\r\n if (onSearchTimer.current) {\r\n clearTimeout(onSearchTimer.current);\r\n onSearchTimer.current = null;\r\n }\r\n if (autoConvertTimer.current) {\r\n clearTimeout(autoConvertTimer.current);\r\n autoConvertTimer.current = null;\r\n }\r\n };\r\n }, []);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLInputElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n // size\uC5D0 \uB530\uB978 \uC544\uC774\uCF58 \uD06C\uAE30\r\n const iconSize = size === \"small\" ? 20 : 24;\r\n\r\n const clearAutoConvertTimer = useCallback(() => {\r\n if (autoConvertTimer.current) {\r\n clearTimeout(autoConvertTimer.current);\r\n autoConvertTimer.current = null;\r\n }\r\n }, []);\r\n\r\n const getResolvedInputValue = useCallback(\r\n (fallbackValue = \"\") =>\r\n internalInputRef.current?.value ?? fallbackValue,\r\n [],\r\n );\r\n\r\n const createSyntheticChangeEvent = useCallback(\r\n (nextValue: string) =>\r\n ({\r\n target: {\r\n name: props.name || \"\",\r\n value: nextValue,\r\n },\r\n }) as React.ChangeEvent<HTMLInputElement>,\r\n [props.name],\r\n );\r\n\r\n // \uD074\uB9AC\uC5B4 \uBC84\uD2BC \uD578\uB4E4\uB7EC\r\n const handleClear = () => {\r\n isClearingRef.current = true;\r\n setForceShrink(true);\r\n setIsFocused(true);\r\n setInternalValue(\"\");\r\n clearAutoConvertTimer();\r\n // onSearch \uD0C0\uC774\uBA38 \uCDE8\uC18C\r\n if (onSearchTimer.current) {\r\n clearTimeout(onSearchTimer.current);\r\n onSearchTimer.current = null;\r\n }\r\n setInternalLoading(false);\r\n // \uC989\uC2DC emit\uC744 \uC704\uD574 fake \uC774\uBCA4\uD2B8 \uC0DD\uC131\r\n const fakeEvent = {\r\n target: { name: props.name || \"\", value: \"\" },\r\n } as React.ChangeEvent<HTMLInputElement>;\r\n emitChange(fakeEvent, \"\", true);\r\n if (onSearch && minLength !== undefined) {\r\n lastSearchValueRef.current = \"\";\r\n onSearch(\"\");\r\n }\r\n onClear?.();\r\n // \uD074\uB9AC\uC5B4 \uD6C4 \uD3EC\uCEE4\uC2A4\r\n internalInputRef.current?.focus();\r\n setTimeout(() => {\r\n isClearingRef.current = false;\r\n }, 0);\r\n };\r\n\r\n const triggerSearch = useCallback(\r\n (nextValue: string, immediate = false) => {\r\n if (!onSearch || minLength === undefined) {\r\n return;\r\n }\r\n\r\n if (onSearchTimer.current) {\r\n clearTimeout(onSearchTimer.current);\r\n onSearchTimer.current = null;\r\n }\r\n\r\n const normalizedValue = nextValue;\r\n const shouldReset = normalizedValue.length === 0;\r\n const shouldSearch = normalizedValue.length >= minLength;\r\n\r\n if (!shouldReset && !shouldSearch) {\r\n setInternalLoading(false);\r\n if (lastSearchValueRef.current !== \"\") {\r\n lastSearchValueRef.current = \"\";\r\n onSearch(\"\");\r\n }\r\n return;\r\n }\r\n\r\n const runSearch = () => {\r\n setInternalLoading(false);\r\n if (lastSearchValueRef.current === normalizedValue) {\r\n return;\r\n }\r\n lastSearchValueRef.current = normalizedValue;\r\n onSearch(normalizedValue);\r\n };\r\n\r\n if (immediate || debounce === undefined || debounce === 0) {\r\n runSearch();\r\n return;\r\n }\r\n\r\n setInternalLoading(true);\r\n onSearchTimer.current = setTimeout(() => {\r\n runSearch();\r\n onSearchTimer.current = null;\r\n }, debounce);\r\n },\r\n [debounce, minLength, onSearch],\r\n );\r\n\r\n const applyImmediateValue = useCallback(\r\n (nextValue: string, selectionStart?: number | null) => {\r\n clearAutoConvertTimer();\r\n setInternalValue(nextValue);\r\n emitChange(\r\n createSyntheticChangeEvent(nextValue),\r\n nextValue,\r\n true,\r\n );\r\n\r\n if (onSearch && minLength !== undefined) {\r\n triggerSearch(nextValue, true);\r\n }\r\n\r\n if (selectionStart == null) {\r\n return;\r\n }\r\n\r\n setTimeout(() => {\r\n internalInputRef.current?.focus();\r\n internalInputRef.current?.setSelectionRange(\r\n selectionStart,\r\n selectionStart,\r\n );\r\n }, 0);\r\n },\r\n [\r\n clearAutoConvertTimer,\r\n createSyntheticChangeEvent,\r\n emitChange,\r\n minLength,\r\n onSearch,\r\n triggerSearch,\r\n ],\r\n );\r\n\r\n const commitAutoConvertedValue = useCallback(\r\n (nextValue: string) => {\r\n isComposingRef.current = false;\r\n\r\n setInternalValue(nextValue);\r\n emitChange(\r\n createSyntheticChangeEvent(nextValue),\r\n nextValue,\r\n true,\r\n );\r\n\r\n if (onSearch && minLength !== undefined) {\r\n triggerSearch(nextValue, true);\r\n }\r\n\r\n if (restoreFocusAfterAutoConvertRef.current) {\r\n restoreFocusAfterAutoConvertRef.current = false;\r\n setTimeout(() => {\r\n internalInputRef.current?.focus();\r\n const length =\r\n internalInputRef.current?.value.length ?? 0;\r\n internalInputRef.current?.setSelectionRange(\r\n length,\r\n length,\r\n );\r\n }, 0);\r\n }\r\n },\r\n [\r\n createSyntheticChangeEvent,\r\n emitChange,\r\n minLength,\r\n onSearch,\r\n triggerSearch,\r\n ],\r\n );\r\n\r\n const scheduleAutoConvert = useCallback(\r\n (rawValue: string) => {\r\n clearAutoConvertTimer();\r\n\r\n if (onSearchTimer.current) {\r\n clearTimeout(onSearchTimer.current);\r\n onSearchTimer.current = null;\r\n }\r\n setInternalLoading(false);\r\n\r\n autoConvertTimer.current = setTimeout(() => {\r\n autoConvertTimer.current = null;\r\n\r\n if (isComposingRef.current) {\r\n const input = internalInputRef.current;\r\n const taskId = compositionTaskIdRef.current + 1;\r\n const composingValue = input?.value ?? rawValue;\r\n\r\n forcedAutoConvertTaskRef.current = taskId;\r\n suppressBlurRef.current = true;\r\n input?.blur();\r\n\r\n setTimeout(() => {\r\n if (forcedAutoConvertTaskRef.current !== taskId) {\r\n return;\r\n }\r\n\r\n forcedAutoConvertTaskRef.current = null;\r\n const resolvedValue =\r\n getResolvedInputValue(composingValue);\r\n const converted =\r\n convertMistypedKoreanImeToEnglish(\r\n resolvedValue,\r\n );\r\n\r\n if (converted === resolvedValue) {\r\n commitAutoConvertedValue(resolvedValue);\r\n return;\r\n }\r\n\r\n commitAutoConvertedValue(converted);\r\n }, 0);\r\n return;\r\n }\r\n\r\n const converted =\r\n convertMistypedKoreanImeToEnglish(rawValue);\r\n\r\n if (converted === rawValue) {\r\n commitAutoConvertedValue(rawValue);\r\n return;\r\n }\r\n\r\n commitAutoConvertedValue(converted);\r\n }, autoConvertKoreanImeDelay);\r\n },\r\n [\r\n autoConvertKoreanImeDelay,\r\n clearAutoConvertTimer,\r\n commitAutoConvertedValue,\r\n getResolvedInputValue,\r\n ],\r\n );\r\n\r\n const resolvedLoading = loading || internalLoading;\r\n\r\n const handleManualDelete = useCallback(\r\n (deleteDirection: \"backward\" | \"forward\") => {\r\n if (\r\n readonly ||\r\n !autoConvertKoreanImeToEnglish ||\r\n isComposingRef.current\r\n ) {\r\n return false;\r\n }\r\n\r\n const input = internalInputRef.current;\r\n const currentValue = input?.value ?? internalValue;\r\n\r\n if (!/^[\\x20-\\x7E]*$/.test(currentValue)) {\r\n return false;\r\n }\r\n\r\n const selectionStart =\r\n input?.selectionStart ?? currentValue.length;\r\n const selectionEnd = input?.selectionEnd ?? currentValue.length;\r\n\r\n if (\r\n deleteDirection === \"backward\" &&\r\n selectionStart === 0 &&\r\n selectionEnd === 0\r\n ) {\r\n return true;\r\n }\r\n\r\n if (\r\n deleteDirection === \"forward\" &&\r\n selectionStart === currentValue.length &&\r\n selectionEnd === currentValue.length\r\n ) {\r\n return true;\r\n }\r\n\r\n const hasSelection = selectionStart !== selectionEnd;\r\n const nextValue = hasSelection\r\n ? `${currentValue.slice(0, selectionStart)}${currentValue.slice(selectionEnd)}`\r\n : deleteDirection === \"backward\"\r\n ? `${currentValue.slice(0, Math.max(0, selectionStart - 1))}${currentValue.slice(selectionEnd)}`\r\n : `${currentValue.slice(0, selectionStart)}${currentValue.slice(selectionStart + 1)}`;\r\n const nextSelectionStart = hasSelection\r\n ? selectionStart\r\n : deleteDirection === \"backward\"\r\n ? Math.max(0, selectionStart - 1)\r\n : selectionStart;\r\n applyImmediateValue(nextValue, nextSelectionStart);\r\n return true;\r\n },\r\n [\r\n applyImmediateValue,\r\n autoConvertKoreanImeToEnglish,\r\n internalValue,\r\n readonly,\r\n ],\r\n );\r\n\r\n useEffect(() => {\r\n const input = internalInputRef.current;\r\n if (!input) {\r\n return;\r\n }\r\n\r\n const ownerDocument = input.ownerDocument;\r\n\r\n const handleNativeDelete = (\r\n deleteDirection: \"backward\" | \"forward\",\r\n ) => {\r\n if (ownerDocument.activeElement !== internalInputRef.current) {\r\n return false;\r\n }\r\n\r\n if (handleManualDelete(deleteDirection)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n };\r\n\r\n const handleNativeKeyDownCapture = (event: KeyboardEvent) => {\r\n if (event.defaultPrevented) {\r\n return;\r\n }\r\n\r\n const deleteDirection =\r\n event.key === \"Backspace\"\r\n ? \"backward\"\r\n : event.key === \"Delete\"\r\n ? \"forward\"\r\n : null;\r\n\r\n if (!deleteDirection) {\r\n return;\r\n }\r\n\r\n if (handleNativeDelete(deleteDirection)) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n };\r\n\r\n const handleNativeBeforeInputCapture = (event: InputEvent) => {\r\n if (event.defaultPrevented) {\r\n return;\r\n }\r\n\r\n const deleteDirection =\r\n event.inputType === \"deleteContentBackward\"\r\n ? \"backward\"\r\n : event.inputType === \"deleteContentForward\"\r\n ? \"forward\"\r\n : null;\r\n\r\n if (!deleteDirection) {\r\n return;\r\n }\r\n\r\n if (handleNativeDelete(deleteDirection)) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n };\r\n\r\n ownerDocument.addEventListener(\r\n \"keydown\",\r\n handleNativeKeyDownCapture,\r\n true,\r\n );\r\n ownerDocument.addEventListener(\r\n \"beforeinput\",\r\n handleNativeBeforeInputCapture,\r\n true,\r\n );\r\n\r\n return () => {\r\n ownerDocument.removeEventListener(\r\n \"keydown\",\r\n handleNativeKeyDownCapture,\r\n true,\r\n );\r\n ownerDocument.removeEventListener(\r\n \"beforeinput\",\r\n handleNativeBeforeInputCapture,\r\n true,\r\n );\r\n };\r\n }, [handleManualDelete]);\r\n\r\n const handleKeyDown = useCallback(\r\n (event: React.KeyboardEvent<HTMLInputElement>) => {\r\n props.onKeyDown?.(event);\r\n },\r\n [props],\r\n );\r\n\r\n const handleInputChange = useCallback(\r\n (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const nextValue = e.target.value;\r\n\r\n setInternalValue(nextValue);\r\n\r\n if (isComposingRef.current) {\r\n if (\r\n autoConvertKoreanImeToEnglish &&\r\n shouldAutoConvertKoreanImeQuery(nextValue)\r\n ) {\r\n restoreFocusAfterAutoConvertRef.current =\r\n document.activeElement === internalInputRef.current;\r\n scheduleAutoConvert(nextValue);\r\n } else {\r\n clearAutoConvertTimer();\r\n }\r\n emitChange(e, nextValue, true);\r\n return;\r\n }\r\n\r\n if (\r\n autoConvertKoreanImeToEnglish &&\r\n shouldAutoConvertKoreanImeQuery(nextValue)\r\n ) {\r\n restoreFocusAfterAutoConvertRef.current =\r\n document.activeElement === internalInputRef.current;\r\n scheduleAutoConvert(nextValue);\r\n return;\r\n }\r\n\r\n clearAutoConvertTimer();\r\n emitChange(e, nextValue);\r\n\r\n if (onSearch && minLength !== undefined) {\r\n triggerSearch(nextValue);\r\n }\r\n },\r\n [\r\n autoConvertKoreanImeToEnglish,\r\n autoConvertKoreanImeDelay,\r\n clearAutoConvertTimer,\r\n emitChange,\r\n minLength,\r\n onSearch,\r\n scheduleAutoConvert,\r\n setInternalValue,\r\n triggerSearch,\r\n ],\r\n );\r\n\r\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\r\n setIsFocused(true);\r\n onFocus?.(event);\r\n };\r\n\r\n const handleBlurWithFocus = (\r\n event: React.FocusEvent<HTMLInputElement>,\r\n ) => {\r\n if (suppressBlurRef.current) {\r\n suppressBlurRef.current = false;\r\n setIsFocused(false);\r\n setForceShrink(false);\r\n return;\r\n }\r\n\r\n if (isClearingRef.current) {\r\n isClearingRef.current = false;\r\n handleBlur(event);\r\n return;\r\n }\r\n\r\n if (\r\n autoConvertKoreanImeToEnglish &&\r\n autoConvertTimer.current &&\r\n shouldAutoConvertKoreanImeQuery(internalValue)\r\n ) {\r\n setIsFocused(false);\r\n setForceShrink(false);\r\n onBlur?.(event);\r\n return;\r\n }\r\n\r\n setIsFocused(false);\r\n setForceShrink(false);\r\n handleBlur(event);\r\n };\r\n\r\n const handleCompositionStartInternal = (\r\n event: React.CompositionEvent<HTMLInputElement>,\r\n ) => {\r\n compositionTaskIdRef.current += 1;\r\n isComposingRef.current = true;\r\n clearAutoConvertTimer();\r\n onCompositionStart?.(event);\r\n };\r\n\r\n const handleCompositionEndInternal = (\r\n event: React.CompositionEvent<HTMLInputElement>,\r\n ) => {\r\n compositionTaskIdRef.current += 1;\r\n const compositionTaskId = compositionTaskIdRef.current;\r\n isComposingRef.current = false;\r\n onCompositionEnd?.(event);\r\n\r\n if (forcedAutoConvertTaskRef.current != null) {\r\n return;\r\n }\r\n\r\n const fallbackValue = event.currentTarget.value ?? \"\";\r\n\r\n setTimeout(() => {\r\n if (compositionTaskId !== compositionTaskIdRef.current) {\r\n return;\r\n }\r\n\r\n const nextValue = getResolvedInputValue(fallbackValue);\r\n setInternalValue(nextValue);\r\n\r\n if (\r\n autoConvertKoreanImeToEnglish &&\r\n shouldAutoConvertKoreanImeQuery(nextValue)\r\n ) {\r\n restoreFocusAfterAutoConvertRef.current =\r\n document.activeElement === internalInputRef.current;\r\n scheduleAutoConvert(nextValue);\r\n return;\r\n }\r\n\r\n clearAutoConvertTimer();\r\n emitChange(\r\n createSyntheticChangeEvent(nextValue),\r\n nextValue,\r\n true,\r\n );\r\n\r\n if (onSearch && minLength !== undefined) {\r\n triggerSearch(nextValue, true);\r\n }\r\n }, 0);\r\n };\r\n\r\n // readonly\uC77C \uB54C \uD3EC\uCEE4\uC2A4 \uC2A4\uD0C0\uC77C \uC81C\uAC70\r\n const readonlyStyles = readonly\r\n ? {\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n const shouldShrink = forceShrink || isFocused || internalValue !== \"\";\r\n const hasLabel = Boolean(props.label);\r\n const labelTranslateX = size === \"small\" ? 42 : 46;\r\n const labelTranslateY = size === \"small\" ? 9 : 16;\r\n const labelOffsetSx =\r\n searchIcon && hasLabel\r\n ? {\r\n \"&:not(.MuiInputLabel-shrink)\": {\r\n transform: `translate(${labelTranslateX}px, ${labelTranslateY}px) scale(1)`,\r\n },\r\n }\r\n : undefined;\r\n\r\n const resolveInputLabelSlotProps = (\r\n ownerState: MuiBaseTextFieldProps,\r\n ): Record<string, unknown> => {\r\n const baseInputLabel = slotProps?.inputLabel;\r\n const resolvedInputLabel =\r\n typeof baseInputLabel === \"function\"\r\n ? baseInputLabel(ownerState)\r\n : baseInputLabel;\r\n\r\n const resolvedSx = (resolvedInputLabel as { sx?: unknown })?.sx;\r\n const mergedSx = labelOffsetSx\r\n ? Array.isArray(resolvedSx)\r\n ? [labelOffsetSx, ...resolvedSx]\r\n : resolvedSx\r\n ? [labelOffsetSx, resolvedSx]\r\n : [labelOffsetSx]\r\n : resolvedSx;\r\n\r\n return {\r\n ...resolvedInputLabel,\r\n shrink:\r\n (resolvedInputLabel as { shrink?: boolean })?.shrink ??\r\n shouldShrink,\r\n sx: mergedSx,\r\n };\r\n };\r\n\r\n return (\r\n <TextField\r\n {...props}\r\n ref={ref}\r\n inputRef={internalInputRef}\r\n size={size}\r\n value={internalValue}\r\n onChange={handleInputChange}\r\n onFocus={handleFocus}\r\n onBlur={handleBlurWithFocus}\r\n onKeyDown={handleKeyDown}\r\n onCompositionStart={handleCompositionStartInternal}\r\n onCompositionEnd={handleCompositionEndInternal}\r\n focused={isFocused || isClearingRef.current}\r\n autoComplete=\"off\"\r\n spellCheck={spellCheck}\r\n sx={{\r\n backgroundColor: \"#fff\",\r\n \"& .MuiOutlinedInput-root\": {\r\n backgroundColor: \"#fff\",\r\n },\r\n ...readonlyStyles,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...props.sx,\r\n }}\r\n slotProps={{\r\n ...slotProps,\r\n inputLabel: resolveInputLabelSlotProps,\r\n input: {\r\n ...slotProps?.input,\r\n readOnly: readonly,\r\n notched: shouldShrink,\r\n startAdornment: searchIcon ? (\r\n <InputAdornment\r\n position=\"start\"\r\n sx={{ m: \"0 !important\", mr: \"8px !important\" }}\r\n >\r\n <SearchIcon\r\n sx={{\r\n color: searchIconColor,\r\n fontSize: iconSize,\r\n }}\r\n />\r\n </InputAdornment>\r\n ) : undefined,\r\n endAdornment:\r\n clearIcon && !readonly ? (\r\n <InputAdornment\r\n position=\"end\"\r\n sx={{\r\n visibility: internalValue\r\n ? \"visible\"\r\n : \"hidden\",\r\n mr: 0,\r\n }}\r\n >\r\n {resolvedLoading ? (\r\n <CircularProgress\r\n size={size === \"small\" ? 14 : 16}\r\n />\r\n ) : (\r\n <IconButton\r\n size=\"small\"\r\n onMouseDown={(event) => {\r\n event.preventDefault();\r\n if (!readonly) {\r\n handleClear();\r\n }\r\n }}\r\n edge=\"end\"\r\n tabIndex={-1}\r\n disabled={readonly}\r\n sx={{\r\n padding:\r\n size === \"small\"\r\n ? \"2px\"\r\n : \"4px\",\r\n color: clearIconColor,\r\n \"&:hover\": {\r\n color: \"#333\",\r\n backgroundColor:\r\n \"rgba(0, 0, 0, 0.04)\",\r\n },\r\n }}\r\n >\r\n <ClearIcon\r\n sx={{ fontSize: iconSize - 4 }}\r\n />\r\n </IconButton>\r\n )}\r\n </InputAdornment>\r\n ) : undefined,\r\n },\r\n }}\r\n />\r\n );\r\n },\r\n);\r\n\r\nconst SearchTextFieldWithForm = forwardRef<\r\n HTMLDivElement,\r\n SearchTextFieldProps\r\n>(function SearchTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"SearchTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"SearchTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <SearchTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const SearchTextField = forwardRef<HTMLDivElement, SearchTextFieldProps>(\r\n function SearchTextField(props, ref) {\r\n if (props.form) {\r\n return <SearchTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <SearchTextFieldBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * useTextFieldBase.ts\r\n *\r\n * TextField \uCEF4\uD3EC\uB10C\uD2B8\uB4E4\uC758 \uACF5\uD1B5 \uB85C\uC9C1\uC744 \uB2F4\uB2F9\uD558\uB294 \uD6C5\r\n * - \uB514\uBC14\uC6B4\uC2A4 \uCC98\uB9AC\r\n * - \uB0B4\uBD80 \uC0C1\uD0DC \uAD00\uB9AC\r\n * - blur \uC2DC flush\r\n * - \uC678\uBD80 value \uB3D9\uAE30\uD654\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { useState, useRef, useEffect, useCallback, ChangeEvent } from \"react\";\r\n\r\nexport interface UseTextFieldBaseOptions {\r\n value: string; // \uC678\uBD80\uC5D0\uC11C \uC804\uB2EC\uBC1B\uC740 value\r\n name?: string; // \uD544\uB4DC \uC774\uB984 (name \uC18D\uC131)\r\n debounce?: number; // \uB514\uBC14\uC6B4\uC2A4 \uC9C0\uC5F0 \uC2DC\uAC04 (ms). undefined\uBA74 \uB514\uBC14\uC6B4\uC2A4 \uC5C6\uC74C\r\n onChange?: (e: ChangeEvent<HTMLInputElement>) => void; // \uAC12 \uBCC0\uACBD \uC2DC \uD638\uCD9C\uB418\uB294 \uCF5C\uBC31\r\n onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void; // blur \uC774\uBCA4\uD2B8 \uCF5C\uBC31\r\n // \uB0B4\uBD80 \uAC12\uC744 \uBCC0\uD658\uD558\uB294 \uD568\uC218 (\uC608: \uC804\uD654\uBC88\uD638 \uD3EC\uB9F7\uD305, \uC22B\uC790 \uD3EC\uB9F7\uD305 \uB4F1)\r\n transformValue?: (\r\n inputValue: string,\r\n currentDisplayValue: string,\r\n ) => {\r\n displayValue: string;\r\n emitValue: string;\r\n };\r\n}\r\n\r\nexport interface UseTextFieldBaseReturn {\r\n internalValue: string; // \uD654\uBA74\uC5D0 \uD45C\uC2DC\uD560 \uB0B4\uBD80 \uAC12\r\n setInternalValue: (value: string) => void; // \uB0B4\uBD80 \uAC12\uC744 \uC9C1\uC811 \uC124\uC815\r\n handleChange: (e: ChangeEvent<HTMLInputElement>) => void; // TextField onChange \uD578\uB4E4\uB7EC\r\n handleBlur: (e: React.FocusEvent<HTMLInputElement>) => void; // TextField onBlur \uD578\uB4E4\uB7EC\r\n emitChange: (\r\n // \uD2B9\uC815 \uAC12\uC73C\uB85C \uBCC0\uACBD\uC744 emit (immediate=true\uBA74 \uB514\uBC14\uC6B4\uC2A4 \uBB34\uC2DC)\r\n e: ChangeEvent<HTMLInputElement> | React.FocusEvent<HTMLInputElement>,\r\n newValue: string,\r\n immediate?: boolean,\r\n ) => void;\r\n lastEmittedValue: React.MutableRefObject<string>; // \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uB41C \uAC12\r\n debounceTimer: React.MutableRefObject<ReturnType<typeof setTimeout> | null>; // \uB514\uBC14\uC6B4\uC2A4 \uD0C0\uC774\uBA38 ref\r\n}\r\n\r\nexport function useTextFieldBase({\r\n value,\r\n name = \"\",\r\n debounce,\r\n onChange,\r\n onBlur,\r\n transformValue,\r\n}: UseTextFieldBaseOptions): UseTextFieldBaseReturn {\r\n // \uD654\uBA74\uC5D0 \uD45C\uC2DC\uB418\uB294 \uB0B4\uBD80 \uAC12\r\n const [internalValue, setInternalValue] = useState<string>(value ?? \"\");\r\n\r\n // \uB9C8\uC9C0\uB9C9\uC73C\uB85C onChange\uAC00 \uD638\uCD9C\uB41C \uAC12 (\uC911\uBCF5 \uD638\uCD9C \uBC29\uC9C0)\r\n const lastEmittedValue = useRef<string>(value ?? \"\");\r\n\r\n // \uB514\uBC14\uC6B4\uC2A4 \uD0C0\uC774\uBA38\r\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n // \uC774\uC804 \uC678\uBD80 value (\uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uAC83\uC778\uC9C0 \uAC10\uC9C0)\r\n const prevExternalValue = useRef<string>(value ?? \"\");\r\n\r\n // \uCEF4\uD3EC\uB10C\uD2B8 \uC5B8\uB9C8\uC6B4\uD2B8 \uC2DC \uD0C0\uC774\uBA38 \uC815\uB9AC\r\n useEffect(() => {\r\n return () => {\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n }\r\n };\r\n }, []);\r\n\r\n // \uC678\uBD80 value prop \uBCC0\uACBD \uC2DC \uB0B4\uBD80 \uC0C1\uD0DC \uB3D9\uAE30\uD654\r\n useEffect(() => {\r\n const newValue = value ?? \"\";\r\n // \uC678\uBD80\uC5D0\uC11C \uAC12\uC774 \uBCC0\uACBD\uB418\uC5C8\uACE0, \uADF8 \uAC12\uC774 \uC6B0\uB9AC\uAC00 \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uD55C \uAC12\uACFC \uB2E4\uB974\uBA74 \uB3D9\uAE30\uD654\r\n if (\r\n newValue !== prevExternalValue.current &&\r\n newValue !== lastEmittedValue.current\r\n ) {\r\n setInternalValue(newValue);\r\n lastEmittedValue.current = newValue;\r\n }\r\n prevExternalValue.current = newValue;\r\n }, [value]);\r\n\r\n // onChange\uB97C emit\uD558\uB294 \uD568\uC218\r\n const emitChange = useCallback(\r\n (\r\n e:\r\n | ChangeEvent<HTMLInputElement>\r\n | React.FocusEvent<HTMLInputElement>,\r\n newValue: string,\r\n immediate = false,\r\n ) => {\r\n // \uAC19\uC740 \uAC12\uC774\uBA74 \uD638\uCD9C\uD558\uC9C0 \uC54A\uC74C\r\n if (newValue === lastEmittedValue.current) {\r\n return;\r\n }\r\n\r\n const doEmit = () => {\r\n if (newValue !== lastEmittedValue.current) {\r\n lastEmittedValue.current = newValue;\r\n if (onChange) {\r\n const syntheticEvent = {\r\n ...e,\r\n target: {\r\n ...e.target,\r\n name: name,\r\n value: newValue,\r\n },\r\n } as ChangeEvent<HTMLInputElement>;\r\n onChange(syntheticEvent);\r\n }\r\n }\r\n };\r\n\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n }\r\n\r\n if (immediate || debounce === undefined || debounce === 0) {\r\n doEmit();\r\n } else {\r\n debounceTimer.current = setTimeout(doEmit, debounce);\r\n }\r\n },\r\n [onChange, debounce, name],\r\n );\r\n\r\n // TextField onChange \uD578\uB4E4\uB7EC\r\n const handleChange = useCallback(\r\n (e: ChangeEvent<HTMLInputElement>) => {\r\n const inputValue = e.target.value;\r\n\r\n if (transformValue) {\r\n // \uBCC0\uD658 \uD568\uC218\uAC00 \uC788\uC73C\uBA74 \uC0AC\uC6A9\r\n const { displayValue, emitValue } = transformValue(\r\n inputValue,\r\n internalValue,\r\n );\r\n setInternalValue(displayValue);\r\n emitChange(e, emitValue);\r\n } else {\r\n // \uBCC0\uD658 \uC5C6\uC774 \uADF8\uB300\uB85C \uC0AC\uC6A9\r\n setInternalValue(inputValue);\r\n emitChange(e, inputValue);\r\n }\r\n },\r\n [transformValue, internalValue, emitChange],\r\n );\r\n\r\n // blur \uC2DC \uB300\uAE30 \uC911\uC778 \uB514\uBC14\uC6B4\uC2A4 \uC989\uC2DC \uC2E4\uD589\r\n const handleBlur = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>) => {\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n debounceTimer.current = null;\r\n\r\n // \uD604\uC7AC \uB0B4\uBD80 \uAC12\uC73C\uB85C \uC989\uC2DC emit\r\n if (internalValue !== lastEmittedValue.current) {\r\n lastEmittedValue.current = internalValue;\r\n if (onChange) {\r\n const syntheticEvent = {\r\n ...e,\r\n target: {\r\n ...e.target,\r\n name: name,\r\n value: internalValue,\r\n },\r\n } as ChangeEvent<HTMLInputElement>;\r\n onChange(syntheticEvent);\r\n }\r\n }\r\n }\r\n\r\n // \uC6D0\uB798 onBlur \uD638\uCD9C\r\n if (onBlur) {\r\n onBlur(e);\r\n }\r\n },\r\n [internalValue, onChange, onBlur, name],\r\n );\r\n\r\n return {\r\n internalValue,\r\n setInternalValue,\r\n handleChange,\r\n handleBlur,\r\n emitChange,\r\n lastEmittedValue,\r\n debounceTimer,\r\n };\r\n}\r\n\r\n// \uB514\uBC14\uC6B4\uC2A4\uB41C onChange emit\uB9CC \uB2F4\uB2F9\uD558\uB294 \uAC04\uB2E8\uD55C \uD6C5 (\uBCF5\uC7A1\uD55C \uD3EC\uB9F7\uD305 \uB85C\uC9C1\uC774 \uC788\uB294 \uCEF4\uD3EC\uB10C\uD2B8\uC5D0\uC11C \uC0AC\uC6A9)\r\nexport interface UseDebouncedEmitOptions {\r\n name?: string; // \uD544\uB4DC \uC774\uB984 (name \uC18D\uC131)\r\n debounce?: number; // \uB514\uBC14\uC6B4\uC2A4 \uC9C0\uC5F0 \uC2DC\uAC04 (ms). undefined\uBA74 \uB514\uBC14\uC6B4\uC2A4 \uC5C6\uC74C\r\n onChange?: (e: ChangeEvent<HTMLInputElement>) => void; // \uAC12 \uBCC0\uACBD \uC2DC \uD638\uCD9C\uB418\uB294 \uCF5C\uBC31\r\n}\r\n\r\nexport interface UseDebouncedEmitReturn {\r\n emitChange: (\r\n // \uB514\uBC14\uC6B4\uC2A4\uB41C onChange emit\r\n e:\r\n | ChangeEvent<HTMLInputElement>\r\n | React.FocusEvent<HTMLInputElement>\r\n | null,\r\n newValue: string,\r\n immediate?: boolean,\r\n ) => void;\r\n flushOnBlur: (\r\n // blur \uC2DC \uB300\uAE30 \uC911\uC778 \uB514\uBC14\uC6B4\uC2A4 flush\r\n e: React.FocusEvent<HTMLInputElement>,\r\n currentValue: string,\r\n ) => void;\r\n lastEmittedValue: React.MutableRefObject<string>; // \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uB41C \uAC12\r\n debounceTimer: React.MutableRefObject<ReturnType<typeof setTimeout> | null>; // \uB514\uBC14\uC6B4\uC2A4 \uD0C0\uC774\uBA38 ref\r\n}\r\n\r\nexport function useDebouncedEmit({\r\n name = \"\",\r\n debounce,\r\n onChange,\r\n}: UseDebouncedEmitOptions): UseDebouncedEmitReturn {\r\n // \uB9C8\uC9C0\uB9C9\uC73C\uB85C onChange\uAC00 \uD638\uCD9C\uB41C \uAC12 (\uC911\uBCF5 \uD638\uCD9C \uBC29\uC9C0)\r\n const lastEmittedValue = useRef<string>(\"\");\r\n\r\n // \uB514\uBC14\uC6B4\uC2A4 \uD0C0\uC774\uBA38\r\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n // \uCEF4\uD3EC\uB10C\uD2B8 \uC5B8\uB9C8\uC6B4\uD2B8 \uC2DC \uD0C0\uC774\uBA38 \uC815\uB9AC\r\n useEffect(() => {\r\n return () => {\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n }\r\n };\r\n }, []);\r\n\r\n // onChange\uB97C emit\uD558\uB294 \uD568\uC218\r\n const emitChange = useCallback(\r\n (\r\n e:\r\n | ChangeEvent<HTMLInputElement>\r\n | React.FocusEvent<HTMLInputElement>\r\n | null,\r\n newValue: string,\r\n immediate = false,\r\n ) => {\r\n // \uAC19\uC740 \uAC12\uC774\uBA74 \uD638\uCD9C\uD558\uC9C0 \uC54A\uC74C\r\n if (newValue === lastEmittedValue.current) {\r\n return;\r\n }\r\n\r\n const doEmit = () => {\r\n if (newValue !== lastEmittedValue.current) {\r\n lastEmittedValue.current = newValue;\r\n if (onChange) {\r\n const syntheticEvent = {\r\n ...(e || {}),\r\n target: {\r\n ...(e?.target || {}),\r\n name: name,\r\n value: newValue,\r\n },\r\n } as ChangeEvent<HTMLInputElement>;\r\n onChange(syntheticEvent);\r\n }\r\n }\r\n };\r\n\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n }\r\n\r\n if (immediate || debounce === undefined || debounce === 0) {\r\n doEmit();\r\n } else {\r\n debounceTimer.current = setTimeout(doEmit, debounce);\r\n }\r\n },\r\n [onChange, debounce, name],\r\n );\r\n\r\n // blur \uC2DC \uB300\uAE30 \uC911\uC778 \uB514\uBC14\uC6B4\uC2A4 flush\r\n const flushOnBlur = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>, currentValue: string) => {\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n debounceTimer.current = null;\r\n\r\n if (currentValue !== lastEmittedValue.current) {\r\n lastEmittedValue.current = currentValue;\r\n if (onChange) {\r\n const syntheticEvent = {\r\n ...e,\r\n target: {\r\n ...e.target,\r\n name: name,\r\n value: currentValue,\r\n },\r\n } as ChangeEvent<HTMLInputElement>;\r\n onChange(syntheticEvent);\r\n }\r\n }\r\n }\r\n },\r\n [onChange, name],\r\n );\r\n\r\n return {\r\n emitChange,\r\n flushOnBlur,\r\n lastEmittedValue,\r\n debounceTimer,\r\n };\r\n}\r\n", "/**\r\n * useKoreanHolidays.ts\r\n *\r\n * \uD55C\uAD6D\uCC9C\uBB38\uC5F0\uAD6C\uC6D0 \uD2B9\uC77C \uC815\uBCF4 API\uB97C \uC774\uC6A9\uD558\uC5EC \uACF5\uD734\uC77C\uC744 \uC870\uD68C\uD558\uB294 \uCEE4\uC2A4\uD140 \uD6C5\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { useState, useEffect, useCallback } from \"react\";\r\n\r\n// \uB85C\uCEEC\uC2A4\uD1A0\uB9AC\uC9C0 \uD0A4 prefix\r\nconst STORAGE_KEY_PREFIX = \"korean-holidays-\";\r\n\r\n// API \uC751\uB2F5 \uD0C0\uC785\r\ninterface HolidayItem {\r\n dateKind: string;\r\n dateName: string;\r\n isHoliday: string;\r\n locdate: number;\r\n seq: number;\r\n}\r\n\r\ninterface ApiResponse {\r\n response: {\r\n header: {\r\n resultCode: string;\r\n resultMsg: string;\r\n };\r\n body: {\r\n items: {\r\n item: HolidayItem | HolidayItem[];\r\n };\r\n numOfRows: number;\r\n pageNo: number;\r\n totalCount: number;\r\n };\r\n };\r\n}\r\n\r\n// \uCE90\uC2DC\uB41C \uACF5\uD734\uC77C \uB370\uC774\uD130 \uD0C0\uC785\r\ninterface CachedHolidays {\r\n year: number;\r\n holidays: string[]; // YYYYMMDD \uD615\uC2DD\r\n fetchedAt: number; // timestamp\r\n}\r\n\r\n/**\r\n * \uD55C\uAD6D \uACF5\uD734\uC77C\uC744 \uC870\uD68C\uD558\uB294 \uCEE4\uC2A4\uD140 \uD6C5\r\n *\r\n * @param apiKey - \uACF5\uACF5\uB370\uC774\uD130\uD3EC\uD138 API \uC778\uC99D\uD0A4 (Encoding)\r\n * @param year - \uC870\uD68C\uD560 \uC5F0\uB3C4 (\uAE30\uBCF8\uAC12: \uD604\uC7AC \uC5F0\uB3C4)\r\n * @returns { holidays: Date[], loading: boolean, error: string | null }\r\n */\r\nexport function useKoreanHolidays(apiKey?: string, year?: number) {\r\n const targetYear = year ?? new Date().getFullYear();\r\n const [holidays, setHolidays] = useState<Date[]>([]);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n // \uB85C\uCEEC\uC2A4\uD1A0\uB9AC\uC9C0\uC5D0\uC11C \uCE90\uC2DC\uB41C \uB370\uC774\uD130 \uAC00\uC838\uC624\uAE30\r\n const getCachedHolidays = useCallback((year: number): Date[] | null => {\r\n try {\r\n const cached = localStorage.getItem(`${STORAGE_KEY_PREFIX}${year}`);\r\n if (!cached) return null;\r\n\r\n const data: CachedHolidays = JSON.parse(cached);\r\n\r\n // 1\uB144 \uC774\uC0C1 \uB41C \uCE90\uC2DC\uB294 \uBB34\uD6A8\uD654 (\uB2E4\uC74C \uD574\uC5D0 \uB2E4\uC2DC \uC870\uD68C)\r\n const oneYearMs = 365 * 24 * 60 * 60 * 1000;\r\n if (Date.now() - data.fetchedAt > oneYearMs) {\r\n localStorage.removeItem(`${STORAGE_KEY_PREFIX}${year}`);\r\n return null;\r\n }\r\n\r\n // YYYYMMDD \uBB38\uC790\uC5F4\uC744 Date \uAC1D\uCCB4\uB85C \uBCC0\uD658\r\n return data.holidays.map((dateStr) => {\r\n const y = parseInt(dateStr.slice(0, 4), 10);\r\n const m = parseInt(dateStr.slice(4, 6), 10) - 1;\r\n const d = parseInt(dateStr.slice(6, 8), 10);\r\n return new Date(y, m, d);\r\n });\r\n } catch {\r\n return null;\r\n }\r\n }, []);\r\n\r\n // \uB85C\uCEEC\uC2A4\uD1A0\uB9AC\uC9C0\uC5D0 \uCE90\uC2DC \uC800\uC7A5\r\n const setCachedHolidays = useCallback(\r\n (year: number, holidays: string[]) => {\r\n try {\r\n const data: CachedHolidays = {\r\n year,\r\n holidays,\r\n fetchedAt: Date.now(),\r\n };\r\n localStorage.setItem(\r\n `${STORAGE_KEY_PREFIX}${year}`,\r\n JSON.stringify(data)\r\n );\r\n } catch {\r\n // \uB85C\uCEEC\uC2A4\uD1A0\uB9AC\uC9C0 \uC6A9\uB7C9 \uCD08\uACFC \uB4F1\uC758 \uC5D0\uB7EC \uBB34\uC2DC\r\n }\r\n },\r\n []\r\n );\r\n\r\n // API\uC5D0\uC11C \uACF5\uD734\uC77C \uC870\uD68C\r\n const fetchHolidays = useCallback(\r\n async (year: number): Promise<Date[]> => {\r\n if (!apiKey) {\r\n throw new Error(\"API \uD0A4\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.\");\r\n }\r\n\r\n const baseUrl =\r\n \"https://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/getRestDeInfo\";\r\n const params = new URLSearchParams({\r\n serviceKey: apiKey,\r\n solYear: String(year),\r\n numOfRows: \"100\",\r\n _type: \"json\",\r\n });\r\n\r\n const response = await fetch(`${baseUrl}?${params.toString()}`);\r\n\r\n if (!response.ok) {\r\n throw new Error(`API \uC694\uCCAD \uC2E4\uD328: ${response.status}`);\r\n }\r\n\r\n const data: ApiResponse = await response.json();\r\n\r\n if (data.response.header.resultCode !== \"00\") {\r\n throw new Error(`API \uC5D0\uB7EC: ${data.response.header.resultMsg}`);\r\n }\r\n\r\n const items = data.response.body.items?.item;\r\n if (!items) {\r\n return [];\r\n }\r\n\r\n // \uB2E8\uC77C \uD56D\uBAA9\uC77C \uACBD\uC6B0 \uBC30\uC5F4\uB85C \uBCC0\uD658\r\n const itemArray = Array.isArray(items) ? items : [items];\r\n\r\n // isHoliday\uAC00 \"Y\"\uC778 \uD56D\uBAA9\uB9CC \uD544\uD130\uB9C1\r\n const holidayDates = itemArray\r\n .filter((item) => item.isHoliday === \"Y\")\r\n .map((item) => {\r\n const dateStr = String(item.locdate);\r\n const y = parseInt(dateStr.slice(0, 4), 10);\r\n const m = parseInt(dateStr.slice(4, 6), 10) - 1;\r\n const d = parseInt(dateStr.slice(6, 8), 10);\r\n return new Date(y, m, d);\r\n });\r\n\r\n // \uCE90\uC2DC\uC5D0 \uC800\uC7A5 (YYYYMMDD \uD615\uC2DD\uC73C\uB85C)\r\n const holidayStrings = itemArray\r\n .filter((item) => item.isHoliday === \"Y\")\r\n .map((item) => String(item.locdate));\r\n setCachedHolidays(year, holidayStrings);\r\n\r\n return holidayDates;\r\n },\r\n [apiKey, setCachedHolidays]\r\n );\r\n\r\n useEffect(() => {\r\n if (!apiKey) {\r\n setHolidays([]);\r\n return;\r\n }\r\n\r\n // \uCE90\uC2DC\uB41C \uB370\uC774\uD130 \uD655\uC778\r\n const cached = getCachedHolidays(targetYear);\r\n if (cached) {\r\n setHolidays(cached);\r\n return;\r\n }\r\n\r\n // API \uD638\uCD9C\r\n setLoading(true);\r\n setError(null);\r\n\r\n fetchHolidays(targetYear)\r\n .then((dates) => {\r\n setHolidays(dates);\r\n })\r\n .catch((err) => {\r\n setError(err.message);\r\n setHolidays([]);\r\n })\r\n .finally(() => {\r\n setLoading(false);\r\n });\r\n }, [apiKey, targetYear, getCachedHolidays, fetchHolidays]);\r\n\r\n return { holidays, loading, error };\r\n}\r\n\r\n/**\r\n * \uC5EC\uB7EC \uC5F0\uB3C4\uC758 \uACF5\uD734\uC77C\uC744 \uD55C\uBC88\uC5D0 \uC870\uD68C\uD558\uB294 \uD6C5\r\n */\r\nexport function useKoreanHolidaysRange(\r\n apiKey?: string,\r\n startYear?: number,\r\n endYear?: number\r\n) {\r\n const currentYear = new Date().getFullYear();\r\n const start = startYear ?? currentYear;\r\n const end = endYear ?? currentYear;\r\n\r\n const [holidays, setHolidays] = useState<Date[]>([]);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n useEffect(() => {\r\n if (!apiKey) {\r\n setHolidays([]);\r\n return;\r\n }\r\n\r\n const years: number[] = [];\r\n for (let y = start; y <= end; y++) {\r\n years.push(y);\r\n }\r\n\r\n setLoading(true);\r\n setError(null);\r\n\r\n // \uAC01 \uC5F0\uB3C4\uBCC4\uB85C \uCE90\uC2DC \uD655\uC778 \uB610\uB294 API \uD638\uCD9C\r\n Promise.all(\r\n years.map(async (year) => {\r\n const storageKey = `${STORAGE_KEY_PREFIX}${year}`;\r\n const cached = localStorage.getItem(storageKey);\r\n\r\n if (cached) {\r\n try {\r\n const data: CachedHolidays = JSON.parse(cached);\r\n return data.holidays.map((dateStr) => {\r\n const y = parseInt(dateStr.slice(0, 4), 10);\r\n const m = parseInt(dateStr.slice(4, 6), 10) - 1;\r\n const d = parseInt(dateStr.slice(6, 8), 10);\r\n return new Date(y, m, d);\r\n });\r\n } catch {\r\n // \uD30C\uC2F1 \uC2E4\uD328 \uC2DC API \uD638\uCD9C\r\n }\r\n }\r\n\r\n // API \uD638\uCD9C\r\n const baseUrl =\r\n \"https://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/getRestDeInfo\";\r\n const params = new URLSearchParams({\r\n serviceKey: apiKey,\r\n solYear: String(year),\r\n numOfRows: \"100\",\r\n _type: \"json\",\r\n });\r\n\r\n const response = await fetch(`${baseUrl}?${params.toString()}`);\r\n if (!response.ok) {\r\n throw new Error(`API \uC694\uCCAD \uC2E4\uD328: ${response.status}`);\r\n }\r\n\r\n const data: ApiResponse = await response.json();\r\n if (data.response.header.resultCode !== \"00\") {\r\n throw new Error(data.response.header.resultMsg);\r\n }\r\n\r\n const items = data.response.body.items?.item;\r\n if (!items) return [];\r\n\r\n const itemArray = Array.isArray(items) ? items : [items];\r\n const holidayStrings = itemArray\r\n .filter((item) => item.isHoliday === \"Y\")\r\n .map((item) => String(item.locdate));\r\n\r\n // \uCE90\uC2DC \uC800\uC7A5\r\n const cacheData: CachedHolidays = {\r\n year,\r\n holidays: holidayStrings,\r\n fetchedAt: Date.now(),\r\n };\r\n localStorage.setItem(storageKey, JSON.stringify(cacheData));\r\n\r\n return holidayStrings.map((dateStr) => {\r\n const y = parseInt(dateStr.slice(0, 4), 10);\r\n const m = parseInt(dateStr.slice(4, 6), 10) - 1;\r\n const d = parseInt(dateStr.slice(6, 8), 10);\r\n return new Date(y, m, d);\r\n });\r\n })\r\n )\r\n .then((results) => {\r\n const allHolidays = results.flat();\r\n setHolidays(allHolidays);\r\n })\r\n .catch((err) => {\r\n setError(err.message);\r\n setHolidays([]);\r\n })\r\n .finally(() => {\r\n setLoading(false);\r\n });\r\n }, [apiKey, start, end]);\r\n\r\n return { holidays, loading, error };\r\n}\r\n", "/**\r\n * useGroupedInput.ts\r\n *\r\n * \uADF8\uB8F9\uD654\uB41C \uC785\uB825 \uD544\uB4DC(\uC8FC\uBBFC\uBC88\uD638, \uC0AC\uC5C5\uC790\uBC88\uD638, \uC2DC\uAC04 \uB4F1)\uC5D0\uC11C \uACF5\uD1B5\uC73C\uB85C \uC0AC\uC6A9\uD558\uB294\r\n * \uCEE4\uC11C \uAD00\uB9AC, \uD3EC\uCEE4\uC2A4 \uAD00\uB9AC, \uD0A4\uBCF4\uB4DC \uD578\uB4E4\uB9C1 \uB85C\uC9C1\uC744 \uC81C\uACF5\uD558\uB294 \uD6C5\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { useRef, useState, useCallback, useMemo, RefObject } from \"react\";\r\n\r\nexport interface GroupConfig {\r\n maxLength: number;\r\n ref: RefObject<HTMLInputElement | null>;\r\n value: string;\r\n setValue: (value: string) => void;\r\n}\r\n\r\nexport interface UseGroupedInputOptions {\r\n groups: GroupConfig[];\r\n fontFamily?: string;\r\n fontSize: number;\r\n onComplete?: () => void;\r\n disabled?: boolean;\r\n readonly?: boolean;\r\n}\r\n\r\nexport interface UseGroupedInputReturn {\r\n focusedGroup: number | null;\r\n setFocusedGroup: (group: number | null) => void;\r\n cursorVisible: boolean;\r\n setCursorVisible: (visible: boolean) => void;\r\n cursorPosRef: RefObject<number>;\r\n isClickFocusRef: RefObject<boolean>;\r\n inputComplete: boolean;\r\n setInputComplete: (complete: boolean) => void;\r\n renderTrigger: number;\r\n measureTextWidth: (text: string) => number;\r\n getCursorLeft: (groupIndex: number) => number;\r\n createMouseDownHandler: (\r\n groupIndex: number\r\n ) => (e: React.MouseEvent) => void;\r\n createClickHandler: (groupIndex: number) => (e: React.MouseEvent) => void;\r\n createContainerClickHandler: () => (e: React.MouseEvent) => void;\r\n createFocusHandler: (groupIndex: number) => () => void;\r\n createBlurHandler: () => () => void;\r\n createKeyDownHandler: (\r\n groupIndex: number,\r\n onValueChange?: (newValue: string, groupIndex: number) => void\r\n ) => (e: React.KeyboardEvent<HTMLInputElement>) => void;\r\n createChangeHandler: (\r\n groupIndex: number,\r\n onAfterChange?: (\r\n newValue: string,\r\n groupIndex: number,\r\n isComplete: boolean\r\n ) => void\r\n ) => (e: React.ChangeEvent<HTMLInputElement>) => void;\r\n getCursorPosFromClick: (\r\n e: React.MouseEvent,\r\n value: string,\r\n inputRef: RefObject<HTMLInputElement | null>\r\n ) => number;\r\n forceRender: () => void;\r\n}\r\n\r\nexport function useGroupedInput({\r\n groups,\r\n fontFamily,\r\n fontSize,\r\n onComplete,\r\n disabled = false,\r\n readonly = false,\r\n}: UseGroupedInputOptions): UseGroupedInputReturn {\r\n const [focusedGroup, setFocusedGroup] = useState<number | null>(null);\r\n const [cursorVisible, setCursorVisible] = useState(false);\r\n const [inputComplete, setInputComplete] = useState(false);\r\n const [renderTrigger, setRenderTrigger] = useState(0);\r\n\r\n const cursorPosRef = useRef(0);\r\n const isClickFocusRef = useRef(false);\r\n const isArrowFocusRef = useRef(false);\r\n const arrowTargetPosRef = useRef(0);\r\n\r\n // \uD14D\uC2A4\uD2B8 \uB108\uBE44 \uCE21\uC815\r\n const measureTextWidth = useCallback(\r\n (text: string): number => {\r\n if (typeof document === \"undefined\")\r\n return text.length * fontSize * 0.6;\r\n const canvas = document.createElement(\"canvas\");\r\n const ctx = canvas.getContext(\"2d\");\r\n if (!ctx) return text.length * fontSize * 0.6;\r\n ctx.font = `${fontSize}px ${fontFamily || \"Roboto, sans-serif\"}`;\r\n return ctx.measureText(text).width;\r\n },\r\n [fontSize, fontFamily]\r\n );\r\n\r\n // \uD074\uB9AD \uC704\uCE58\uC5D0\uC11C \uCEE4\uC11C \uC704\uCE58 \uACC4\uC0B0\r\n const getCursorPosFromClick = useCallback(\r\n (\r\n e: React.MouseEvent,\r\n value: string,\r\n inputRef: RefObject<HTMLInputElement | null>\r\n ): number => {\r\n const input = inputRef.current;\r\n if (!input) return value.length;\r\n\r\n const rect = input.getBoundingClientRect();\r\n const clickX = e.clientX - rect.left - 4; // padding \uBCF4\uC815\r\n\r\n let newPos = value.length;\r\n for (let i = 0; i <= value.length; i++) {\r\n const textWidth = measureTextWidth(value.slice(0, i));\r\n if (clickX < textWidth + measureTextWidth(\"0\") / 2) {\r\n newPos = i;\r\n break;\r\n }\r\n }\r\n return newPos;\r\n },\r\n [measureTextWidth]\r\n );\r\n\r\n // \uCEE4\uC11C \uC704\uCE58 \uACC4\uC0B0 (\uB80C\uB354\uB9C1\uC6A9)\r\n const getCursorLeft = useCallback(\r\n (groupIndex: number): number => {\r\n if (focusedGroup !== groupIndex) return 0;\r\n const group = groups[groupIndex];\r\n if (!group) return 0;\r\n const textBeforeCursor = group.value.slice(0, cursorPosRef.current);\r\n return measureTextWidth(textBeforeCursor);\r\n },\r\n [focusedGroup, groups, measureTextWidth]\r\n );\r\n\r\n // \uAC15\uC81C \uB9AC\uB80C\uB354\uB9C1\r\n const forceRender = useCallback(() => {\r\n setRenderTrigger((prev) => prev + 1);\r\n }, []);\r\n\r\n // MouseDown \uD578\uB4E4\uB7EC \uC0DD\uC131\r\n const createMouseDownHandler = useCallback(\r\n (groupIndex: number) => {\r\n return (e: React.MouseEvent) => {\r\n if (disabled || readonly) return;\r\n isClickFocusRef.current = true;\r\n const group = groups[groupIndex];\r\n const newPos = getCursorPosFromClick(e, group.value, group.ref);\r\n cursorPosRef.current = newPos;\r\n };\r\n },\r\n [disabled, readonly, groups, getCursorPosFromClick]\r\n );\r\n\r\n // Click \uD578\uB4E4\uB7EC \uC0DD\uC131 - \uD074\uB9AD \uC2DC \uC804\uCCB4 \uC120\uD0DD\r\n const createClickHandler = useCallback(\r\n (groupIndex: number) => {\r\n return (e: React.MouseEvent) => {\r\n if (disabled || readonly) return;\r\n e.stopPropagation();\r\n\r\n const group = groups[groupIndex];\r\n const input = group.ref.current;\r\n\r\n // \uAC12\uC774 \uC788\uC73C\uBA74 \uC804\uCCB4 \uC120\uD0DD\r\n if (input && group.value.length > 0) {\r\n setTimeout(() => {\r\n input.setSelectionRange(0, group.value.length);\r\n }, 0);\r\n setCursorVisible(false); // \uC804\uCCB4 \uC120\uD0DD \uC2DC \uCEE4\uC11C \uC228\uAE40\r\n } else {\r\n // \uAC12\uC774 \uC5C6\uC73C\uBA74 \uCEE4\uC11C \uD45C\uC2DC\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n\r\n setInputComplete(false);\r\n setFocusedGroup(groupIndex);\r\n setRenderTrigger((prev) => prev + 1);\r\n };\r\n },\r\n [disabled, readonly, groups]\r\n );\r\n\r\n // \uCEE8\uD14C\uC774\uB108 \uD074\uB9AD \uD578\uB4E4\uB7EC \uC0DD\uC131 - \uC678\uACFD \uD074\uB9AD \uC2DC \uCCAB \uBC88\uC9F8 \uBE48 \uCE78 \uB610\uB294 \uB9C8\uC9C0\uB9C9 \uCE78\uC73C\uB85C \uC774\uB3D9\r\n const createContainerClickHandler = useCallback(() => {\r\n return (e: React.MouseEvent) => {\r\n if (disabled || readonly) return;\r\n\r\n // \uC774\uBBF8 input\uC5D0\uC11C \uCC98\uB9AC\uB41C \uD074\uB9AD\uC774\uBA74 \uBB34\uC2DC\r\n const target = e.target as HTMLElement;\r\n if (target.tagName === \"INPUT\") return;\r\n\r\n // \uCCAB \uBC88\uC9F8 \uBE48 \uCE78 \uCC3E\uAE30\r\n let targetIndex = -1;\r\n for (let i = 0; i < groups.length; i++) {\r\n if (groups[i].value.length === 0) {\r\n targetIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n // \uBE48 \uCE78\uC774 \uC5C6\uC73C\uBA74 \uB9C8\uC9C0\uB9C9 \uCE78 \uC120\uD0DD\r\n if (targetIndex === -1) {\r\n targetIndex = groups.length - 1;\r\n }\r\n\r\n const targetGroup = groups[targetIndex];\r\n const input = targetGroup.ref.current;\r\n\r\n if (targetGroup.value.length > 0) {\r\n // \uAC12\uC774 \uC788\uC73C\uBA74 \uC804\uCCB4 \uC120\uD0DD\r\n input?.focus();\r\n setTimeout(() => {\r\n input?.setSelectionRange(0, targetGroup.value.length);\r\n }, 0);\r\n setCursorVisible(false);\r\n } else {\r\n // \uAC12\uC774 \uC5C6\uC73C\uBA74 \uCEE4\uC11C \uD45C\uC2DC\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n input?.focus();\r\n }\r\n\r\n setFocusedGroup(targetIndex);\r\n setInputComplete(false);\r\n setRenderTrigger((prev) => prev + 1);\r\n };\r\n }, [disabled, readonly, groups]);\r\n\r\n // Focus \uD578\uB4E4\uB7EC \uC0DD\uC131\r\n const createFocusHandler = useCallback(\r\n (groupIndex: number) => {\r\n return () => {\r\n const group = groups[groupIndex];\r\n\r\n // \uD074\uB9AD\uC73C\uB85C \uC778\uD55C \uD3EC\uCEE4\uC2A4\uBA74 \uD074\uB9AD \uD578\uB4E4\uB7EC\uC5D0\uC11C \uCC98\uB9AC \uC644\uB8CC\uB428\r\n if (isClickFocusRef.current) {\r\n isClickFocusRef.current = false;\r\n // \uD074\uB9AD \uD578\uB4E4\uB7EC\uC5D0\uC11C \uC804\uCCB4 \uC120\uD0DD \uCC98\uB9AC\uD588\uC73C\uBBC0\uB85C \uC5EC\uAE30\uC11C\uB294 \uC0C1\uD0DC\uB9CC \uC124\uC815\r\n setFocusedGroup(groupIndex);\r\n return;\r\n }\r\n\r\n // \uBC29\uD5A5\uD0A4\uB85C \uC778\uD55C \uD3EC\uCEE4\uC2A4\uBA74 \uC9C0\uC815\uB41C \uC704\uCE58\uB85C\r\n if (isArrowFocusRef.current) {\r\n isArrowFocusRef.current = false;\r\n cursorPosRef.current = arrowTargetPosRef.current;\r\n setCursorVisible(true);\r\n setFocusedGroup(groupIndex);\r\n setRenderTrigger((prev) => prev + 1);\r\n return;\r\n }\r\n\r\n // \uC77C\uBC18 \uD3EC\uCEE4\uC2A4 (\uD0ED \uB4F1) - \uC804\uCCB4 \uC120\uD0DD\r\n const input = group.ref.current;\r\n if (input && group.value.length > 0) {\r\n setTimeout(() => {\r\n input.setSelectionRange(0, group.value.length);\r\n }, 0);\r\n setCursorVisible(false);\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n setFocusedGroup(groupIndex);\r\n };\r\n },\r\n [groups]\r\n );\r\n\r\n // Blur \uD578\uB4E4\uB7EC \uC0DD\uC131\r\n const createBlurHandler = useCallback(() => {\r\n return () => {\r\n setTimeout(() => {\r\n const activeElement = document.activeElement;\r\n const isStillFocused = groups.some(\r\n (group) => group.ref.current === activeElement\r\n );\r\n if (!isStillFocused) {\r\n setCursorVisible(false);\r\n setFocusedGroup(null);\r\n }\r\n }, 0);\r\n };\r\n }, [groups]);\r\n\r\n // KeyDown \uD578\uB4E4\uB7EC \uC0DD\uC131\r\n const createKeyDownHandler = useCallback(\r\n (\r\n groupIndex: number,\r\n onValueChange?: (newValue: string, groupIndex: number) => void\r\n ) => {\r\n return (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n const group = groups[groupIndex];\r\n const input = group.ref.current;\r\n const selectionStart = input?.selectionStart ?? 0;\r\n const selectionEnd = input?.selectionEnd ?? 0;\r\n const hasSelection = selectionEnd > selectionStart;\r\n\r\n if (e.key === \"ArrowLeft\") {\r\n // 3-2. \uD604\uC7AC\uCE78 \uCCAB\uBC88\uC9F8\uC5D0\uC11C \uC67C\uCABD\uD0A4 \u2192 \uC774\uC804\uCE78 \uB9C8\uC9C0\uB9C9 \uBB38\uC790\uB85C\r\n if (selectionStart === 0 && groupIndex > 0) {\r\n e.preventDefault();\r\n const prevGroup = groups[groupIndex - 1];\r\n // \uB9C8\uC9C0\uB9C9 \uBB38\uC790 \uC704\uCE58 (length - 1), \uBE48 \uACBD\uC6B0 0\r\n const newPos =\r\n prevGroup.value.length > 0\r\n ? prevGroup.value.length - 1\r\n : 0;\r\n isArrowFocusRef.current = true;\r\n arrowTargetPosRef.current = newPos;\r\n prevGroup.ref.current?.focus();\r\n prevGroup.ref.current?.setSelectionRange(\r\n newPos,\r\n newPos\r\n );\r\n } else if (selectionStart > 0) {\r\n e.preventDefault();\r\n const newPos = selectionStart - 1;\r\n input?.setSelectionRange(newPos, newPos);\r\n cursorPosRef.current = newPos;\r\n setCursorVisible(true);\r\n setRenderTrigger((prev) => prev + 1);\r\n }\r\n } else if (e.key === \"ArrowRight\") {\r\n // 3-1. \uD604\uC7AC\uCE78 \uB9C8\uC9C0\uB9C9 \uBB38\uC790\uC5D0\uC11C \uC624\uB978\uCABD\uD0A4 \u2192 \uB2E4\uC74C\uCE78 \uCCAB\uBC88\uC9F8\uB85C\r\n if (\r\n selectionEnd >= group.value.length - 1 &&\r\n group.value.length > 0 &&\r\n groupIndex < groups.length - 1\r\n ) {\r\n e.preventDefault();\r\n const nextGroup = groups[groupIndex + 1];\r\n isArrowFocusRef.current = true;\r\n arrowTargetPosRef.current = 0;\r\n nextGroup.ref.current?.focus();\r\n nextGroup.ref.current?.setSelectionRange(0, 0);\r\n } else if (selectionEnd < group.value.length - 1) {\r\n // \uB9C8\uC9C0\uB9C9 \uBB38\uC790 \uC804\uAE4C\uC9C0\uB9CC \uC624\uB978\uCABD \uC774\uB3D9\r\n e.preventDefault();\r\n const newPos = selectionEnd + 1;\r\n input?.setSelectionRange(newPos, newPos);\r\n cursorPosRef.current = newPos;\r\n setCursorVisible(true);\r\n setRenderTrigger((prev) => prev + 1);\r\n }\r\n } else if (e.key === \"Backspace\") {\r\n // \uC804\uCCB4 \uC120\uD0DD \uC0C1\uD0DC\uC5D0\uC11C\uB294 \uC804\uCCB4 \uC0AD\uC81C\r\n if (hasSelection) {\r\n e.preventDefault();\r\n const newValue =\r\n group.value.slice(0, selectionStart) +\r\n group.value.slice(selectionEnd);\r\n group.setValue(newValue);\r\n cursorPosRef.current = selectionStart;\r\n setCursorVisible(true);\r\n setInputComplete(false);\r\n setRenderTrigger((prev) => prev + 1);\r\n setTimeout(() => {\r\n input?.setSelectionRange(\r\n selectionStart,\r\n selectionStart\r\n );\r\n }, 0);\r\n onValueChange?.(newValue, groupIndex);\r\n } else if (selectionStart > 0) {\r\n // 1-3. \uD604\uC7AC\uCEE4\uC11C \uC55E\uC790\uB9AC \uC0AD\uC81C\r\n e.preventDefault();\r\n const newValue =\r\n group.value.slice(0, selectionStart - 1) +\r\n group.value.slice(selectionStart);\r\n group.setValue(newValue);\r\n const newPos = selectionStart - 1;\r\n cursorPosRef.current = newPos;\r\n setCursorVisible(true);\r\n setInputComplete(false);\r\n setRenderTrigger((prev) => prev + 1);\r\n setTimeout(() => {\r\n input?.setSelectionRange(newPos, newPos);\r\n }, 0);\r\n onValueChange?.(newValue, groupIndex);\r\n } else if (groupIndex > 0) {\r\n // 1-4. \uD604\uC7AC\uCE78 \uC81C\uC77C \uC55E\uC5D0\uC11C \u2192 \uC774\uC804\uCE78 \uB9C8\uC9C0\uB9C9 \uC790\uB9AC\uAC12 \uC0AD\uC81C \uB610\uB294 \uCEE4\uC11C \uC774\uB3D9\r\n e.preventDefault();\r\n const prevGroup = groups[groupIndex - 1];\r\n const prevLen = prevGroup.value.length;\r\n\r\n if (prevLen > 0) {\r\n // \uC774\uC804 \uCE78\uC5D0 \uAC12\uC774 \uC788\uC73C\uBA74 \uB9C8\uC9C0\uB9C9 \uAC12 \uC0AD\uC81C\r\n const newPrevValue = prevGroup.value.slice(0, -1);\r\n prevGroup.setValue(newPrevValue);\r\n cursorPosRef.current = newPrevValue.length;\r\n setInputComplete(false);\r\n onValueChange?.(newPrevValue, groupIndex - 1);\r\n } else {\r\n // \uC774\uC804 \uCE78\uC774 \uBE44\uC5B4\uC788\uC73C\uBA74 \uCEE4\uC11C\uB9CC \uC774\uB3D9\r\n cursorPosRef.current = 0;\r\n }\r\n\r\n setCursorVisible(true);\r\n setFocusedGroup(groupIndex - 1);\r\n setRenderTrigger((prev) => prev + 1);\r\n prevGroup.ref.current?.focus();\r\n const finalPos = prevLen > 0 ? prevLen - 1 : 0;\r\n prevGroup.ref.current?.setSelectionRange(\r\n finalPos,\r\n finalPos\r\n );\r\n }\r\n } else if (e.key === \"Delete\") {\r\n // \uC804\uCCB4 \uC120\uD0DD \uC0C1\uD0DC\uC5D0\uC11C\uB294 \uC804\uCCB4 \uC0AD\uC81C\r\n if (hasSelection) {\r\n e.preventDefault();\r\n const newValue =\r\n group.value.slice(0, selectionStart) +\r\n group.value.slice(selectionEnd);\r\n group.setValue(newValue);\r\n cursorPosRef.current = selectionStart;\r\n setCursorVisible(true);\r\n setInputComplete(false);\r\n setRenderTrigger((prev) => prev + 1);\r\n setTimeout(() => {\r\n input?.setSelectionRange(\r\n selectionStart,\r\n selectionStart\r\n );\r\n }, 0);\r\n onValueChange?.(newValue, groupIndex);\r\n } else if (selectionStart < group.value.length) {\r\n // 1-5. del \uD0A4\uB85C \uD604\uC7AC \uCEE4\uC11C \uC704\uCE58 \uAC12 \uC0AD\uC81C\r\n e.preventDefault();\r\n const newValue =\r\n group.value.slice(0, selectionStart) +\r\n group.value.slice(selectionStart + 1);\r\n group.setValue(newValue);\r\n cursorPosRef.current = selectionStart;\r\n setCursorVisible(true);\r\n setInputComplete(false);\r\n setRenderTrigger((prev) => prev + 1);\r\n setTimeout(() => {\r\n input?.setSelectionRange(\r\n selectionStart,\r\n selectionStart\r\n );\r\n }, 0);\r\n onValueChange?.(newValue, groupIndex);\r\n }\r\n }\r\n };\r\n },\r\n [groups]\r\n );\r\n\r\n // Change \uD578\uB4E4\uB7EC \uC0DD\uC131\r\n const createChangeHandler = useCallback(\r\n (\r\n groupIndex: number,\r\n onAfterChange?: (\r\n newValue: string,\r\n groupIndex: number,\r\n isComplete: boolean\r\n ) => void\r\n ) => {\r\n return (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const group = groups[groupIndex];\r\n const numbers = e.target.value\r\n .replace(/\\D/g, \"\")\r\n .slice(0, group.maxLength);\r\n group.setValue(numbers);\r\n cursorPosRef.current = numbers.length;\r\n setCursorVisible(true); // \uC785\uB825 \uC2DC \uCEE4\uC11C \uD45C\uC2DC\r\n\r\n // \uCD5C\uB300 \uAE38\uC774 \uC785\uB825 \uC2DC \uB2E4\uC74C \uADF8\uB8F9\uC73C\uB85C \uC774\uB3D9\r\n const isGroupComplete = numbers.length === group.maxLength;\r\n if (isGroupComplete && groupIndex < groups.length - 1) {\r\n setTimeout(() => {\r\n const nextGroup = groups[groupIndex + 1];\r\n nextGroup.ref.current?.focus();\r\n nextGroup.ref.current?.setSelectionRange(0, 0);\r\n cursorPosRef.current = 0;\r\n }, 0);\r\n }\r\n\r\n // \uC804\uCCB4 \uC644\uB8CC \uCCB4\uD06C\r\n const allComplete =\r\n isGroupComplete &&\r\n groupIndex === groups.length - 1 &&\r\n groups\r\n .slice(0, -1)\r\n .every((g) => g.value.length === g.maxLength);\r\n\r\n if (allComplete) {\r\n setInputComplete(true);\r\n onComplete?.();\r\n } else {\r\n setInputComplete(false);\r\n }\r\n\r\n setRenderTrigger((prev) => prev + 1);\r\n onAfterChange?.(numbers, groupIndex, allComplete);\r\n };\r\n },\r\n [groups, onComplete]\r\n );\r\n\r\n return {\r\n focusedGroup,\r\n setFocusedGroup,\r\n cursorVisible,\r\n setCursorVisible,\r\n cursorPosRef,\r\n isClickFocusRef,\r\n inputComplete,\r\n setInputComplete,\r\n renderTrigger,\r\n measureTextWidth,\r\n getCursorLeft,\r\n createMouseDownHandler,\r\n createClickHandler,\r\n createContainerClickHandler,\r\n createFocusHandler,\r\n createBlurHandler,\r\n createKeyDownHandler,\r\n createChangeHandler,\r\n getCursorPosFromClick,\r\n forceRender,\r\n };\r\n}\r\n", "const HANGUL_SYLLABLE_START = 0xac00;\r\nconst HANGUL_SYLLABLE_END = 0xd7a3;\r\nconst HANGUL_SYLLABLE_BASE = 0xac00;\r\nconst HANGUL_JUNGSEONG_COUNT = 21;\r\nconst HANGUL_JONGSEONG_COUNT = 28;\r\n\r\nconst CHOSEONG_TO_ENGLISH_KEYS = [\r\n \"r\",\r\n \"R\",\r\n \"s\",\r\n \"e\",\r\n \"E\",\r\n \"f\",\r\n \"a\",\r\n \"q\",\r\n \"Q\",\r\n \"t\",\r\n \"T\",\r\n \"d\",\r\n \"w\",\r\n \"W\",\r\n \"c\",\r\n \"z\",\r\n \"x\",\r\n \"v\",\r\n \"g\",\r\n] as const;\r\n\r\nconst JUNGSEONG_TO_ENGLISH_KEYS = [\r\n \"k\",\r\n \"o\",\r\n \"i\",\r\n \"O\",\r\n \"j\",\r\n \"p\",\r\n \"u\",\r\n \"P\",\r\n \"h\",\r\n \"hk\",\r\n \"ho\",\r\n \"hl\",\r\n \"y\",\r\n \"n\",\r\n \"nj\",\r\n \"np\",\r\n \"nl\",\r\n \"b\",\r\n \"m\",\r\n \"ml\",\r\n \"l\",\r\n] as const;\r\n\r\nconst JONGSEONG_TO_ENGLISH_KEYS = [\r\n \"\",\r\n \"r\",\r\n \"R\",\r\n \"rt\",\r\n \"s\",\r\n \"sw\",\r\n \"sg\",\r\n \"e\",\r\n \"f\",\r\n \"fr\",\r\n \"fa\",\r\n \"fq\",\r\n \"ft\",\r\n \"fx\",\r\n \"fv\",\r\n \"fg\",\r\n \"a\",\r\n \"q\",\r\n \"qt\",\r\n \"t\",\r\n \"T\",\r\n \"d\",\r\n \"w\",\r\n \"c\",\r\n \"z\",\r\n \"x\",\r\n \"v\",\r\n \"g\",\r\n] as const;\r\n\r\nconst COMPATIBILITY_JAMO_TO_ENGLISH_KEYS: Record<string, string> = {\r\n \u3131: \"r\",\r\n \u3132: \"R\",\r\n \u3133: \"rt\",\r\n \u3134: \"s\",\r\n \u3135: \"sw\",\r\n \u3136: \"sg\",\r\n \u3137: \"e\",\r\n \u3138: \"E\",\r\n \u3139: \"f\",\r\n \u313A: \"fr\",\r\n \u313B: \"fa\",\r\n \u313C: \"fq\",\r\n \u313D: \"ft\",\r\n \u313E: \"fx\",\r\n \u313F: \"fv\",\r\n \u3140: \"fg\",\r\n \u3141: \"a\",\r\n \u3142: \"q\",\r\n \u3143: \"Q\",\r\n \u3144: \"qt\",\r\n \u3145: \"t\",\r\n \u3146: \"T\",\r\n \u3147: \"d\",\r\n \u3148: \"w\",\r\n \u3149: \"W\",\r\n \u314A: \"c\",\r\n \u314B: \"z\",\r\n \u314C: \"x\",\r\n \u314D: \"v\",\r\n \u314E: \"g\",\r\n \u314F: \"k\",\r\n \u3150: \"o\",\r\n \u3151: \"i\",\r\n \u3152: \"O\",\r\n \u3153: \"j\",\r\n \u3154: \"p\",\r\n \u3155: \"u\",\r\n \u3156: \"P\",\r\n \u3157: \"h\",\r\n \u3158: \"hk\",\r\n \u3159: \"ho\",\r\n \u315A: \"hl\",\r\n \u315B: \"y\",\r\n \u315C: \"n\",\r\n \u315D: \"nj\",\r\n \u315E: \"np\",\r\n \u315F: \"nl\",\r\n \u3160: \"b\",\r\n \u3161: \"m\",\r\n \u3162: \"ml\",\r\n \u3163: \"l\",\r\n};\r\n\r\nconst MODERN_CHOSEONG_TO_ENGLISH_KEYS: Record<string, string> = {\r\n \u1100: \"r\",\r\n \u1101: \"R\",\r\n \u1102: \"s\",\r\n \u1103: \"e\",\r\n \u1104: \"E\",\r\n \u1105: \"f\",\r\n \u1106: \"a\",\r\n \u1107: \"q\",\r\n \u1108: \"Q\",\r\n \u1109: \"t\",\r\n \u110A: \"T\",\r\n \u110B: \"d\",\r\n \u110C: \"w\",\r\n \u110D: \"W\",\r\n \u110E: \"c\",\r\n \u110F: \"z\",\r\n \u1110: \"x\",\r\n \u1111: \"v\",\r\n \u1112: \"g\",\r\n};\r\n\r\nconst MODERN_JUNGSEONG_TO_ENGLISH_KEYS: Record<string, string> = {\r\n \u1161: \"k\",\r\n \u1162: \"o\",\r\n \u1163: \"i\",\r\n \u1164: \"O\",\r\n \u1165: \"j\",\r\n \u1166: \"p\",\r\n \u1167: \"u\",\r\n \u1168: \"P\",\r\n \u1169: \"h\",\r\n \u116A: \"hk\",\r\n \u116B: \"ho\",\r\n \u116C: \"hl\",\r\n \u116D: \"y\",\r\n \u116E: \"n\",\r\n \u116F: \"nj\",\r\n \u1170: \"np\",\r\n \u1171: \"nl\",\r\n \u1172: \"b\",\r\n \u1173: \"m\",\r\n \u1174: \"ml\",\r\n \u1175: \"l\",\r\n};\r\n\r\nconst MODERN_JONGSEONG_TO_ENGLISH_KEYS: Record<string, string> = {\r\n \u11A8: \"r\",\r\n \u11A9: \"R\",\r\n \u11AA: \"rt\",\r\n \u11AB: \"s\",\r\n \u11AC: \"sw\",\r\n \u11AD: \"sg\",\r\n \u11AE: \"e\",\r\n \u11AF: \"f\",\r\n \u11B0: \"fr\",\r\n \u11B1: \"fa\",\r\n \u11B2: \"fq\",\r\n \u11B3: \"ft\",\r\n \u11B4: \"fx\",\r\n \u11B5: \"fv\",\r\n \u11B6: \"fg\",\r\n \u11B7: \"a\",\r\n \u11B8: \"q\",\r\n \u11B9: \"qt\",\r\n \u11BA: \"t\",\r\n \u11BB: \"T\",\r\n \u11BC: \"d\",\r\n \u11BD: \"w\",\r\n \u11BE: \"c\",\r\n \u11BF: \"z\",\r\n \u11C0: \"x\",\r\n \u11C1: \"v\",\r\n \u11C2: \"g\",\r\n};\r\n\r\nconst KOREAN_CHAR_RE = /[\u3131-\u314E\u314F-\u3163\uAC00-\uD7A3\u1100-\u11C2]/;\r\nconst KOREAN_IME_QUERY_RE = /^[0-9\u3131-\u314E\u314F-\u3163\uAC00-\uD7A3\u1100-\u11C2\\s]+$/;\r\n\r\nconst convertCompatibilityJamoToEnglish = (char: string) =>\r\n COMPATIBILITY_JAMO_TO_ENGLISH_KEYS[char] ?? null;\r\n\r\nconst convertModernJamoToEnglish = (char: string) =>\r\n MODERN_CHOSEONG_TO_ENGLISH_KEYS[char] ??\r\n MODERN_JUNGSEONG_TO_ENGLISH_KEYS[char] ??\r\n MODERN_JONGSEONG_TO_ENGLISH_KEYS[char] ??\r\n null;\r\n\r\nconst convertHangulSyllableToEnglish = (char: string) => {\r\n const codePoint = char.codePointAt(0);\r\n if (codePoint == null) {\r\n return null;\r\n }\r\n if (codePoint < HANGUL_SYLLABLE_START || codePoint > HANGUL_SYLLABLE_END) {\r\n return null;\r\n }\r\n\r\n const syllableIndex = codePoint - HANGUL_SYLLABLE_BASE;\r\n const choseongIndex = Math.floor(\r\n syllableIndex / (HANGUL_JUNGSEONG_COUNT * HANGUL_JONGSEONG_COUNT),\r\n );\r\n const jungseongIndex = Math.floor(\r\n (syllableIndex % (HANGUL_JUNGSEONG_COUNT * HANGUL_JONGSEONG_COUNT)) /\r\n HANGUL_JONGSEONG_COUNT,\r\n );\r\n const jongseongIndex = syllableIndex % HANGUL_JONGSEONG_COUNT;\r\n\r\n return `${CHOSEONG_TO_ENGLISH_KEYS[choseongIndex] ?? \"\"}${JUNGSEONG_TO_ENGLISH_KEYS[jungseongIndex] ?? \"\"}${JONGSEONG_TO_ENGLISH_KEYS[jongseongIndex] ?? \"\"}`;\r\n};\r\n\r\nexport const convertMistypedKoreanImeToEnglish = (\r\n value: string | null | undefined,\r\n) =>\r\n Array.from(value ?? \"\")\r\n .map((char) => {\r\n const compatibilityJamo = convertCompatibilityJamoToEnglish(char);\r\n if (compatibilityJamo != null) {\r\n return compatibilityJamo;\r\n }\r\n\r\n const modernJamo = convertModernJamoToEnglish(char);\r\n if (modernJamo != null) {\r\n return modernJamo;\r\n }\r\n\r\n const syllable = convertHangulSyllableToEnglish(char);\r\n if (syllable != null) {\r\n return syllable;\r\n }\r\n\r\n return char;\r\n })\r\n .join(\"\");\r\n\r\nexport const shouldAutoConvertKoreanImeQuery = (\r\n value: string | null | undefined,\r\n) => {\r\n const trimmed = (value ?? \"\").trim();\r\n if (!trimmed) {\r\n return false;\r\n }\r\n\r\n if (!KOREAN_CHAR_RE.test(trimmed)) {\r\n return false;\r\n }\r\n\r\n return KOREAN_IME_QUERY_RE.test(trimmed);\r\n};\r\n", "/**\r\n * ClearTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n forwardRef,\r\n useCallback,\r\n useRef,\r\n useImperativeHandle,\r\n useState,\r\n} from \"react\";\r\nimport { TextField, IconButton, InputAdornment } from \"@mui/material\";\r\nimport type { BaseTextFieldProps as MuiBaseTextFieldProps } from \"@mui/material/TextField\";\r\nimport ClearIcon from \"@mui/icons-material/Clear\";\r\nimport type { ClearTextFieldProps } from \"./types\";\r\nimport { useTextFieldBase } from \"./hooks\";\r\n\r\nconst ClearTextFieldBase = forwardRef<HTMLDivElement, ClearTextFieldProps>(\r\n function ClearTextFieldBase(\r\n {\r\n value,\r\n clearIcon = true,\r\n debounce = 0,\r\n readonly,\r\n spellCheck = false,\r\n onChange,\r\n onBlur,\r\n onFocus,\r\n onClear,\r\n slotProps,\r\n size,\r\n inputRef: externalInputRef,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const {\r\n internalValue,\r\n setInternalValue,\r\n handleChange,\r\n handleBlur,\r\n emitChange,\r\n lastEmittedValue,\r\n debounceTimer,\r\n } = useTextFieldBase({\r\n value: (value as string) ?? \"\",\r\n name: props.name,\r\n debounce,\r\n onChange,\r\n onBlur,\r\n });\r\n\r\n const [isFocused, setIsFocused] = useState(false);\r\n const [forceShrink, setForceShrink] = useState(false);\r\n const isClearingRef = useRef(false);\r\n\r\n // input ref for focus after clear\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLInputElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n // size\uC5D0 \uB530\uB978 \uC544\uC774\uCF58 \uD06C\uAE30\r\n const iconSize = size === \"small\" ? 20 : 24;\r\n\r\n // \uD074\uB9AC\uC5B4 \uBC84\uD2BC \uD578\uB4E4\uB7EC\r\n const handleClear = () => {\r\n isClearingRef.current = true;\r\n setForceShrink(true);\r\n setIsFocused(true);\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n debounceTimer.current = null;\r\n }\r\n\r\n if (internalValue !== \"\") {\r\n lastEmittedValue.current = internalValue;\r\n }\r\n setInternalValue(\"\");\r\n // \uC989\uC2DC emit\uC744 \uC704\uD574 fake \uC774\uBCA4\uD2B8 \uC0DD\uC131\r\n const eventTarget = {\r\n name: props.name || \"\",\r\n value: \"\",\r\n } as HTMLInputElement;\r\n const fakeEvent = {\r\n target: eventTarget,\r\n currentTarget: eventTarget,\r\n } as unknown as React.ChangeEvent<HTMLInputElement>;\r\n emitChange(fakeEvent, \"\", true);\r\n onClear?.();\r\n // \uD074\uB9AC\uC5B4 \uD6C4 \uD3EC\uCEE4\uC2A4\r\n internalInputRef.current?.focus();\r\n setTimeout(() => {\r\n isClearingRef.current = false;\r\n }, 0);\r\n };\r\n\r\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\r\n setIsFocused(true);\r\n onFocus?.(event);\r\n };\r\n\r\n const handleBlurWithFocus = (\r\n event: React.FocusEvent<HTMLInputElement>,\r\n ) => {\r\n if (isClearingRef.current) {\r\n isClearingRef.current = false;\r\n handleBlur(event);\r\n return;\r\n }\r\n\r\n setIsFocused(false);\r\n setForceShrink(false);\r\n handleBlur(event);\r\n };\r\n\r\n // readonly\uC77C \uB54C \uD3EC\uCEE4\uC2A4 \uC2A4\uD0C0\uC77C \uC81C\uAC70\r\n const readonlyStyles = readonly\r\n ? {\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n const shouldShrink = forceShrink || isFocused || internalValue !== \"\";\r\n\r\n const resolveInputLabelSlotProps = (\r\n ownerState: MuiBaseTextFieldProps,\r\n ): Record<string, unknown> => {\r\n const baseInputLabel = slotProps?.inputLabel;\r\n const resolvedInputLabel =\r\n typeof baseInputLabel === \"function\"\r\n ? baseInputLabel(ownerState)\r\n : baseInputLabel;\r\n\r\n return {\r\n ...resolvedInputLabel,\r\n shrink:\r\n (resolvedInputLabel as { shrink?: boolean })?.shrink ??\r\n shouldShrink,\r\n };\r\n };\r\n\r\n return (\r\n <TextField\r\n {...props}\r\n ref={ref}\r\n inputRef={internalInputRef}\r\n size={size}\r\n focused={isFocused || isClearingRef.current}\r\n value={internalValue}\r\n onChange={handleChange}\r\n onFocus={handleFocus}\r\n onBlur={handleBlurWithFocus}\r\n autoComplete=\"off\"\r\n spellCheck={spellCheck}\r\n sx={{\r\n ...readonlyStyles,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...(props.sx ?? {}),\r\n }}\r\n slotProps={{\r\n ...slotProps,\r\n inputLabel: resolveInputLabelSlotProps,\r\n input: {\r\n ...slotProps?.input,\r\n readOnly: readonly,\r\n notched: shouldShrink,\r\n endAdornment:\r\n clearIcon && !readonly ? (\r\n <InputAdornment\r\n position=\"end\"\r\n sx={{\r\n visibility: internalValue\r\n ? isFocused\r\n ? \"visible\"\r\n : \"hidden\"\r\n : \"hidden\",\r\n mr: 0,\r\n }}\r\n >\r\n <IconButton\r\n size=\"small\"\r\n onMouseDown={(event) => {\r\n event.preventDefault();\r\n if (!readonly) {\r\n handleClear();\r\n }\r\n }}\r\n edge=\"end\"\r\n tabIndex={-1}\r\n disabled={readonly}\r\n sx={{\r\n padding:\r\n size === \"small\"\r\n ? \"2px\"\r\n : \"4px\",\r\n color: \"#666\",\r\n \"&:hover\": {\r\n color: \"#333\",\r\n backgroundColor:\r\n \"rgba(0, 0, 0, 0.04)\",\r\n },\r\n }}\r\n >\r\n <ClearIcon\r\n sx={{ fontSize: iconSize - 4 }}\r\n />\r\n </IconButton>\r\n </InputAdornment>\r\n ) : undefined,\r\n },\r\n }}\r\n />\r\n );\r\n },\r\n);\r\n\r\nconst ClearTextFieldWithForm = forwardRef<HTMLDivElement, ClearTextFieldProps>(\r\n function ClearTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"ClearTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"ClearTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <ClearTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const ClearTextField = forwardRef<HTMLDivElement, ClearTextFieldProps>(\r\n function ClearTextField(props, ref) {\r\n if (props.form) {\r\n return <ClearTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <ClearTextFieldBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * PasswordTextField.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n forwardRef,\r\n useRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField, IconButton, InputAdornment } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport Visibility from \"@mui/icons-material/Visibility\";\r\nimport VisibilityOff from \"@mui/icons-material/VisibilityOff\";\r\nimport type { PasswordTextFieldProps } from \"./types\";\r\nimport { useTextFieldBase } from \"./hooks\";\r\nimport {\r\n DEFAULT_PASSWORD_VALIDATION_RULES as DEFAULT_VALIDATION_RULES,\r\n validatePassword,\r\n} from \"./utils\";\r\n\r\nconst PasswordTextFieldBase = forwardRef<\r\n HTMLDivElement,\r\n PasswordTextFieldProps\r\n>(function PasswordTextFieldBase(\r\n {\r\n showToggle = true,\r\n label,\r\n validationRules,\r\n onValidationChange,\r\n invalidBorderColor,\r\n debounce,\r\n readonly,\r\n slotProps,\r\n sx,\r\n size,\r\n value,\r\n onChange,\r\n onBlur,\r\n inputRef: externalInputRef,\r\n ...props\r\n },\r\n ref,\r\n) {\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLInputElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n const [showPassword, setShowPassword] = useState(false);\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n\r\n // useTextFieldBase \uD6C5 \uC0AC\uC6A9\r\n const { internalValue, handleChange, handleBlur } = useTextFieldBase({\r\n value: (value as string) ?? \"\",\r\n name: props.name,\r\n debounce,\r\n onChange,\r\n onBlur,\r\n });\r\n\r\n // size\uC5D0 \uB530\uB978 \uC544\uC774\uCF58 \uD06C\uAE30\r\n const iconSize = size === \"small\" ? 20 : 24;\r\n\r\n const handleTogglePassword = () => {\r\n setShowPassword((prev) => !prev);\r\n };\r\n const performValidation = useCallback(\r\n (inputValue: string) => {\r\n const rules = validationRules || {};\r\n const mergedRules = { ...DEFAULT_VALIDATION_RULES, ...rules };\r\n const result = validatePassword(inputValue, mergedRules);\r\n // \uCD5C\uC18C\uAE38\uC774 \uC774\uC0C1 \uC785\uB825\uB418\uC5C8\uC744 \uB54C\uB9CC invalid \uC0C1\uD0DC \uC801\uC6A9\r\n const minLength = mergedRules.minLength || 8;\r\n setIsInvalid(\r\n !result.isValid &&\r\n inputValue.length >= minLength &&\r\n inputValue.length > 0,\r\n );\r\n if (onValidationChange) {\r\n onValidationChange(result);\r\n }\r\n },\r\n [validationRules, onValidationChange],\r\n );\r\n\r\n // internalValue \uBCC0\uACBD \uC2DC \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n useEffect(() => {\r\n performValidation(internalValue);\r\n }, [internalValue, performValidation]);\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uC2E4\uD328 \uC2DC \uD14C\uB450\uB9AC \uC2A4\uD0C0\uC77C (invalidBorderColor\uAC00 \uC124\uC815\uB41C \uACBD\uC6B0\uC5D0\uB9CC)\r\n const invalidStyles: SxProps<Theme> =\r\n isInvalid && invalidBorderColor\r\n ? {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n \"&:hover fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n \"&.Mui-focused fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n },\r\n \"& .MuiFilledInput-root\": {\r\n \"&:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:hover:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:after\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n },\r\n \"& .MuiInput-root\": {\r\n \"&:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:hover:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:after\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n },\r\n }\r\n : {};\r\n\r\n // readonly\uC77C \uB54C \uD3EC\uCEE4\uC2A4 \uC2A4\uD0C0\uC77C \uC81C\uAC70\r\n const readonlyStyles = readonly\r\n ? {\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n return (\r\n <TextField\r\n {...props}\r\n ref={ref}\r\n inputRef={internalInputRef}\r\n value={internalValue}\r\n onChange={handleChange}\r\n onBlur={handleBlur}\r\n label={label}\r\n size={size}\r\n type={showPassword ? \"text\" : \"password\"}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n sx={{\r\n ...invalidStyles,\r\n ...readonlyStyles,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...sx,\r\n }}\r\n slotProps={{\r\n ...slotProps,\r\n input: {\r\n ...slotProps?.input,\r\n readOnly: readonly,\r\n endAdornment:\r\n showToggle && !readonly ? (\r\n <InputAdornment\r\n position=\"end\"\r\n sx={{ ml: 1, mr: size === \"small\" ? -0.5 : 1 }}\r\n >\r\n <IconButton\r\n onClick={handleTogglePassword}\r\n edge=\"end\"\r\n tabIndex={-1}\r\n size={size}\r\n sx={{\r\n color: \"#666\",\r\n \"&:hover\": {\r\n color: \"#333\",\r\n backgroundColor:\r\n \"rgba(0, 0, 0, 0.04)\",\r\n },\r\n }}\r\n >\r\n {showPassword ? (\r\n <VisibilityOff\r\n sx={{ fontSize: iconSize }}\r\n />\r\n ) : (\r\n <Visibility\r\n sx={{ fontSize: iconSize }}\r\n />\r\n )}\r\n </IconButton>\r\n </InputAdornment>\r\n ) : undefined,\r\n },\r\n }}\r\n />\r\n );\r\n});\r\n\r\nconst PasswordTextFieldWithForm = forwardRef<\r\n HTMLDivElement,\r\n PasswordTextFieldProps\r\n>(function PasswordTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"PasswordTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"PasswordTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name) as string | undefined;\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <PasswordTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const PasswordTextField = forwardRef<\r\n HTMLDivElement,\r\n PasswordTextFieldProps\r\n>(function PasswordTextField(props, ref) {\r\n if (props.form) {\r\n return <PasswordTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <PasswordTextFieldBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * date.ts - \uB0A0\uC9DC \uAD00\uB828 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport type { DateFormat, DateTimeFormat } from \"../types\";\r\n\r\n/**\r\n * \uC724\uB144 \uCCB4\uD06C\r\n */\r\nexport function isLeapYear(year: number): boolean {\r\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\r\n}\r\n\r\n/**\r\n * \uD574\uB2F9 \uC6D4\uC758 \uB9D0\uC77C \uACC4\uC0B0\r\n */\r\nexport function getDaysInMonth(year: number, month: number): number {\r\n if (month === 2) {\r\n return isLeapYear(year) ? 29 : 28;\r\n }\r\n if ([4, 6, 9, 11].includes(month)) {\r\n return 30;\r\n }\r\n return 31;\r\n}\r\n\r\n/**\r\n * \uB0A0\uC9DC \uD3EC\uB9F7\uC5D0 \uB530\uB978 \uAD6C\uBD84\uC790 \uAC00\uC838\uC624\uAE30\r\n */\r\nexport function getSeparator(format: DateFormat): string {\r\n if (format.includes(\".\")) return \".\";\r\n if (format.includes(\"/\")) return \"/\";\r\n return \"-\";\r\n}\r\n\r\n/**\r\n * \uB0A0\uC9DC \uC790\uB3D9 \uD3EC\uB9F7\uD305 \uD568\uC218\r\n */\r\nexport function formatDate(value: string, format: DateFormat): string {\r\n const rawNumbers = value.replace(/\\D/g, \"\");\r\n const separator = getSeparator(format);\r\n\r\n if (rawNumbers.length === 0) return \"\";\r\n\r\n // \uC785\uB825\uB41C \uC22B\uC790\uB97C \uC720\uD6A8\uD55C \uBC94\uC704\uB85C \uBCF4\uC815\r\n const numbers = constrainDateNumbers(rawNumbers, format);\r\n\r\n // YYYY-MM-DD, YYYY.MM.DD, YYYY/MM/DD (\uAE30\uBCF8)\r\n if (format.startsWith(\"YYYY\")) {\r\n if (numbers.length < 4) return numbers;\r\n if (numbers.length === 4) return `${numbers}${separator}`;\r\n if (numbers.length < 6)\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(4)}`;\r\n if (numbers.length === 6)\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(\r\n 4\r\n )}${separator}`;\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(\r\n 4,\r\n 6\r\n )}${separator}${numbers.slice(6, 8)}`;\r\n }\r\n\r\n // MM-DD-YYYY, MM.DD.YYYY, MM/DD/YYYY (\uBBF8\uAD6D\uC2DD)\r\n if (\r\n format.startsWith(\"MM\") &&\r\n format.includes(\"DD\") &&\r\n format.endsWith(\"YYYY\")\r\n ) {\r\n if (numbers.length < 2) return numbers;\r\n if (numbers.length === 2) return `${numbers}${separator}`;\r\n if (numbers.length < 4)\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(2)}`;\r\n if (numbers.length === 4)\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(\r\n 2\r\n )}${separator}`;\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(\r\n 2,\r\n 4\r\n )}${separator}${numbers.slice(4, 8)}`;\r\n }\r\n\r\n // MM-DD, MM.DD, MM/DD (\uC6D4\uC77C\uB9CC)\r\n if (\r\n format.startsWith(\"MM\") &&\r\n format.includes(\"DD\") &&\r\n !format.includes(\"YYYY\")\r\n ) {\r\n if (numbers.length < 2) return numbers;\r\n if (numbers.length === 2) return `${numbers}${separator}`;\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(2, 4)}`;\r\n }\r\n\r\n // DD-MM-YYYY, DD.MM.YYYY, DD/MM/YYYY (\uC720\uB7FD\uC2DD)\r\n if (format.startsWith(\"DD\") && format.endsWith(\"YYYY\")) {\r\n if (numbers.length < 2) return numbers;\r\n if (numbers.length === 2) return `${numbers}${separator}`;\r\n if (numbers.length < 4)\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(2)}`;\r\n if (numbers.length === 4)\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(\r\n 2\r\n )}${separator}`;\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(\r\n 2,\r\n 4\r\n )}${separator}${numbers.slice(4, 8)}`;\r\n }\r\n\r\n // DD-MM, DD.MM, DD/MM (\uC77C\uC6D4\uB9CC)\r\n if (\r\n format.startsWith(\"DD\") &&\r\n format.includes(\"MM\") &&\r\n !format.includes(\"YYYY\")\r\n ) {\r\n if (numbers.length < 2) return numbers;\r\n if (numbers.length === 2) return `${numbers}${separator}`;\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(2, 4)}`;\r\n }\r\n\r\n // YY-MM-DD, YY.MM.DD (2\uC790\uB9AC \uC5F0\uB3C4)\r\n if (format.startsWith(\"YY\") && !format.startsWith(\"YYYY\")) {\r\n if (numbers.length < 2) return numbers;\r\n if (numbers.length === 2) return `${numbers}${separator}`;\r\n if (numbers.length < 4)\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(2)}`;\r\n if (numbers.length === 4)\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(\r\n 2\r\n )}${separator}`;\r\n return `${numbers.slice(0, 2)}${separator}${numbers.slice(\r\n 2,\r\n 4\r\n )}${separator}${numbers.slice(4, 6)}`;\r\n }\r\n\r\n // \uAE30\uBCF8: YYYY-MM-DD\r\n if (numbers.length < 4) return numbers;\r\n if (numbers.length === 4) return `${numbers}${separator}`;\r\n if (numbers.length < 6)\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(4)}`;\r\n if (numbers.length === 6)\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(\r\n 4\r\n )}${separator}`;\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(\r\n 4,\r\n 6\r\n )}${separator}${numbers.slice(6, 8)}`;\r\n}\r\n\r\n/**\r\n * \uD3EC\uB9F7\uC5D0 \uB530\uB978 \uCD5C\uB300 \uAE38\uC774 \uACC4\uC0B0\r\n */\r\nexport function getMaxLength(format: DateFormat): number {\r\n if (format === \"MM-DD\" || format === \"MM.DD\" || format === \"MM/DD\")\r\n return 5;\r\n if (format === \"DD-MM\" || format === \"DD.MM\" || format === \"DD/MM\")\r\n return 5;\r\n if (format === \"YY-MM\" || format === \"YY.MM\" || format === \"YY/MM\")\r\n return 5;\r\n if (format === \"YYYY-MM\" || format === \"YYYY.MM\" || format === \"YYYY/MM\")\r\n return 7;\r\n if (format.startsWith(\"YY\") && !format.startsWith(\"YYYY\")) return 8;\r\n return 10;\r\n}\r\n\r\n/**\r\n * \uD3EC\uB9F7\uC5D0 \uB530\uB978 \uC644\uC131 \uC22B\uC790 \uAE38\uC774\r\n */\r\nexport function getCompleteLength(format: DateFormat): number {\r\n if (format === \"MM-DD\" || format === \"MM.DD\" || format === \"MM/DD\")\r\n return 4;\r\n if (format === \"DD-MM\" || format === \"DD.MM\" || format === \"DD/MM\")\r\n return 4;\r\n if (format === \"YY-MM\" || format === \"YY.MM\" || format === \"YY/MM\")\r\n return 4;\r\n if (format === \"YYYY-MM\" || format === \"YYYY.MM\" || format === \"YYYY/MM\")\r\n return 6;\r\n if (format.startsWith(\"YY\") && !format.startsWith(\"YYYY\")) return 6;\r\n return 8;\r\n}\r\n\r\n/**\r\n * \uB0A0\uC9DC \uBB38\uC790\uC5F4\uC5D0\uC11C \uC5F0/\uC6D4/\uC77C \uCD94\uCD9C\r\n */\r\nexport function parseDateParts(\r\n value: string,\r\n format: DateFormat\r\n): { year: number; month: number; day: number } | null {\r\n const numbers = value.replace(/\\D/g, \"\");\r\n const completeLength = getCompleteLength(format);\r\n\r\n if (numbers.length !== completeLength) return null;\r\n\r\n let year: number, month: number, day: number;\r\n\r\n if (format === \"YYYY-MM\" || format === \"YYYY.MM\" || format === \"YYYY/MM\") {\r\n year = parseInt(numbers.slice(0, 4), 10);\r\n month = parseInt(numbers.slice(4, 6), 10);\r\n day = 1;\r\n } else if (format === \"YY-MM\" || format === \"YY.MM\" || format === \"YY/MM\") {\r\n const yy = parseInt(numbers.slice(0, 2), 10);\r\n year = yy >= 50 ? 1900 + yy : 2000 + yy;\r\n month = parseInt(numbers.slice(2, 4), 10);\r\n day = 1;\r\n } else if (format === \"MM-DD\" || format === \"MM.DD\" || format === \"MM/DD\") {\r\n month = parseInt(numbers.slice(0, 2), 10);\r\n day = parseInt(numbers.slice(2, 4), 10);\r\n year = new Date().getFullYear();\r\n } else if (format === \"DD-MM\" || format === \"DD.MM\" || format === \"DD/MM\") {\r\n day = parseInt(numbers.slice(0, 2), 10);\r\n month = parseInt(numbers.slice(2, 4), 10);\r\n year = new Date().getFullYear();\r\n } else if (format.startsWith(\"YYYY\")) {\r\n year = parseInt(numbers.slice(0, 4), 10);\r\n month = parseInt(numbers.slice(4, 6), 10);\r\n day = parseInt(numbers.slice(6, 8), 10);\r\n } else if (format.startsWith(\"MM\") && format.endsWith(\"YYYY\")) {\r\n month = parseInt(numbers.slice(0, 2), 10);\r\n day = parseInt(numbers.slice(2, 4), 10);\r\n year = parseInt(numbers.slice(4, 8), 10);\r\n } else if (format.startsWith(\"DD\") && format.endsWith(\"YYYY\")) {\r\n day = parseInt(numbers.slice(0, 2), 10);\r\n month = parseInt(numbers.slice(2, 4), 10);\r\n year = parseInt(numbers.slice(4, 8), 10);\r\n } else if (format.startsWith(\"YY\") && !format.startsWith(\"YYYY\")) {\r\n const yy = parseInt(numbers.slice(0, 2), 10);\r\n year = yy >= 50 ? 1900 + yy : 2000 + yy;\r\n month = parseInt(numbers.slice(2, 4), 10);\r\n day = parseInt(numbers.slice(4, 6), 10);\r\n } else {\r\n year = parseInt(numbers.slice(0, 4), 10);\r\n month = parseInt(numbers.slice(4, 6), 10);\r\n day = parseInt(numbers.slice(6, 8), 10);\r\n }\r\n\r\n return { year, month, day };\r\n}\r\n\r\n/**\r\n * \uB0A0\uC9DC \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n */\r\nexport function validateDate(\r\n value: string,\r\n format: DateFormat,\r\n minDate?: Date,\r\n maxDate?: Date\r\n): boolean {\r\n const parts = parseDateParts(value, format);\r\n if (!parts) return false;\r\n\r\n const { year, month, day } = parts;\r\n\r\n if (month < 1 || month > 12) return false;\r\n if (day < 1 || day > 31) return false;\r\n\r\n const daysInMonth = new Date(year, month, 0).getDate();\r\n if (day > daysInMonth) return false;\r\n\r\n const date = new Date(year, month - 1, day);\r\n\r\n if (minDate && date < minDate) return false;\r\n if (maxDate && date > maxDate) return false;\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * \uB0A0\uC9DC \uBB38\uC790\uC5F4\uC744 Date \uAC1D\uCCB4\uB85C \uBCC0\uD658\r\n */\r\nexport function parseToDate(value: string, format: DateFormat): Date | null {\r\n const parts = parseDateParts(value, format);\r\n if (!parts) return null;\r\n\r\n const { year, month, day } = parts;\r\n\r\n if (month < 1 || month > 12 || day < 1 || day > 31) return null;\r\n\r\n return new Date(year, month - 1, day);\r\n}\r\n\r\n/**\r\n * \uB0A0\uC9DC \uAC12 \uC81C\uD55C (\uB144/\uC6D4/\uC77C)\r\n */\r\nexport function clampDateValue(\r\n value: string,\r\n type: \"year\" | \"month\" | \"day\",\r\n yearValue?: string,\r\n monthValue?: string\r\n): string {\r\n if (value.length === 0) return value;\r\n\r\n if (type === \"year\") {\r\n if (value.length === 1) {\r\n const digit = parseInt(value, 10);\r\n if (digit !== 1 && digit !== 2) return \"2\";\r\n }\r\n return value;\r\n }\r\n\r\n if (type === \"month\") {\r\n if (value.length === 1) {\r\n const digit = parseInt(value, 10);\r\n if (digit > 1) return \"0\" + value;\r\n }\r\n if (value.length === 2) {\r\n const num = parseInt(value, 10);\r\n if (num > 12) return \"12\";\r\n if (num < 1) return \"01\";\r\n }\r\n return value;\r\n }\r\n\r\n if (type === \"day\") {\r\n if (value.length === 1) {\r\n const digit = parseInt(value, 10);\r\n if (digit > 3) return \"0\" + value;\r\n }\r\n if (value.length === 2) {\r\n const num = parseInt(value, 10);\r\n const year = yearValue ? parseInt(yearValue, 10) : 0;\r\n const month = monthValue ? parseInt(monthValue, 10) : 0;\r\n const maxDay = year && month ? getDaysInMonth(year, month) : 31;\r\n if (num > maxDay) return String(maxDay).padStart(2, \"0\");\r\n if (num < 1) return \"01\";\r\n }\r\n return value;\r\n }\r\n\r\n return value;\r\n}\r\n\r\n/**\r\n * DateTimeFormat\uC5D0\uC11C DateFormat \uBD80\uBD84 \uCD94\uCD9C\r\n */\r\nexport function extractDateFormat(format: DateTimeFormat): DateFormat {\r\n const datePart = format.split(\" \")[0];\r\n return datePart as DateFormat;\r\n}\r\n\r\n/**\r\n * \uCD08 \uD544\uB4DC\uAC00 \uC788\uB294\uC9C0 \uD655\uC778\r\n */\r\nexport function hasSecondField(format: DateTimeFormat): boolean {\r\n return format.includes(\":ss\");\r\n}\r\n\r\n/**\r\n * \uC785\uB825\uB41C \uC22B\uC790\uB97C \uC720\uD6A8\uD55C \uBC94\uC704\uB85C \uBCF4\uC815 (\uB0A0\uC9DC\uC6A9)\r\n */\r\nexport function constrainDateNumbers(\r\n numbers: string,\r\n format: DateFormat\r\n): string {\r\n if (numbers.length === 0) return \"\";\r\n\r\n let result = \"\";\r\n let year = 0;\r\n let month = 0;\r\n\r\n // YYYY-MM-DD, YYYY.MM.DD, YYYY/MM/DD\r\n if (format.startsWith(\"YYYY\")) {\r\n if (numbers.length >= 1) {\r\n const firstDigit = numbers[0];\r\n if (firstDigit !== \"1\" && firstDigit !== \"2\") {\r\n result += \"2\";\r\n } else {\r\n result += firstDigit;\r\n }\r\n }\r\n if (numbers.length >= 2) result += numbers[1];\r\n if (numbers.length >= 3) result += numbers[2];\r\n if (numbers.length >= 4) {\r\n result += numbers[3];\r\n year = parseInt(result, 10);\r\n }\r\n\r\n if (numbers.length >= 5) {\r\n let monthStr = numbers.slice(4, 6);\r\n if (monthStr.length === 1) {\r\n if (parseInt(monthStr, 10) > 1) {\r\n monthStr = \"0\" + monthStr;\r\n } else {\r\n result += monthStr;\r\n return result;\r\n }\r\n }\r\n month = parseInt(monthStr, 10);\r\n if (month > 12) month = 12;\r\n if (month < 1 && monthStr.length === 2) month = 1;\r\n result += month.toString().padStart(2, \"0\");\r\n }\r\n\r\n if (numbers.length >= 7) {\r\n let dayStr = numbers.slice(6, 8);\r\n if (dayStr.length === 1) {\r\n if (parseInt(dayStr, 10) > 3) {\r\n dayStr = \"0\" + dayStr;\r\n } else {\r\n result += dayStr;\r\n return result;\r\n }\r\n }\r\n let day = parseInt(dayStr, 10);\r\n const maxDay =\r\n year > 0 && month > 0 ? getDaysInMonth(year, month) : 31;\r\n if (day > maxDay) day = maxDay;\r\n if (day < 1 && dayStr.length === 2) day = 1;\r\n result += day.toString().padStart(2, \"0\");\r\n }\r\n\r\n return result;\r\n }\r\n\r\n // MM-DD, MM.DD, MM/DD (\uC6D4\uC77C\uB9CC)\r\n if (\r\n format.startsWith(\"MM\") &&\r\n format.includes(\"DD\") &&\r\n !format.includes(\"YYYY\") &&\r\n !format.includes(\"YY\")\r\n ) {\r\n // \uC6D4 \uCC98\uB9AC\r\n if (numbers.length >= 1) {\r\n let monthStr = numbers.slice(0, 2);\r\n if (monthStr.length === 1) {\r\n if (parseInt(monthStr, 10) > 1) {\r\n monthStr = \"0\" + monthStr;\r\n } else {\r\n result += monthStr;\r\n return result;\r\n }\r\n }\r\n month = parseInt(monthStr, 10);\r\n if (month > 12) month = 12;\r\n if (month < 1 && monthStr.length === 2) month = 1;\r\n result += month.toString().padStart(2, \"0\");\r\n }\r\n\r\n // \uC77C \uCC98\uB9AC\r\n if (numbers.length >= 3) {\r\n let dayStr = numbers.slice(2, 4);\r\n if (dayStr.length === 1) {\r\n if (parseInt(dayStr, 10) > 3) {\r\n dayStr = \"0\" + dayStr;\r\n } else {\r\n result += dayStr;\r\n return result;\r\n }\r\n }\r\n let day = parseInt(dayStr, 10);\r\n const maxDay =\r\n month > 0\r\n ? getDaysInMonth(new Date().getFullYear(), month)\r\n : 31;\r\n if (day > maxDay) day = maxDay;\r\n if (day < 1 && dayStr.length === 2) day = 1;\r\n result += day.toString().padStart(2, \"0\");\r\n }\r\n\r\n return result;\r\n }\r\n\r\n // DD-MM, DD.MM, DD/MM (\uC77C\uC6D4\uB9CC)\r\n if (\r\n format.startsWith(\"DD\") &&\r\n format.includes(\"MM\") &&\r\n !format.includes(\"YYYY\") &&\r\n !format.includes(\"YY\")\r\n ) {\r\n // \uC77C \uCC98\uB9AC (\uC6D4\uC744 \uBAA8\uB974\uBBC0\uB85C \uCD5C\uB300 31\uAE4C\uC9C0)\r\n if (numbers.length >= 1) {\r\n let dayStr = numbers.slice(0, 2);\r\n if (dayStr.length === 1) {\r\n if (parseInt(dayStr, 10) > 3) {\r\n dayStr = \"0\" + dayStr;\r\n } else {\r\n result += dayStr;\r\n return result;\r\n }\r\n }\r\n let day = parseInt(dayStr, 10);\r\n if (day > 31) day = 31;\r\n if (day < 1 && dayStr.length === 2) day = 1;\r\n result += day.toString().padStart(2, \"0\");\r\n }\r\n\r\n // \uC6D4 \uCC98\uB9AC\r\n if (numbers.length >= 3) {\r\n let monthStr = numbers.slice(2, 4);\r\n if (monthStr.length === 1) {\r\n if (parseInt(monthStr, 10) > 1) {\r\n monthStr = \"0\" + monthStr;\r\n } else {\r\n result += monthStr;\r\n return result;\r\n }\r\n }\r\n month = parseInt(monthStr, 10);\r\n if (month > 12) month = 12;\r\n if (month < 1 && monthStr.length === 2) month = 1;\r\n result += month.toString().padStart(2, \"0\");\r\n }\r\n\r\n return result;\r\n }\r\n\r\n // MM-DD-YYYY, MM.DD.YYYY (\uBBF8\uAD6D\uC2DD)\r\n if (\r\n format.startsWith(\"MM\") &&\r\n format.includes(\"DD\") &&\r\n format.endsWith(\"YYYY\")\r\n ) {\r\n // \uC6D4 \uCC98\uB9AC\r\n if (numbers.length >= 1) {\r\n let monthStr = numbers.slice(0, 2);\r\n if (monthStr.length === 1) {\r\n if (parseInt(monthStr, 10) > 1) {\r\n monthStr = \"0\" + monthStr;\r\n } else {\r\n result += monthStr;\r\n return result;\r\n }\r\n }\r\n month = parseInt(monthStr, 10);\r\n if (month > 12) month = 12;\r\n if (month < 1 && monthStr.length === 2) month = 1;\r\n result += month.toString().padStart(2, \"0\");\r\n }\r\n\r\n // \uC77C \uCC98\uB9AC\r\n if (numbers.length >= 3) {\r\n let dayStr = numbers.slice(2, 4);\r\n if (dayStr.length === 1) {\r\n if (parseInt(dayStr, 10) > 3) {\r\n dayStr = \"0\" + dayStr;\r\n } else {\r\n result += dayStr;\r\n return result;\r\n }\r\n }\r\n let day = parseInt(dayStr, 10);\r\n if (day > 31) day = 31;\r\n if (day < 1 && dayStr.length === 2) day = 1;\r\n result += day.toString().padStart(2, \"0\");\r\n }\r\n\r\n // \uC5F0\uB3C4 \uCC98\uB9AC\r\n if (numbers.length >= 5) {\r\n const yearStr = numbers.slice(4, 8);\r\n if (yearStr.length >= 1) {\r\n const firstDigit = yearStr[0];\r\n if (firstDigit !== \"1\" && firstDigit !== \"2\") {\r\n result += \"2\";\r\n } else {\r\n result += firstDigit;\r\n }\r\n }\r\n if (yearStr.length >= 2) result += yearStr[1];\r\n if (yearStr.length >= 3) result += yearStr[2];\r\n if (yearStr.length >= 4) result += yearStr[3];\r\n }\r\n\r\n return result;\r\n }\r\n\r\n // DD-MM-YYYY, DD.MM.YYYY (\uC720\uB7FD\uC2DD)\r\n if (format.startsWith(\"DD\") && format.endsWith(\"YYYY\")) {\r\n // \uC77C \uCC98\uB9AC\r\n if (numbers.length >= 1) {\r\n let dayStr = numbers.slice(0, 2);\r\n if (dayStr.length === 1) {\r\n if (parseInt(dayStr, 10) > 3) {\r\n dayStr = \"0\" + dayStr;\r\n } else {\r\n result += dayStr;\r\n return result;\r\n }\r\n }\r\n let day = parseInt(dayStr, 10);\r\n if (day > 31) day = 31;\r\n if (day < 1 && dayStr.length === 2) day = 1;\r\n result += day.toString().padStart(2, \"0\");\r\n }\r\n\r\n // \uC6D4 \uCC98\uB9AC\r\n if (numbers.length >= 3) {\r\n let monthStr = numbers.slice(2, 4);\r\n if (monthStr.length === 1) {\r\n if (parseInt(monthStr, 10) > 1) {\r\n monthStr = \"0\" + monthStr;\r\n } else {\r\n result += monthStr;\r\n return result;\r\n }\r\n }\r\n month = parseInt(monthStr, 10);\r\n if (month > 12) month = 12;\r\n if (month < 1 && monthStr.length === 2) month = 1;\r\n result += month.toString().padStart(2, \"0\");\r\n }\r\n\r\n // \uC5F0\uB3C4 \uCC98\uB9AC\r\n if (numbers.length >= 5) {\r\n const yearStr = numbers.slice(4, 8);\r\n if (yearStr.length >= 1) {\r\n const firstDigit = yearStr[0];\r\n if (firstDigit !== \"1\" && firstDigit !== \"2\") {\r\n result += \"2\";\r\n } else {\r\n result += firstDigit;\r\n }\r\n }\r\n if (yearStr.length >= 2) result += yearStr[1];\r\n if (yearStr.length >= 3) result += yearStr[2];\r\n if (yearStr.length >= 4) result += yearStr[3];\r\n }\r\n\r\n return result;\r\n }\r\n\r\n // YY-MM-DD (2\uC790\uB9AC \uC5F0\uB3C4)\r\n if (format.startsWith(\"YY\") && !format.startsWith(\"YYYY\")) {\r\n // \uC5F0\uB3C4 \uCC98\uB9AC (2\uC790\uB9AC)\r\n if (numbers.length >= 1) result += numbers[0];\r\n if (numbers.length >= 2) result += numbers[1];\r\n\r\n // \uC6D4 \uCC98\uB9AC\r\n if (numbers.length >= 3) {\r\n let monthStr = numbers.slice(2, 4);\r\n if (monthStr.length === 1) {\r\n if (parseInt(monthStr, 10) > 1) {\r\n monthStr = \"0\" + monthStr;\r\n } else {\r\n result += monthStr;\r\n return result;\r\n }\r\n }\r\n month = parseInt(monthStr, 10);\r\n if (month > 12) month = 12;\r\n if (month < 1 && monthStr.length === 2) month = 1;\r\n result += month.toString().padStart(2, \"0\");\r\n }\r\n\r\n // \uC77C \uCC98\uB9AC\r\n if (numbers.length >= 5) {\r\n let dayStr = numbers.slice(4, 6);\r\n if (dayStr.length === 1) {\r\n if (parseInt(dayStr, 10) > 3) {\r\n dayStr = \"0\" + dayStr;\r\n } else {\r\n result += dayStr;\r\n return result;\r\n }\r\n }\r\n let day = parseInt(dayStr, 10);\r\n const maxDay =\r\n month > 0\r\n ? getDaysInMonth(new Date().getFullYear(), month)\r\n : 31;\r\n if (day > maxDay) day = maxDay;\r\n if (day < 1 && dayStr.length === 2) day = 1;\r\n result += day.toString().padStart(2, \"0\");\r\n }\r\n\r\n return result;\r\n }\r\n\r\n return numbers;\r\n}\r\n\r\n/**\r\n * \uB0A0\uC9DC \uC790\uB3D9 \uD3EC\uB9F7\uD305 \uD568\uC218 (DateTimeTextField\uC6A9)\r\n */\r\nexport function formatDateValue(value: string, format: DateFormat): string {\r\n const rawNumbers = value.replace(/\\D/g, \"\");\r\n const separator = getSeparator(format);\r\n\r\n if (rawNumbers.length === 0) return \"\";\r\n\r\n const numbers = constrainDateNumbers(rawNumbers, format);\r\n\r\n if (format.startsWith(\"YYYY\")) {\r\n if (numbers.length <= 4) return numbers;\r\n if (numbers.length === 4) return `${numbers}${separator}`;\r\n if (numbers.length <= 6)\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(4)}`;\r\n if (numbers.length === 6)\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(\r\n 4\r\n )}${separator}`;\r\n return `${numbers.slice(0, 4)}${separator}${numbers.slice(\r\n 4,\r\n 6\r\n )}${separator}${numbers.slice(6, 8)}`;\r\n }\r\n\r\n return numbers;\r\n}\r\n\r\n/**\r\n * \uB0A0\uC9DC \uD3EC\uB9F7\uC744 \uBC11\uC904 placeholder\uB85C \uBCC0\uD658\r\n */\r\nexport function formatToPlaceholder(format: DateFormat): string {\r\n return format\r\n .replace(/YYYY/g, \"Y___\")\r\n .replace(/YY/g, \"__\")\r\n .replace(/MM/g, \"__\")\r\n .replace(/DD/g, \"__\");\r\n}\r\n\r\n/**\r\n * \uD074\uB9AD \uC704\uCE58\uC5D0 \uB530\uB77C \uC120\uD0DD\uD560 \uC601\uC5ED\uC758 \uC2DC\uC791/\uB05D \uC778\uB371\uC2A4 \uBC18\uD658\r\n */\r\nexport function getSegmentRange(\r\n cursorPos: number,\r\n format: DateFormat\r\n): { start: number; end: number } {\r\n if (format === \"MM-DD\" || format === \"MM.DD\" || format === \"MM/DD\") {\r\n if (cursorPos <= 2) return { start: 0, end: 2 };\r\n return { start: 3, end: 5 };\r\n }\r\n\r\n if (format === \"DD-MM\" || format === \"DD.MM\" || format === \"DD/MM\") {\r\n if (cursorPos <= 2) return { start: 0, end: 2 };\r\n return { start: 3, end: 5 };\r\n }\r\n\r\n if (format === \"YYYY-MM\" || format === \"YYYY.MM\" || format === \"YYYY/MM\") {\r\n if (cursorPos <= 4) return { start: 0, end: 4 };\r\n return { start: 5, end: 7 };\r\n }\r\n\r\n if (format === \"YY-MM\" || format === \"YY.MM\" || format === \"YY/MM\") {\r\n if (cursorPos <= 2) return { start: 0, end: 2 };\r\n return { start: 3, end: 5 };\r\n }\r\n\r\n if (format.startsWith(\"YY\") && !format.startsWith(\"YYYY\")) {\r\n if (cursorPos <= 2) return { start: 0, end: 2 };\r\n if (cursorPos <= 5) return { start: 3, end: 5 };\r\n return { start: 6, end: 8 };\r\n }\r\n\r\n if (\r\n format.startsWith(\"MM\") &&\r\n format.includes(\"DD\") &&\r\n format.endsWith(\"YYYY\")\r\n ) {\r\n if (cursorPos <= 2) return { start: 0, end: 2 };\r\n if (cursorPos <= 5) return { start: 3, end: 5 };\r\n return { start: 6, end: 10 };\r\n }\r\n\r\n if (format.startsWith(\"DD\") && format.endsWith(\"YYYY\")) {\r\n if (cursorPos <= 2) return { start: 0, end: 2 };\r\n if (cursorPos <= 5) return { start: 3, end: 5 };\r\n return { start: 6, end: 10 };\r\n }\r\n\r\n if (cursorPos <= 4) return { start: 0, end: 4 };\r\n if (cursorPos <= 7) return { start: 5, end: 7 };\r\n return { start: 8, end: 10 };\r\n}\r\n\r\n/**\r\n * \uD3EC\uB9F7\uC5D0 \uC5F0\uB3C4\uAC00 \uD3EC\uD568\uB418\uC5B4 \uC788\uB294\uC9C0 \uD655\uC778\r\n * - YYYY \uB610\uB294 YY\uAC00 \uD3EC\uD568\uB418\uC5B4 \uC788\uC73C\uBA74 \uC5F0\uB3C4\uAC00 \uC788\uB294 \uD3EC\uB9F7\r\n */\r\nexport function hasYearInFormat(format: DateFormat): boolean {\r\n return format.includes(\"YYYY\") || format.includes(\"YY\");\r\n}\r\n\r\n/**\r\n * \uD3EC\uB9F7\uC774 2\uC790\uB9AC \uC5F0\uB3C4(YY)\uB97C \uC0AC\uC6A9\uD558\uB294\uC9C0 \uD655\uC778\r\n */\r\nexport function has2DigitYear(format: DateFormat): boolean {\r\n return format.includes(\"YY\") && !format.includes(\"YYYY\");\r\n}\r\n\r\n/**\r\n * 2\uC790\uB9AC \uC5F0\uB3C4\uB97C 4\uC790\uB9AC \uC5F0\uB3C4\uB85C \uBCC0\uD658\r\n * - 50 \uC774\uC0C1\uC774\uBA74 1900\uB144\uB300, 50 \uBBF8\uB9CC\uC774\uBA74 2000\uB144\uB300\r\n */\r\nexport function convertYY2YYYY(yy: number): number {\r\n return yy >= 50 ? 1900 + yy : 2000 + yy;\r\n}\r\n\r\n/**\r\n * \uD3EC\uB9F7\uC5D0\uC11C \uB0A0\uC9DC \uD30C\uC2F1 (\uC5F0\uB3C4 \uC5C6\uB294 \uD3EC\uB9F7 \uC9C0\uC6D0, internalYear \uD65C\uC6A9)\r\n */\r\nexport function parseDateWithInternalYear(\r\n formattedValue: string,\r\n format: DateFormat,\r\n internalYear?: number | null\r\n): { year: number; month: number; day: number } | null {\r\n const numbers = formattedValue.replace(/\\D/g, \"\");\r\n const completeLength = getCompleteLength(format);\r\n\r\n if (numbers.length !== completeLength) return null;\r\n\r\n let year: number, month: number, day: number;\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\r\n if (!hasYearInFormat(format)) {\r\n year = internalYear || new Date().getFullYear();\r\n if (format.startsWith(\"MM\")) {\r\n month = parseInt(numbers.slice(0, 2), 10);\r\n day = parseInt(numbers.slice(2, 4), 10);\r\n } else {\r\n day = parseInt(numbers.slice(0, 2), 10);\r\n month = parseInt(numbers.slice(2, 4), 10);\r\n }\r\n } else if (has2DigitYear(format)) {\r\n // 2\uC790\uB9AC \uC5F0\uB3C4 \uD3EC\uB9F7\r\n const yy = parseInt(numbers.slice(0, 2), 10);\r\n year = convertYY2YYYY(yy);\r\n month = parseInt(numbers.slice(2, 4), 10);\r\n day = numbers.length >= 6 ? parseInt(numbers.slice(4, 6), 10) : 1;\r\n } else if (format.startsWith(\"YYYY\")) {\r\n year = parseInt(numbers.slice(0, 4), 10);\r\n month = parseInt(numbers.slice(4, 6), 10);\r\n day = numbers.length >= 8 ? parseInt(numbers.slice(6, 8), 10) : 1;\r\n } else if (format.startsWith(\"MM\") && format.endsWith(\"YYYY\")) {\r\n month = parseInt(numbers.slice(0, 2), 10);\r\n day = parseInt(numbers.slice(2, 4), 10);\r\n year = parseInt(numbers.slice(4, 8), 10);\r\n } else if (format.startsWith(\"DD\") && format.endsWith(\"YYYY\")) {\r\n day = parseInt(numbers.slice(0, 2), 10);\r\n month = parseInt(numbers.slice(2, 4), 10);\r\n year = parseInt(numbers.slice(4, 8), 10);\r\n } else {\r\n // \uAE30\uBCF8: YYYY-MM-DD\r\n year = parseInt(numbers.slice(0, 4), 10);\r\n month = parseInt(numbers.slice(4, 6), 10);\r\n day = numbers.length >= 8 ? parseInt(numbers.slice(6, 8), 10) : 1;\r\n }\r\n\r\n if (month < 1 || month > 12 || day < 1 || day > 31) return null;\r\n\r\n return { year, month, day };\r\n}\r\n\r\n/**\r\n * \uB2EC\uB825 \uC120\uD0DD \uB610\uB294 \uC785\uB825\uAC12\uC744 \uCD9C\uB825\uC6A9 \uBB38\uC790\uC5F4\uB85C \uBCC0\uD658 (\uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC774\uC5B4\uB3C4 \uC5F0\uB3C4 \uD3EC\uD568)\r\n * @param formattedValue - \uD3EC\uB9F7\uB41C \uB0A0\uC9DC \uBB38\uC790\uC5F4 (\uC608: \"12-25\")\r\n * @param format - \uB0A0\uC9DC \uD3EC\uB9F7\r\n * @param separator - \uCD9C\uB825 \uAD6C\uBD84\uC790\r\n * @param internalYear - \uB0B4\uBD80\uC801\uC73C\uB85C \uAD00\uB9AC\uD558\uB294 \uC5F0\uB3C4 (\uC5F0\uB3C4 \uC5C6\uB294 \uD3EC\uB9F7\uC6A9)\r\n * @returns \uCD9C\uB825\uC6A9 \uB0A0\uC9DC \uBB38\uC790\uC5F4 (\uD56D\uC0C1 \uC5F0\uB3C4 \uD3EC\uD568, \uC608: \"2024-12-25\")\r\n */\r\nexport function buildDateOutputValue(\r\n formattedValue: string,\r\n format: DateFormat,\r\n separator: string,\r\n internalYear?: number | null\r\n): string {\r\n const formatSeparator = getSeparator(format);\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC788\uB294 \uD3EC\uB9F7: \uAD6C\uBD84\uC790\uB9CC \uBCC0\uD658\r\n if (hasYearInFormat(format)) {\r\n return formattedValue.replace(\r\n new RegExp(`\\\\${formatSeparator}`, \"g\"),\r\n separator\r\n );\r\n }\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7: \uC5F0\uB3C4 \uCD94\uAC00\uD558\uC5EC YYYY-MM-DD \uD615\uC2DD\uC73C\uB85C \uCD9C\uB825\r\n const numbers = formattedValue.replace(/\\D/g, \"\");\r\n const completeLength = getCompleteLength(format);\r\n\r\n if (numbers.length !== completeLength) {\r\n // \uC644\uC131\uB418\uC9C0 \uC54A\uC740 \uACBD\uC6B0 \uAD6C\uBD84\uC790\uB9CC \uBCC0\uD658\r\n return formattedValue.replace(\r\n new RegExp(`\\\\${formatSeparator}`, \"g\"),\r\n separator\r\n );\r\n }\r\n\r\n const yearToUse = internalYear || new Date().getFullYear();\r\n let month: string, day: string;\r\n\r\n if (format.startsWith(\"MM\")) {\r\n month = numbers.slice(0, 2);\r\n day = numbers.slice(2, 4);\r\n } else {\r\n day = numbers.slice(0, 2);\r\n month = numbers.slice(2, 4);\r\n }\r\n\r\n return `${yearToUse}${separator}${month}${separator}${day}`;\r\n}\r\n\r\n/**\r\n * Date \uAC1D\uCCB4\uC5D0\uC11C \uD3EC\uB9F7\uC5D0 \uB9DE\uB294 \uC22B\uC790 \uBB38\uC790\uC5F4 \uC0DD\uC131\r\n */\r\nexport function dateToNumbers(date: Date, format: DateFormat): string {\r\n const year = String(date.getFullYear());\r\n const year2 = year.slice(-2);\r\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\r\n const day = String(date.getDate()).padStart(2, \"0\");\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\r\n if (!hasYearInFormat(format)) {\r\n return format.startsWith(\"MM\") ? `${month}${day}` : `${day}${month}`;\r\n }\r\n\r\n // YYYY-MM, YY-MM (\uB144\uC6D4\uB9CC)\r\n if (!format.includes(\"DD\")) {\r\n return has2DigitYear(format) ? `${year2}${month}` : `${year}${month}`;\r\n }\r\n\r\n // 2\uC790\uB9AC \uC5F0\uB3C4\r\n if (has2DigitYear(format)) {\r\n return `${year2}${month}${day}`;\r\n }\r\n\r\n // DD-MM-YYYY (\uC720\uB7FD\uC2DD)\r\n if (format.startsWith(\"DD\") && format.endsWith(\"YYYY\")) {\r\n return `${day}${month}${year}`;\r\n }\r\n\r\n // MM-DD-YYYY (\uBBF8\uAD6D\uC2DD)\r\n if (\r\n format.startsWith(\"MM\") &&\r\n format.includes(\"DD\") &&\r\n format.endsWith(\"YYYY\")\r\n ) {\r\n return `${month}${day}${year}`;\r\n }\r\n\r\n // \uAE30\uBCF8: YYYY-MM-DD\r\n return `${year}${month}${day}`;\r\n}\r\n", "/**\r\n * time.ts - \uC2DC\uAC04 \uAD00\uB828 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport type { TimeFormat } from \"../types\";\r\n\r\n/**\r\n * \uD3EC\uB9F7\uC5D0 \uB530\uB978 \uD544\uB4DC \uAC1C\uC218 (2: \uC2DC:\uBD84, 3: \uC2DC:\uBD84:\uCD08)\r\n */\r\nexport function getTimeFieldCount(format: TimeFormat): number {\r\n if (format === \"HH:mm:ss\" || format === \"hh:mm:ss\") {\r\n return 3;\r\n }\r\n return 2;\r\n}\r\n\r\n/**\r\n * 12\uC2DC\uAC04 \uD615\uC2DD\uC778\uC9C0 \uD655\uC778\r\n */\r\nexport function is12HourFormat(format: string): boolean {\r\n return format.includes(\"hh:\");\r\n}\r\n\r\n/**\r\n * \uC2DC\uAC04 \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n * @param formatOrIs12Hour - TimeFormat \uBB38\uC790\uC5F4 \uB610\uB294 12\uC2DC\uAC04\uC81C \uC5EC\uBD80 boolean\r\n */\r\nexport function validateTime(\r\n hour: string,\r\n minute: string,\r\n second: string,\r\n formatOrIs12Hour: TimeFormat | boolean,\r\n minTime?: string,\r\n maxTime?: string\r\n): boolean {\r\n const is12Hour = typeof formatOrIs12Hour === \"boolean\" ? formatOrIs12Hour : is12HourFormat(formatOrIs12Hour);\r\n const h = parseInt(hour, 10);\r\n const m = parseInt(minute, 10);\r\n const s = second ? parseInt(second, 10) : 0;\r\n\r\n if (isNaN(h) || isNaN(m) || (second && isNaN(s))) return false;\r\n\r\n if (is12Hour) {\r\n if (h < 0 || h > 12) return false;\r\n } else {\r\n if (h < 0 || h > 23) return false;\r\n }\r\n\r\n if (m < 0 || m > 59) return false;\r\n if (s < 0 || s > 59) return false;\r\n\r\n if (minTime || maxTime) {\r\n const timeValue = h * 3600 + m * 60 + s;\r\n\r\n if (minTime) {\r\n const minParts = minTime.split(\":\");\r\n const minH = parseInt(minParts[0], 10) || 0;\r\n const minM = parseInt(minParts[1], 10) || 0;\r\n const minS = parseInt(minParts[2], 10) || 0;\r\n const minValue = minH * 3600 + minM * 60 + minS;\r\n if (timeValue < minValue) return false;\r\n }\r\n\r\n if (maxTime) {\r\n const maxParts = maxTime.split(\":\");\r\n const maxH = parseInt(maxParts[0], 10) || 0;\r\n const maxM = parseInt(maxParts[1], 10) || 0;\r\n const maxS = parseInt(maxParts[2], 10) || 0;\r\n const maxValue = maxH * 3600 + maxM * 60 + maxS;\r\n if (timeValue > maxValue) return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * \uC2DC\uAC04 \uAC12 \uC81C\uD55C (\uC2DC/\uBD84/\uCD08)\r\n * - 24\uC2DC\uAC04 \uD615\uC2DD\uC5D0\uC11C 24 \uC774\uC0C1\uC744 \uC785\uB825\uD558\uBA74 24\uB97C \uBE7C\uC11C \uBCC0\uD658 (24\u219200, 25\u219201, 26\u219202, ...)\r\n * - \uCCAB \uC790\uB9AC\uAC00 \uBC94\uC704 \uCD08\uACFC \uC2DC \uC55E\uC5D0 0\uC744 \uBD99\uC5EC\uC11C \uB450 \uC790\uB9AC\uB85C \uBCC0\uD658\r\n */\r\nexport function clampTimeValue(value: string, type: \"hour\" | \"minute\" | \"second\", is12Hour: boolean = false): string {\r\n if (value.length === 0) return value;\r\n\r\n if (value.length === 1) {\r\n const digit = parseInt(value, 10);\r\n if (type === \"hour\") {\r\n const maxFirstDigit = is12Hour ? 1 : 2;\r\n // \uCCAB \uC790\uB9AC\uAC00 \uBC94\uC704 \uCD08\uACFC\uD558\uBA74 \uC55E\uC5D0 0\uC744 \uBD99\uC5EC\uC11C \uB450 \uC790\uB9AC\uB85C \uB9CC\uB4E6\r\n if (digit > maxFirstDigit) return `0${digit}`;\r\n } else {\r\n // \uBD84/\uCD08: \uCCAB \uC790\uB9AC\uAC00 6-9\uBA74 \uC55E\uC5D0 0 \uBD99\uC784\r\n if (digit > 5) return `0${digit}`;\r\n }\r\n return value;\r\n }\r\n\r\n const num = parseInt(value, 10);\r\n if (isNaN(num)) return value;\r\n\r\n if (type === \"hour\") {\r\n // 24\uC2DC\uAC04 \uD615\uC2DD\uC5D0\uC11C 24 \uC774\uC0C1\uC744 \uC785\uB825\uD558\uBA74 24\uB97C \uBE7C\uC11C \uBCC0\uD658\r\n if (!is12Hour && num >= 24) {\r\n return String(num - 24).padStart(2, \"0\");\r\n }\r\n const maxHour = is12Hour ? 12 : 23;\r\n if (num > maxHour) return String(maxHour).padStart(2, \"0\");\r\n } else {\r\n if (num > 59) return \"59\";\r\n }\r\n return value;\r\n}\r\n", "/**\r\n * number.ts - \uC22B\uC790 \uD3EC\uB9F7\uD305 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\n/**\r\n * \uC22B\uC790 \uD3EC\uB9F7\uD305 \uD568\uC218\r\n */\r\nexport function formatNumber(value: string, thousandSeparator: boolean, decimalLength?: number): string {\r\n if (!value) return \"\";\r\n\r\n // \uB9C8\uC774\uB108\uC2A4\uB9CC \uC788\uB294 \uACBD\uC6B0 \uADF8\uB300\uB85C \uBC18\uD658\r\n if (value === \"-\") return \"-\";\r\n\r\n // \uC22B\uC790, \uC18C\uC218\uC810, \uB9C8\uC774\uB108\uC2A4\uB9CC \uD5C8\uC6A9\r\n let cleaned = value.replace(/[^\\d.-]/g, \"\");\r\n\r\n // \uB9C8\uC774\uB108\uC2A4\uB294 \uB9E8 \uC55E\uC5D0\uB9CC \uD5C8\uC6A9\r\n const isNegative = cleaned.startsWith(\"-\");\r\n cleaned = cleaned.replace(/-/g, \"\");\r\n\r\n // \uC18C\uC218\uC810 \uCC98\uB9AC\r\n const parts = cleaned.split(\".\");\r\n let integerPart = parts[0] || \"\";\r\n let decimalPart = parts.length > 1 ? parts[1] : \"\";\r\n\r\n // \uC18C\uC218\uC810 \uAE38\uC774 \uC81C\uD55C\r\n if (decimalLength !== undefined && decimalPart.length > decimalLength) {\r\n decimalPart = decimalPart.slice(0, decimalLength);\r\n }\r\n\r\n // \uCC9C \uB2E8\uC704 \uAD6C\uBD84\uC790 \uCD94\uAC00\r\n if (thousandSeparator && integerPart) {\r\n integerPart = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\r\n }\r\n\r\n // \uACB0\uACFC \uC870\uD569\r\n let result = integerPart;\r\n if (parts.length > 1 || value.endsWith(\".\")) {\r\n result += \".\" + decimalPart;\r\n }\r\n if (isNegative && result) {\r\n result = \"-\" + result;\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * \uD45C\uC2DC \uAC12\uC5D0\uC11C \uC2E4\uC81C \uC22B\uC790 \uAC12 \uCD94\uCD9C\r\n */\r\nexport function parseNumber(displayValue: string): string {\r\n return displayValue.replace(/,/g, \"\");\r\n}\r\n", "/**\r\n * email.ts - \uC774\uBA54\uC77C \uAD00\uB828 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\n/**\r\n * \uAE30\uBCF8 \uB3C4\uBA54\uC778 \uC81C\uC548 \uBAA9\uB85D\r\n */\r\nexport const DEFAULT_EMAIL_DOMAINS = [\r\n \"gmail.com\",\r\n \"naver.com\",\r\n \"daum.net\",\r\n \"hanmail.net\",\r\n \"kakao.com\",\r\n \"nate.com\",\r\n \"hotmail.com\",\r\n \"outlook.com\",\r\n \"yahoo.com\",\r\n \"icloud.com\",\r\n];\r\n\r\n/**\r\n * \uC774\uBA54\uC77C \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n */\r\nexport function validateEmail(email: string): boolean {\r\n if (!email) return false;\r\n // RFC 5322 \uAE30\uBC18 \uAC04\uC18C\uD654\uB41C \uC774\uBA54\uC77C \uC815\uADDC\uC2DD\r\n const emailRegex =\r\n /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;\r\n return emailRegex.test(email);\r\n}\r\n", "/**\r\n * phone.ts - \uC804\uD654\uBC88\uD638 \uAD00\uB828 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport type { PhoneFormat } from \"../types\";\r\n\r\n/**\r\n * \uC804\uD654\uBC88\uD638 \uC790\uB3D9 \uD3EC\uB9F7\uD305 \uD568\uC218\r\n * \uC785\uB825\uB41C \uBC88\uD638\uB97C \uBCF4\uACE0 \uC790\uB3D9\uC73C\uB85C \uD3EC\uB9F7 \uD310\uB2E8\r\n */\r\nexport function formatPhoneNumber(value: string, customFormat?: PhoneFormat): string {\r\n const numbers = value.replace(/\\D/g, \"\");\r\n\r\n if (numbers.length === 0) return \"\";\r\n\r\n // prefix\uC640 \uD568\uAED8 \uC0AC\uC6A9\uB418\uB294 \uCEE4\uC2A4\uD140 \uD3EC\uB9F7 (010-000-0000: 3-3-4)\r\n if (customFormat === \"010-000-0000\") {\r\n if (numbers.length < 3) return numbers;\r\n if (numbers.length === 3) return `${numbers}-`;\r\n if (numbers.length < 6) return `${numbers.slice(0, 3)}-${numbers.slice(3)}`;\r\n if (numbers.length === 6) return `${numbers.slice(0, 3)}-${numbers.slice(3, 6)}-`;\r\n return `${numbers.slice(0, 3)}-${numbers.slice(3, 6)}-${numbers.slice(6, 10)}`;\r\n }\r\n\r\n // prefix\uC640 \uD568\uAED8 \uC0AC\uC6A9\uB418\uB294 \uCEE4\uC2A4\uD140 \uD3EC\uB9F7 (010-0000-0000: 3-4-4)\r\n if (customFormat === \"010-0000-0000\") {\r\n if (numbers.length < 3) return numbers;\r\n if (numbers.length === 3) return `${numbers}-`;\r\n if (numbers.length < 7) return `${numbers.slice(0, 3)}-${numbers.slice(3)}`;\r\n if (numbers.length === 7) return `${numbers.slice(0, 3)}-${numbers.slice(3, 7)}-`;\r\n return `${numbers.slice(0, 3)}-${numbers.slice(3, 7)}-${numbers.slice(7, 11)}`;\r\n }\r\n\r\n // \uC804\uAD6D\uB300\uD45C\uBC88\uD638 (1588, 1577, 1544, 1600, 1800 \uB4F1)\r\n if (/^1[0-9]{3}/.test(numbers)) {\r\n if (numbers.length <= 4) return numbers;\r\n if (numbers.length === 4) return `${numbers}-`;\r\n return `${numbers.slice(0, 4)}-${numbers.slice(4, 8)}`;\r\n }\r\n\r\n // \uC11C\uC6B8 \uC9C0\uC5ED\uBC88\uD638 (02)\r\n if (numbers.startsWith(\"02\")) {\r\n if (numbers.length < 2) return numbers;\r\n if (numbers.length === 2) return `${numbers}-`;\r\n // 9\uC790\uB9AC \uC774\uD558: 02-000-0000 (2-3-4)\r\n if (numbers.length <= 9) {\r\n if (numbers.length < 5) return `${numbers.slice(0, 2)}-${numbers.slice(2)}`;\r\n if (numbers.length === 5) return `${numbers.slice(0, 2)}-${numbers.slice(2, 5)}-`;\r\n return `${numbers.slice(0, 2)}-${numbers.slice(2, 5)}-${numbers.slice(5, 9)}`;\r\n }\r\n // 10\uC790\uB9AC: 02-0000-0000 (2-4-4)\r\n return `${numbers.slice(0, 2)}-${numbers.slice(2, 6)}-${numbers.slice(6, 10)}`;\r\n }\r\n\r\n // \uD734\uB300\uD3F0 (010, 011, 016, 017, 018, 019) \uB610\uB294 \uC9C0\uC5ED\uBC88\uD638 (031, 032, 033 \uB4F1)\r\n if (numbers.length < 3) return numbers;\r\n if (numbers.length === 3) return `${numbers}-`;\r\n\r\n // 10\uC790\uB9AC: 000-000-0000 (3-3-4)\r\n if (numbers.length <= 10) {\r\n if (numbers.length < 6) return `${numbers.slice(0, 3)}-${numbers.slice(3)}`;\r\n if (numbers.length === 6) return `${numbers.slice(0, 3)}-${numbers.slice(3, 6)}-`;\r\n return `${numbers.slice(0, 3)}-${numbers.slice(3, 6)}-${numbers.slice(6, 10)}`;\r\n }\r\n\r\n // 11\uC790\uB9AC: 000-0000-0000 (3-4-4)\r\n return `${numbers.slice(0, 3)}-${numbers.slice(3, 7)}-${numbers.slice(7, 11)}`;\r\n}\r\n\r\n/**\r\n * \uC785\uB825\uB41C \uBC88\uD638\uC5D0 \uB530\uB978 \uCD5C\uB300 \uAE38\uC774 \uACC4\uC0B0\r\n */\r\nexport function getPhoneMaxLength(numbers: string): number {\r\n // \uC804\uAD6D\uB300\uD45C\uBC88\uD638\r\n if (/^1[0-9]{0,3}/.test(numbers)) {\r\n return 9; // 1588-1234\r\n }\r\n // \uC11C\uC6B8\r\n if (numbers.startsWith(\"02\")) {\r\n return 12; // 02-1234-5678\r\n }\r\n // \uD734\uB300\uD3F0/\uC9C0\uC5ED\uBC88\uD638\r\n return 13; // 010-1234-5678\r\n}\r\n", "/**\r\n * password.ts - \uBE44\uBC00\uBC88\uD638 \uAD00\uB828 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport type { PasswordValidationRules, PasswordValidationResult } from \"../types\";\r\n\r\nexport const DEFAULT_SPECIAL_CHARS = \"!@#$%^&*()_+-=[]{}|;:,.<>?\";\r\n\r\n/**\r\n * \uAE30\uBCF8 \uC720\uD6A8\uC131 \uAC80\uC0AC \uADDC\uCE59\r\n */\r\nexport const DEFAULT_PASSWORD_VALIDATION_RULES: PasswordValidationRules = {\r\n minLength: 8,\r\n maxLength: 20,\r\n requireLowercase: true,\r\n requireNumber: true,\r\n};\r\n\r\n/**\r\n * \uBE44\uBC00\uBC88\uD638 \uC720\uD6A8\uC131 \uAC80\uC0AC \uD568\uC218\r\n */\r\nexport function validatePassword(value: string, rules: PasswordValidationRules): PasswordValidationResult {\r\n // \uAE30\uBCF8\uAC12\uACFC \uBCD1\uD569\r\n const mergedRules = { ...DEFAULT_PASSWORD_VALIDATION_RULES, ...rules };\r\n const errors: PasswordValidationResult[\"errors\"] = {};\r\n\r\n if (mergedRules.minLength !== undefined && value.length < mergedRules.minLength) {\r\n errors.minLength = true;\r\n }\r\n\r\n if (mergedRules.maxLength !== undefined && value.length > mergedRules.maxLength) {\r\n errors.maxLength = true;\r\n }\r\n\r\n if (mergedRules.requireUppercase && !/[A-Z]/.test(value)) {\r\n errors.requireUppercase = true;\r\n }\r\n\r\n if (mergedRules.requireLowercase && !/[a-z]/.test(value)) {\r\n errors.requireLowercase = true;\r\n }\r\n\r\n if (mergedRules.requireNumber && !/[0-9]/.test(value)) {\r\n errors.requireNumber = true;\r\n }\r\n\r\n if (mergedRules.requireSpecialChar) {\r\n const specialChars = mergedRules.specialChars || DEFAULT_SPECIAL_CHARS;\r\n const escapedChars = specialChars.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, \"\\\\$&\");\r\n const regex = new RegExp(`[${escapedChars}]`);\r\n if (!regex.test(value)) {\r\n errors.requireSpecialChar = true;\r\n }\r\n }\r\n\r\n return {\r\n isValid: Object.keys(errors).length === 0,\r\n errors,\r\n };\r\n}\r\n", "/**\r\n * biznum.ts - \uC0AC\uC5C5\uC790\uBC88\uD638 \uAD00\uB828 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\n/**\r\n * \uC0AC\uC5C5\uC790\uBC88\uD638 \uC720\uD6A8\uC131 \uAC80\uC0AC (\uAC80\uC99D \uC54C\uACE0\uB9AC\uC998)\r\n * \uC0AC\uC5C5\uC790\uB4F1\uB85D\uBC88\uD638\uB294 10\uC790\uB9AC \uC22B\uC790\uC774\uBA70, \uB9C8\uC9C0\uB9C9 \uC790\uB9AC\uAC00 \uAC80\uC99D\uBC88\uD638\uC785\uB2C8\uB2E4.\r\n */\r\nexport function validateBusinessNumber(value: string): boolean {\r\n const numbers = value.replace(/\\D/g, \"\");\r\n\r\n if (numbers.length !== 10) {\r\n return false;\r\n }\r\n\r\n // \uC0AC\uC5C5\uC790\uB4F1\uB85D\uBC88\uD638 \uAC80\uC99D \uC54C\uACE0\uB9AC\uC998\r\n const checkKey = [1, 3, 7, 1, 3, 7, 1, 3, 5];\r\n let sum = 0;\r\n\r\n for (let i = 0; i < 9; i++) {\r\n sum += parseInt(numbers[i], 10) * checkKey[i];\r\n }\r\n\r\n // 8\uBC88\uC9F8 \uC790\uB9AC * 5 \uC758 \uC2ED\uC758 \uC790\uB9AC \uCD94\uAC00\r\n sum += Math.floor((parseInt(numbers[8], 10) * 5) / 10);\r\n\r\n // \uAC80\uC99D\uBC88\uD638 \uACC4\uC0B0\r\n const checkNum = (10 - (sum % 10)) % 10;\r\n\r\n return checkNum === parseInt(numbers[9], 10);\r\n}\r\n", "/**\r\n * card.ts - \uCE74\uB4DC\uBC88\uD638 \uAD00\uB828 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\n/** \uCE74\uB4DC \uBE0C\uB79C\uB4DC \uD0C0\uC785 */\r\nexport type CardBrand = \"visa\" | \"mastercard\" | \"amex\" | \"jcb\" | \"diners\" | \"discover\" | \"unionpay\" | \"bc\" | null;\r\n\r\n/**\r\n * \uCE74\uB4DC\uBC88\uD638 \uC720\uD6A8\uC131 \uAC80\uC0AC (Luhn \uC54C\uACE0\uB9AC\uC998)\r\n */\r\nexport function validateCardNumber(value: string): boolean {\r\n const numbers = value.replace(/\\D/g, \"\");\r\n\r\n if (numbers.length !== 16) {\r\n return false;\r\n }\r\n\r\n // Luhn \uC54C\uACE0\uB9AC\uC998\r\n let sum = 0;\r\n let isEven = false;\r\n\r\n for (let i = numbers.length - 1; i >= 0; i--) {\r\n let digit = parseInt(numbers[i], 10);\r\n\r\n if (isEven) {\r\n digit *= 2;\r\n if (digit > 9) {\r\n digit -= 9;\r\n }\r\n }\r\n\r\n sum += digit;\r\n isEven = !isEven;\r\n }\r\n\r\n return sum % 10 === 0;\r\n}\r\n\r\n/**\r\n * \uCE74\uB4DC \uBE0C\uB79C\uB4DC \uAC10\uC9C0 (\uAD6D\uC81C \uBE0C\uB79C\uB4DC \uAE30\uC900)\r\n */\r\nexport function detectCardBrand(value: string): CardBrand {\r\n const numbers = value.replace(/\\D/g, \"\");\r\n\r\n if (!numbers) return null;\r\n\r\n // Visa: 4\uB85C \uC2DC\uC791\r\n if (/^4/.test(numbers)) return \"visa\";\r\n\r\n // Mastercard: 51-55 \uB610\uB294 2221-2720\r\n if (/^5[1-5]/.test(numbers) || /^2(2[2-9]|[3-6]\\d|7[01]|720)/.test(numbers)) return \"mastercard\";\r\n\r\n // AMEX: 34, 37\r\n if (/^3[47]/.test(numbers)) return \"amex\";\r\n\r\n // JCB: 3528-3589\r\n if (/^35(2[89]|[3-8]\\d)/.test(numbers)) return \"jcb\";\r\n\r\n // Diners Club: 36, 38, 300-305, 309\r\n if (/^3(6|8|0[0-59])/.test(numbers)) return \"diners\";\r\n\r\n // Discover: 6011, 622126-622925, 644-649, 65\r\n if (/^(6011|65|64[4-9]|622(1[2-9][6-9]|[2-8]\\d\\d|9[01]\\d|92[0-5]))/.test(numbers)) return \"discover\";\r\n\r\n // UnionPay (\uC911\uAD6D\uC740\uB828): 62\uB85C \uC2DC\uC791 (Discover\uC640 \uACB9\uCE58\uC9C0 \uC54A\uB294 \uBC94\uC704)\r\n if (/^62(?!(2(1[2-9][6-9]|[2-8]\\d\\d|9[01]\\d|92[0-5])))/.test(numbers)) return \"unionpay\";\r\n\r\n // BC\uCE74\uB4DC: 94\uB85C \uC2DC\uC791\r\n if (/^94/.test(numbers)) return \"bc\";\r\n\r\n return null;\r\n}\r\n", "/**\r\n * jumin.ts - \uC8FC\uBBFC\uB4F1\uB85D\uBC88\uD638 \uAD00\uB828 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport type { JuminInfo } from \"../types\";\r\n\r\n/**\r\n * \uC8FC\uBBFC\uBC88\uD638 \uB4B7\uC790\uB9AC 2~3\uBC88\uC9F8 \uC22B\uC790\uB85C \uC9C0\uC5ED \uCD94\uCD9C\r\n * (2020\uB144 10\uC6D4 \uC774\uD6C4 \uCD9C\uC0DD\uC790\uB294 \uB79C\uB364 \uBD80\uC5EC\uB85C \uC758\uBBF8 \uC5C6\uC74C)\r\n */\r\nexport const REGION_MAP: Record<string, string> = {\r\n \"0\": \"\uC11C\uC6B8\",\r\n \"1\": \"\uC11C\uC6B8\",\r\n \"2\": \"\uC11C\uC6B8\",\r\n \"3\": \"\uC11C\uC6B8\",\r\n \"4\": \"\uC11C\uC6B8\",\r\n \"5\": \"\uC11C\uC6B8\",\r\n \"6\": \"\uC11C\uC6B8\",\r\n \"7\": \"\uC11C\uC6B8\",\r\n \"8\": \"\uC11C\uC6B8\",\r\n \"9\": \"\uBD80\uC0B0\",\r\n \"10\": \"\uBD80\uC0B0\",\r\n \"11\": \"\uBD80\uC0B0\",\r\n \"12\": \"\uBD80\uC0B0\",\r\n \"13\": \"\uC778\uCC9C\",\r\n \"14\": \"\uC778\uCC9C\",\r\n \"15\": \"\uC778\uCC9C\",\r\n \"16\": \"\uACBD\uAE30\",\r\n \"17\": \"\uACBD\uAE30\",\r\n \"18\": \"\uACBD\uAE30\",\r\n \"19\": \"\uACBD\uAE30\",\r\n \"20\": \"\uACBD\uAE30\",\r\n \"21\": \"\uACBD\uAE30\",\r\n \"22\": \"\uACBD\uAE30\",\r\n \"23\": \"\uACBD\uAE30\",\r\n \"24\": \"\uACBD\uAE30\",\r\n \"25\": \"\uACBD\uAE30\",\r\n \"26\": \"\uAC15\uC6D0\",\r\n \"27\": \"\uAC15\uC6D0\",\r\n \"28\": \"\uAC15\uC6D0\",\r\n \"29\": \"\uAC15\uC6D0\",\r\n \"30\": \"\uAC15\uC6D0\",\r\n \"31\": \"\uAC15\uC6D0\",\r\n \"32\": \"\uAC15\uC6D0\",\r\n \"33\": \"\uAC15\uC6D0\",\r\n \"34\": \"\uAC15\uC6D0\",\r\n \"35\": \"\uCDA9\uBD81\",\r\n \"36\": \"\uCDA9\uBD81\",\r\n \"37\": \"\uCDA9\uBD81\",\r\n \"38\": \"\uCDA9\uBD81\",\r\n \"39\": \"\uCDA9\uB0A8\",\r\n \"40\": \"\uCDA9\uB0A8\",\r\n \"41\": \"\uB300\uC804\",\r\n \"42\": \"\uCDA9\uB0A8\",\r\n \"43\": \"\uCDA9\uB0A8\",\r\n \"44\": \"\uCDA9\uB0A8\",\r\n \"45\": \"\uCDA9\uB0A8\",\r\n \"46\": \"\uCDA9\uB0A8\",\r\n \"47\": \"\uCDA9\uB0A8\",\r\n \"48\": \"\uC804\uBD81\",\r\n \"49\": \"\uC804\uBD81\",\r\n \"50\": \"\uC804\uBD81\",\r\n \"51\": \"\uC804\uBD81\",\r\n \"52\": \"\uC804\uBD81\",\r\n \"53\": \"\uC804\uBD81\",\r\n \"54\": \"\uC804\uB0A8\",\r\n \"55\": \"\uC804\uB0A8\",\r\n \"56\": \"\uAD11\uC8FC\",\r\n \"57\": \"\uC804\uB0A8\",\r\n \"58\": \"\uC804\uB0A8\",\r\n \"59\": \"\uC804\uB0A8\",\r\n \"60\": \"\uC804\uB0A8\",\r\n \"61\": \"\uC804\uB0A8\",\r\n \"62\": \"\uC804\uB0A8\",\r\n \"63\": \"\uC804\uB0A8\",\r\n \"64\": \"\uC804\uB0A8\",\r\n \"65\": \"\uACBD\uBD81\",\r\n \"66\": \"\uACBD\uBD81\",\r\n \"67\": \"\uACBD\uBD81\",\r\n \"68\": \"\uACBD\uBD81\",\r\n \"69\": \"\uACBD\uBD81\",\r\n \"70\": \"\uACBD\uBD81\",\r\n \"71\": \"\uACBD\uBD81\",\r\n \"72\": \"\uACBD\uBD81\",\r\n \"73\": \"\uACBD\uBD81\",\r\n \"74\": \"\uACBD\uBD81\",\r\n \"75\": \"\uACBD\uBD81\",\r\n \"76\": \"\uB300\uAD6C\",\r\n \"77\": \"\uB300\uAD6C\",\r\n \"78\": \"\uB300\uAD6C\",\r\n \"79\": \"\uACBD\uB0A8\",\r\n \"80\": \"\uACBD\uB0A8\",\r\n \"81\": \"\uACBD\uB0A8\",\r\n \"82\": \"\uACBD\uB0A8\",\r\n \"83\": \"\uC6B8\uC0B0\",\r\n \"84\": \"\uACBD\uB0A8\",\r\n \"85\": \"\uACBD\uB0A8\",\r\n \"86\": \"\uACBD\uB0A8\",\r\n \"87\": \"\uACBD\uB0A8\",\r\n \"88\": \"\uACBD\uB0A8\",\r\n \"89\": \"\uACBD\uB0A8\",\r\n \"90\": \"\uACBD\uB0A8\",\r\n \"91\": \"\uC81C\uC8FC\",\r\n \"92\": \"\uC81C\uC8FC\",\r\n \"93\": \"\uC138\uC885\",\r\n};\r\n\r\n/**\r\n * \uC8FC\uBBFC\uBC88\uD638\uC5D0\uC11C \uC815\uBCF4 \uCD94\uCD9C\r\n */\r\nexport function extractJuminInfo(value: string): Omit<JuminInfo, \"isValid\"> {\r\n const numbers = value.replace(/\\D/g, \"\");\r\n\r\n const result: Omit<JuminInfo, \"isValid\"> = {\r\n value: numbers,\r\n birthDate: null,\r\n gender: null,\r\n isForeigner: null,\r\n region: null,\r\n };\r\n\r\n if (numbers.length < 7) {\r\n return result;\r\n }\r\n\r\n // \uB4B7\uC790\uB9AC \uCCAB \uBC88\uC9F8 \uC22B\uC790 (\uC131\uBCC4/\uC138\uAE30/\uC678\uAD6D\uC778 \uAD6C\uBD84)\r\n const genderCode = numbers[6];\r\n\r\n // \uC131\uBCC4 \uBC0F \uC678\uAD6D\uC778 \uC5EC\uBD80 \uD310\uB2E8\r\n // 1, 2: 1900\uB144\uB300 \uB0B4\uAD6D\uC778 (\uB0A8/\uC5EC)\r\n // 3, 4: 2000\uB144\uB300 \uB0B4\uAD6D\uC778 (\uB0A8/\uC5EC)\r\n // 5, 6: 1900\uB144\uB300 \uC678\uAD6D\uC778 (\uB0A8/\uC5EC)\r\n // 7, 8: 2000\uB144\uB300 \uC678\uAD6D\uC778 (\uB0A8/\uC5EC)\r\n // 9, 0: 1800\uB144\uB300 \uB0B4\uAD6D\uC778 (\uB0A8/\uC5EC)\r\n switch (genderCode) {\r\n case \"1\":\r\n case \"3\":\r\n case \"5\":\r\n case \"7\":\r\n case \"9\":\r\n result.gender = \"male\";\r\n break;\r\n case \"2\":\r\n case \"4\":\r\n case \"6\":\r\n case \"8\":\r\n case \"0\":\r\n result.gender = \"female\";\r\n break;\r\n }\r\n\r\n // \uC678\uAD6D\uC778 \uC5EC\uBD80\r\n if ([\"5\", \"6\", \"7\", \"8\"].includes(genderCode)) {\r\n result.isForeigner = true;\r\n } else if ([\"1\", \"2\", \"3\", \"4\", \"9\", \"0\"].includes(genderCode)) {\r\n result.isForeigner = false;\r\n }\r\n\r\n // \uC0DD\uB144\uC6D4\uC77C \uCD94\uCD9C\r\n if (numbers.length >= 6) {\r\n const yy = numbers.slice(0, 2);\r\n const mm = numbers.slice(2, 4);\r\n const dd = numbers.slice(4, 6);\r\n\r\n let century = \"19\";\r\n if ([\"3\", \"4\", \"7\", \"8\"].includes(genderCode)) {\r\n century = \"20\";\r\n } else if ([\"9\", \"0\"].includes(genderCode)) {\r\n century = \"18\";\r\n }\r\n\r\n const year = century + yy;\r\n result.birthDate = `${year}-${mm}-${dd}`;\r\n }\r\n\r\n // \uC9C0\uC5ED \uCD94\uCD9C (\uB0B4\uAD6D\uC778\uB9CC, \uB4B7\uC790\uB9AC 2~3\uBC88\uC9F8 \uC22B\uC790)\r\n if (numbers.length >= 9 && result.isForeigner === false) {\r\n const regionCode = numbers.slice(7, 9);\r\n const regionNum = parseInt(regionCode, 10);\r\n result.region = REGION_MAP[String(regionNum)] || null;\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * \uC8FC\uBBFC\uB4F1\uB85D\uBC88\uD638 \uCCB4\uD06C\uC12C \uAC80\uC99D\r\n * - 13\uC790\uB9AC \uAC01 \uC22B\uC790\uC5D0 \uAC00\uC911\uCE58 [2,3,4,5,6,7,8,9,2,3,4,5]\uB97C \uACF1\uD558\uC5EC \uD569\uC0B0\r\n * - (11 - (\uD569\uACC4 % 11)) % 10 === \uB9C8\uC9C0\uB9C9 \uC790\uB9AC\r\n */\r\nexport function validateJuminChecksum(numbers: string): boolean {\r\n if (numbers.length !== 13) return false;\r\n\r\n const weights = [2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5];\r\n let sum = 0;\r\n\r\n for (let i = 0; i < 12; i++) {\r\n sum += parseInt(numbers[i], 10) * weights[i];\r\n }\r\n\r\n const checkDigit = (11 - (sum % 11)) % 10;\r\n const lastDigit = parseInt(numbers[12], 10);\r\n\r\n return checkDigit === lastDigit;\r\n}\r\n\r\n/**\r\n * \uC8FC\uBBFC\uB4F1\uB85D\uBC88\uD638 \uC0DD\uB144\uC6D4\uC77C \uC720\uD6A8\uC131 \uAC80\uC99D\r\n */\r\nexport function validateJuminBirthDate(numbers: string): boolean {\r\n if (numbers.length < 7) return false;\r\n\r\n const yy = parseInt(numbers.slice(0, 2), 10);\r\n const mm = parseInt(numbers.slice(2, 4), 10);\r\n const dd = parseInt(numbers.slice(4, 6), 10);\r\n const genderCode = numbers[6];\r\n\r\n // \uC6D4 \uAC80\uC99D (1-12)\r\n if (mm < 1 || mm > 12) return false;\r\n\r\n // \uC138\uAE30 \uACB0\uC815\r\n let century = 1900;\r\n if ([\"3\", \"4\", \"7\", \"8\"].includes(genderCode)) {\r\n century = 2000;\r\n } else if ([\"9\", \"0\"].includes(genderCode)) {\r\n century = 1800;\r\n }\r\n\r\n const year = century + yy;\r\n\r\n // \uAC01 \uC6D4\uC758 \uC77C\uC218 (\uC724\uB144 \uACE0\uB824)\r\n const isLeapYear = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\r\n const daysInMonth = [31, isLeapYear ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\r\n\r\n // \uC77C \uAC80\uC99D\r\n if (dd < 1 || dd > daysInMonth[mm - 1]) return false;\r\n\r\n return true;\r\n}\r\n", "/**\r\n * TextField.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \u0010a8ud10a8uc601uc9c4 (Kim Young Jin)\r\n * @author \u0010a8ud10a8uc601uc9c4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useRef, useImperativeHandle } from \"react\";\r\nimport { TextField as MuiTextField } from \"@mui/material\";\r\nimport type { TextFieldProps } from \"@mui/material/TextField\";\r\nimport type { BaseTextFieldProps } from \"./types\";\r\nimport { useTextFieldBase } from \"./hooks\";\r\n\r\ntype CombinedTextFieldProps = TextFieldProps & BaseTextFieldProps;\r\n\r\nconst TextFieldBase = forwardRef<HTMLDivElement, CombinedTextFieldProps>(function TextFieldBase(\r\n { value, onChange, onBlur, debounce, readonly, slotProps, inputRef: externalInputRef, sx, ...props },\r\n ref\r\n) {\r\n const resolvedValue = value === undefined || value === null ? \"\" : String(value);\r\n\r\n const { internalValue, handleChange, handleBlur } = useTextFieldBase({\r\n value: resolvedValue,\r\n name: props.name,\r\n debounce,\r\n onChange,\r\n onBlur,\r\n });\r\n\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n\r\n useImperativeHandle(externalInputRef as React.Ref<HTMLInputElement>, () => internalInputRef.current!, []);\r\n\r\n const readonlyStyles = readonly\r\n ? {\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n return (\r\n <MuiTextField\r\n {...props}\r\n ref={ref}\r\n inputRef={internalInputRef}\r\n value={internalValue}\r\n onChange={handleChange}\r\n onBlur={handleBlur}\r\n sx={{\r\n ...readonlyStyles,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...sx,\r\n }}\r\n slotProps={{\r\n ...slotProps,\r\n input: {\r\n ...slotProps?.input,\r\n readOnly: readonly,\r\n },\r\n }}\r\n />\r\n );\r\n});\r\n\r\nconst TextFieldWithForm = forwardRef<HTMLDivElement, CombinedTextFieldProps>(function TextFieldWithForm(\r\n { form, name, onChange, ...rest },\r\n ref\r\n) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\"TextField form prop is missing. Provide a form from useForm or useGlobalForm.\");\r\n }\r\n if (!name) {\r\n throw new Error(\"TextField requires a name when form prop is provided.\");\r\n }\r\n\r\n const formValue = form.useFormValue(name) as string | number | null;\r\n const handleFormChange = (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n };\r\n\r\n return <TextFieldBase {...rest} ref={ref} name={name} value={formValue ?? \"\"} onChange={handleFormChange} />;\r\n});\r\n\r\nexport const TextField = forwardRef<HTMLDivElement, CombinedTextFieldProps>(function TextField(props, ref) {\r\n if (props.form) {\r\n return <TextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <TextFieldBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * TextArea.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n forwardRef,\r\n useCallback,\r\n useImperativeHandle,\r\n useRef,\r\n useState,\r\n} from \"react\";\r\nimport { Box, FormControl, InputLabel, TextareaAutosize } from \"@mui/material\";\r\nimport type { TextAreaProps } from \"./types\";\r\nimport { useTextFieldBase } from \"./hooks\";\r\n\r\nconst TextAreaBase = forwardRef<HTMLTextAreaElement, TextAreaProps>(\r\n function TextAreaBase(\r\n {\r\n label,\r\n value,\r\n name,\r\n onChange,\r\n onBlur,\r\n onFocus,\r\n minRows = 3,\r\n maxRows,\r\n placeholder,\r\n disabled,\r\n readonly,\r\n fullWidth = true,\r\n inputRef: externalInputRef,\r\n sx,\r\n inputProps,\r\n debounce,\r\n form,\r\n ...rest\r\n },\r\n ref,\r\n ) {\r\n const internalInputRef = useRef<HTMLTextAreaElement>(null);\r\n const [isFocused, setIsFocused] = useState(false);\r\n\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLTextAreaElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n const { internalValue, setInternalValue, emitChange, handleBlur } =\r\n useTextFieldBase({\r\n value: (value as string) ?? \"\",\r\n name,\r\n debounce,\r\n onChange: onChange as unknown as (\r\n e: React.ChangeEvent<HTMLInputElement>,\r\n ) => void,\r\n onBlur: onBlur as unknown as (\r\n e: React.FocusEvent<HTMLInputElement>,\r\n ) => void,\r\n });\r\n\r\n const handleChange = useCallback(\r\n (event: React.ChangeEvent<HTMLTextAreaElement>) => {\r\n const newValue = event.target.value;\r\n setInternalValue(newValue);\r\n emitChange(\r\n event as unknown as React.ChangeEvent<HTMLInputElement>,\r\n newValue,\r\n );\r\n },\r\n [emitChange, setInternalValue],\r\n );\r\n\r\n const handleFocus = useCallback(\r\n (event: React.FocusEvent<HTMLTextAreaElement>) => {\r\n setIsFocused(true);\r\n onFocus?.(event);\r\n },\r\n [onFocus],\r\n );\r\n\r\n const handleBlurWithFocus = useCallback(\r\n (event: React.FocusEvent<HTMLTextAreaElement>) => {\r\n setIsFocused(false);\r\n handleBlur(\r\n event as unknown as React.FocusEvent<HTMLInputElement>,\r\n );\r\n },\r\n [handleBlur],\r\n );\r\n\r\n return (\r\n <FormControl\r\n fullWidth={fullWidth}\r\n disabled={disabled}\r\n sx={{ width: fullWidth ? \"100%\" : undefined, ...sx }}\r\n >\r\n {label && (\r\n <InputLabel\r\n shrink={isFocused || internalValue.length > 0}\r\n sx={{\r\n position: \"static\",\r\n transform: \"none\",\r\n mb: 1,\r\n color: readonly\r\n ? \"rgba(0, 0, 0, 0.6)\"\r\n : \"text.primary\",\r\n }}\r\n >\r\n {label}\r\n </InputLabel>\r\n )}\r\n <Box\r\n sx={{\r\n border: \"1px solid rgba(0, 0, 0, 0.23)\",\r\n borderRadius: 1,\r\n px: 1.5,\r\n py: 1.25,\r\n transition: \"border-color 0.15s ease\",\r\n ...(isFocused &&\r\n !readonly && {\r\n borderColor: \"primary.main\",\r\n }),\r\n ...(readonly && {\r\n backgroundColor: \"rgba(0, 0, 0, 0.02)\",\r\n }),\r\n }}\r\n >\r\n <TextareaAutosize\r\n {...inputProps}\r\n {...rest}\r\n ref={(node: HTMLTextAreaElement | null) => {\r\n internalInputRef.current = node;\r\n if (typeof ref === \"function\") {\r\n ref(node);\r\n } else if (ref) {\r\n (\r\n ref as React.MutableRefObject<HTMLTextAreaElement | null>\r\n ).current = node;\r\n }\r\n }}\r\n name={name}\r\n value={internalValue}\r\n minRows={minRows}\r\n maxRows={maxRows}\r\n placeholder={placeholder}\r\n disabled={disabled}\r\n readOnly={readonly}\r\n onChange={handleChange}\r\n onFocus={handleFocus}\r\n onBlur={handleBlurWithFocus}\r\n style={{\r\n width: \"100%\",\r\n border: \"none\",\r\n outline: \"none\",\r\n resize: \"vertical\",\r\n background: \"transparent\",\r\n font: \"inherit\",\r\n color: \"inherit\",\r\n }}\r\n />\r\n </Box>\r\n </FormControl>\r\n );\r\n },\r\n);\r\n\r\nconst TextAreaWithForm = forwardRef<HTMLTextAreaElement, TextAreaProps>(\r\n function TextAreaWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"TextArea form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"TextArea requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLTextAreaElement>) => {\r\n form.handleFormChange(\r\n event as unknown as React.ChangeEvent<HTMLInputElement>,\r\n );\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <TextAreaBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue as string}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(\r\n function TextArea(props, ref) {\r\n if (props.form) {\r\n return <TextAreaWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <TextAreaBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * Checkbox.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback } from \"react\";\r\nimport { Checkbox as MuiCheckbox, FormControlLabel } from \"@mui/material\";\r\nimport type { CheckboxProps } from \"./types\";\r\n\r\nconst CheckboxBase = forwardRef<HTMLButtonElement, CheckboxProps>(\r\n function CheckboxBase(\r\n { label, name, checked, onChange, readonly, disabled, form, ...props },\r\n ref,\r\n ) {\r\n return (\r\n <FormControlLabel\r\n label={label}\r\n control={\r\n <MuiCheckbox\r\n {...props}\r\n ref={ref}\r\n name={name}\r\n checked={!!checked}\r\n onChange={onChange}\r\n disabled={disabled || readonly}\r\n />\r\n }\r\n />\r\n );\r\n },\r\n);\r\n\r\nconst CheckboxWithForm = forwardRef<HTMLButtonElement, CheckboxProps>(\r\n function CheckboxWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"Checkbox form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"Checkbox requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (\r\n event: React.ChangeEvent<HTMLInputElement>,\r\n nextChecked: boolean,\r\n ) => {\r\n const syntheticEvent = {\r\n ...event,\r\n target: {\r\n ...event.target,\r\n name,\r\n value: nextChecked,\r\n checked: nextChecked,\r\n },\r\n } as unknown as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n onChange?.(event, nextChecked);\r\n },\r\n [form, name, onChange],\r\n );\r\n\r\n return (\r\n <CheckboxBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n checked={Boolean(formValue)}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const Checkbox = forwardRef<HTMLButtonElement, CheckboxProps>(\r\n function Checkbox(props, ref) {\r\n if (props.form) {\r\n return <CheckboxWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <CheckboxBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * RadioGroup.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback } from \"react\";\r\nimport {\r\n FormControl,\r\n FormLabel,\r\n RadioGroup as MuiRadioGroup,\r\n FormControlLabel,\r\n Radio,\r\n} from \"@mui/material\";\r\nimport type { RadioGroupProps } from \"./types\";\r\n\r\nconst RadioGroupBase = forwardRef<HTMLDivElement, RadioGroupProps>(\r\n function RadioGroupBase(\r\n { label, name, value, options, onChange, readonly, disabled, ...props },\r\n ref,\r\n ) {\r\n return (\r\n <FormControl ref={ref} disabled={disabled}>\r\n {label && <FormLabel>{label}</FormLabel>}\r\n <MuiRadioGroup\r\n {...props}\r\n name={name}\r\n value={value ?? \"\"}\r\n onChange={onChange}\r\n >\r\n {options.map((option) => (\r\n <FormControlLabel\r\n key={option.value}\r\n value={option.value}\r\n control={<Radio />}\r\n label={option.label}\r\n disabled={disabled || option.disabled || readonly}\r\n />\r\n ))}\r\n </MuiRadioGroup>\r\n </FormControl>\r\n );\r\n },\r\n);\r\n\r\nconst RadioGroupWithForm = forwardRef<HTMLDivElement, RadioGroupProps>(\r\n function RadioGroupWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"RadioGroup form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"RadioGroup requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>, nextValue: string) => {\r\n const syntheticEvent = {\r\n ...event,\r\n target: {\r\n ...event.target,\r\n name,\r\n value: nextValue,\r\n },\r\n } as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n onChange?.(event, nextValue);\r\n },\r\n [form, name, onChange],\r\n );\r\n\r\n return (\r\n <RadioGroupBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={(formValue as string) ?? \"\"}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(\r\n function RadioGroup(props, ref) {\r\n if (props.form) {\r\n return <RadioGroupWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <RadioGroupBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * Switch.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback } from \"react\";\r\nimport { Switch as MuiSwitch, FormControlLabel } from \"@mui/material\";\r\nimport type { SwitchProps } from \"./types\";\r\n\r\nconst SwitchBase = forwardRef<HTMLButtonElement, SwitchProps>(\r\n function SwitchBase(\r\n { label, name, checked, onChange, readonly, disabled, form, ...props },\r\n ref,\r\n ) {\r\n const switchNode = (\r\n <MuiSwitch\r\n {...props}\r\n ref={ref}\r\n name={name}\r\n checked={!!checked}\r\n onChange={onChange}\r\n disabled={disabled || readonly}\r\n />\r\n );\r\n\r\n if (label !== undefined) {\r\n return <FormControlLabel label={label} control={switchNode} />;\r\n }\r\n\r\n return (\r\n switchNode\r\n );\r\n },\r\n);\r\n\r\nconst SwitchWithForm = forwardRef<HTMLButtonElement, SwitchProps>(\r\n function SwitchWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"Switch form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"Switch requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (\r\n event: React.ChangeEvent<HTMLInputElement>,\r\n nextChecked: boolean,\r\n ) => {\r\n const syntheticEvent = {\r\n ...event,\r\n target: {\r\n ...event.target,\r\n name,\r\n value: nextChecked,\r\n checked: nextChecked,\r\n },\r\n } as unknown as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n onChange?.(event, nextChecked);\r\n },\r\n [form, name, onChange],\r\n );\r\n\r\n return (\r\n <SwitchBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n checked={Boolean(formValue)}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const Switch = forwardRef<HTMLButtonElement, SwitchProps>(\r\n function Switch(props, ref) {\r\n if (props.form) {\r\n return <SwitchWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <SwitchBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * Rating.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \u0010a8ud10a8uc601uc9c4 (Kim Young Jin)\r\n * @author \u0010a8ud10a8uc601uc9c4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback } from \"react\";\r\nimport { Rating as MuiRating } from \"@mui/material\";\r\nimport type { RatingProps } from \"./types\";\r\n\r\nconst RatingBase = forwardRef<HTMLSpanElement, RatingProps>(function RatingBase(\r\n { name, value, onChange, readonly, disabled, ...props },\r\n ref,\r\n) {\r\n return (\r\n <MuiRating\r\n {...props}\r\n ref={ref}\r\n name={name}\r\n value={value ?? null}\r\n onChange={onChange}\r\n readOnly={readonly}\r\n disabled={disabled}\r\n />\r\n );\r\n});\r\n\r\nconst RatingWithForm = forwardRef<HTMLSpanElement, RatingProps>(\r\n function RatingWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"Rating form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"Rating requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name) as number | null | undefined;\r\n const resolvedValue =\r\n formValue !== undefined ? formValue : (rest.value ?? null);\r\n\r\n const handleFormChange = useCallback(\r\n (event: React.SyntheticEvent, nextValue: number | null) => {\r\n const syntheticEvent = {\r\n target: {\r\n name,\r\n value: nextValue ?? \"\",\r\n },\r\n } as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n onChange?.(event, nextValue);\r\n },\r\n [form, name, onChange],\r\n );\r\n\r\n return (\r\n <RatingBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={resolvedValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const Rating = forwardRef<HTMLSpanElement, RatingProps>(\r\n function Rating(props, ref) {\r\n if (props.form) {\r\n return <RatingWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <RatingBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * ToggleButton.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \u0010a8ud10a8uc601uc9c4 (Kim Young Jin)\r\n * @author \u0010a8ud10a8uc601uc9c4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback } from \"react\";\r\nimport { ToggleButton as MuiToggleButton } from \"@mui/material\";\r\nimport type { ToggleButtonProps } from \"./types\";\r\n\r\nconst ToggleButtonBase = forwardRef<HTMLButtonElement, Omit<ToggleButtonProps, \"form\">>(function ToggleButtonBase(\r\n { name, value, selected, onChange, readonly, disabled, ...props },\r\n ref\r\n) {\r\n if (selected === undefined) {\r\n return (\r\n <MuiToggleButton\r\n {...props}\r\n ref={ref}\r\n name={name}\r\n value={value ?? \"\"}\r\n onChange={readonly ? undefined : onChange}\r\n disabled={disabled || readonly}\r\n />\r\n );\r\n }\r\n\r\n return (\r\n <MuiToggleButton\r\n {...props}\r\n ref={ref}\r\n name={name}\r\n value={value ?? \"\"}\r\n selected={selected}\r\n onChange={readonly ? undefined : onChange}\r\n disabled={disabled || readonly}\r\n />\r\n );\r\n});\r\n\r\nconst ToggleButtonWithForm = forwardRef<HTMLButtonElement, ToggleButtonProps>(function ToggleButtonWithForm(\r\n { form, name, onChange, selected, value, readonly, disabled, ...rest },\r\n ref\r\n) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\"ToggleButton form prop is missing. Provide a form from useForm or useGlobalForm.\");\r\n }\r\n if (!name) {\r\n throw new Error(\"ToggleButton requires a name when form prop is provided.\");\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const resolvedSelected =\r\n formValue !== undefined ? (value !== undefined ? formValue === value : Boolean(formValue)) : Boolean(selected);\r\n\r\n const handleFormChange = useCallback(\r\n (event: React.MouseEvent<HTMLElement>) => {\r\n if (readonly || disabled) {\r\n return;\r\n }\r\n\r\n const nextSelected = !resolvedSelected;\r\n const nextValue = value !== undefined ? (nextSelected ? value : \"\") : nextSelected;\r\n\r\n const syntheticEvent = {\r\n target: {\r\n name,\r\n value: nextValue,\r\n },\r\n } as React.ChangeEvent<HTMLInputElement>;\r\n\r\n form.handleFormChange(syntheticEvent);\r\n onChange?.(event, value as never);\r\n },\r\n [disabled, form, name, onChange, readonly, resolvedSelected, value]\r\n );\r\n\r\n return (\r\n <ToggleButtonBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={value}\r\n selected={resolvedSelected}\r\n readonly={readonly}\r\n disabled={disabled}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const ToggleButton = forwardRef<HTMLButtonElement, ToggleButtonProps>(function ToggleButton(props, ref) {\r\n if (props.form) {\r\n return <ToggleButtonWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <ToggleButtonBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * ToggleButtonGroup.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback } from \"react\";\r\nimport {\r\n ToggleButton as MuiToggleButton,\r\n ToggleButtonGroup as MuiToggleButtonGroup,\r\n} from \"@mui/material\";\r\nimport type { ToggleButtonGroupProps } from \"./types\";\r\n\r\nconst ToggleButtonGroupBase = forwardRef<\r\n HTMLDivElement,\r\n ToggleButtonGroupProps\r\n>(function ToggleButtonGroupBase(\r\n {\r\n options,\r\n value,\r\n onChange,\r\n fullWidth = false,\r\n readonly,\r\n disabled,\r\n form,\r\n onDeselect,\r\n ...props\r\n },\r\n ref,\r\n) {\r\n return (\r\n <MuiToggleButtonGroup\r\n {...props}\r\n ref={ref}\r\n value={value}\r\n onChange={readonly ? undefined : onChange}\r\n disabled={disabled || readonly}\r\n sx={{\r\n ...(fullWidth ? { width: \"100%\" } : undefined),\r\n ...props.sx,\r\n }}\r\n >\r\n {options.map((option) => (\r\n <MuiToggleButton\r\n key={String(option.value)}\r\n value={option.value}\r\n disabled={option.disabled}\r\n >\r\n {option.label}\r\n </MuiToggleButton>\r\n ))}\r\n </MuiToggleButtonGroup>\r\n );\r\n});\r\n\r\nconst ToggleButtonGroupWithForm = forwardRef<\r\n HTMLDivElement,\r\n ToggleButtonGroupProps\r\n>(function ToggleButtonGroupWithForm(\r\n { form, name, onChange, onDeselect = \"keep\", exclusive, ...rest },\r\n ref,\r\n) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"ToggleButtonGroup form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"ToggleButtonGroup requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.MouseEvent<HTMLElement>, nextValue: unknown) => {\r\n const resolvedValue =\r\n nextValue === null && onDeselect === \"keep\"\r\n ? formValue\r\n : nextValue;\r\n\r\n if (typeof form.setFormValue === \"function\") {\r\n form.setFormValue(name, resolvedValue);\r\n } else {\r\n const syntheticEvent = {\r\n target: {\r\n name,\r\n value: resolvedValue,\r\n },\r\n } as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n }\r\n\r\n onChange?.(event, resolvedValue);\r\n },\r\n [form, formValue, name, onChange, onDeselect],\r\n );\r\n\r\n return (\r\n <ToggleButtonGroupBase\r\n {...rest}\r\n ref={ref}\r\n exclusive={exclusive}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const ToggleButtonGroup = forwardRef<\r\n HTMLDivElement,\r\n ToggleButtonGroupProps\r\n>(function ToggleButtonGroup(props, ref) {\r\n if (props.form) {\r\n return <ToggleButtonGroupWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <ToggleButtonGroupBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * ButtonGroup.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \u0010a8ud10a8uc601uc9c4 (Kim Young Jin)\r\n * @author \u0010a8ud10a8uc601uc9c4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { forwardRef } from \"react\";\r\nimport { ButtonGroup as MuiButtonGroup } from \"@mui/material\";\r\nimport type { ButtonGroupProps as MuiButtonGroupProps } from \"@mui/material/ButtonGroup\";\r\n\r\nexport const ButtonGroup = forwardRef<HTMLDivElement, MuiButtonGroupProps>(function ButtonGroup(props, ref) {\r\n return <MuiButtonGroup ref={ref} {...props} />;\r\n});\r\n", "/**\r\n * DateRange.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { Box } from \"@mui/material\";\r\nimport type { DateRangeProps } from \"./types\";\r\nimport { DateTextField } from \"./DateTextField\";\r\n\r\nexport function DateRange({\r\n form,\r\n startName,\r\n endName,\r\n startLabel = \"\uC2DC\uC791\uC77C\",\r\n endLabel = \"\uC885\uB8CC\uC77C\",\r\n startValue,\r\n endValue,\r\n onStartChange,\r\n onEndChange,\r\n fullWidth = true,\r\n size,\r\n readonly,\r\n gap = 2,\r\n startProps,\r\n endProps,\r\n}: DateRangeProps) {\r\n if (form) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\"DateRange form prop is missing. Provide a form from useForm or useGlobalForm.\");\r\n }\r\n if (!startName || !endName) {\r\n throw new Error(\"DateRange requires startName and endName when form prop is provided.\");\r\n }\r\n\r\n return (\r\n <Box\r\n sx={{\r\n display: \"grid\",\r\n gap,\r\n gridTemplateColumns: { xs: \"1fr\", sm: \"1fr 1fr\" },\r\n }}\r\n >\r\n <DateTextField\r\n {...startProps}\r\n name={startName}\r\n label={startLabel}\r\n form={form}\r\n fullWidth={fullWidth}\r\n size={size}\r\n readonly={readonly}\r\n />\r\n <DateTextField\r\n {...endProps}\r\n name={endName}\r\n label={endLabel}\r\n form={form}\r\n fullWidth={fullWidth}\r\n size={size}\r\n readonly={readonly}\r\n />\r\n </Box>\r\n );\r\n }\r\n\r\n return (\r\n <Box\r\n sx={{\r\n display: \"grid\",\r\n gap,\r\n gridTemplateColumns: { xs: \"1fr\", sm: \"1fr 1fr\" },\r\n }}\r\n >\r\n <DateTextField\r\n {...startProps}\r\n name={startName}\r\n label={startLabel}\r\n value={startValue}\r\n onChange={onStartChange}\r\n fullWidth={fullWidth}\r\n size={size}\r\n readonly={readonly}\r\n />\r\n <DateTextField\r\n {...endProps}\r\n name={endName}\r\n label={endLabel}\r\n value={endValue}\r\n onChange={onEndChange}\r\n fullWidth={fullWidth}\r\n size={size}\r\n readonly={readonly}\r\n />\r\n </Box>\r\n );\r\n}\r\n", "/**\r\n * DateTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n ChangeEvent,\r\n useMemo,\r\n useRef,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField, InputAdornment, IconButton } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport type { DateTextFieldProps } from \"./types\";\r\nimport { DatePicker } from \"@ehfuse/mui-datetime-picker\";\r\nimport { CalendarIcon } from \"./icons\";\r\nimport { useDebouncedEmit } from \"./hooks\";\r\nimport {\r\n getSeparator,\r\n formatDate,\r\n getMaxLength,\r\n getCompleteLength,\r\n validateDate,\r\n formatToPlaceholder,\r\n hasYearInFormat,\r\n parseDateWithInternalYear,\r\n buildDateOutputValue,\r\n dateToNumbers,\r\n} from \"./utils\";\r\n\r\nconst DateTextFieldBase = forwardRef<HTMLDivElement, DateTextFieldProps>(\r\n function DateTextFieldBase(\r\n {\r\n label,\r\n format = \"YYYY-MM-DD\",\r\n separator = \"-\",\r\n minDate,\r\n maxDate,\r\n holidays = [],\r\n holidayColor = \"red\",\r\n calendarIcon = true,\r\n selectedColor,\r\n showToday = true,\r\n invalidBorderColor,\r\n debounce,\r\n slotProps,\r\n sx,\r\n value,\r\n onChange,\r\n onBlur,\r\n placeholder,\r\n onCalendarDismiss,\r\n onCalendarOpen,\r\n onCalendarClose,\r\n name = \"\",\r\n disabled,\r\n readonly = false,\r\n size,\r\n inputRef: externalInputRef,\r\n calendarAnchorOrigin,\r\n calendarTransformOrigin,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n const [displayValue, setDisplayValue] = useState(\"\");\r\n const [prevNumbers, setPrevNumbers] = useState(\"\");\r\n const [calendarOpen, setCalendarOpen] = useState(false);\r\n const [calendarAnchorPos, setCalendarAnchorPos] = useState(\r\n null as { top: number; left: number } | null,\r\n );\r\n const calendarCloseReasonRef = useRef<\"select\" | null>(null);\r\n const [internalYear, setInternalYear] = useState<number | null>(null); // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC6A9\r\n\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLInputElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange, flushOnBlur, lastEmittedValue } = useDebouncedEmit({\r\n name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n const maxLength = getMaxLength(format);\r\n const completeLength = getCompleteLength(format);\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC778\uC9C0 \uD655\uC778 (YYYY, YY\uAC00 \uC5C6\uB294 \uD3EC\uB9F7)\r\n const isYearlessFormat = !hasYearInFormat(format);\r\n\r\n // \uD604\uC7AC \uC120\uD0DD\uB41C \uB0A0\uC9DC \uACC4\uC0B0\r\n const selectedDate = useMemo((): Date | null => {\r\n const parsed = parseDateWithInternalYear(\r\n displayValue,\r\n format,\r\n internalYear,\r\n );\r\n if (!parsed) return null;\r\n return new Date(parsed.year, parsed.month - 1, parsed.day);\r\n }, [displayValue, format, internalYear]);\r\n\r\n // \uB2EC\uB825\uC5D0 \uC804\uB2EC\uD560 \uB0A0\uC9DC \uACC4\uC0B0\r\n const calendarSelectedDate = useMemo((): Date => {\r\n // \uC120\uD0DD\uB41C \uB0A0\uC9DC\uAC00 \uC788\uC73C\uBA74 \uADF8\uB300\uB85C \uC0AC\uC6A9\r\n if (selectedDate) return selectedDate;\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC758 \uACBD\uC6B0 internalYear \uB610\uB294 \uD604\uC7AC \uC5F0\uB3C4 \uC0AC\uC6A9\r\n if (isYearlessFormat) {\r\n const yearToUse = internalYear || new Date().getFullYear();\r\n const parsed = parseDateWithInternalYear(\r\n displayValue,\r\n format,\r\n yearToUse,\r\n );\r\n if (\r\n parsed &&\r\n parsed.month >= 1 &&\r\n parsed.month <= 12 &&\r\n parsed.day >= 1 &&\r\n parsed.day <= 31\r\n ) {\r\n return new Date(yearToUse, parsed.month - 1, parsed.day);\r\n }\r\n return new Date(\r\n yearToUse,\r\n new Date().getMonth(),\r\n new Date().getDate(),\r\n );\r\n }\r\n\r\n return new Date();\r\n }, [\r\n selectedDate,\r\n displayValue,\r\n format,\r\n isYearlessFormat,\r\n internalYear,\r\n ]);\r\n\r\n // onChange\uB85C \uC804\uB2EC\uD560 \uAC12 \uC0DD\uC131 (\uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC774\uC5B4\uB3C4 \uC5F0\uB3C4 \uD3EC\uD568)\r\n const buildOutputValue = useCallback(\r\n (formattedValue: string): string => {\r\n return buildDateOutputValue(\r\n formattedValue,\r\n format,\r\n separator,\r\n internalYear,\r\n );\r\n },\r\n [format, separator, internalYear],\r\n );\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uC218\uD589\r\n const performValidation = useCallback(\r\n (inputValue: string) => {\r\n const numbers = inputValue.replace(/\\D/g, \"\");\r\n\r\n // \uC644\uC131\uB41C \uACBD\uC6B0\uC5D0\uB9CC \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n if (numbers.length === completeLength) {\r\n const isValid = validateDate(\r\n inputValue,\r\n format,\r\n minDate,\r\n maxDate,\r\n );\r\n setIsInvalid(!isValid);\r\n } else {\r\n setIsInvalid(false);\r\n }\r\n },\r\n [format, minDate, maxDate, completeLength],\r\n );\r\n\r\n // value \uBCC0\uACBD \uC2DC displayValue \uC5C5\uB370\uC774\uD2B8 (\uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uACBD\uC6B0\uB9CC)\r\n useEffect(() => {\r\n if (value !== undefined && value !== null) {\r\n const strValue = String(value);\r\n const formattedValue = formatDate(strValue, format);\r\n const currentNumbers = formattedValue.replace(/\\D/g, \"\");\r\n\r\n // \uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uAC12\uC774 \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uD55C \uAC12\uACFC \uB2E4\uB97C \uB54C\uB9CC \uB3D9\uAE30\uD654\r\n // (\uC0AC\uC6A9\uC790 \uC785\uB825 \uC911 \uB514\uBC14\uC6B4\uC2A4\uB85C \uC778\uD55C \uB418\uB3CC\uB9BC \uBC29\uC9C0)\r\n if (strValue !== lastEmittedValue.current) {\r\n setDisplayValue(formattedValue);\r\n setPrevNumbers(currentNumbers);\r\n performValidation(formattedValue);\r\n lastEmittedValue.current = strValue;\r\n }\r\n } else {\r\n if (lastEmittedValue.current !== \"\") {\r\n setDisplayValue(\"\");\r\n setPrevNumbers(\"\");\r\n lastEmittedValue.current = \"\";\r\n }\r\n }\r\n }, [value, format, performValidation, lastEmittedValue]);\r\n\r\n // \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\r\n const input = e.target;\r\n const newValue = input.value;\r\n const newNumbers = newValue.replace(/\\D/g, \"\");\r\n\r\n // \uBC31\uC2A4\uD398\uC774\uC2A4 \uAC10\uC9C0\r\n const isBackspace =\r\n newNumbers.length <= prevNumbers.length &&\r\n newValue.length < displayValue.length;\r\n\r\n let formattedValue: string;\r\n\r\n if (isBackspace && newNumbers.length === prevNumbers.length) {\r\n // \uAD6C\uBD84\uC790\uB9CC \uC0AD\uC81C\uB41C \uACBD\uC6B0: \uC22B\uC790\uB3C4 \uD558\uB098 \uC0AD\uC81C\r\n const trimmedNumbers = newNumbers.slice(0, -1);\r\n formattedValue = formatDate(trimmedNumbers, format);\r\n } else {\r\n // \uC22B\uC790\uAC00 completeLength\uB97C \uCD08\uACFC\uD558\uC9C0 \uC54A\uB3C4\uB85D \uC81C\uD55C\r\n const limitedNumbers = newNumbers.slice(0, completeLength);\r\n formattedValue = formatDate(limitedNumbers, format);\r\n }\r\n\r\n setDisplayValue(formattedValue);\r\n const currentNumbers = formattedValue.replace(/\\D/g, \"\");\r\n setPrevNumbers(currentNumbers);\r\n\r\n // \uCEE4\uC11C \uC704\uCE58 \uC870\uC815: \uD3EC\uB9F7\uD305\uB41C \uC22B\uC790 \uAC1C\uC218\uC5D0 \uB9DE\uAC8C \uC704\uCE58 \uACB0\uC815\r\n requestAnimationFrame(() => {\r\n if (input) {\r\n const formatSep = getSeparator(format);\r\n let cursorPos = formattedValue.length; // \uAE30\uBCF8\uAC12: \uB05D\r\n\r\n if (!isBackspace) {\r\n // \uD3EC\uB9F7\uD305\uB41C \uBB38\uC790\uC5F4\uC758 \uC2E4\uC81C \uC22B\uC790 \uAC1C\uC218 \uC0AC\uC6A9 (constrainDateNumbers\uAC00 \uC790\uB3D9\uC73C\uB85C 0\uC744 \uCD94\uAC00\uD560 \uC218 \uC788\uC74C)\r\n const inputNumberCount = currentNumbers.length;\r\n\r\n // \uD3EC\uB9F7\uD305\uB41C \uBB38\uC790\uC5F4\uC5D0\uC11C \uD574\uB2F9 \uC22B\uC790 \uC704\uCE58 \uCC3E\uAE30\r\n let numberCount = 0;\r\n\r\n for (let i = 0; i < formattedValue.length; i++) {\r\n if (/\\d/.test(formattedValue[i])) {\r\n numberCount++;\r\n // \uC785\uB825\uB41C \uC22B\uC790 \uAC1C\uC218\uC640 \uC77C\uCE58\uD558\uB294 \uC704\uCE58 \uCC3E\uAE30\r\n if (numberCount === inputNumberCount) {\r\n cursorPos = i + 1;\r\n // \uB2E4\uC74C \uBB38\uC790\uAC00 \uAD6C\uBD84\uC790\uBA74 \uAC74\uB108\uB6F0\uAE30 (\uC608: \"2024-\"\uC5D0\uC11C \"-\" \uB4A4\uB85C)\r\n if (\r\n cursorPos < formattedValue.length &&\r\n formattedValue[cursorPos] === formatSep\r\n ) {\r\n cursorPos++;\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // \uC22B\uC790\uB97C \uCC3E\uC9C0 \uBABB\uD55C \uACBD\uC6B0 (\uC774\uB860\uC801\uC73C\uB85C \uBC1C\uC0DD\uD558\uC9C0 \uC54A\uC544\uC57C \uD568)\r\n if (numberCount < inputNumberCount) {\r\n cursorPos = formattedValue.length;\r\n }\r\n } else {\r\n // \uBC31\uC2A4\uD398\uC774\uC2A4\uC778 \uACBD\uC6B0: \uD604\uC7AC \uC22B\uC790 \uAC1C\uC218\uC5D0 \uB9DE\uAC8C \uC704\uCE58 \uACB0\uC815\r\n const targetNumberCount = currentNumbers.length;\r\n let numberCount = 0;\r\n\r\n for (let i = 0; i < formattedValue.length; i++) {\r\n if (/\\d/.test(formattedValue[i])) {\r\n numberCount++;\r\n if (numberCount === targetNumberCount) {\r\n cursorPos = i + 1;\r\n // \uB2E4\uC74C \uBB38\uC790\uAC00 \uAD6C\uBD84\uC790\uBA74 \uAC74\uB108\uB6F0\uAE30\r\n if (\r\n cursorPos < formattedValue.length &&\r\n formattedValue[cursorPos] === formatSep\r\n ) {\r\n cursorPos++;\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n input.setSelectionRange(cursorPos, cursorPos);\r\n }\r\n });\r\n\r\n performValidation(formattedValue);\r\n\r\n // onChange\uB85C \uC804\uB2EC\uD560 \uAC12\r\n const outputValue = buildOutputValue(formattedValue);\r\n\r\n // \uB514\uBC14\uC6B4\uC2A4 \uC801\uC6A9\r\n emitChange(e, outputValue);\r\n };\r\n\r\n // blur \uC2DC \uB300\uAE30 \uC911\uC778 \uB514\uBC14\uC6B4\uC2A4 \uC989\uC2DC \uC2E4\uD589\r\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\r\n const outputValue = buildOutputValue(displayValue);\r\n flushOnBlur(e, outputValue);\r\n if (onBlur) {\r\n onBlur(e);\r\n }\r\n };\r\n\r\n // \uD074\uB9AD \uC2DC \uC804\uCCB4 \uC120\uD0DD (\uC785\uB825\uD558\uBA74 \uCC98\uC74C\uBD80\uD130 \uC0C8\uB85C \uC785\uB825)\r\n const handleClick = useCallback(\r\n (e: React.MouseEvent<HTMLInputElement>) => {\r\n if (disabled || readonly) return;\r\n\r\n const input = e.target as HTMLInputElement;\r\n\r\n // \uAC12\uC774 \uC788\uC744 \uB54C \uC804\uCCB4 \uC120\uD0DD\r\n if (displayValue.length > 0) {\r\n requestAnimationFrame(() => {\r\n if (\r\n input &&\r\n typeof input.setSelectionRange === \"function\"\r\n ) {\r\n input.setSelectionRange(0, displayValue.length);\r\n }\r\n });\r\n }\r\n },\r\n [disabled, readonly, displayValue],\r\n );\r\n\r\n // \uD0A4 \uC785\uB825 \uC81C\uD55C \uD578\uB4E4\uB7EC (\uC5F0\uB3C4 \uCCAB \uC790\uB9AC 1, 2\uB9CC \uD5C8\uC6A9)\r\n const handleKeyDown = useCallback(\r\n (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n // \uC22B\uC790\uAC00 \uC544\uB2CC \uD0A4\uB294 \uD1B5\uACFC (\uBC31\uC2A4\uD398\uC774\uC2A4, \uD654\uC0B4\uD45C \uB4F1)\r\n if (!/^\\d$/.test(e.key)) return;\r\n\r\n const currentNumbers = displayValue.replace(/\\D/g, \"\");\r\n const numLen = currentNumbers.length;\r\n\r\n // YYYY-MM-DD \uD3EC\uB9F7: \uC5F0\uB3C4 \uCCAB \uC790\uB9AC (\uC22B\uC790 0\uBC88\uC9F8)\uB294 1 \uB610\uB294 2\uB9CC \uD5C8\uC6A9\r\n if (format.startsWith(\"YYYY\") && numLen === 0) {\r\n if (e.key !== \"1\" && e.key !== \"2\") {\r\n e.preventDefault();\r\n return;\r\n }\r\n }\r\n\r\n // MM-DD-YYYY \uD3EC\uB9F7: \uC5F0\uB3C4 \uCCAB \uC790\uB9AC (\uC22B\uC790 4\uBC88\uC9F8)\uB294 1 \uB610\uB294 2\uB9CC \uD5C8\uC6A9\r\n if (\r\n format.startsWith(\"MM\") &&\r\n format.endsWith(\"YYYY\") &&\r\n numLen === 4\r\n ) {\r\n if (e.key !== \"1\" && e.key !== \"2\") {\r\n e.preventDefault();\r\n return;\r\n }\r\n }\r\n\r\n // DD-MM-YYYY \uD3EC\uB9F7: \uC5F0\uB3C4 \uCCAB \uC790\uB9AC (\uC22B\uC790 4\uBC88\uC9F8)\uB294 1 \uB610\uB294 2\uB9CC \uD5C8\uC6A9\r\n if (\r\n format.startsWith(\"DD\") &&\r\n format.endsWith(\"YYYY\") &&\r\n numLen === 4\r\n ) {\r\n if (e.key !== \"1\" && e.key !== \"2\") {\r\n e.preventDefault();\r\n return;\r\n }\r\n }\r\n },\r\n [displayValue, format],\r\n );\r\n\r\n // \uB2EC\uB825\uC5D0\uC11C \uB0A0\uC9DC \uC120\uD0DD \uC2DC \uD578\uB4E4\uB7EC\r\n const handleCalendarSelect = (date: Date) => {\r\n const year = date.getFullYear();\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC758 \uACBD\uC6B0 internalYear\uC5D0 \uC800\uC7A5\r\n if (isYearlessFormat) {\r\n setInternalYear(year);\r\n }\r\n\r\n // \uD3EC\uB9F7\uC5D0 \uB9DE\uAC8C \uC22B\uC790 \uBB38\uC790\uC5F4 \uC0DD\uC131\r\n const numbers = dateToNumbers(date, format);\r\n\r\n // \uD604\uC7AC \uD3EC\uB9F7\uC5D0 \uB9DE\uAC8C \uBCC0\uD658\r\n const formattedValue = formatDate(numbers, format);\r\n\r\n setDisplayValue(formattedValue);\r\n setPrevNumbers(numbers);\r\n performValidation(formattedValue);\r\n\r\n // onChange \uD638\uCD9C - \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC774\uC5B4\uB3C4 \uC5F0\uB3C4 \uD3EC\uD568\r\n const outputValue = buildDateOutputValue(\r\n formattedValue,\r\n format,\r\n separator,\r\n year,\r\n );\r\n\r\n // \uB2EC\uB825 \uC120\uD0DD \uC2DC \uC989\uC2DC emit\r\n emitChange(null, outputValue, true);\r\n\r\n const activeElement = document.activeElement as HTMLElement | null;\r\n const inputRoot =\r\n internalInputRef.current?.closest(\".MuiInputBase-root\");\r\n\r\n if (activeElement && inputRoot?.contains(activeElement)) {\r\n activeElement.blur();\r\n }\r\n\r\n calendarCloseReasonRef.current = \"select\";\r\n };\r\n\r\n // \uB2EC\uB825 Popover \uC5F4\uAE30/\uB2EB\uAE30\r\n const handleOpenCalendar = () => {\r\n calendarCloseReasonRef.current = null;\r\n const inputEl = internalInputRef.current;\r\n if (inputEl) {\r\n const rect = inputEl.getBoundingClientRect();\r\n setCalendarAnchorPos({\r\n top: rect.bottom + window.scrollY,\r\n left: rect.left + window.scrollX,\r\n });\r\n }\r\n setCalendarOpen(true);\r\n onCalendarOpen?.();\r\n setTimeout(() => {\r\n const popperPaper = document.querySelector(\r\n '[data-custom-date-picker-popper=\"true\"]',\r\n ) as HTMLElement | null;\r\n popperPaper?.focus();\r\n }, 0);\r\n };\r\n\r\n const handleCloseCalendar = () => {\r\n const isSelectClose = calendarCloseReasonRef.current === \"select\";\r\n calendarCloseReasonRef.current = null;\r\n const activeElement = document.activeElement as HTMLElement | null;\r\n const inputRoot =\r\n internalInputRef.current?.closest(\".MuiInputBase-root\");\r\n\r\n if (activeElement && inputRoot?.contains(activeElement)) {\r\n activeElement.blur();\r\n }\r\n setCalendarOpen(false);\r\n onCalendarClose?.();\r\n if (!isSelectClose) {\r\n onCalendarDismiss?.();\r\n }\r\n };\r\n\r\n const isCalendarOpen = calendarOpen;\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uC2E4\uD328 \uC2DC \uD14C\uB450\uB9AC \uC2A4\uD0C0\uC77C\r\n const invalidStyles: SxProps<Theme> =\r\n isInvalid && invalidBorderColor\r\n ? {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n \"&:hover fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n \"&.Mui-focused fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n },\r\n \"& .MuiFilledInput-root\": {\r\n \"&:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:hover:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:after\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n },\r\n \"& .MuiInput-root\": {\r\n \"&:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:hover:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:after\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n },\r\n }\r\n : {};\r\n\r\n // readonly\uC77C \uB54C \uD3EC\uCEE4\uC2A4 \uC2A4\uD0C0\uC77C \uC81C\uAC70\r\n const readonlyStyles = readonly\r\n ? {\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n return (\r\n <>\r\n <TextField\r\n {...props}\r\n ref={ref}\r\n size={size}\r\n disabled={disabled}\r\n value={displayValue}\r\n label={label}\r\n placeholder={placeholder || formatToPlaceholder(format)}\r\n onChange={handleChange}\r\n onBlur={handleBlur}\r\n onClick={handleClick}\r\n onKeyDown={handleKeyDown}\r\n inputRef={internalInputRef}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n sx={{\r\n ...invalidStyles,\r\n ...readonlyStyles,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...(props.fullWidth && { minWidth: 0 }),\r\n ...sx,\r\n }}\r\n slotProps={{\r\n ...slotProps,\r\n input: {\r\n ...slotProps?.input,\r\n readOnly: readonly,\r\n endAdornment:\r\n calendarIcon && !readonly ? (\r\n <InputAdornment\r\n position=\"end\"\r\n sx={{\r\n mr: size === \"small\" ? -0.5 : 0,\r\n }}\r\n >\r\n <IconButton\r\n onMouseDown={(e) => {\r\n e.preventDefault();\r\n }}\r\n onClick={handleOpenCalendar}\r\n edge=\"end\"\r\n size=\"small\"\r\n disabled={disabled}\r\n sx={{\r\n color: \"text.secondary\",\r\n opacity: 0.5,\r\n transition:\r\n \"opacity 0.2s, color 0.2s\",\r\n \"&:hover\": {\r\n opacity: 1,\r\n color: \"text.primary\",\r\n },\r\n \"&.Mui-disabled\": {\r\n opacity: 0.5,\r\n color: \"text.secondary\",\r\n },\r\n }}\r\n >\r\n <CalendarIcon\r\n size={\r\n size === \"small\" ? 16 : 18\r\n }\r\n />\r\n </IconButton>\r\n </InputAdornment>\r\n ) : undefined,\r\n },\r\n htmlInput: {\r\n ...slotProps?.htmlInput,\r\n maxLength: maxLength,\r\n inputMode: \"numeric\",\r\n },\r\n }}\r\n />\r\n {/* MUI \uC2A4\uD0C0\uC77C \uB2EC\uB825 */}\r\n <DatePicker\r\n open={isCalendarOpen}\r\n anchorEl={internalInputRef}\r\n onClose={handleCloseCalendar}\r\n anchorReference={\r\n calendarAnchorPos ? \"anchorPosition\" : \"anchorEl\"\r\n }\r\n anchorPosition={\r\n calendarAnchorPos\r\n ? {\r\n top: calendarAnchorPos.top,\r\n left: calendarAnchorPos.left,\r\n }\r\n : undefined\r\n }\r\n anchorOrigin={\r\n calendarAnchorOrigin || {\r\n vertical: \"bottom\",\r\n horizontal: \"left\",\r\n }\r\n }\r\n transformOrigin={\r\n calendarTransformOrigin || {\r\n vertical: \"top\",\r\n horizontal: \"left\",\r\n }\r\n }\r\n selectedDate={calendarSelectedDate}\r\n onDateChange={handleCalendarSelect}\r\n minDate={minDate}\r\n maxDate={maxDate}\r\n holidays={holidays}\r\n styles={{ selectedColor, holidayColor }}\r\n showToday={showToday}\r\n autoApply={true}\r\n showFooter={false}\r\n />\r\n </>\r\n );\r\n },\r\n);\r\n\r\nconst DateTextFieldWithForm = forwardRef<HTMLDivElement, DateTextFieldProps>(\r\n function DateTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"DateTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"DateTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <DateTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const DateTextField = forwardRef<HTMLDivElement, DateTextFieldProps>(\r\n function DateTextField(props, ref) {\r\n if (props.form) {\r\n return <DateTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <DateTextFieldBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * utils/index.ts\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\n/** \uC8FC \uC815\uBCF4 \uD0C0\uC785 */\r\nexport interface WeekInfo {\r\n weekOfMonth: number; // \uD574\uB2F9 \uC6D4\uC758 \uBA87 \uBC88\uC9F8 \uC8FC (1-indexed)\r\n startDate: Date; // \uC8FC\uC758 \uC2DC\uC791\uC77C (\uC77C\uC694\uC77C)\r\n endDate: Date; // \uC8FC\uC758 \uC885\uB8CC\uC77C (\uD1A0\uC694\uC77C)\r\n}\r\n\r\n/**\r\n * \uC8FC \uC815\uBCF4 \uACC4\uC0B0 (\uD574\uB2F9 \uC6D4\uC758 \uBA87 \uBC88\uC9F8 \uC8FC, \uC8FC\uC758 \uC2DC\uC791\uC77C, \uC885\uB8CC\uC77C)\r\n * @param date - \uACC4\uC0B0\uD560 \uB0A0\uC9DC\r\n * @returns \uC8FC \uC815\uBCF4 \uAC1D\uCCB4\r\n */\r\nexport const getWeekInfo = (date: Date): WeekInfo => {\r\n const dayOfWeek = date.getDay(); // 0(\uC77C) ~ 6(\uD1A0)\r\n\r\n // \uD574\uB2F9 \uC8FC\uC758 \uC2DC\uC791\uC77C (\uC77C\uC694\uC77C)\r\n const startDate = new Date(date);\r\n startDate.setDate(date.getDate() - dayOfWeek);\r\n startDate.setHours(0, 0, 0, 0);\r\n\r\n // \uD574\uB2F9 \uC8FC\uC758 \uC885\uB8CC\uC77C (\uD1A0\uC694\uC77C)\r\n const endDate = new Date(date);\r\n endDate.setDate(date.getDate() + (6 - dayOfWeek));\r\n endDate.setHours(23, 59, 59, 999);\r\n\r\n // \uD574\uB2F9 \uC6D4\uC758 \uBA87 \uBC88\uC9F8 \uC8FC\uC778\uC9C0 \uACC4\uC0B0 (\uD574\uB2F9 \uC6D4 1\uC77C \uAE30\uC900)\r\n const firstDayOfMonth = new Date(date.getFullYear(), date.getMonth(), 1);\r\n const firstDayOfWeek = firstDayOfMonth.getDay();\r\n const weekOfMonth = Math.ceil((date.getDate() + firstDayOfWeek) / 7);\r\n\r\n return { weekOfMonth, startDate, endDate };\r\n};\r\n\r\n/**\r\n * \uB450 \uB0A0\uC9DC\uAC00 \uAC19\uC740 \uC8FC\uC778\uC9C0 \uD655\uC778\r\n * @param date1 - \uCCAB \uBC88\uC9F8 \uB0A0\uC9DC\r\n * @param date2 - \uB450 \uBC88\uC9F8 \uB0A0\uC9DC\r\n * @returns \uAC19\uC740 \uC8FC\uC774\uBA74 true\r\n */\r\nexport const isSameWeek = (date1: Date, date2: Date): boolean => {\r\n const week1 = getWeekInfo(date1);\r\n const week2 = getWeekInfo(date2);\r\n return week1.startDate.getTime() === week2.startDate.getTime();\r\n};\r\n\r\n/**\r\n * \uB450 \uB0A0\uC9DC\uAC00 \uAC19\uC740 \uB0A0\uC778\uC9C0 \uD655\uC778\r\n * @param d1 - \uCCAB \uBC88\uC9F8 \uB0A0\uC9DC\r\n * @param d2 - \uB450 \uBC88\uC9F8 \uB0A0\uC9DC\r\n * @returns \uAC19\uC740 \uB0A0\uC774\uBA74 true\r\n */\r\nexport const isSameDay = (d1: Date | null, d2: Date | null): boolean => {\r\n if (!d1 || !d2) return false;\r\n return (\r\n d1.getFullYear() === d2.getFullYear() &&\r\n d1.getMonth() === d2.getMonth() &&\r\n d1.getDate() === d2.getDate()\r\n );\r\n};\r\n\r\n/**\r\n * `showFooter === false`\uC774\uBA74 \uD655\uC778/\uCDE8\uC18C \uD478\uD130\uAC00 \uC5C6\uC5B4 `autoApply === false`(\uC784\uC2DC \uC120\uD0DD \uD6C4 \uD655\uC778)\uC640\r\n * \uB3D9\uC2DC\uC5D0 \uB458 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uC774 \uC870\uD569\uC774\uBA74 `autoApply`\uB97C true\uB85C \uB9DE\uCDB0 \uB0A0\uC9DC \uD074\uB9AD\uC774 \uACE7\uBC14\uB85C \uBC18\uC601\uB418\uAC8C \uD569\uB2C8\uB2E4.\r\n */\r\nexport function resolveFooterAndAutoApply(\r\n showFooter: boolean,\r\n autoApply: boolean,\r\n): { showFooter: boolean; autoApply: boolean } {\r\n if (!showFooter && !autoApply) {\r\n return { showFooter: false, autoApply: true };\r\n }\r\n return { showFooter, autoApply };\r\n}\r\n", "/**\r\n * locale.ts\r\n * \uCE98\uB9B0\uB354 \uB85C\uCF00\uC77C \uC815\uC758\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\n/** \uCE98\uB9B0\uB354 \uB85C\uCF00\uC77C \uD0C0\uC785 (\uD14D\uC2A4\uD2B8 \uCEE4\uC2A4\uD130\uB9C8\uC774\uC9D5) */\r\nexport interface CalendarLocale {\r\n weekdays: [string, string, string, string, string, string, string]; // \uC694\uC77C (\uC77C~\uD1A0)\r\n months: [\r\n string,\r\n string,\r\n string,\r\n string,\r\n string,\r\n string,\r\n string,\r\n string,\r\n string,\r\n string,\r\n string,\r\n string\r\n ]; // \uC6D4 (1~12\uC6D4)\r\n today: string; // \uC624\uB298 \uBC84\uD2BC\r\n confirm: string; // \uD655\uC778 \uBC84\uD2BC\r\n cancel: string; // \uCDE8\uC18C \uBC84\uD2BC\r\n close: string; // \uB2EB\uAE30 \uBC84\uD2BC\r\n}\r\n\r\n/** \uCE98\uB9B0\uB354 \uD14D\uC2A4\uD2B8 \uD0C0\uC785 (\uBD80\uBD84 \uCEE4\uC2A4\uD130\uB9C8\uC774\uC9D5\uC6A9) */\r\nexport type CalendarTexts = Partial<CalendarLocale>;\r\n\r\n/** \uD55C\uAD6D\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const koLocale: CalendarLocale = {\r\n weekdays: [\"\uC77C\", \"\uC6D4\", \"\uD654\", \"\uC218\", \"\uBAA9\", \"\uAE08\", \"\uD1A0\"],\r\n months: [\r\n \"1\uC6D4\",\r\n \"2\uC6D4\",\r\n \"3\uC6D4\",\r\n \"4\uC6D4\",\r\n \"5\uC6D4\",\r\n \"6\uC6D4\",\r\n \"7\uC6D4\",\r\n \"8\uC6D4\",\r\n \"9\uC6D4\",\r\n \"10\uC6D4\",\r\n \"11\uC6D4\",\r\n \"12\uC6D4\",\r\n ],\r\n today: \"\uC624\uB298\",\r\n confirm: \"\uD655\uC778\",\r\n cancel: \"\uCDE8\uC18C\",\r\n close: \"\uB2EB\uAE30\",\r\n};\r\n\r\n/** \uC601\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const enLocale: CalendarLocale = {\r\n weekdays: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\r\n months: [\r\n \"Jan\",\r\n \"Feb\",\r\n \"Mar\",\r\n \"Apr\",\r\n \"May\",\r\n \"Jun\",\r\n \"Jul\",\r\n \"Aug\",\r\n \"Sep\",\r\n \"Oct\",\r\n \"Nov\",\r\n \"Dec\",\r\n ],\r\n today: \"Today\",\r\n confirm: \"OK\",\r\n cancel: \"Cancel\",\r\n close: \"Close\",\r\n};\r\n\r\n/** \uC77C\uBCF8\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const jaLocale: CalendarLocale = {\r\n weekdays: [\"\u65E5\", \"\u6708\", \"\u706B\", \"\u6C34\", \"\u6728\", \"\u91D1\", \"\u571F\"],\r\n months: [\r\n \"1\u6708\",\r\n \"2\u6708\",\r\n \"3\u6708\",\r\n \"4\u6708\",\r\n \"5\u6708\",\r\n \"6\u6708\",\r\n \"7\u6708\",\r\n \"8\u6708\",\r\n \"9\u6708\",\r\n \"10\u6708\",\r\n \"11\u6708\",\r\n \"12\u6708\",\r\n ],\r\n today: \"\u4ECA\u65E5\",\r\n confirm: \"\u78BA\u8A8D\",\r\n cancel: \"\u30AD\u30E3\u30F3\u30BB\u30EB\",\r\n close: \"\u9589\u3058\u308B\",\r\n};\r\n\r\n/** \uC911\uAD6D\uC5B4 \uAC04\uCCB4 \uB85C\uCF00\uC77C */\r\nexport const zhCNLocale: CalendarLocale = {\r\n weekdays: [\"\u65E5\", \"\u4E00\", \"\u4E8C\", \"\u4E09\", \"\u56DB\", \"\u4E94\", \"\u516D\"],\r\n months: [\r\n \"1\u6708\",\r\n \"2\u6708\",\r\n \"3\u6708\",\r\n \"4\u6708\",\r\n \"5\u6708\",\r\n \"6\u6708\",\r\n \"7\u6708\",\r\n \"8\u6708\",\r\n \"9\u6708\",\r\n \"10\u6708\",\r\n \"11\u6708\",\r\n \"12\u6708\",\r\n ],\r\n today: \"\u4ECA\u5929\",\r\n confirm: \"\u786E\u8BA4\",\r\n cancel: \"\u53D6\u6D88\",\r\n close: \"\u5173\u95ED\",\r\n};\r\n\r\n/** \uC911\uAD6D\uC5B4 \uBC88\uCCB4 \uB85C\uCF00\uC77C */\r\nexport const zhTWLocale: CalendarLocale = {\r\n weekdays: [\"\u65E5\", \"\u4E00\", \"\u4E8C\", \"\u4E09\", \"\u56DB\", \"\u4E94\", \"\u516D\"],\r\n months: [\r\n \"1\u6708\",\r\n \"2\u6708\",\r\n \"3\u6708\",\r\n \"4\u6708\",\r\n \"5\u6708\",\r\n \"6\u6708\",\r\n \"7\u6708\",\r\n \"8\u6708\",\r\n \"9\u6708\",\r\n \"10\u6708\",\r\n \"11\u6708\",\r\n \"12\u6708\",\r\n ],\r\n today: \"\u4ECA\u5929\",\r\n confirm: \"\u78BA\u8A8D\",\r\n cancel: \"\u53D6\u6D88\",\r\n close: \"\u95DC\u9589\",\r\n};\r\n\r\n/** \uC2A4\uD398\uC778\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const esLocale: CalendarLocale = {\r\n weekdays: [\"Dom\", \"Lun\", \"Mar\", \"Mi\u00E9\", \"Jue\", \"Vie\", \"S\u00E1b\"],\r\n months: [\r\n \"Ene\",\r\n \"Feb\",\r\n \"Mar\",\r\n \"Abr\",\r\n \"May\",\r\n \"Jun\",\r\n \"Jul\",\r\n \"Ago\",\r\n \"Sep\",\r\n \"Oct\",\r\n \"Nov\",\r\n \"Dic\",\r\n ],\r\n today: \"Hoy\",\r\n confirm: \"Aceptar\",\r\n cancel: \"Cancelar\",\r\n close: \"Cerrar\",\r\n};\r\n\r\n/** \uD504\uB791\uC2A4\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const frLocale: CalendarLocale = {\r\n weekdays: [\"Dim\", \"Lun\", \"Mar\", \"Mer\", \"Jeu\", \"Ven\", \"Sam\"],\r\n months: [\r\n \"Jan\",\r\n \"F\u00E9v\",\r\n \"Mar\",\r\n \"Avr\",\r\n \"Mai\",\r\n \"Juin\",\r\n \"Juil\",\r\n \"Ao\u00FB\",\r\n \"Sep\",\r\n \"Oct\",\r\n \"Nov\",\r\n \"D\u00E9c\",\r\n ],\r\n today: \"Aujourd'hui\",\r\n confirm: \"OK\",\r\n cancel: \"Annuler\",\r\n close: \"Fermer\",\r\n};\r\n\r\n/** \uB3C5\uC77C\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const deLocale: CalendarLocale = {\r\n weekdays: [\"So\", \"Mo\", \"Di\", \"Mi\", \"Do\", \"Fr\", \"Sa\"],\r\n months: [\r\n \"Jan\",\r\n \"Feb\",\r\n \"M\u00E4r\",\r\n \"Apr\",\r\n \"Mai\",\r\n \"Jun\",\r\n \"Jul\",\r\n \"Aug\",\r\n \"Sep\",\r\n \"Okt\",\r\n \"Nov\",\r\n \"Dez\",\r\n ],\r\n today: \"Heute\",\r\n confirm: \"OK\",\r\n cancel: \"Abbrechen\",\r\n close: \"Schlie\u00DFen\",\r\n};\r\n\r\n/** \uD3EC\uB974\uD22C\uAC08\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const ptLocale: CalendarLocale = {\r\n weekdays: [\"Dom\", \"Seg\", \"Ter\", \"Qua\", \"Qui\", \"Sex\", \"S\u00E1b\"],\r\n months: [\r\n \"Jan\",\r\n \"Fev\",\r\n \"Mar\",\r\n \"Abr\",\r\n \"Mai\",\r\n \"Jun\",\r\n \"Jul\",\r\n \"Ago\",\r\n \"Set\",\r\n \"Out\",\r\n \"Nov\",\r\n \"Dez\",\r\n ],\r\n today: \"Hoje\",\r\n confirm: \"OK\",\r\n cancel: \"Cancelar\",\r\n close: \"Fechar\",\r\n};\r\n\r\n/** \uB7EC\uC2DC\uC544\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const ruLocale: CalendarLocale = {\r\n weekdays: [\"\u0412\u0441\", \"\u041F\u043D\", \"\u0412\u0442\", \"\u0421\u0440\", \"\u0427\u0442\", \"\u041F\u0442\", \"\u0421\u0431\"],\r\n months: [\r\n \"\u042F\u043D\u0432\",\r\n \"\u0424\u0435\u0432\",\r\n \"\u041C\u0430\u0440\",\r\n \"\u0410\u043F\u0440\",\r\n \"\u041C\u0430\u0439\",\r\n \"\u0418\u044E\u043D\",\r\n \"\u0418\u044E\u043B\",\r\n \"\u0410\u0432\u0433\",\r\n \"\u0421\u0435\u043D\",\r\n \"\u041E\u043A\u0442\",\r\n \"\u041D\u043E\u044F\",\r\n \"\u0414\u0435\u043A\",\r\n ],\r\n today: \"\u0421\u0435\u0433\u043E\u0434\u043D\u044F\",\r\n confirm: \"\u041E\u041A\",\r\n cancel: \"\u041E\u0442\u043C\u0435\u043D\u0430\",\r\n close: \"\u0417\u0430\u043A\u0440\u044B\u0442\u044C\",\r\n};\r\n\r\n/** \uC774\uD0C8\uB9AC\uC544\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const itLocale: CalendarLocale = {\r\n weekdays: [\"Dom\", \"Lun\", \"Mar\", \"Mer\", \"Gio\", \"Ven\", \"Sab\"],\r\n months: [\r\n \"Gen\",\r\n \"Feb\",\r\n \"Mar\",\r\n \"Apr\",\r\n \"Mag\",\r\n \"Giu\",\r\n \"Lug\",\r\n \"Ago\",\r\n \"Set\",\r\n \"Ott\",\r\n \"Nov\",\r\n \"Dic\",\r\n ],\r\n today: \"Oggi\",\r\n confirm: \"OK\",\r\n cancel: \"Annulla\",\r\n close: \"Chiudi\",\r\n};\r\n\r\n/** \uC544\uB78D\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const arLocale: CalendarLocale = {\r\n weekdays: [\"\u0623\u062D\u062F\", \"\u0625\u062B\u0646\", \"\u062B\u0644\u0627\", \"\u0623\u0631\u0628\", \"\u062E\u0645\u064A\", \"\u062C\u0645\u0639\", \"\u0633\u0628\u062A\"],\r\n months: [\r\n \"\u064A\u0646\u0627\u064A\u0631\",\r\n \"\u0641\u0628\u0631\u0627\u064A\u0631\",\r\n \"\u0645\u0627\u0631\u0633\",\r\n \"\u0623\u0628\u0631\u064A\u0644\",\r\n \"\u0645\u0627\u064A\u0648\",\r\n \"\u064A\u0648\u0646\u064A\u0648\",\r\n \"\u064A\u0648\u0644\u064A\u0648\",\r\n \"\u0623\u063A\u0633\u0637\u0633\",\r\n \"\u0633\u0628\u062A\u0645\u0628\u0631\",\r\n \"\u0623\u0643\u062A\u0648\u0628\u0631\",\r\n \"\u0646\u0648\u0641\u0645\u0628\u0631\",\r\n \"\u062F\u064A\u0633\u0645\u0628\u0631\",\r\n ],\r\n today: \"\u0627\u0644\u064A\u0648\u0645\",\r\n confirm: \"\u0645\u0648\u0627\u0641\u0642\",\r\n cancel: \"\u0625\u0644\u063A\u0627\u0621\",\r\n close: \"\u0625\u063A\u0644\u0627\u0642\",\r\n};\r\n\r\n/** \uD78C\uB514\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const hiLocale: CalendarLocale = {\r\n weekdays: [\"\u0930\u0935\u093F\", \"\u0938\u094B\u092E\", \"\u092E\u0902\u0917\u0932\", \"\u092C\u0941\u0927\", \"\u0917\u0941\u0930\u0941\", \"\u0936\u0941\u0915\u094D\u0930\", \"\u0936\u0928\u093F\"],\r\n months: [\r\n \"\u091C\u0928\",\r\n \"\u092B\u0930\",\r\n \"\u092E\u093E\u0930\u094D\u091A\",\r\n \"\u0905\u092A\u094D\u0930\u0948\",\r\n \"\u092E\u0908\",\r\n \"\u091C\u0942\u0928\",\r\n \"\u091C\u0941\u0932\u093E\",\r\n \"\u0905\u0917\",\r\n \"\u0938\u093F\u0924\",\r\n \"\u0905\u0915\u094D\u091F\u0942\",\r\n \"\u0928\u0935\",\r\n \"\u0926\u093F\u0938\",\r\n ],\r\n today: \"\u0906\u091C\",\r\n confirm: \"\u0920\u0940\u0915\",\r\n cancel: \"\u0930\u0926\u094D\u0926\",\r\n close: \"\u092C\u0902\u0926\",\r\n};\r\n\r\n/** \uBCA0\uD2B8\uB0A8\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const viLocale: CalendarLocale = {\r\n weekdays: [\"CN\", \"T2\", \"T3\", \"T4\", \"T5\", \"T6\", \"T7\"],\r\n months: [\r\n \"Th1\",\r\n \"Th2\",\r\n \"Th3\",\r\n \"Th4\",\r\n \"Th5\",\r\n \"Th6\",\r\n \"Th7\",\r\n \"Th8\",\r\n \"Th9\",\r\n \"Th10\",\r\n \"Th11\",\r\n \"Th12\",\r\n ],\r\n today: \"H\u00F4m nay\",\r\n confirm: \"OK\",\r\n cancel: \"H\u1EE7y\",\r\n close: \"\u0110\u00F3ng\",\r\n};\r\n\r\n/** \uD0DC\uAD6D\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const thLocale: CalendarLocale = {\r\n weekdays: [\"\u0E2D\u0E32\", \"\u0E08\", \"\u0E2D\", \"\u0E1E\", \"\u0E1E\u0E24\", \"\u0E28\", \"\u0E2A\"],\r\n months: [\r\n \"\u0E21.\u0E04.\",\r\n \"\u0E01.\u0E1E.\",\r\n \"\u0E21\u0E35.\u0E04.\",\r\n \"\u0E40\u0E21.\u0E22.\",\r\n \"\u0E1E.\u0E04.\",\r\n \"\u0E21\u0E34.\u0E22.\",\r\n \"\u0E01.\u0E04.\",\r\n \"\u0E2A.\u0E04.\",\r\n \"\u0E01.\u0E22.\",\r\n \"\u0E15.\u0E04.\",\r\n \"\u0E1E.\u0E22.\",\r\n \"\u0E18.\u0E04.\",\r\n ],\r\n today: \"\u0E27\u0E31\u0E19\u0E19\u0E35\u0E49\",\r\n confirm: \"\u0E15\u0E01\u0E25\u0E07\",\r\n cancel: \"\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01\",\r\n close: \"\u0E1B\u0E34\u0E14\",\r\n};\r\n\r\n/** \uC778\uB3C4\uB124\uC2DC\uC544\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const idLocale: CalendarLocale = {\r\n weekdays: [\"Min\", \"Sen\", \"Sel\", \"Rab\", \"Kam\", \"Jum\", \"Sab\"],\r\n months: [\r\n \"Jan\",\r\n \"Feb\",\r\n \"Mar\",\r\n \"Apr\",\r\n \"Mei\",\r\n \"Jun\",\r\n \"Jul\",\r\n \"Agu\",\r\n \"Sep\",\r\n \"Okt\",\r\n \"Nov\",\r\n \"Des\",\r\n ],\r\n today: \"Hari ini\",\r\n confirm: \"OK\",\r\n cancel: \"Batal\",\r\n close: \"Tutup\",\r\n};\r\n\r\n/** \uB124\uB35C\uB780\uB4DC\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const nlLocale: CalendarLocale = {\r\n weekdays: [\"Zo\", \"Ma\", \"Di\", \"Wo\", \"Do\", \"Vr\", \"Za\"],\r\n months: [\r\n \"Jan\",\r\n \"Feb\",\r\n \"Mrt\",\r\n \"Apr\",\r\n \"Mei\",\r\n \"Jun\",\r\n \"Jul\",\r\n \"Aug\",\r\n \"Sep\",\r\n \"Okt\",\r\n \"Nov\",\r\n \"Dec\",\r\n ],\r\n today: \"Vandaag\",\r\n confirm: \"OK\",\r\n cancel: \"Annuleren\",\r\n close: \"Sluiten\",\r\n};\r\n\r\n/** \uD3F4\uB780\uB4DC\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const plLocale: CalendarLocale = {\r\n weekdays: [\"Nd\", \"Pn\", \"Wt\", \"\u015Ar\", \"Cz\", \"Pt\", \"So\"],\r\n months: [\r\n \"Sty\",\r\n \"Lut\",\r\n \"Mar\",\r\n \"Kwi\",\r\n \"Maj\",\r\n \"Cze\",\r\n \"Lip\",\r\n \"Sie\",\r\n \"Wrz\",\r\n \"Pa\u017A\",\r\n \"Lis\",\r\n \"Gru\",\r\n ],\r\n today: \"Dzi\u015B\",\r\n confirm: \"OK\",\r\n cancel: \"Anuluj\",\r\n close: \"Zamknij\",\r\n};\r\n\r\n/** \uD130\uD0A4\uC5B4 \uB85C\uCF00\uC77C */\r\nexport const trLocale: CalendarLocale = {\r\n weekdays: [\"Paz\", \"Pzt\", \"Sal\", \"\u00C7ar\", \"Per\", \"Cum\", \"Cmt\"],\r\n months: [\r\n \"Oca\",\r\n \"\u015Eub\",\r\n \"Mar\",\r\n \"Nis\",\r\n \"May\",\r\n \"Haz\",\r\n \"Tem\",\r\n \"A\u011Fu\",\r\n \"Eyl\",\r\n \"Eki\",\r\n \"Kas\",\r\n \"Ara\",\r\n ],\r\n today: \"Bug\u00FCn\",\r\n confirm: \"Tamam\",\r\n cancel: \"\u0130ptal\",\r\n close: \"Kapat\",\r\n};\r\n\r\n/** \uAE30\uBCF8 \uB85C\uCF00\uC77C (\uD55C\uAD6D\uC5B4) */\r\nexport const defaultLocale = koLocale;\r\n\r\n/** \uB85C\uCF00\uC77C \uB9F5 */\r\nexport const locales = {\r\n ko: koLocale,\r\n en: enLocale,\r\n ja: jaLocale,\r\n zhCN: zhCNLocale,\r\n zhTW: zhTWLocale,\r\n es: esLocale,\r\n fr: frLocale,\r\n de: deLocale,\r\n pt: ptLocale,\r\n ru: ruLocale,\r\n it: itLocale,\r\n ar: arLocale,\r\n hi: hiLocale,\r\n vi: viLocale,\r\n th: thLocale,\r\n id: idLocale,\r\n nl: nlLocale,\r\n pl: plLocale,\r\n tr: trLocale,\r\n} as const;\r\n\r\n/** \uB85C\uCF00\uC77C \uD0A4 \uD0C0\uC785 */\r\nexport type LocaleKey = keyof typeof locales;\r\n\r\n/** \uB85C\uCF00\uC77C \uD504\uB86D \uD0C0\uC785 (\uAC1D\uCCB4 \uB610\uB294 \uBB38\uC790\uC5F4) */\r\nexport type LocaleProp = CalendarLocale | LocaleKey;\r\n\r\n/**\r\n * \uB85C\uCF00\uC77C \uD504\uB86D\uC744 CalendarLocale \uAC1D\uCCB4\uB85C \uBCC0\uD658\r\n * @param locale - CalendarLocale \uAC1D\uCCB4 \uB610\uB294 \uB85C\uCF00\uC77C \uD0A4 \uBB38\uC790\uC5F4 (\uC608: 'ko', 'en')\r\n * @returns CalendarLocale \uAC1D\uCCB4\r\n */\r\nexport function resolveLocale(locale: LocaleProp | undefined): CalendarLocale {\r\n if (!locale) return defaultLocale;\r\n if (typeof locale === \"string\") {\r\n return locales[locale] ?? defaultLocale;\r\n }\r\n return locale;\r\n}\r\n", "/**\r\n * SimpleCalendar.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useMemo,\r\n useEffect,\r\n useRef,\r\n useCallback,\r\n} from \"react\";\r\nimport { Box, Typography, IconButton, Button } from \"@mui/material\";\r\nimport { ChevronLeft, ChevronRight } from \"./icons\";\r\nimport { OverlayScrollbar } from \"@ehfuse/overlay-scrollbar\";\r\nimport type { OverlayScrollbarRef } from \"@ehfuse/overlay-scrollbar\";\r\nimport { TimeSelector } from \"./TimeSelector\";\r\nimport type { SimpleCalendarProps, ViewMode } from \"./types\";\r\nimport { resolveLocale } from \"./locale\";\r\nimport {\r\n getWeekInfo,\r\n isSameDay,\r\n isSameWeek,\r\n resolveFooterAndAutoApply,\r\n} from \"./utils\";\r\n\r\n// \uC0C1\uC218\r\nconst HEADER_HEIGHT = 48;\r\nconst FOOTER_HEIGHT = 48;\r\n\r\n/**\r\n * \uAC04\uB2E8\uD55C MUI \uC2A4\uD0C0\uC77C \uB2EC\uB825 \uCEF4\uD3EC\uB10C\uD2B8\r\n *\r\n * \uAD6C\uC870:\r\n * calendar-root (flex column, 100% height)\r\n * \u251C\u2500\u2500 calendar-header (\uACF5\uD1B5, \uACE0\uC815 \uB192\uC774 40px)\r\n * \u2502 - viewMode\uC5D0 \uB530\uB77C \uB0B4\uC6A9 \uBCC0\uACBD\r\n * \u251C\u2500\u2500 calendar-content (flex: 1)\r\n * \u2502 - [calendar] \uC694\uC77C \uD5E4\uB354 + \uB0A0\uC9DC \uADF8\uB9AC\uB4DC\r\n * \u2502 - [year] \uC5F0\uB3C4 \uADF8\uB9AC\uB4DC (OverlayScrollbar)\r\n * \u2502 - [month] \uC6D4 \uADF8\uB9AC\uB4DC\r\n * \u2514\u2500\u2500 calendar-footer (\uACF5\uD1B5, \uACE0\uC815 \uB192\uC774 40px)\r\n * - viewMode\uC5D0 \uB530\uB77C \uBC84\uD2BC \uBCC0\uACBD\r\n */\r\nexport function SimpleCalendar({\r\n selectedDate,\r\n onSelect,\r\n minDate,\r\n maxDate,\r\n holidays = [],\r\n styles,\r\n onClose,\r\n showToday = true,\r\n showFooter: showFooterProp = true,\r\n autoApply: autoApplyProp = true,\r\n // \uB144\uC6D4\uB9CC \uC120\uD0DD\r\n monthOnly = false,\r\n // \uB144\uB3C4\uB9CC \uC120\uD0DD\r\n yearOnly = false,\r\n // \uB144\uC6D4/\uB144\uB3C4 \uBCC0\uACBD \uCF5C\uBC31\r\n onMonthChange,\r\n onYearChange,\r\n onWeekChange,\r\n // \uC2DC\uAC04 \uC120\uD0DD \uAD00\uB828\r\n showTimePicker = false,\r\n timeValue,\r\n onTimeChange,\r\n timeFormat = \"HH:mm\",\r\n minTime,\r\n maxTime,\r\n minuteStep = 1,\r\n secondStep = 1,\r\n hideDisabledTime = false,\r\n // \uB85C\uCF00\uC77C \uAD00\uB828\r\n locale,\r\n texts,\r\n}: SimpleCalendarProps) {\r\n const { showFooter: footerOn, autoApply: applyImmediate } =\r\n resolveFooterAndAutoApply(showFooterProp, autoApplyProp);\r\n\r\n // \uC2A4\uD0C0\uC77C \uC635\uC158 \uCD94\uCD9C (\uAE30\uBCF8\uAC12 \uC801\uC6A9)\r\n const selectedColor = styles?.selectedColor ?? \"primary.main\";\r\n const todayBorderColor = styles?.todayBorderColor ?? selectedColor;\r\n const holidayColor = styles?.holidayColor ?? \"error.main\";\r\n const saturdayColor = styles?.saturdayColor ?? \"primary.main\";\r\n\r\n // \uB85C\uCF00\uC77C \uD574\uC11D \uBC0F \uBCD1\uD569 (texts\uAC00 \uC788\uC73C\uBA74 \uBD80\uBD84 \uB36E\uC5B4\uC4F0\uAE30)\r\n const resolvedLocale = resolveLocale(locale);\r\n const mergedLocale = useMemo(\r\n () => (texts ? { ...resolvedLocale, ...texts } : resolvedLocale),\r\n [resolvedLocale, texts],\r\n );\r\n\r\n // \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 Date \uD544\uD130\uB9C1\r\n const validHolidays = useMemo(\r\n () => holidays.filter((d) => d instanceof Date && !isNaN(d.getTime())),\r\n [holidays],\r\n );\r\n\r\n const today = new Date();\r\n const [viewDate, setViewDate] = useState(() => {\r\n if (selectedDate) return new Date(selectedDate);\r\n return new Date(today.getFullYear(), today.getMonth(), 1);\r\n });\r\n // yearOnly\uC77C \uB54C\uB294 year \uBDF0\uB85C, monthOnly\uC77C \uB54C\uB294 month \uBDF0\uB85C \uC2DC\uC791\r\n const [viewMode, setViewMode] = useState<ViewMode>(\r\n yearOnly ? \"year\" : monthOnly ? \"month\" : \"calendar\",\r\n );\r\n const [tempYear, setTempYear] = useState<number>(viewDate.getFullYear());\r\n // monthOnly \uBAA8\uB4DC\uC5D0\uC11C \uC784\uC2DC \uC6D4 \uC0C1\uD0DC (autoApply\uAC00 false\uC77C \uB54C \uC0AC\uC6A9)\r\n const [tempMonth, setTempMonth] = useState<number | null>(null);\r\n // yearOnly \uBAA8\uB4DC\uC5D0\uC11C \uC784\uC2DC \uB144\uB3C4 \uC0C1\uD0DC (autoApply\uAC00 false\uC77C \uB54C \uC0AC\uC6A9)\r\n const [tempSelectedYear, setTempSelectedYear] = useState<number | null>(\r\n null,\r\n );\r\n // \uC784\uC2DC \uC120\uD0DD \uB0A0\uC9DC (\uD655\uC778 \uBC84\uD2BC \uB204\uB974\uAE30 \uC804\uAE4C\uC9C0 \uBCF4\uAD00)\r\n const [tempSelectedDate, setTempSelectedDate] = useState<Date | null>(\r\n selectedDate,\r\n );\r\n // \uC784\uC2DC \uC2DC\uAC04 (\uD655\uC778 \uBC84\uD2BC \uB204\uB974\uAE30 \uC804\uAE4C\uC9C0 \uBCF4\uAD00)\r\n const [tempTime, setTempTime] = useState<{\r\n hour: number;\r\n minute: number;\r\n second: number;\r\n }>(() => {\r\n const h = timeValue ? parseInt(timeValue.hour, 10) : NaN;\r\n const m = timeValue ? parseInt(timeValue.minute, 10) : NaN;\r\n const s = timeValue?.second ? parseInt(timeValue.second, 10) : 0;\r\n const now = new Date();\r\n return {\r\n hour: isNaN(h) ? now.getHours() : h,\r\n minute: isNaN(m)\r\n ? Math.floor(now.getMinutes() / minuteStep) * minuteStep\r\n : m,\r\n second: isNaN(s)\r\n ? Math.floor(now.getSeconds() / secondStep) * secondStep\r\n : s,\r\n };\r\n });\r\n\r\n const year = viewDate.getFullYear();\r\n const month = viewDate.getMonth();\r\n\r\n // refs\r\n const yearScrollRef = useRef<OverlayScrollbarRef>(null);\r\n const contentRef = useRef<HTMLDivElement>(null);\r\n\r\n // \uB2EC\uB825 \uB0A0\uC9DC \uC0DD\uC131 (\uD56D\uC0C1 42\uCE78 = 6\uC8FC, \uC774\uC804/\uB2E4\uC74C \uB2EC \uD3EC\uD568)\r\n const calendarDays = useMemo(() => {\r\n const firstDay = new Date(year, month, 1);\r\n const lastDay = new Date(year, month + 1, 0);\r\n const startPadding = firstDay.getDay();\r\n const daysInMonth = lastDay.getDate();\r\n\r\n const days: Date[] = [];\r\n\r\n // \uC774\uC804 \uB2EC \uB0A0\uC9DC\r\n const prevMonth = new Date(year, month, 0); // \uC774\uC804 \uB2EC \uB9C8\uC9C0\uB9C9 \uB0A0\r\n const prevMonthDays = prevMonth.getDate();\r\n for (let i = startPadding - 1; i >= 0; i--) {\r\n days.push(new Date(year, month - 1, prevMonthDays - i));\r\n }\r\n\r\n // \uD604\uC7AC \uB2EC\r\n for (let d = 1; d <= daysInMonth; d++) {\r\n days.push(new Date(year, month, d));\r\n }\r\n\r\n // \uB2E4\uC74C \uB2EC \uB0A0\uC9DC (42\uCE78 \uCC44\uC6B0\uAE30)\r\n let nextDay = 1;\r\n while (days.length < 42) {\r\n days.push(new Date(year, month + 1, nextDay++));\r\n }\r\n\r\n return days;\r\n }, [year, month]);\r\n\r\n // \uC5F0\uB3C4 \uBAA9\uB85D \uC0DD\uC131 (\uACFC\uAC70 50\uB144 ~ \uBBF8\uB798 50\uB144)\r\n const yearList = useMemo(() => {\r\n const currentYear = today.getFullYear();\r\n const years: number[] = [];\r\n for (let y = currentYear - 50; y <= currentYear + 50; y++) {\r\n years.push(y);\r\n }\r\n return years;\r\n }, [today]);\r\n\r\n const isDateDisabled = (date: Date): boolean => {\r\n const dateOnly = new Date(\r\n date.getFullYear(),\r\n date.getMonth(),\r\n date.getDate(),\r\n );\r\n\r\n if (minDate) {\r\n const min = new Date(\r\n minDate.getFullYear(),\r\n minDate.getMonth(),\r\n minDate.getDate(),\r\n );\r\n if (dateOnly.getTime() < min.getTime()) return true;\r\n }\r\n if (maxDate) {\r\n const max = new Date(\r\n maxDate.getFullYear(),\r\n maxDate.getMonth(),\r\n maxDate.getDate(),\r\n );\r\n if (dateOnly.getTime() > max.getTime()) return true;\r\n }\r\n return false;\r\n };\r\n\r\n // \uC2DC\uAC04\uC774 \uBCC0\uACBD\uB418\uC5C8\uB294\uC9C0 \uD655\uC778\r\n const isTimeChanged = (\r\n hour: number,\r\n minute: number,\r\n second?: number,\r\n ): boolean => {\r\n if (!timeValue) return true;\r\n const hasSeconds =\r\n timeFormat === \"HH:mm:ss\" || timeFormat === \"hh:mm:ss\";\r\n if (\r\n parseInt(timeValue.hour, 10) !== hour ||\r\n parseInt(timeValue.minute, 10) !== minute\r\n )\r\n return true;\r\n if (hasSeconds && parseInt(timeValue.second || \"0\", 10) !== second)\r\n return true;\r\n return false;\r\n };\r\n\r\n // \uB144\uB3C4\uAC00 \uBCC0\uACBD\uB418\uC5C8\uB294\uC9C0 \uD655\uC778 (selectedDate \uB610\uB294 \uC624\uB298 \uB0A0\uC9DC \uAE30\uC900)\r\n const isYearChanged = (newYear: number): boolean => {\r\n const compareDate = selectedDate || today;\r\n return compareDate.getFullYear() !== newYear;\r\n };\r\n\r\n // \uC6D4\uC774 \uBCC0\uACBD\uB418\uC5C8\uB294\uC9C0 \uD655\uC778 (selectedDate \uB610\uB294 \uC624\uB298 \uB0A0\uC9DC \uAE30\uC900, month\uB294 1-indexed)\r\n const isMonthChanged = (newYear: number, newMonth: number): boolean => {\r\n const compareDate = selectedDate || today;\r\n return (\r\n compareDate.getFullYear() !== newYear ||\r\n compareDate.getMonth() + 1 !== newMonth\r\n );\r\n };\r\n\r\n // \uC8FC\uAC00 \uBCC0\uACBD\uB418\uC5C8\uB294\uC9C0 \uD655\uC778\r\n const isWeekChanged = (date: Date): boolean => {\r\n const compareDate = selectedDate || today;\r\n return !isSameWeek(date, compareDate);\r\n };\r\n\r\n const goToPrevMonth = () => {\r\n const newDate = new Date(year, month - 1, 1);\r\n setViewDate(newDate);\r\n setTempSelectedDate(null);\r\n // \uC6D4 \uBCC0\uACBD \uCF5C\uBC31 \uD638\uCD9C\r\n onMonthChange?.(newDate.getFullYear(), newDate.getMonth() + 1);\r\n };\r\n\r\n const goToNextMonth = () => {\r\n const newDate = new Date(year, month + 1, 1);\r\n setViewDate(newDate);\r\n setTempSelectedDate(null);\r\n // \uC6D4 \uBCC0\uACBD \uCF5C\uBC31 \uD638\uCD9C\r\n onMonthChange?.(newDate.getFullYear(), newDate.getMonth() + 1);\r\n };\r\n\r\n // \uD720 \uC774\uBCA4\uD2B8\uB85C \uC774\uC804/\uB2E4\uC74C \uB2EC \uC774\uB3D9\r\n const handleWheel = useCallback(\r\n (e: React.WheelEvent) => {\r\n if (viewMode !== \"calendar\") return;\r\n e.preventDefault();\r\n if (e.deltaY > 0) {\r\n goToNextMonth();\r\n } else if (e.deltaY < 0) {\r\n goToPrevMonth();\r\n }\r\n },\r\n [viewMode, year, month],\r\n );\r\n\r\n const handleDateClick = (date: Date) => {\r\n if (!isDateDisabled(date)) {\r\n if (applyImmediate) {\r\n // autoApply\uAC00 true\uBA74 \uBC14\uB85C \uC801\uC6A9 (\uB2EB\uC9C0 \uC54A\uC74C)\r\n // \uAC19\uC740 \uB0A0\uC744 \uB2E4\uC2DC \uB20C\uB7EC\uB3C4 \uC0AC\uC6A9\uC790 \uC81C\uC2A4\uCC98\uC774\uBBC0\uB85C \uD56D\uC0C1 onSelect\r\n onSelect(date);\r\n if (isWeekChanged(date)) {\r\n const weekInfo = getWeekInfo(date);\r\n onWeekChange?.(\r\n weekInfo.weekOfMonth,\r\n weekInfo.startDate,\r\n weekInfo.endDate,\r\n );\r\n }\r\n // \uC2DC\uAC04 \uC120\uD0DD\uC774 \uC788\uC73C\uBA74 \uC2DC\uAC04\uB3C4 \uAC19\uC774 \uC801\uC6A9 (\uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC)\r\n if (\r\n showTimePicker &&\r\n onTimeChange &&\r\n isTimeChanged(\r\n tempTime.hour,\r\n tempTime.minute,\r\n tempTime.second,\r\n )\r\n ) {\r\n const hasSeconds =\r\n timeFormat === \"HH:mm:ss\" || timeFormat === \"hh:mm:ss\";\r\n onTimeChange(\r\n tempTime.hour,\r\n tempTime.minute,\r\n hasSeconds ? tempTime.second : undefined,\r\n );\r\n }\r\n } else {\r\n setTempSelectedDate(date);\r\n }\r\n }\r\n };\r\n\r\n const handleTodayClick = () => {\r\n if (!isDateDisabled(today)) {\r\n const todayYear = today.getFullYear();\r\n const todayMonth = today.getMonth();\r\n\r\n if (applyImmediate) {\r\n // autoApply\uAC00 true\uBA74 \uBC14\uB85C \uC801\uC6A9 (\uB2EB\uC9C0 \uC54A\uC74C)\r\n // \uD604\uC7AC viewDate\uC640 \uBE44\uAD50\uD574\uC11C \uB144/\uC6D4 \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n if (year !== todayYear) {\r\n onYearChange?.(todayYear);\r\n }\r\n if (year !== todayYear || month !== todayMonth) {\r\n onMonthChange?.(todayYear, todayMonth + 1);\r\n }\r\n // \uC624\uB298 \uBC84\uD2BC: \uAC19\uC740 \uB0A0(\uC624\uB298)\uC774\uC5B4\uB3C4 \uD56D\uC0C1 onSelect\r\n onSelect(today);\r\n // \uC2DC\uAC04 \uC120\uD0DD\uC774 \uC788\uC73C\uBA74 \uC2DC\uAC04\uB3C4 \uAC19\uC774 \uC801\uC6A9 (\uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC)\r\n if (\r\n showTimePicker &&\r\n onTimeChange &&\r\n isTimeChanged(\r\n tempTime.hour,\r\n tempTime.minute,\r\n tempTime.second,\r\n )\r\n ) {\r\n const hasSeconds =\r\n timeFormat === \"HH:mm:ss\" || timeFormat === \"hh:mm:ss\";\r\n onTimeChange(\r\n tempTime.hour,\r\n tempTime.minute,\r\n hasSeconds ? tempTime.second : undefined,\r\n );\r\n }\r\n setViewDate(new Date(todayYear, todayMonth, 1));\r\n } else {\r\n setTempSelectedDate(today);\r\n setViewDate(new Date(todayYear, todayMonth, 1));\r\n }\r\n }\r\n };\r\n\r\n const handleConfirm = () => {\r\n if (tempSelectedDate) {\r\n // \uD655\uC778: \uC784\uC2DC \uC120\uD0DD\uC774 \uC788\uC73C\uBA74 selectedDate\uC640 \uAC19\uC544\uB3C4 \uD56D\uC0C1 onSelect\r\n onSelect(tempSelectedDate);\r\n if (isWeekChanged(tempSelectedDate)) {\r\n const weekInfo = getWeekInfo(tempSelectedDate);\r\n onWeekChange?.(\r\n weekInfo.weekOfMonth,\r\n weekInfo.startDate,\r\n weekInfo.endDate,\r\n );\r\n }\r\n }\r\n // \uC2DC\uAC04 \uC120\uD0DD\uC774 \uC788\uC73C\uBA74 \uC2DC\uAC04\uB3C4 \uC801\uC6A9 (\uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC)\r\n if (\r\n showTimePicker &&\r\n onTimeChange &&\r\n isTimeChanged(tempTime.hour, tempTime.minute, tempTime.second)\r\n ) {\r\n const hasSeconds =\r\n timeFormat === \"HH:mm:ss\" || timeFormat === \"hh:mm:ss\";\r\n onTimeChange(\r\n tempTime.hour,\r\n tempTime.minute,\r\n hasSeconds ? tempTime.second : undefined,\r\n );\r\n }\r\n onClose();\r\n };\r\n\r\n // \uC784\uC2DC \uC2DC\uAC04 \uBCC0\uACBD \uD578\uB4E4\uB7EC\r\n const handleTempTimeChange = (\r\n hour: number,\r\n minute: number,\r\n second?: number,\r\n ) => {\r\n setTempTime({\r\n hour,\r\n minute,\r\n second: second ?? 0,\r\n });\r\n\r\n // autoApply\uBA74 \uBC14\uB85C \uC801\uC6A9 (\uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC)\r\n if (applyImmediate && onTimeChange && isTimeChanged(hour, minute, second)) {\r\n const hasSeconds =\r\n timeFormat === \"HH:mm:ss\" || timeFormat === \"hh:mm:ss\";\r\n onTimeChange(hour, minute, hasSeconds ? second : undefined);\r\n }\r\n };\r\n\r\n // \uB144\uC6D4 \uD0C0\uC774\uD2C0 \uD074\uB9AD \u2192 \uC5F0\uB3C4 \uC120\uD0DD \uBAA8\uB4DC\r\n const handleTitleClick = () => {\r\n setTempYear(year);\r\n setViewMode(\"year\");\r\n };\r\n\r\n // \uC5F0\uB3C4 \uC120\uD0DD\r\n const handleYearSelect = (selectedYear: number) => {\r\n if (yearOnly) {\r\n if (applyImmediate) {\r\n // autoApply\uAC00 true\uBA74 \uBC14\uB85C \uC801\uC6A9\uD558\uACE0 \uB2EB\uAE30 (\uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC)\r\n if (isYearChanged(selectedYear)) {\r\n onYearChange?.(selectedYear);\r\n }\r\n onClose();\r\n } else {\r\n // autoApply\uAC00 false\uBA74 \uC784\uC2DC \uC800\uC7A5\uB9CC\r\n setTempSelectedYear(selectedYear);\r\n }\r\n } else if (monthOnly) {\r\n // monthOnly \uBAA8\uB4DC: \uC6D4\uAE4C\uC9C0 \uC120\uD0DD\uD574\uC57C \uCD5C\uC885\uC774\uBBC0\uB85C \uB144\uB3C4 \uC120\uD0DD \uC2DC\uC5D0\uB294 \uC774\uBCA4\uD2B8 \uBC1C\uC0DD \uC548\uD568\r\n setTempYear(selectedYear);\r\n setViewMode(\"month\");\r\n } else {\r\n // \uC77C\uBC18 \uCE98\uB9B0\uB354 \uBAA8\uB4DC: \uB144\uB3C4 \uC120\uD0DD \uC2DC onYearChange \uD638\uCD9C (\uD604\uC7AC viewDate \uAE30\uC900)\r\n if (year !== selectedYear) {\r\n onYearChange?.(selectedYear);\r\n }\r\n setTempYear(selectedYear);\r\n setViewMode(\"month\");\r\n }\r\n };\r\n\r\n // yearOnly \uBAA8\uB4DC\uC5D0\uC11C \uD655\uC778 \uBC84\uD2BC \uD074\uB9AD\r\n const handleYearConfirm = () => {\r\n if (tempSelectedYear !== null) {\r\n // \uB144\uB3C4\uAC00 \uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n if (isYearChanged(tempSelectedYear)) {\r\n onYearChange?.(tempSelectedYear);\r\n }\r\n }\r\n onClose();\r\n };\r\n\r\n // \uC6D4 \uC120\uD0DD\r\n const handleMonthSelect = (selectedMonth: number) => {\r\n if (monthOnly) {\r\n if (applyImmediate) {\r\n // autoApply\uAC00 true\uBA74 \uBC14\uB85C \uC801\uC6A9\uD558\uACE0 \uB2EB\uAE30 (\uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC)\r\n if (isYearChanged(tempYear)) {\r\n onYearChange?.(tempYear);\r\n }\r\n if (isMonthChanged(tempYear, selectedMonth + 1)) {\r\n onMonthChange?.(tempYear, selectedMonth + 1);\r\n }\r\n onClose();\r\n } else {\r\n // autoApply\uAC00 false\uBA74 \uC784\uC2DC \uC800\uC7A5\uB9CC\r\n setTempMonth(selectedMonth);\r\n }\r\n } else {\r\n // \uC77C\uBC18 \uCE98\uB9B0\uB354 \uBAA8\uB4DC: \uB144/\uC6D4 \uC120\uD0DD \uBDF0\uC5D0\uC11C \uC6D4\uC744 \uC120\uD0DD\uD558\uBA74 \uD574\uB2F9 \uC6D4\uB85C \uC774\uB3D9\r\n const newDate = new Date(tempYear, selectedMonth, 1);\r\n // \uC6D4 \uBCC0\uACBD \uCF5C\uBC31 \uD638\uCD9C (\uD604\uC7AC viewDate \uAE30\uC900\uC73C\uB85C \uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC)\r\n if (year !== tempYear || month !== selectedMonth) {\r\n onMonthChange?.(tempYear, selectedMonth + 1);\r\n }\r\n setViewDate(newDate);\r\n setViewMode(\"calendar\");\r\n setTempSelectedDate(null);\r\n }\r\n };\r\n\r\n // monthOnly \uBAA8\uB4DC\uC5D0\uC11C \uD655\uC778 \uBC84\uD2BC \uD074\uB9AD\r\n const handleMonthConfirm = () => {\r\n if (tempMonth !== null) {\r\n // \uB144\uC6D4\uC774 \uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n if (isYearChanged(tempYear)) {\r\n onYearChange?.(tempYear);\r\n }\r\n if (isMonthChanged(tempYear, tempMonth + 1)) {\r\n onMonthChange?.(tempYear, tempMonth + 1);\r\n }\r\n }\r\n onClose();\r\n };\r\n\r\n // \uC5F0\uB3C4 \uC120\uD0DD \uBDF0\uAC00 \uC5F4\uB9B4 \uB54C \uD604\uC7AC\uB144\uB3C4\uB97C \uC911\uC559\uC5D0 \uC704\uCE58\r\n useEffect(() => {\r\n if (\r\n viewMode === \"year\" &&\r\n yearScrollRef.current &&\r\n contentRef.current\r\n ) {\r\n // DOM\uC774 \uB80C\uB354\uB9C1\uB41C \uD6C4 \uC2E4\uC81C \uB192\uC774\uB97C \uACC4\uC0B0\r\n requestAnimationFrame(() => {\r\n if (!yearScrollRef.current || !contentRef.current) return;\r\n\r\n const currentYear = today.getFullYear();\r\n const yearIndex = yearList.findIndex((y) => y === currentYear);\r\n if (yearIndex < 0) return;\r\n\r\n // \uC2E4\uC81C \uADF8\uB9AC\uB4DC \uC694\uC18C \uCC3E\uAE30\r\n const scrollContainer = contentRef.current.querySelector(\r\n \".overlay-scrollbar-content\",\r\n ) as HTMLElement;\r\n const gridElement = scrollContainer?.querySelector(\r\n \"[class*='MuiBox-root']\",\r\n ) as HTMLElement;\r\n\r\n if (!gridElement) return;\r\n\r\n // \uCCAB \uBC88\uC9F8 \uC5F0\uB3C4 \uC544\uC774\uD15C\uC758 \uC2E4\uC81C \uB192\uC774 \uAC00\uC838\uC624\uAE30\r\n const firstYearItem = gridElement.children[0] as HTMLElement;\r\n if (!firstYearItem) return;\r\n\r\n const itemHeight = firstYearItem.offsetHeight;\r\n const gap = 4; // gap: 0.5 = 4px\r\n const rowHeight = itemHeight + gap;\r\n\r\n const rowIndex = Math.floor(yearIndex / 4);\r\n const containerHeight = contentRef.current.clientHeight;\r\n const visibleRows = Math.floor(containerHeight / rowHeight);\r\n const centerRowOffset = Math.floor(visibleRows / 2);\r\n\r\n const scrollTop = (rowIndex - centerRowOffset) * rowHeight;\r\n yearScrollRef.current.scrollTo({\r\n top: Math.max(0, scrollTop),\r\n });\r\n });\r\n }\r\n }, [viewMode, yearList, today]);\r\n\r\n // \uD5E4\uB354 \uB80C\uB354\uB9C1 (viewMode\uC5D0 \uB530\uB77C \uB2E4\uB984)\r\n const renderHeader = () => {\r\n if (viewMode === \"year\") {\r\n // monthOnly \uB610\uB294 yearOnly \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uB4A4\uB85C \uAC08 \uACF3\uC774 \uC5C6\uC73C\uBBC0\uB85C < \uBC84\uD2BC \uC228\uAE40\r\n if (monthOnly || yearOnly) {\r\n return (\r\n <Typography variant=\"body2\" fontWeight={600}>\r\n \uC5F0\uB3C4 \uC120\uD0DD\r\n </Typography>\r\n );\r\n }\r\n // \uC77C\uBC18 \uCE98\uB9B0\uB354\uC5D0\uC11C \uB144\uB3C4 \uC120\uD0DD\uC73C\uB85C \uC654\uC744 \uB54C\uB294 < \uBC84\uD2BC \uD45C\uC2DC\r\n return (\r\n <>\r\n <IconButton\r\n size=\"small\"\r\n onClick={() => {\r\n // \uB4A4\uB85C\uAC00\uAE30 \uC2DC tempYear\uAC00 \uD604\uC7AC viewDate\uC758 year\uC640 \uB2E4\uB974\uBA74 onYearChange \uBC1C\uC0DD\r\n if (tempYear !== year) {\r\n onYearChange?.(year);\r\n }\r\n setTempYear(year);\r\n setViewMode(\"calendar\");\r\n }}\r\n >\r\n <ChevronLeft />\r\n </IconButton>\r\n <Typography\r\n variant=\"body2\"\r\n fontWeight={600}\r\n sx={{ flex: 1, textAlign: \"center\" }}\r\n >\r\n \uC5F0\uB3C4 \uC120\uD0DD\r\n </Typography>\r\n <Box sx={{ width: 28 }} />\r\n </>\r\n );\r\n }\r\n if (viewMode === \"month\") {\r\n return (\r\n <>\r\n <IconButton\r\n size=\"small\"\r\n onClick={() => setViewMode(\"year\")}\r\n >\r\n <ChevronLeft />\r\n </IconButton>\r\n <Typography\r\n variant=\"body2\"\r\n fontWeight={600}\r\n sx={{ flex: 1, textAlign: \"center\" }}\r\n >\r\n {tempYear}\uB144 - \uC6D4 \uC120\uD0DD\r\n </Typography>\r\n <Box sx={{ width: 28 }} /> {/* \uADE0\uD615\uC744 \uC704\uD55C \uBE48 \uACF5\uAC04 */}\r\n </>\r\n );\r\n }\r\n // calendar mode\r\n return (\r\n <>\r\n <IconButton size=\"small\" onClick={goToPrevMonth}>\r\n <ChevronLeft />\r\n </IconButton>\r\n <Typography\r\n variant=\"body2\"\r\n fontWeight={600}\r\n onClick={handleTitleClick}\r\n sx={{\r\n cursor: \"pointer\",\r\n px: 1,\r\n py: 0.5,\r\n borderRadius: 1,\r\n \"&:hover\": {\r\n bgcolor: \"action.hover\",\r\n },\r\n transition: \"background-color 0.15s\",\r\n }}\r\n >\r\n {year}\uB144 {mergedLocale.months[month]}\r\n </Typography>\r\n <IconButton size=\"small\" onClick={goToNextMonth}>\r\n <ChevronRight />\r\n </IconButton>\r\n </>\r\n );\r\n };\r\n\r\n // \uCF58\uD150\uCE20 \uB80C\uB354\uB9C1 (viewMode\uC5D0 \uB530\uB77C \uB2E4\uB984)\r\n const renderContent = () => {\r\n if (viewMode === \"year\") {\r\n return (\r\n <OverlayScrollbar\r\n ref={yearScrollRef}\r\n style={{ width: \"100%\", height: \"100%\" }}\r\n containerStyle={{ padding: \"12px\" }}\r\n thumb={{ width: 6, color: \"rgba(100, 100, 100, 0.5)\" }}\r\n track={{ alignment: \"right\", margin: 0 }}\r\n autoHide={{ enabled: true, delay: 1000 }}\r\n >\r\n <Box\r\n sx={{\r\n display: \"grid\",\r\n gridTemplateColumns: \"repeat(4, 1fr)\",\r\n gap: 0.5,\r\n }}\r\n >\r\n {yearList.map((y) => {\r\n // yearOnly \uBAA8\uB4DC\uC5D0\uC11C\uB294 tempSelectedYear\uB97C, \uADF8 \uC678\uC5D0\uB294 tempYear\uB97C \uAE30\uC900\uC73C\uB85C \uC120\uD0DD \uD45C\uC2DC\r\n const isSelected = yearOnly\r\n ? tempSelectedYear === y\r\n : y === tempYear;\r\n const isCurrent = y === today.getFullYear();\r\n return (\r\n <Box\r\n key={y}\r\n sx={{\r\n display: \"flex\",\r\n justifyContent: \"center\",\r\n }}\r\n >\r\n <Box\r\n onClick={() => handleYearSelect(y)}\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n py: 0.75,\r\n px: 1.5,\r\n borderRadius: 1,\r\n cursor: \"pointer\",\r\n bgcolor: isSelected\r\n ? selectedColor\r\n : \"transparent\",\r\n color: isSelected\r\n ? \"primary.contrastText\"\r\n : \"text.primary\",\r\n border:\r\n isCurrent && !isSelected\r\n ? 1\r\n : 0,\r\n borderColor: selectedColor,\r\n fontSize: \"0.8rem\",\r\n fontWeight:\r\n isSelected || isCurrent\r\n ? 600\r\n : 400,\r\n \"&:hover\": {\r\n bgcolor: isSelected\r\n ? selectedColor\r\n : \"action.hover\",\r\n transform: \"scale(1.05)\",\r\n },\r\n transition:\r\n \"background-color 0.15s, transform 0.15s\",\r\n }}\r\n >\r\n {y}\r\n </Box>\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n </OverlayScrollbar>\r\n );\r\n }\r\n\r\n if (viewMode === \"month\") {\r\n return (\r\n <Box\r\n className=\"month-grid\"\r\n sx={{\r\n display: \"grid\",\r\n gridTemplateColumns: \"repeat(3, 1fr)\",\r\n gridTemplateRows: \"repeat(4, 1fr)\",\r\n gap: 1,\r\n width: \"100%\",\r\n height: \"100%\",\r\n p: 2,\r\n boxSizing: \"border-box\",\r\n }}\r\n >\r\n {mergedLocale.months.map(\r\n (monthName: string, index: number) => {\r\n // monthOnly \uBAA8\uB4DC\uC5D0\uC11C\uB294 tempMonth\uB97C, \uADF8 \uC678\uC5D0\uB294 \uD604\uC7AC viewDate\uC758 month\uB97C \uAE30\uC900\uC73C\uB85C \uC120\uD0DD \uD45C\uC2DC\r\n const isSelected = monthOnly\r\n ? tempMonth === index\r\n : tempYear === year && index === month;\r\n const isCurrent =\r\n tempYear === today.getFullYear() &&\r\n index === today.getMonth();\r\n return (\r\n <Box\r\n key={monthName}\r\n onClick={() => handleMonthSelect(index)}\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n borderRadius: 1,\r\n cursor: \"pointer\",\r\n bgcolor: isSelected\r\n ? selectedColor\r\n : \"transparent\",\r\n color: isSelected\r\n ? \"primary.contrastText\"\r\n : \"text.primary\",\r\n border:\r\n isCurrent && !isSelected ? 1 : 0,\r\n borderColor: selectedColor,\r\n fontSize: \"0.875rem\",\r\n fontWeight:\r\n isSelected || isCurrent ? 600 : 400,\r\n \"&:hover\": {\r\n bgcolor: isSelected\r\n ? selectedColor\r\n : \"action.hover\",\r\n transform: \"scale(1.05)\",\r\n },\r\n transition:\r\n \"background-color 0.15s, transform 0.15s\",\r\n }}\r\n >\r\n {monthName}\r\n </Box>\r\n );\r\n },\r\n )}\r\n </Box>\r\n );\r\n }\r\n\r\n // calendar mode\r\n return (\r\n <Box\r\n className=\"calendar-grid\"\r\n onWheel={handleWheel}\r\n sx={{\r\n width: \"100%\",\r\n height: \"100%\",\r\n px: 2,\r\n boxSizing: \"border-box\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n }}\r\n >\r\n {/* \uC694\uC77C \uD5E4\uB354 */}\r\n <Box\r\n sx={{\r\n display: \"grid\",\r\n gridTemplateColumns: \"repeat(7, 1fr)\",\r\n gap: 0,\r\n mb: 0.5,\r\n }}\r\n >\r\n {mergedLocale.weekdays.map((day: string, i: number) => (\r\n <Box\r\n key={day}\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n height: 22,\r\n fontSize: \"0.7rem\",\r\n color:\r\n i === 0\r\n ? holidayColor\r\n : i === 6\r\n ? saturdayColor\r\n : \"text.secondary\",\r\n fontWeight: 500,\r\n }}\r\n >\r\n {day}\r\n </Box>\r\n ))}\r\n </Box>\r\n\r\n {/* \uB0A0\uC9DC \uADF8\uB9AC\uB4DC */}\r\n <Box\r\n sx={{\r\n flex: 1,\r\n display: \"grid\",\r\n gridTemplateColumns: \"repeat(7, 1fr)\",\r\n gridTemplateRows: \"repeat(6, 1fr)\",\r\n gap: 0,\r\n }}\r\n >\r\n {calendarDays.map((date, index) => {\r\n // autoApply\uC77C \uB54C\uB294 selectedDate\uB9CC, \uC544\uB2D0 \uB54C\uB294 tempSelectedDate \uC6B0\uC120\r\n const isSelected = applyImmediate\r\n ? isSameDay(date, selectedDate)\r\n : isSameDay(date, tempSelectedDate ?? selectedDate);\r\n const isToday = isSameDay(date, today);\r\n const isDisabled = isDateDisabled(date);\r\n const dayOfWeek = date.getDay();\r\n const isCurrentMonth = date.getMonth() === month;\r\n const isHoliday = validHolidays.some((h) =>\r\n isSameDay(h, date),\r\n );\r\n\r\n return (\r\n <Box\r\n key={`${date.toISOString()}-${index}`}\r\n onClick={() =>\r\n !isDisabled && handleDateClick(date)\r\n }\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n width: 32,\r\n height: 32,\r\n mx: \"auto\",\r\n borderRadius: \"50%\",\r\n cursor: isDisabled ? \"default\" : \"pointer\",\r\n bgcolor: isSelected\r\n ? selectedColor\r\n : \"transparent\",\r\n color: isDisabled\r\n ? \"text.disabled\"\r\n : isSelected\r\n ? \"primary.contrastText\"\r\n : !isCurrentMonth\r\n ? \"text.disabled\"\r\n : isHoliday || dayOfWeek === 0\r\n ? holidayColor\r\n : dayOfWeek === 6\r\n ? saturdayColor\r\n : \"text.primary\",\r\n opacity: isCurrentMonth ? 1 : 0.4,\r\n border: isToday ? 1 : 0,\r\n borderColor: todayBorderColor,\r\n \"&:hover\": {\r\n bgcolor: isDisabled\r\n ? \"transparent\"\r\n : isSelected\r\n ? selectedColor\r\n : \"action.hover\",\r\n },\r\n transition: \"background-color 0.15s\",\r\n fontSize: \"0.75rem\",\r\n fontWeight:\r\n isSelected || isToday ? 600 : 400,\r\n }}\r\n >\r\n {date.getDate()}\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n </Box>\r\n );\r\n };\r\n\r\n // \uD478\uD130 \uB80C\uB354\uB9C1 (viewMode\uC5D0 \uB530\uB77C \uB2E4\uB984)\r\n const renderFooter = () => {\r\n // yearOnly \uBAA8\uB4DC\uC77C \uB54C\r\n if (yearOnly) {\r\n if (applyImmediate) {\r\n // autoApply\uAC00 true\uBA74 \uD478\uD130 \uBD88\uD544\uC694\r\n return null;\r\n }\r\n // autoApply\uAC00 false\uBA74 \uD655\uC778/\uCDE8\uC18C \uBC84\uD2BC \uD45C\uC2DC\r\n return (\r\n <>\r\n <Box sx={{ flex: 1 }} />\r\n <Button size=\"small\" onClick={onClose}>\r\n {mergedLocale.cancel}\r\n </Button>\r\n <Button\r\n size=\"small\"\r\n onClick={handleYearConfirm}\r\n variant=\"contained\"\r\n disabled={tempSelectedYear === null}\r\n >\r\n {mergedLocale.confirm}\r\n </Button>\r\n </>\r\n );\r\n }\r\n\r\n // monthOnly \uBAA8\uB4DC\uC77C \uB54C\r\n if (monthOnly) {\r\n if (applyImmediate) {\r\n // autoApply\uAC00 true\uBA74 \uD478\uD130 \uBD88\uD544\uC694\r\n return null;\r\n }\r\n // autoApply\uAC00 false\uBA74 \uD655\uC778/\uCDE8\uC18C \uBC84\uD2BC \uD45C\uC2DC\r\n return (\r\n <>\r\n <Box sx={{ flex: 1 }} />\r\n <Button size=\"small\" onClick={onClose}>\r\n {mergedLocale.cancel}\r\n </Button>\r\n <Button\r\n size=\"small\"\r\n onClick={handleMonthConfirm}\r\n variant=\"contained\"\r\n disabled={tempMonth === null}\r\n >\r\n {mergedLocale.confirm}\r\n </Button>\r\n </>\r\n );\r\n }\r\n\r\n if (viewMode === \"year\") {\r\n return (\r\n <Button size=\"small\" onClick={() => setViewMode(\"calendar\")}>\r\n {mergedLocale.cancel}\r\n </Button>\r\n );\r\n }\r\n if (viewMode === \"month\") {\r\n return (\r\n <Button\r\n size=\"small\"\r\n onClick={() => setViewMode(\"calendar\")}\r\n sx={{ px: 2 }}\r\n >\r\n {mergedLocale.cancel}\r\n </Button>\r\n );\r\n }\r\n // calendar mode - autoApply\uBA74 \uB2EB\uAE30 \uBC84\uD2BC\uB9CC \uD45C\uC2DC\r\n if (applyImmediate) {\r\n return (\r\n <>\r\n {showToday && (\r\n <Button\r\n size=\"small\"\r\n onClick={handleTodayClick}\r\n disabled={isDateDisabled(today)}\r\n >\r\n {mergedLocale.today}\r\n </Button>\r\n )}\r\n <Box sx={{ flex: 1 }} />\r\n <Button size=\"small\" onClick={onClose}>\r\n {mergedLocale.close}\r\n </Button>\r\n </>\r\n );\r\n }\r\n return (\r\n <>\r\n {showToday && (\r\n <Button\r\n size=\"small\"\r\n onClick={handleTodayClick}\r\n disabled={isDateDisabled(today)}\r\n >\r\n {mergedLocale.today}\r\n </Button>\r\n )}\r\n <Box sx={{ flex: 1 }} />\r\n <Button size=\"small\" onClick={onClose}>\r\n {mergedLocale.cancel}\r\n </Button>\r\n <Button\r\n size=\"small\"\r\n onClick={handleConfirm}\r\n variant=\"contained\"\r\n disabled={tempSelectedDate === null}\r\n >\r\n {mergedLocale.confirm}\r\n </Button>\r\n </>\r\n );\r\n };\r\n\r\n // \uD478\uD130 \uD45C\uC2DC \uC5EC\uBD80 \uACB0\uC815 (footerOn\uC774 false\uBA74 \uBB34\uC870\uAC74 \uC228\uAE40)\r\n const showFooter =\r\n footerOn &&\r\n (yearOnly\r\n ? !applyImmediate // yearOnly\uC77C \uB54C\uB294 autoApply\uAC00 false\uBA74 \uD56D\uC0C1 \uD45C\uC2DC\r\n : monthOnly\r\n ? !applyImmediate // monthOnly\uC77C \uB54C\uB294 autoApply\uAC00 false\uBA74 \uD56D\uC0C1 \uD45C\uC2DC (year/month \uBDF0 \uBAA8\uB450)\r\n : !(applyImmediate && !showToday) && viewMode === \"calendar\"); // calendar \uBDF0\uC77C \uB54C\uB9CC \uD45C\uC2DC, year/month \uBDF0\uB294 \uD478\uD130 \uC228\uAE40\r\n\r\n // \uD1B5\uD569\uB41C \uAD6C\uC870\uB85C \uB80C\uB354\uB9C1\r\n const calendarContent = (\r\n <Box\r\n className={`calendar-root calendar-${viewMode}-view`}\r\n sx={{\r\n width: \"100%\",\r\n height: \"100%\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n boxSizing: \"border-box\",\r\n }}\r\n >\r\n {/* \uACF5\uD1B5 \uD5E4\uB354 */}\r\n <Box\r\n className=\"calendar-header\"\r\n sx={{\r\n height: HEADER_HEIGHT,\r\n minHeight: HEADER_HEIGHT,\r\n px: 2,\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent:\r\n viewMode === \"calendar\" ? \"space-between\" : \"center\",\r\n ...(viewMode !== \"calendar\" && {\r\n borderBottom: \"1px solid\",\r\n borderColor: \"divider\",\r\n }),\r\n }}\r\n >\r\n {renderHeader()}\r\n </Box>\r\n\r\n {/* \uCF58\uD150\uCE20 \uC601\uC5ED */}\r\n <Box\r\n ref={contentRef}\r\n className=\"calendar-content\"\r\n sx={{\r\n flex: \"1 1 0\",\r\n minHeight: 0,\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n overflow: \"hidden\",\r\n pb: 1,\r\n }}\r\n >\r\n {renderContent()}\r\n </Box>\r\n </Box>\r\n );\r\n\r\n // \uACF5\uD1B5 \uD478\uD130 \uCEF4\uD3EC\uB10C\uD2B8\r\n const footerContent = showFooter ? (\r\n <Box\r\n className=\"calendar-footer\"\r\n sx={{\r\n height: FOOTER_HEIGHT,\r\n minHeight: FOOTER_HEIGHT,\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"flex-start\",\r\n gap: 1,\r\n px: 1,\r\n borderTop: \"1px solid\",\r\n borderColor: \"divider\",\r\n }}\r\n >\r\n {renderFooter()}\r\n </Box>\r\n ) : null;\r\n\r\n // \uC2DC\uAC04 \uC120\uD0DD\uC774 \uC5C6\uC73C\uBA74 \uB2EC\uB825 + \uD478\uD130\r\n if (!showTimePicker) {\r\n return (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n height: \"100%\",\r\n userSelect: \"none\",\r\n }}\r\n >\r\n {calendarContent}\r\n {footerContent}\r\n </Box>\r\n );\r\n }\r\n\r\n // \uC2DC\uAC04 \uC120\uD0DD\uC774 \uC788\uC73C\uBA74 \uC804\uCCB4 column: \uC0C1\uB2E8(\uB2EC\uB825+\uC2DC\uAC04 row) + \uD558\uB2E8(footer)\r\n return (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n height: \"100%\",\r\n userSelect: \"none\",\r\n }}\r\n >\r\n {/* \uC0C1\uB2E8: \uB2EC\uB825 + \uC2DC\uAC04 (row) */}\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n flex: 1,\r\n minHeight: 0,\r\n overflow: \"hidden\",\r\n }}\r\n >\r\n {/* \uB2EC\uB825 \uC601\uC5ED - \uACE0\uC815 \uB108\uBE44 300px */}\r\n <Box\r\n sx={{\r\n width: 300,\r\n flex: \"0 0 300px\",\r\n borderRight: \"1px solid\",\r\n borderColor: \"divider\",\r\n }}\r\n >\r\n {calendarContent}\r\n </Box>\r\n\r\n {/* \uC2DC\uAC04 \uC120\uD0DD \uC601\uC5ED */}\r\n <Box\r\n sx={{\r\n flex: 1,\r\n minWidth: 0,\r\n height: \"100%\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n overflow: \"hidden\",\r\n }}\r\n >\r\n <TimeSelector\r\n value={{\r\n hour: String(tempTime.hour).padStart(2, \"0\"),\r\n minute: String(tempTime.minute).padStart(2, \"0\"),\r\n second: String(tempTime.second).padStart(2, \"0\"),\r\n }}\r\n onChange={handleTempTimeChange}\r\n format={timeFormat}\r\n minTime={minTime}\r\n maxTime={maxTime}\r\n minuteStep={minuteStep}\r\n secondStep={secondStep}\r\n showHeader={true}\r\n hideDisabledTime={hideDisabledTime}\r\n />\r\n </Box>\r\n </Box>\r\n\r\n {/* \uD558\uB2E8: \uD478\uD130 (\uC804\uCCB4 \uB108\uBE44) */}\r\n {footerContent}\r\n </Box>\r\n );\r\n}\r\n", "/**\r\n * icons/index.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\ninterface IconProps {\r\n size?: \"small\" | \"medium\" | \"large\" | number;\r\n color?: string;\r\n}\r\n\r\nconst getSizeValue = (size: IconProps[\"size\"]) => {\r\n if (typeof size === \"number\") return size;\r\n switch (size) {\r\n case \"small\":\r\n return 16;\r\n case \"large\":\r\n return 28;\r\n case \"medium\":\r\n default:\r\n return 20;\r\n }\r\n};\r\n\r\nexport const ChevronLeft: React.FC<IconProps> = ({\r\n size = \"medium\",\r\n color = \"currentColor\",\r\n}) => {\r\n const s = getSizeValue(size);\r\n return (\r\n <svg\r\n width={s}\r\n height={s}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke={color}\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <polyline points=\"15 18 9 12 15 6\" />\r\n </svg>\r\n );\r\n};\r\n\r\nexport const ChevronRight: React.FC<IconProps> = ({\r\n size = \"medium\",\r\n color = \"currentColor\",\r\n}) => {\r\n const s = getSizeValue(size);\r\n return (\r\n <svg\r\n width={s}\r\n height={s}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke={color}\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <polyline points=\"9 18 15 12 9 6\" />\r\n </svg>\r\n );\r\n};\r\n\r\nexport const ColonIcon: React.FC<IconProps> = ({\r\n size = \"medium\",\r\n color = \"currentColor\",\r\n}) => {\r\n const s = getSizeValue(size);\r\n return (\r\n <svg width={s} height={s} viewBox=\"0 0 24 24\" fill={color}>\r\n <circle cx=\"12\" cy=\"8\" r=\"2\" />\r\n <circle cx=\"12\" cy=\"16\" r=\"2\" />\r\n </svg>\r\n );\r\n};\r\n", "/**\r\n * TimeSelector.tsx\r\n * \uC2DC\uAC04 \uC120\uD0DD UI \uCEF4\uD3EC\uB10C\uD2B8 (\uC7AC\uC0AC\uC6A9 \uAC00\uB2A5)\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { useState, useEffect, useRef, useCallback } from \"react\";\r\nimport { Box, Typography } from \"@mui/material\";\r\nimport { OverlayScrollbar } from \"@ehfuse/overlay-scrollbar\";\r\nimport type { OverlayScrollbarRef } from \"@ehfuse/overlay-scrollbar\";\r\nimport { ColonIcon } from \"./icons\";\r\nimport type { TimeSelectorProps } from \"./types\";\r\n\r\nexport function TimeSelector({\r\n value,\r\n onChange,\r\n format,\r\n minTime,\r\n maxTime,\r\n minuteStep = 1,\r\n secondStep = 1,\r\n showHeader = true,\r\n hideDisabledTime = false,\r\n}: TimeSelectorProps) {\r\n const [selectedHour, setSelectedHour] = useState<number | null>(() => {\r\n const h = parseInt(value.hour, 10);\r\n if (!isNaN(h)) return h;\r\n return new Date().getHours();\r\n });\r\n const [selectedMinute, setSelectedMinute] = useState<number | null>(() => {\r\n const m = parseInt(value.minute, 10);\r\n if (!isNaN(m)) return Math.floor(m / minuteStep) * minuteStep;\r\n return Math.floor(new Date().getMinutes() / minuteStep) * minuteStep;\r\n });\r\n const [selectedSecond, setSelectedSecond] = useState<number | null>(() => {\r\n const s = value.second ? parseInt(value.second, 10) : 0;\r\n if (!isNaN(s)) return Math.floor(s / secondStep) * secondStep;\r\n return Math.floor(new Date().getSeconds() / secondStep) * secondStep;\r\n });\r\n const initialScrollDone = useRef(false);\r\n\r\n const hourRef = useRef<OverlayScrollbarRef>(null);\r\n const minuteRef = useRef<OverlayScrollbarRef>(null);\r\n const secondRef = useRef<OverlayScrollbarRef>(null);\r\n\r\n const hasSeconds = format === \"HH:mm:ss\" || format === \"hh:mm:ss\";\r\n const is12Hour = format.startsWith(\"hh\");\r\n const maxHour = is12Hour ? 12 : 23;\r\n const minHourValue = is12Hour ? 1 : 0;\r\n\r\n // \uC2DC\uAC04 \uBC30\uC5F4 \uC0DD\uC131\r\n const hours = Array.from(\r\n { length: maxHour - minHourValue + 1 },\r\n (_, i) => minHourValue + i,\r\n );\r\n const minutes = Array.from(\r\n { length: Math.ceil(60 / minuteStep) },\r\n (_, i) => i * minuteStep,\r\n );\r\n const seconds = hasSeconds\r\n ? Array.from(\r\n { length: Math.ceil(60 / secondStep) },\r\n (_, i) => i * secondStep,\r\n )\r\n : [];\r\n\r\n // \uC120\uD0DD\uB41C \uD56D\uBAA9\uC73C\uB85C \uC2A4\uD06C\uB864 (\uC138\uB85C \uC911\uC559\uC5D0 \uC624\uB3C4\uB85D)\r\n const scrollToCenter = useCallback(\r\n (\r\n scrollbarRef: React.RefObject<OverlayScrollbarRef | null>,\r\n val: number,\r\n ) => {\r\n if (!scrollbarRef.current) return;\r\n\r\n const scrollContainer = scrollbarRef.current.getScrollContainer();\r\n if (!scrollContainer) return;\r\n\r\n const element = scrollContainer.querySelector(\r\n `[data-value=\"${val}\"]`,\r\n ) as HTMLElement;\r\n if (!element) return;\r\n\r\n const containerHeight = scrollbarRef.current.clientHeight;\r\n const elementTop = element.offsetTop;\r\n const elementHeight = element.offsetHeight;\r\n\r\n const scrollTop =\r\n elementTop - containerHeight / 2 + elementHeight / 2;\r\n scrollbarRef.current.scrollTo({ top: Math.max(0, scrollTop) });\r\n },\r\n [],\r\n );\r\n\r\n // \uCD08\uAE30 \uC2A4\uD06C\uB864 (\uD55C \uBC88\uB9CC)\r\n useEffect(() => {\r\n if (initialScrollDone.current) return;\r\n if (selectedHour === null || selectedMinute === null) return;\r\n if (hasSeconds && selectedSecond === null) return;\r\n\r\n const timer = setTimeout(() => {\r\n scrollToCenter(hourRef, selectedHour);\r\n scrollToCenter(minuteRef, selectedMinute);\r\n if (hasSeconds && selectedSecond !== null) {\r\n scrollToCenter(secondRef, selectedSecond);\r\n }\r\n initialScrollDone.current = true;\r\n }, 50);\r\n return () => clearTimeout(timer);\r\n }, [\r\n selectedHour,\r\n selectedMinute,\r\n selectedSecond,\r\n hasSeconds,\r\n scrollToCenter,\r\n ]);\r\n\r\n // \uC2DC\uAC04 \uBC94\uC704 \uCCB4\uD06C\r\n const isTimeInRange = (h: number, m: number, s: number = 0): boolean => {\r\n const timeValue = h * 3600 + m * 60 + s;\r\n\r\n if (minTime) {\r\n const minParts = minTime.split(\":\");\r\n const minH = parseInt(minParts[0], 10) || 0;\r\n const minM = parseInt(minParts[1], 10) || 0;\r\n const minS = parseInt(minParts[2], 10) || 0;\r\n const minValue = minH * 3600 + minM * 60 + minS;\r\n if (timeValue < minValue) return false;\r\n }\r\n\r\n if (maxTime) {\r\n const maxParts = maxTime.split(\":\");\r\n const maxH = parseInt(maxParts[0], 10) || 0;\r\n const maxM = parseInt(maxParts[1], 10) || 0;\r\n const maxS = parseInt(maxParts[2], 10) || 0;\r\n const maxValue = maxH * 3600 + maxM * 60 + maxS;\r\n if (timeValue > maxValue) return false;\r\n }\r\n\r\n return true;\r\n };\r\n\r\n // \uC120\uD0DD \uD578\uB4E4\uB7EC - \uC120\uD0DD \uC2DC \uBC14\uB85C onChange \uD638\uCD9C\r\n const handleHourSelect = (hour: number) => {\r\n setSelectedHour(hour);\r\n onChange(\r\n hour,\r\n selectedMinute ?? 0,\r\n hasSeconds ? (selectedSecond ?? 0) : undefined,\r\n );\r\n };\r\n\r\n const handleMinuteSelect = (minute: number) => {\r\n setSelectedMinute(minute);\r\n onChange(\r\n selectedHour ?? 0,\r\n minute,\r\n hasSeconds ? (selectedSecond ?? 0) : undefined,\r\n );\r\n };\r\n\r\n const handleSecondSelect = (second: number) => {\r\n setSelectedSecond(second);\r\n onChange(selectedHour ?? 0, selectedMinute ?? 0, second);\r\n };\r\n\r\n // \uC544\uC774\uD15C \uB80C\uB354\uB9C1\r\n const renderItem = (\r\n val: number,\r\n selected: boolean,\r\n disabled: boolean,\r\n onClick: () => void,\r\n ) => (\r\n <Box\r\n key={val}\r\n data-value={val}\r\n onClick={disabled ? undefined : onClick}\r\n sx={{\r\n py: 0.5,\r\n px: 1,\r\n cursor: disabled ? \"not-allowed\" : \"pointer\",\r\n textAlign: \"center\",\r\n borderRadius: 1,\r\n backgroundColor: selected ? \"primary.main\" : \"transparent\",\r\n color: disabled\r\n ? \"text.disabled\"\r\n : selected\r\n ? \"primary.contrastText\"\r\n : \"text.primary\",\r\n opacity: disabled ? 0.4 : 1,\r\n transition: \"background-color 0.15s, color 0.15s\",\r\n \"&:hover\": {\r\n backgroundColor: disabled\r\n ? \"transparent\"\r\n : selected\r\n ? \"primary.dark\"\r\n : \"action.hover\",\r\n },\r\n fontVariantNumeric: \"tabular-nums\",\r\n minWidth: 32,\r\n }}\r\n >\r\n <Typography\r\n variant=\"body2\"\r\n sx={{ fontWeight: selected ? 600 : 400 }}\r\n >\r\n {String(val).padStart(2, \"0\")}\r\n </Typography>\r\n </Box>\r\n );\r\n\r\n // \uC5F4 \uB80C\uB354\uB9C1\r\n const renderColumn = (\r\n ref: React.RefObject<OverlayScrollbarRef | null>,\r\n items: number[],\r\n selectedValue: number | null,\r\n onSelect: (val: number) => void,\r\n checkDisabled: (val: number) => boolean,\r\n ) => (\r\n <OverlayScrollbar\r\n ref={ref as React.RefObject<OverlayScrollbarRef>}\r\n style={{ height: \"100%\" }}\r\n thumb={{ width: 4 }}\r\n track={{ alignment: \"right\" }}\r\n >\r\n <div style={{ padding: \"0.25rem\" }}>\r\n {items.map((item) => {\r\n const isDisabled = checkDisabled(item);\r\n // hideDisabledTime\uC774 true\uC774\uACE0 disabled\uBA74 \uB80C\uB354\uB9C1\uD558\uC9C0 \uC54A\uC74C\r\n if (hideDisabledTime && isDisabled) return null;\r\n return renderItem(\r\n item,\r\n selectedValue === item,\r\n isDisabled,\r\n () => onSelect(item),\r\n );\r\n })}\r\n </div>\r\n </OverlayScrollbar>\r\n );\r\n\r\n // \uC2DC\uAC04 \uBE44\uD65C\uC131\uD654 \uCCB4\uD06C\r\n const isHourDisabled = (hour: number): boolean => {\r\n for (const minute of minutes) {\r\n if (hasSeconds) {\r\n for (const second of seconds) {\r\n if (isTimeInRange(hour, minute, second)) return false;\r\n }\r\n } else {\r\n if (isTimeInRange(hour, minute)) return false;\r\n }\r\n }\r\n return true;\r\n };\r\n\r\n const isMinuteDisabled = (minute: number): boolean => {\r\n if (selectedHour === null) return false;\r\n if (hasSeconds) {\r\n for (const second of seconds) {\r\n if (isTimeInRange(selectedHour, minute, second)) return false;\r\n }\r\n return true;\r\n }\r\n return !isTimeInRange(selectedHour, minute);\r\n };\r\n\r\n const isSecondDisabled = (second: number): boolean => {\r\n if (selectedHour === null || selectedMinute === null) return false;\r\n return !isTimeInRange(selectedHour, selectedMinute, second);\r\n };\r\n\r\n return (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n height: \"100%\",\r\n userSelect: \"none\",\r\n }}\r\n >\r\n {/* \uD604\uC7AC \uC120\uD0DD\uB41C \uC2DC\uAC04 \uD45C\uC2DC */}\r\n {showHeader && (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n justifyContent: \"center\",\r\n alignItems: \"center\",\r\n height: 48,\r\n borderBottom: \"1px solid\",\r\n borderColor: \"divider\",\r\n gap: 0.5,\r\n }}\r\n >\r\n <Typography\r\n variant=\"h6\"\r\n sx={{\r\n fontWeight: 500,\r\n fontVariantNumeric: \"tabular-nums\",\r\n }}\r\n >\r\n {selectedHour !== null\r\n ? String(selectedHour).padStart(2, \"0\")\r\n : \"--\"}\r\n </Typography>\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n ml: \"1px\",\r\n }}\r\n >\r\n <ColonIcon size=\"small\" />\r\n </Box>\r\n <Typography\r\n variant=\"h6\"\r\n sx={{\r\n fontWeight: 500,\r\n fontVariantNumeric: \"tabular-nums\",\r\n }}\r\n >\r\n {selectedMinute !== null\r\n ? String(selectedMinute).padStart(2, \"0\")\r\n : \"--\"}\r\n </Typography>\r\n {hasSeconds && (\r\n <>\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n ml: \"1px\",\r\n }}\r\n >\r\n <ColonIcon size=\"small\" />\r\n </Box>\r\n <Typography\r\n variant=\"h6\"\r\n sx={{\r\n fontWeight: 500,\r\n fontVariantNumeric: \"tabular-nums\",\r\n }}\r\n >\r\n {selectedSecond !== null\r\n ? String(selectedSecond).padStart(2, \"0\")\r\n : \"--\"}\r\n </Typography>\r\n </>\r\n )}\r\n </Box>\r\n )}\r\n\r\n {/* \uC2DC\uAC04 \uC120\uD0DD \uCEF8\uB7FC */}\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n justifyContent: \"center\",\r\n flex: 1,\r\n minHeight: 0,\r\n overflow: \"hidden\",\r\n }}\r\n >\r\n {renderColumn(\r\n hourRef,\r\n hours,\r\n selectedHour,\r\n handleHourSelect,\r\n isHourDisabled,\r\n )}\r\n\r\n <Box\r\n sx={{\r\n width: \"1px\",\r\n backgroundColor: \"divider\",\r\n }}\r\n />\r\n\r\n {renderColumn(\r\n minuteRef,\r\n minutes,\r\n selectedMinute,\r\n handleMinuteSelect,\r\n isMinuteDisabled,\r\n )}\r\n\r\n {hasSeconds && (\r\n <>\r\n <Box\r\n sx={{\r\n width: \"1px\",\r\n backgroundColor: \"divider\",\r\n alignSelf: \"stretch\",\r\n }}\r\n />\r\n {renderColumn(\r\n secondRef,\r\n seconds,\r\n selectedSecond,\r\n handleSecondSelect,\r\n isSecondDisabled,\r\n )}\r\n </>\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n", "/**\r\n * TimePicker.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { useState, useEffect, useMemo } from \"react\";\r\nimport { Box, Popover, Button } from \"@mui/material\";\r\nimport type { PopoverProps } from \"@mui/material/Popover\";\r\nimport { TimeSelector } from \"./TimeSelector\";\r\nimport type { TimePickerProps, AnchorElType } from \"./types\";\r\nimport { resolveLocale } from \"./locale\";\r\n\r\n// anchorEl\uC774 RefObject\uC778\uC9C0 \uD655\uC778\uD558\uACE0 \uC2E4\uC81C \uC5D8\uB9AC\uBA3C\uD2B8 \uBC18\uD658\r\nfunction resolveAnchorEl(\r\n anchorEl: AnchorElType | undefined,\r\n): PopoverProps[\"anchorEl\"] {\r\n if (!anchorEl) return null;\r\n // RefObject\uC778 \uACBD\uC6B0 current \uBC18\uD658\r\n if (typeof anchorEl === \"object\" && \"current\" in anchorEl) {\r\n return anchorEl.current;\r\n }\r\n return anchorEl;\r\n}\r\n\r\nexport function TimePicker({\r\n anchorEl,\r\n open,\r\n onClose,\r\n value,\r\n onChange,\r\n format,\r\n minTime,\r\n maxTime,\r\n minuteStep = 1,\r\n secondStep = 1,\r\n hideDisabledTime = false,\r\n autoApply = false,\r\n // \uB85C\uCF00\uC77C \uAD00\uB828\r\n locale,\r\n texts,\r\n}: TimePickerProps) {\r\n const hasSeconds = format === \"HH:mm:ss\" || format === \"hh:mm:ss\";\r\n\r\n // \uB85C\uCF00\uC77C \uD574\uC11D \uBC0F \uBCD1\uD569 (texts\uAC00 \uC788\uC73C\uBA74 \uBD80\uBD84 \uB36E\uC5B4\uC4F0\uAE30)\r\n const resolvedLocale = resolveLocale(locale);\r\n const mergedLocale = useMemo(\r\n () => (texts ? { ...resolvedLocale, ...texts } : resolvedLocale),\r\n [resolvedLocale, texts],\r\n );\r\n\r\n // anchorEl \uD574\uC11D\r\n const resolvedAnchorEl = resolveAnchorEl(anchorEl);\r\n\r\n // \uC784\uC2DC \uC120\uD0DD\uAC12 (\uD655\uC778 \uBC84\uD2BC \uB204\uB974\uAE30 \uC804\uAE4C\uC9C0 \uBCF4\uAD00)\r\n const [tempHour, setTempHour] = useState<number>(0);\r\n const [tempMinute, setTempMinute] = useState<number>(0);\r\n const [tempSecond, setTempSecond] = useState<number>(0);\r\n\r\n // value prop \uBCC0\uACBD \uC2DC \uC784\uC2DC\uAC12 \uCD08\uAE30\uD654\r\n useEffect(() => {\r\n if (open) {\r\n const h = parseInt(value.hour, 10);\r\n const m = parseInt(value.minute, 10);\r\n const s = value.second ? parseInt(value.second, 10) : 0;\r\n\r\n const now = new Date();\r\n setTempHour(isNaN(h) ? now.getHours() : h);\r\n setTempMinute(\r\n isNaN(m)\r\n ? Math.floor(now.getMinutes() / minuteStep) * minuteStep\r\n : Math.floor(m / minuteStep) * minuteStep,\r\n );\r\n if (hasSeconds) {\r\n setTempSecond(\r\n isNaN(s)\r\n ? Math.floor(now.getSeconds() / secondStep) * secondStep\r\n : Math.floor(s / secondStep) * secondStep,\r\n );\r\n }\r\n }\r\n }, [open, value, minuteStep, secondStep, hasSeconds]);\r\n\r\n // TimeSelector\uC5D0\uC11C \uC120\uD0DD \uBCC0\uACBD \uC2DC\r\n const handleTimeChange = (\r\n hour: number,\r\n minute: number,\r\n second?: number,\r\n ) => {\r\n setTempHour(hour);\r\n setTempMinute(minute);\r\n if (second !== undefined) {\r\n setTempSecond(second);\r\n }\r\n\r\n // autoApply\uAC00 true\uBA74 \uBC14\uB85C \uC801\uC6A9\r\n if (autoApply) {\r\n const h = String(hour).padStart(2, \"0\");\r\n const m = String(minute).padStart(2, \"0\");\r\n const s = hasSeconds\r\n ? String(second ?? 0).padStart(2, \"0\")\r\n : undefined;\r\n onChange(h, m, s);\r\n onClose();\r\n }\r\n };\r\n\r\n // \uD655\uC778 \uBC84\uD2BC \uD074\uB9AD \uC2DC onChange \uD638\uCD9C\r\n const handleConfirm = () => {\r\n const h = String(tempHour).padStart(2, \"0\");\r\n const m = String(tempMinute).padStart(2, \"0\");\r\n const s = hasSeconds ? String(tempSecond).padStart(2, \"0\") : undefined;\r\n onChange(h, m, s);\r\n onClose();\r\n };\r\n\r\n return (\r\n <Popover\r\n open={open}\r\n anchorEl={resolvedAnchorEl}\r\n onClose={onClose}\r\n anchorOrigin={{\r\n vertical: \"bottom\",\r\n horizontal: \"right\",\r\n }}\r\n transformOrigin={{\r\n vertical: \"top\",\r\n horizontal: \"right\",\r\n }}\r\n slotProps={{\r\n paper: {\r\n sx: {\r\n mt: 1,\r\n borderRadius: 2,\r\n boxShadow: 3,\r\n minWidth: hasSeconds ? 165 : 110,\r\n userSelect: \"none\",\r\n },\r\n },\r\n }}\r\n >\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n height: autoApply ? 288 : 336,\r\n }}\r\n >\r\n <Box sx={{ flex: 1, minHeight: 0, overflow: \"hidden\" }}>\r\n <TimeSelector\r\n value={{\r\n hour: String(tempHour).padStart(2, \"0\"),\r\n minute: String(tempMinute).padStart(2, \"0\"),\r\n second: hasSeconds\r\n ? String(tempSecond).padStart(2, \"0\")\r\n : undefined,\r\n }}\r\n onChange={handleTimeChange}\r\n format={format}\r\n minTime={minTime}\r\n maxTime={maxTime}\r\n minuteStep={minuteStep}\r\n secondStep={secondStep}\r\n showHeader={true}\r\n hideDisabledTime={hideDisabledTime}\r\n />\r\n </Box>\r\n\r\n {/* \uD558\uB2E8 \uD655\uC778 \uBC84\uD2BC - autoApply\uAC00 false\uC77C \uB54C\uB9CC \uD45C\uC2DC */}\r\n {!autoApply && (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n justifyContent: \"center\",\r\n alignItems: \"center\",\r\n height: 48,\r\n px: 1.5,\r\n borderTop: \"1px solid\",\r\n borderColor: \"divider\",\r\n }}\r\n >\r\n <Button size=\"small\" onClick={handleConfirm} fullWidth>\r\n {mergedLocale.confirm}\r\n </Button>\r\n </Box>\r\n )}\r\n </Box>\r\n </Popover>\r\n );\r\n}\r\n", "/**\r\n * DatePicker.tsx\r\n * Popover \uAE30\uBC18 \uB0A0\uC9DC \uC120\uD0DD \uCEF4\uD3EC\uB10C\uD2B8\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { useState, useEffect } from \"react\";\r\nimport { Popover } from \"@mui/material\";\r\nimport type { PopoverProps } from \"@mui/material/Popover\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport { SimpleCalendar } from \"./SimpleCalendar\";\r\nimport type { DatePickerProps, AnchorElType } from \"./types\";\r\nimport { defaultLocale } from \"./locale\";\r\nimport { resolveFooterAndAutoApply } from \"./utils\";\r\n\r\n// anchorEl\uC774 RefObject\uC778\uC9C0 \uD655\uC778\uD558\uACE0 \uC2E4\uC81C \uC5D8\uB9AC\uBA3C\uD2B8 \uBC18\uD658\r\nfunction resolveAnchorEl(\r\n anchorEl: AnchorElType | undefined,\r\n): PopoverProps[\"anchorEl\"] {\r\n if (!anchorEl) return null;\r\n // RefObject\uC778 \uACBD\uC6B0 current \uBC18\uD658\r\n if (typeof anchorEl === \"object\" && \"current\" in anchorEl) {\r\n return anchorEl.current;\r\n }\r\n return anchorEl;\r\n}\r\n\r\n/**\r\n * DatePicker - Popover \uAE30\uBC18 \uB0A0\uC9DC \uC120\uD0DD \uCEF4\uD3EC\uB10C\uD2B8\r\n *\r\n * \uB0A0\uC9DC\uB9CC \uC120\uD0DD\uD560 \uB54C \uC0AC\uC6A9\uD569\uB2C8\uB2E4.\r\n * \uC2DC\uAC04 \uC120\uD0DD\uC774 \uD544\uC694\uD558\uBA74 DateTimePicker\uB97C \uC0AC\uC6A9\uD558\uC138\uC694.\r\n */\r\nexport function DatePicker({\r\n open,\r\n onClose,\r\n anchorEl,\r\n selectedDate,\r\n onDateChange,\r\n minDate,\r\n maxDate,\r\n holidays = [],\r\n styles,\r\n showToday = true,\r\n showFooter = true,\r\n autoApply = true,\r\n anchorOrigin = { vertical: \"bottom\", horizontal: \"left\" },\r\n transformOrigin = { vertical: \"top\", horizontal: \"left\" },\r\n slotProps,\r\n // \uB85C\uCF00\uC77C \uAD00\uB828\r\n locale = defaultLocale,\r\n texts,\r\n // \uB144\uC6D4\uB9CC \uC120\uD0DD\r\n monthOnly = false,\r\n // \uB144\uB3C4\uB9CC \uC120\uD0DD\r\n yearOnly = false,\r\n // \uB144\uC6D4/\uB144\uB3C4 \uBCC0\uACBD \uCF5C\uBC31\r\n onMonthChange,\r\n onYearChange,\r\n onWeekChange,\r\n ...popoverProps\r\n}: DatePickerProps) {\r\n const { showFooter: footerOn, autoApply: applyImmediate } =\r\n resolveFooterAndAutoApply(showFooter, autoApply);\r\n\r\n const mergedPaperProps = {\r\n ...slotProps?.paper,\r\n \"data-custom-date-picker-popper\": \"true\",\r\n tabIndex: -1,\r\n sx: {\r\n mt: 1,\r\n borderRadius: 2,\r\n boxShadow: 3,\r\n width: 300,\r\n height: footerOn ? 380 : 332,\r\n overflow: \"hidden\",\r\n userSelect: \"none\",\r\n ...((slotProps?.paper as { sx?: SxProps<Theme> })?.sx ?? {}),\r\n },\r\n } as unknown as NonNullable<PopoverProps[\"slotProps\"]>[\"paper\"];\r\n\r\n // anchorEl \uD574\uC11D\r\n const resolvedAnchorEl = resolveAnchorEl(anchorEl);\r\n\r\n // \uB0B4\uBD80 \uC784\uC2DC \uB0A0\uC9DC \uC0C1\uD0DC\r\n const [tempDate, setTempDate] = useState<Date | null>(selectedDate ?? null);\r\n\r\n // \uC774\uC804\uC5D0 \uC120\uD0DD\uB41C \uB0A0\uC9DC\uC758 \uB144/\uC6D4 \uCD94\uC801 (\uC774\uBCA4\uD2B8 \uBC1C\uC0DD \uC5EC\uBD80 \uD310\uB2E8\uC6A9)\r\n const prevYear = selectedDate?.getFullYear();\r\n const prevMonth = selectedDate?.getMonth();\r\n\r\n // open\uB420 \uB54C \uC678\uBD80 \uAC12\uC73C\uB85C \uCD08\uAE30\uD654\r\n useEffect(() => {\r\n if (open) {\r\n setTempDate(selectedDate ?? null);\r\n }\r\n }, [open, selectedDate]);\r\n\r\n // \uB0A0\uC9DC \uC120\uD0DD \uD578\uB4E4\uB7EC (SimpleCalendar\uC5D0\uC11C \uD638\uCD9C)\r\n const handleDateSelect = (date: Date) => {\r\n setTempDate(date);\r\n onDateChange?.(date);\r\n\r\n // monthOnly/yearOnly\uAC00 \uC544\uB2D0 \uB54C\uB9CC \uC5EC\uAE30\uC11C \uB144/\uC6D4 \uBCC0\uACBD \uCF5C\uBC31 \uBC1C\uC0DD\r\n // monthOnly/yearOnly\uC77C \uB54C\uB294 SimpleCalendar\uC5D0\uC11C \uC774\uBCA4\uD2B8 \uCC98\uB9AC\r\n if (!monthOnly && !yearOnly) {\r\n const newYear = date.getFullYear();\r\n const newMonth = date.getMonth();\r\n if (prevYear !== newYear) {\r\n onYearChange?.(newYear);\r\n }\r\n if (prevYear !== newYear || prevMonth !== newMonth) {\r\n onMonthChange?.(newYear, newMonth + 1);\r\n }\r\n }\r\n\r\n // \uC989\uC2DC \uC801\uC6A9\uC774\uBA74 \uB0A0\uC9DC \uC120\uD0DD \uC2DC \uBC14\uB85C \uB2EB\uAE30\r\n if (applyImmediate) {\r\n onClose();\r\n }\r\n };\r\n\r\n return (\r\n <Popover\r\n open={open}\r\n anchorEl={resolvedAnchorEl}\r\n onClose={onClose}\r\n anchorOrigin={anchorOrigin}\r\n transformOrigin={transformOrigin}\r\n {...popoverProps}\r\n slotProps={{\r\n ...slotProps,\r\n paper: mergedPaperProps,\r\n }}\r\n >\r\n <SimpleCalendar\r\n selectedDate={tempDate}\r\n onSelect={handleDateSelect}\r\n onClose={onClose}\r\n minDate={minDate}\r\n maxDate={maxDate}\r\n holidays={holidays}\r\n styles={styles}\r\n showToday={showToday}\r\n showFooter={footerOn}\r\n autoApply={applyImmediate}\r\n showTimePicker={false}\r\n locale={locale}\r\n texts={texts}\r\n monthOnly={monthOnly}\r\n yearOnly={yearOnly}\r\n // monthOnly/yearOnly \uBAA8\uB4DC\uC77C \uB54C\uB9CC SimpleCalendar\uC758 \uC774\uBCA4\uD2B8\uB97C \uC804\uB2EC\r\n // \uC77C\uBC18 \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uB0A0\uC9DC \uC120\uD0DD \uC2DC\uC5D0\uB9CC \uB144/\uC6D4 \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n onYearChange={monthOnly || yearOnly ? onYearChange : undefined}\r\n onMonthChange={\r\n monthOnly || yearOnly ? onMonthChange : undefined\r\n }\r\n onWeekChange={onWeekChange}\r\n />\r\n </Popover>\r\n );\r\n}\r\n", "/**\r\n * DateTimePicker.tsx\r\n * Popover \uAE30\uBC18 \uB0A0\uC9DC + \uC2DC\uAC04 \uC120\uD0DD \uCEF4\uD3EC\uB10C\uD2B8\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { useState, useEffect } from \"react\";\r\nimport { Popover } from \"@mui/material\";\r\nimport type { PopoverProps } from \"@mui/material/Popover\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport { SimpleCalendar } from \"./SimpleCalendar\";\r\nimport type { DateTimePickerProps, TimeValue, AnchorElType } from \"./types\";\r\nimport { defaultLocale } from \"./locale\";\r\nimport { resolveFooterAndAutoApply } from \"./utils\";\r\n\r\n// anchorEl\uC774 RefObject\uC778\uC9C0 \uD655\uC778\uD558\uACE0 \uC2E4\uC81C \uC5D8\uB9AC\uBA3C\uD2B8 \uBC18\uD658\r\nfunction resolveAnchorEl(\r\n anchorEl: AnchorElType | undefined,\r\n): PopoverProps[\"anchorEl\"] {\r\n if (!anchorEl) return null;\r\n // RefObject\uC778 \uACBD\uC6B0 current \uBC18\uD658\r\n if (typeof anchorEl === \"object\" && \"current\" in anchorEl) {\r\n return anchorEl.current;\r\n }\r\n return anchorEl;\r\n}\r\n\r\n/**\r\n * DateTimePicker - Popover \uAE30\uBC18 \uB0A0\uC9DC + \uC2DC\uAC04 \uC120\uD0DD \uCEF4\uD3EC\uB10C\uD2B8\r\n *\r\n * \uB0A0\uC9DC\uC640 \uC2DC\uAC04\uC744 \uD568\uAED8 \uC120\uD0DD\uD560 \uB54C \uC0AC\uC6A9\uD569\uB2C8\uB2E4.\r\n * \uB0A0\uC9DC\uB9CC \uC120\uD0DD\uD558\uB824\uBA74 DatePicker\uB97C, \uC2DC\uAC04\uB9CC \uC120\uD0DD\uD558\uB824\uBA74 TimePicker\uB97C \uC0AC\uC6A9\uD558\uC138\uC694.\r\n */\r\nexport function DateTimePicker({\r\n open,\r\n onClose,\r\n anchorEl,\r\n selectedDate,\r\n onDateChange,\r\n timeValue,\r\n onTimeChange,\r\n minDate,\r\n maxDate,\r\n holidays = [],\r\n styles,\r\n showToday = true,\r\n showFooter = true,\r\n autoApply = true,\r\n timeFormat = \"HH:mm\",\r\n minTime,\r\n maxTime,\r\n minuteStep = 1,\r\n secondStep = 1,\r\n hideDisabledTime = false,\r\n anchorOrigin = { vertical: \"bottom\", horizontal: \"left\" },\r\n transformOrigin = { vertical: \"top\", horizontal: \"left\" },\r\n slotProps,\r\n // \uB85C\uCF00\uC77C \uAD00\uB828\r\n locale = defaultLocale,\r\n texts,\r\n // \uB144\uC6D4/\uB144\uB3C4 \uBCC0\uACBD \uCF5C\uBC31\r\n onMonthChange,\r\n onYearChange,\r\n onWeekChange,\r\n ...popoverProps\r\n}: DateTimePickerProps) {\r\n const { showFooter: footerOn, autoApply: applyImmediate } =\r\n resolveFooterAndAutoApply(showFooter, autoApply);\r\n\r\n const hasSeconds = timeFormat === \"HH:mm:ss\" || timeFormat === \"hh:mm:ss\";\r\n\r\n // anchorEl \uD574\uC11D\r\n const resolvedAnchorEl = resolveAnchorEl(anchorEl);\r\n\r\n // \uB0B4\uBD80 \uC784\uC2DC \uB0A0\uC9DC \uC0C1\uD0DC\r\n const [tempDate, setTempDate] = useState<Date | null>(selectedDate ?? null);\r\n\r\n // \uB0B4\uBD80 \uC784\uC2DC \uC2DC\uAC04 \uC0C1\uD0DC\r\n const [tempTime, setTempTime] = useState<TimeValue>(() => {\r\n if (timeValue) return timeValue;\r\n const now = new Date();\r\n return {\r\n hour: String(now.getHours()).padStart(2, \"0\"),\r\n minute: String(\r\n Math.floor(now.getMinutes() / minuteStep) * minuteStep,\r\n ).padStart(2, \"0\"),\r\n second: hasSeconds\r\n ? String(\r\n Math.floor(now.getSeconds() / secondStep) * secondStep,\r\n ).padStart(2, \"0\")\r\n : undefined,\r\n };\r\n });\r\n\r\n // open\uB420 \uB54C \uC678\uBD80 \uAC12\uC73C\uB85C \uCD08\uAE30\uD654\r\n useEffect(() => {\r\n if (open) {\r\n setTempDate(selectedDate ?? null);\r\n if (timeValue) {\r\n setTempTime(timeValue);\r\n } else {\r\n const now = new Date();\r\n setTempTime({\r\n hour: String(now.getHours()).padStart(2, \"0\"),\r\n minute: String(\r\n Math.floor(now.getMinutes() / minuteStep) * minuteStep,\r\n ).padStart(2, \"0\"),\r\n second: hasSeconds\r\n ? String(\r\n Math.floor(now.getSeconds() / secondStep) *\r\n secondStep,\r\n ).padStart(2, \"0\")\r\n : undefined,\r\n });\r\n }\r\n }\r\n }, [open, selectedDate, timeValue, minuteStep, secondStep, hasSeconds]);\r\n\r\n // \uC774\uC804\uC5D0 \uC120\uD0DD\uB41C \uB0A0\uC9DC\uC758 \uB144/\uC6D4 \uCD94\uC801 (\uC774\uBCA4\uD2B8 \uBC1C\uC0DD \uC5EC\uBD80 \uD310\uB2E8\uC6A9)\r\n const prevYear = selectedDate?.getFullYear();\r\n const prevMonth = selectedDate?.getMonth();\r\n\r\n // \uB0A0\uC9DC \uC120\uD0DD \uD578\uB4E4\uB7EC (SimpleCalendar\uC5D0\uC11C \uD638\uCD9C)\r\n const handleDateSelect = (date: Date) => {\r\n setTempDate(date);\r\n // \uB0A0\uC9DC\uAC00 \uC120\uD0DD\uB418\uBA74 \uD56D\uC0C1 \uCF5C\uBC31 \uD638\uCD9C (\uD655\uC778 \uBC84\uD2BC\uC5D0\uC11C\uB3C4 \uD638\uCD9C\uB428)\r\n onDateChange?.(date);\r\n\r\n // \uB0A0\uC9DC \uC120\uD0DD \uC2DC \uB144/\uC6D4 \uBCC0\uACBD \uCF5C\uBC31 \uBC1C\uC0DD (\uC774\uC804 \uB0A0\uC9DC\uC640 \uBE44\uAD50)\r\n const newYear = date.getFullYear();\r\n const newMonth = date.getMonth();\r\n if (prevYear !== newYear) {\r\n onYearChange?.(newYear);\r\n }\r\n if (prevYear !== newYear || prevMonth !== newMonth) {\r\n onMonthChange?.(newYear, newMonth + 1);\r\n }\r\n };\r\n\r\n // SimpleCalendar\uC5D0\uC11C \uC2DC\uAC04 \uBCC0\uACBD\r\n const handleCalendarTimeChange = (\r\n hour: number,\r\n minute: number,\r\n second?: number,\r\n ) => {\r\n const newTime = {\r\n hour: String(hour).padStart(2, \"0\"),\r\n minute: String(minute).padStart(2, \"0\"),\r\n second:\r\n second !== undefined\r\n ? String(second).padStart(2, \"0\")\r\n : undefined,\r\n };\r\n setTempTime(newTime);\r\n\r\n // \uC2DC\uAC04\uC774 \uBCC0\uACBD\uB418\uBA74 \uD56D\uC0C1 \uCF5C\uBC31 \uD638\uCD9C (\uD655\uC778 \uBC84\uD2BC\uC5D0\uC11C\uB3C4 \uD638\uCD9C\uB428)\r\n onTimeChange?.(newTime.hour, newTime.minute, newTime.second);\r\n };\r\n\r\n // \uD31D\uC624\uBC84 \uD06C\uAE30 \uACB0\uC815 (datetime \uC804\uC6A9)\r\n const width = 300 + (hasSeconds ? 165 : 110);\r\n const height = footerOn ? 380 : 332;\r\n\r\n return (\r\n <Popover\r\n open={open}\r\n anchorEl={resolvedAnchorEl}\r\n onClose={onClose}\r\n anchorOrigin={anchorOrigin}\r\n transformOrigin={transformOrigin}\r\n {...popoverProps}\r\n slotProps={{\r\n ...slotProps,\r\n paper: {\r\n ...slotProps?.paper,\r\n sx: {\r\n mt: 1,\r\n borderRadius: 2,\r\n boxShadow: 3,\r\n width,\r\n height,\r\n overflow: \"hidden\",\r\n userSelect: \"none\",\r\n ...((slotProps?.paper as { sx?: SxProps<Theme> })?.sx ??\r\n {}),\r\n },\r\n },\r\n }}\r\n >\r\n <SimpleCalendar\r\n selectedDate={tempDate}\r\n onSelect={handleDateSelect}\r\n onClose={onClose}\r\n minDate={minDate}\r\n maxDate={maxDate}\r\n holidays={holidays}\r\n styles={styles}\r\n showToday={showToday}\r\n showFooter={footerOn}\r\n autoApply={applyImmediate}\r\n showTimePicker={true}\r\n timeValue={tempTime}\r\n onTimeChange={handleCalendarTimeChange}\r\n timeFormat={timeFormat}\r\n minTime={minTime}\r\n maxTime={maxTime}\r\n minuteStep={minuteStep}\r\n secondStep={secondStep}\r\n hideDisabledTime={hideDisabledTime}\r\n locale={locale}\r\n texts={texts}\r\n // DateTimePicker\uB294 \uC77C\uBC18 \uBAA8\uB4DC\uB9CC \uC788\uC73C\uBBC0\uB85C \uB0A0\uC9DC \uC120\uD0DD \uC2DC\uC5D0\uB9CC \uB144/\uC6D4 \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n onWeekChange={onWeekChange}\r\n />\r\n </Popover>\r\n );\r\n}\r\n", "/**\r\n * CalendarIcon.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\nexport const CalendarIcon = ({ size = 20 }: { size?: number }) => (\r\n <svg\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\r\n <line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\" />\r\n <line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\" />\r\n <line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\" />\r\n </svg>\r\n);\r\n", "/**\r\n * ChevronLeft.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\nexport const ChevronLeft = () => (\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\" />\r\n </svg>\r\n);\r\n", "/**\r\n * ChevronRight.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\nexport const ChevronRight = () => (\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M8.59 16.59L10 18l6-6-6-6-1.41 1.41L13.17 12z\" />\r\n </svg>\r\n);\r\n", "/**\r\n * ClockIcon.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\ninterface ClockIconProps {\r\n size?: number;\r\n color?: string;\r\n}\r\n\r\nexport function ClockIcon({\r\n size = 22,\r\n color = \"currentColor\",\r\n}: ClockIconProps) {\r\n return (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke={color}\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n >\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\r\n <polyline points=\"12 6 12 12 16 14\" />\r\n </svg>\r\n );\r\n}\r\n", "/**\r\n * ColonIcon.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\ninterface ColonIconProps {\r\n size?: \"small\" | \"medium\";\r\n color?: string;\r\n}\r\n\r\nexport function ColonIcon({\r\n size = \"small\",\r\n color = \"rgba(0, 0, 0, 0.87)\",\r\n}: ColonIconProps) {\r\n const height = size === \"small\" ? 14 : 18;\r\n const dotRadius = size === \"small\" ? 1.2 : 1.5;\r\n // width\uB97C dotRadius * 2 + \uC5EC\uC720\uACF5\uAC04\uC73C\uB85C \uC124\uC815\r\n const width = dotRadius * 2 + 2;\r\n const centerX = width / 2;\r\n\r\n return (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${width} ${height}`}\r\n fill={color}\r\n style={{\r\n display: \"inline-block\",\r\n visibility: \"visible\",\r\n opacity: 1,\r\n width: `${width}px`,\r\n height: `${height}px`,\r\n minWidth: `${width}px`,\r\n minHeight: `${height}px`,\r\n maxWidth: `${width}px`,\r\n maxHeight: `${height}px`,\r\n flexShrink: 0,\r\n overflow: \"visible\",\r\n margin: \"0 1px\",\r\n padding: 0,\r\n border: \"none\",\r\n background: \"transparent\",\r\n verticalAlign: \"middle\",\r\n pointerEvents: \"none\",\r\n }}\r\n >\r\n <circle\r\n cx={centerX}\r\n cy={height * 0.32}\r\n r={dotRadius}\r\n style={{\r\n fill: color,\r\n stroke: \"none\",\r\n visibility: \"visible\",\r\n opacity: 1,\r\n }}\r\n />\r\n <circle\r\n cx={centerX}\r\n cy={height * 0.68}\r\n r={dotRadius}\r\n style={{\r\n fill: color,\r\n stroke: \"none\",\r\n visibility: \"visible\",\r\n opacity: 1,\r\n }}\r\n />\r\n </svg>\r\n );\r\n}\r\n", "/**\r\n * DashIcon.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\ninterface DashIconProps {\r\n size?: \"small\" | \"medium\";\r\n}\r\n\r\nexport function DashIcon({ size = \"small\" }: DashIconProps) {\r\n const width = size === \"small\" ? 8 : 10;\r\n const height = size === \"small\" ? 1 : 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${width} ${height}`}\r\n style={{ display: \"block\" }}\r\n >\r\n <rect\r\n x=\"0\"\r\n y=\"0\"\r\n width={width}\r\n height={height}\r\n rx={height / 2}\r\n fill=\"currentColor\"\r\n />\r\n </svg>\r\n );\r\n}\r\n", "/**\r\n * CopyIcon.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\ninterface CopyIconProps {\r\n size?: \"small\" | \"medium\";\r\n}\r\n\r\nexport function CopyIcon({ size = \"small\" }: CopyIconProps) {\r\n const iconSize = size === \"small\" ? 16 : 20;\r\n\r\n return (\r\n <svg\r\n width={iconSize}\r\n height={iconSize}\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n style={{ display: \"block\" }}\r\n >\r\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\r\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\r\n </svg>\r\n );\r\n}\r\n", "/**\r\n * card-icons.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\ninterface CardIconProps {\r\n size?: number;\r\n color?: string;\r\n}\r\n\r\n// \uACF5\uD1B5 \uCE74\uB4DC \uD06C\uAE30 (8:5 \uBE44\uC728, \uC2E4\uC81C \uC2E0\uC6A9\uCE74\uB4DC \uBE44\uC728\uC5D0 \uAC00\uAE4C\uC6C0)\r\nconst CARD_WIDTH = 36;\r\nconst CARD_HEIGHT = 25;\r\n\r\n// \uAE30\uBCF8 \uCE74\uB4DC \uC544\uC774\uCF58 (\uBE0C\uB79C\uB4DC \uBBF8\uD655\uC778)\r\nexport function CardIcon({ size = 24, color = \"#9e9e9e\" }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox=\"0 0 40 25\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <g transform=\"translate(8, 4)\">\r\n <rect\r\n x=\"0\"\r\n y=\"0\"\r\n width=\"24\"\r\n height=\"17\"\r\n rx=\"2\"\r\n stroke={color}\r\n strokeWidth=\"1.2\"\r\n fill=\"none\"\r\n />\r\n <line\r\n x1=\"0\"\r\n y1=\"5\"\r\n x2=\"24\"\r\n y2=\"5\"\r\n stroke={color}\r\n strokeWidth=\"2\"\r\n />\r\n <rect\r\n x=\"2\"\r\n y=\"10\"\r\n width=\"5\"\r\n height=\"2.5\"\r\n rx=\"0.5\"\r\n fill={color}\r\n />\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\n// Visa \uB85C\uACE0\r\nexport function VisaIcon({ size = 24 }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n // \uC6D0\uBCF8 viewBox: 262.3 x 85\r\n const logoWidth = 262.3;\r\n const logoHeight = 85;\r\n // \uB85C\uACE0\uB97C \uCE74\uB4DC \uB0B4\uBD80\uC5D0 \uB9DE\uCD94\uAE30 \uC704\uD55C \uC2A4\uCF00\uC77C (\uC5EC\uC720 \uC788\uAC8C)\r\n const logoScale = Math.min(\r\n (CARD_WIDTH * 0.75) / logoWidth,\r\n (CARD_HEIGHT * 0.6) / logoHeight\r\n );\r\n const offsetX = (CARD_WIDTH - logoWidth * logoScale) / 2;\r\n const offsetY = (CARD_HEIGHT - logoHeight * logoScale) / 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <g\r\n transform={`translate(${offsetX}, ${offsetY}) scale(${logoScale})`}\r\n >\r\n <path\r\n fill=\"#1434CB\"\r\n d=\"M170.9,0c-18.6,0-35.3,9.7-35.3,27.5c0,20.5,29.5,21.9,29.5,32.1c0,4.3-5,8.2-13.4,8.2c-12,0-21-5.4-21-5.4l-3.8,18c0,0,10.3,4.6,24.1,4.6c20.4,0,36.4-10.1,36.4-28.3c0-21.6-29.6-23-29.6-32.5c0-3.4,4.1-7.1,12.5-7.1c9.5,0,17.3,3.9,17.3,3.9l3.8-17.4C191.3,3.6,182.8,0,170.9,0L170.9,0z M0.5,1.3L0,3.9c0,0,7.8,1.4,14.9,4.3c9.1,3.3,9.7,5.2,11.3,11.1l16.7,64.3h22.4L99.6,1.3H77.3l-22.1,56l-9-47.5c-0.8-5.4-5-8.5-10.2-8.5C36,1.3,0.5,1.3,0.5,1.3z M108.6,1.3L91.1,83.6h21.3l17.4-82.3L108.6,1.3L108.6,1.3z M227.2,1.3c-5.1,0-7.8,2.7-9.8,7.5l-31.2,74.8h22.3l4.3-12.5H240l2.6,12.5h19.7L245.2,1.3L227.2,1.3L227.2,1.3z M230.1,23.6l6.6,30.9H219L230.1,23.6L230.1,23.6z\"\r\n />\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\n// Mastercard \uB85C\uACE0\r\nexport function MastercardIcon({ size = 24 }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n // \uC6D0\uBCF8 viewBox: 999.2 x 618 (\uC6D0 2\uAC1C)\r\n const logoWidth = 999.2;\r\n const logoHeight = 618;\r\n const logoScale = Math.min(\r\n (CARD_WIDTH * 0.75) / logoWidth,\r\n (CARD_HEIGHT * 0.75) / logoHeight\r\n );\r\n const offsetX = (CARD_WIDTH - logoWidth * logoScale) / 2;\r\n const offsetY = (CARD_HEIGHT - logoHeight * logoScale) / 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`}\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <g\r\n transform={`translate(${offsetX}, ${offsetY}) scale(${logoScale})`}\r\n >\r\n <rect\r\n x=\"364\"\r\n y=\"66.1\"\r\n fill=\"#FF5A00\"\r\n width=\"270.4\"\r\n height=\"485.8\"\r\n />\r\n <path\r\n fill=\"#EB001B\"\r\n d=\"M382,309c0-98.7,46.4-186.3,117.6-242.9C447.2,24.9,381.1,0,309,0C138.2,0,0,138.2,0,309s138.2,309,309,309c72.1,0,138.2-24.9,190.6-66.1C428.3,496.1,382,407.7,382,309z\"\r\n />\r\n <path\r\n fill=\"#F79E1B\"\r\n d=\"M999.2,309c0,170.8-138.2,309-309,309c-72.1,0-138.2-24.9-190.6-66.1c72.1-56.7,117.6-144.2,117.6-242.9S570.8,122.7,499.6,66.1C551.9,24.9,618,0,690.1,0C861,0,999.2,139.1,999.2,309z\"\r\n />\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\n// AMEX \uB85C\uACE0\r\nexport function AmexIcon({ size = 24 }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n // \uC6D0\uBCF8 viewBox: 48 x 48 (\uC815\uC0AC\uAC01\uD615) - \uCE74\uB4DC \uBC30\uACBD \uD3EC\uD568\r\n const logoWidth = 48;\r\n const logoHeight = 48;\r\n const logoScale = Math.min(\r\n (CARD_WIDTH * 1.1) / logoWidth,\r\n (CARD_HEIGHT * 1.15) / logoHeight\r\n );\r\n const offsetX = (CARD_WIDTH - logoWidth * logoScale) / 2;\r\n const offsetY = (CARD_HEIGHT - logoHeight * logoScale) / 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <g\r\n transform={`translate(${offsetX}, ${offsetY}) scale(${logoScale})`}\r\n >\r\n <path\r\n fill=\"#1976D2\"\r\n d=\"M45,35c0,2.209-1.791,4-4,4H7c-2.209,0-4-1.791-4-4V13c0-2.209,1.791-4,4-4h34c2.209,0,4,1.791,4,4V35z\"\r\n />\r\n <path\r\n fill=\"#FFF\"\r\n d=\"M22.255 20l-2.113 4.683L18.039 20h-2.695v6.726L12.341 20h-2.274L7 26.981h1.815l.671-1.558h3.432l.682 1.558h3.465v-5.185l2.299 5.185h1.563l2.351-5.095v5.095H25V20H22.255zM10.135 23.915l1.026-2.44 1.066 2.44H10.135zM37.883 23.413L41 20.018h-2.217l-1.994 2.164L34.86 20H28v6.982h6.635l2.092-2.311L38.767 27h2.21L37.883 23.413zM33.728 25.516h-4.011v-1.381h3.838v-1.323h-3.838v-1.308l4.234.012 1.693 1.897L33.728 25.516z\"\r\n />\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\n// JCB \uB85C\uACE0\r\nexport function JcbIcon({ size = 24 }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n // \uC6D0\uBCF8 viewBox: 300 x 231.511\r\n const logoWidth = 300;\r\n const logoHeight = 231.511;\r\n const logoScale = Math.min(\r\n (CARD_WIDTH * 0.85) / logoWidth,\r\n (CARD_HEIGHT * 0.85) / logoHeight\r\n );\r\n const offsetX = (CARD_WIDTH - logoWidth * logoScale) / 2;\r\n const offsetY = (CARD_HEIGHT - logoHeight * logoScale) / 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <g\r\n transform={`translate(${offsetX}, ${offsetY}) scale(${logoScale})`}\r\n >\r\n <defs>\r\n <linearGradient\r\n id=\"jcbGreen1\"\r\n x1=\"117.3856\"\r\n y1=\"81.3986\"\r\n x2=\"157.3299\"\r\n y2=\"81.3986\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n gradientTransform=\"matrix(1.125,0,0,1.125,-11.9755,-13.8615)\"\r\n >\r\n <stop offset=\"0\" stopColor=\"#007940\" />\r\n <stop offset=\"0.2285\" stopColor=\"#00873F\" />\r\n <stop offset=\"0.7433\" stopColor=\"#40A737\" />\r\n <stop offset=\"1\" stopColor=\"#5CB531\" />\r\n </linearGradient>\r\n <linearGradient\r\n id=\"jcbGreen2\"\r\n x1=\"117.3844\"\r\n y1=\"75.1714\"\r\n x2=\"157.3318\"\r\n y2=\"75.1714\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n gradientTransform=\"matrix(1.125,0,0,1.125,-11.9755,-13.8615)\"\r\n >\r\n <stop offset=\"0\" stopColor=\"#007940\" />\r\n <stop offset=\"0.2285\" stopColor=\"#00873F\" />\r\n <stop offset=\"0.7433\" stopColor=\"#40A737\" />\r\n <stop offset=\"1\" stopColor=\"#5CB531\" />\r\n </linearGradient>\r\n <linearGradient\r\n id=\"jcbGreen3\"\r\n x1=\"117.3846\"\r\n y1=\"68.3991\"\r\n x2=\"157.33051\"\r\n y2=\"68.3991\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n gradientTransform=\"matrix(1.125,0,0,1.125,-11.9755,-13.8615)\"\r\n >\r\n <stop offset=\"0\" stopColor=\"#007940\" />\r\n <stop offset=\"0.2285\" stopColor=\"#00873F\" />\r\n <stop offset=\"0.7433\" stopColor=\"#40A737\" />\r\n <stop offset=\"1\" stopColor=\"#5CB531\" />\r\n </linearGradient>\r\n <linearGradient\r\n id=\"jcbBlue\"\r\n x1=\"27.9594\"\r\n y1=\"75.1714\"\r\n x2=\"68.5221\"\r\n y2=\"75.1714\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n gradientTransform=\"matrix(1.125,0,0,1.125,-11.9755,-13.8615)\"\r\n >\r\n <stop offset=\"0\" stopColor=\"#1F286F\" />\r\n <stop offset=\"0.4751\" stopColor=\"#004E94\" />\r\n <stop offset=\"0.8261\" stopColor=\"#0066B1\" />\r\n <stop offset=\"1\" stopColor=\"#006FBC\" />\r\n </linearGradient>\r\n <linearGradient\r\n id=\"jcbRed\"\r\n x1=\"72.4595\"\r\n y1=\"75.1714\"\r\n x2=\"111.8553\"\r\n y2=\"75.1714\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n gradientTransform=\"matrix(1.125,0,0,1.125,-11.9755,-13.8615)\"\r\n >\r\n <stop offset=\"0\" stopColor=\"#6C2C2F\" />\r\n <stop offset=\"0.1735\" stopColor=\"#882730\" />\r\n <stop offset=\"0.5731\" stopColor=\"#BE1833\" />\r\n <stop offset=\"0.8585\" stopColor=\"#DC0436\" />\r\n <stop offset=\"1\" stopColor=\"#E60039\" />\r\n </linearGradient>\r\n </defs>\r\n <g transform=\"translate(-9.4,96.811)\">\r\n <g transform=\"matrix(1.8215159,0,0,1.8215159,-8.5437653,-109.83667)\">\r\n <path\r\n fill=\"#ffffff\"\r\n d=\"m 174,108.3 c 0,14 -11.4,25.4 -25.4,25.4 l -138.2,0 0,-100.6 c 0,-14 11.4,-25.4 25.4,-25.4 l 138.2,0 0,100.6 z\"\r\n />\r\n <path\r\n fill=\"url(#jcbGreen1)\"\r\n d=\"m 129,82.5 10.5,0 c 0.3,0 1,-0.1 1.3,-0.1 2,-0.4 3.7,-2.2 3.7,-4.7 0,-2.4 -1.7,-4.2 -3.7,-4.7 -0.3,-0.1 -0.9,-0.1 -1.3,-0.1 l -10.5,0 0,9.6 z\"\r\n />\r\n <path\r\n fill=\"url(#jcbGreen2)\"\r\n d=\"m 138.3,16.2 c -10,0 -18.2,8.1 -18.2,18.2 l 0,18.9 25.7,0 c 0.6,0 1.3,0 1.8,0.1 5.8,0.3 10.1,3.3 10.1,8.5 0,4.1 -2.9,7.6 -8.3,8.3 l 0,0.2 c 5.9,0.4 10.4,3.7 10.4,8.8 0,5.5 -5,9.1 -11.6,9.1 l -28.2,0 0,37 26.7,0 c 10,0 18.2,-8.1 18.2,-18.2 l 0,-90.9 -26.6,0 z\"\r\n />\r\n <path\r\n fill=\"url(#jcbGreen3)\"\r\n d=\"m 143.2,63.1 c 0,-2.4 -1.7,-4 -3.7,-4.3 -0.2,0 -0.7,-0.1 -1,-0.1 l -9.5,0 0,8.8 9.5,0 c 0.3,0 0.9,0 1,-0.1 2,-0.3 3.7,-1.9 3.7,-4.3 z\"\r\n />\r\n <path\r\n fill=\"url(#jcbBlue)\"\r\n d=\"m 37.7,16.2 c -10,0 -18.2,8.1 -18.2,18.2 l 0,44.9 c 5.1,2.5 10.4,4.1 15.7,4.1 6.3,0 9.7,-3.8 9.7,-9 l 0,-21.2 15.6,0 0,21.1 c 0,8.2 -5.1,14.9 -22.4,14.9 -10.5,0 -18.7,-2.3 -18.7,-2.3 l 0,38.3 26.7,0 c 10,0 18.2,-8.1 18.2,-18.2 l 0,-90.8 -26.6,0 z\"\r\n />\r\n <path\r\n fill=\"url(#jcbRed)\"\r\n d=\"m 88,16.2 c -10,0 -18.2,8.1 -18.2,18.2 l 0,23.8 c 4.6,-3.9 12.6,-6.4 25.5,-5.8 6.9,0.3 14.3,2.2 14.3,2.2 l 0,7.7 c -3.7,-1.9 -8.1,-3.6 -13.8,-4 -9.8,-0.7 -15.7,4.1 -15.7,12.5 0,8.5 5.9,13.3 15.7,12.5 5.7,-0.4 10.1,-2.2 13.8,-4 l 0,7.7 c 0,0 -7.3,1.9 -14.3,2.2 -12.9,0.6 -20.9,-1.9 -25.5,-5.8 l 0,42 26.7,0 c 10,0 18.2,-8.1 18.2,-18.2 l 0,-91 -26.7,0 z\"\r\n />\r\n </g>\r\n </g>\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\n// Diners Club \uB85C\uACE0\r\nexport function DinersIcon({ size = 24 }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n // \uC6D0\uBCF8 viewBox: 419.87 x 333.3\r\n const logoWidth = 419.87;\r\n const logoHeight = 333.3;\r\n const logoScale = Math.min(\r\n (CARD_WIDTH * 0.8) / logoWidth,\r\n (CARD_HEIGHT * 0.8) / logoHeight\r\n );\r\n const offsetX = (CARD_WIDTH - logoWidth * logoScale) / 2;\r\n const offsetY = (CARD_HEIGHT - logoHeight * logoScale) / 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <g\r\n transform={`translate(${offsetX}, ${offsetY}) scale(${logoScale})`}\r\n >\r\n <g transform=\"translate(-180.06, -83.35)\">\r\n <path\r\n d=\"m599.93 251.45c0-99.416-82.979-168.13-173.9-168.1h-78.241c-92.003-0.033-167.73 68.705-167.73 168.1 0 90.931 75.729 165.64 167.73 165.2h78.241c90.913 0.437 173.9-74.293 173.9-165.2z\"\r\n fill=\"#0079BE\"\r\n />\r\n <path\r\n d=\"m348.28 97.432c-84.069 0.026-152.19 68.308-152.22 152.58 0.021 84.258 68.145 152.53 152.22 152.56 84.088-0.025 152.23-68.301 152.24-152.56-0.011-84.274-68.15-152.55-152.24-152.58z\"\r\n fill=\"#ffffff\"\r\n />\r\n <path\r\n d=\"m252.07 249.6c0.08-41.18 25.747-76.296 61.94-90.25v180.48c-36.193-13.946-61.861-49.044-61.94-90.229zm131 90.275v-180.52c36.208 13.921 61.915 49.057 61.98 90.256-0.066 41.212-25.772 76.322-61.98 90.269z\"\r\n fill=\"#0079BE\"\r\n />\r\n </g>\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\n// Discover \uB85C\uACE0\r\nexport function DiscoverIcon({ size = 24 }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n // 2\uC904 \uB808\uC774\uC544\uC6C3: Disc + \uB3D9\uADF8\uB77C\uBBF8 / ver\r\n const logoWidth = 700;\r\n const logoHeight = 450;\r\n const logoScale = Math.min(\r\n (CARD_WIDTH * 0.95) / logoWidth,\r\n (CARD_HEIGHT * 0.95) / logoHeight\r\n );\r\n const offsetX = (CARD_WIDTH - logoWidth * logoScale) / 2;\r\n const offsetY = (CARD_HEIGHT - logoHeight * logoScale) / 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n xmlnsXlink=\"http://www.w3.org/1999/xlink\"\r\n >\r\n <defs>\r\n <radialGradient\r\n id=\"discoverGradient\"\r\n cx=\"141.25\"\r\n cy=\"77.588577\"\r\n r=\"77.916664\"\r\n fx=\"141.25\"\r\n fy=\"77.588577\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n >\r\n <stop offset=\"0\" stopColor=\"#f0f0f0\" />\r\n <stop offset=\"1\" stopColor=\"#ff8330\" />\r\n </radialGradient>\r\n </defs>\r\n <g\r\n transform={`translate(${offsetX}, ${offsetY}) scale(${logoScale})`}\r\n >\r\n {/* \uCCAB\uBC88\uC9F8 \uC904: Disc + \uC8FC\uD669\uC0C9 \uB3D9\uADF8\uB77C\uBBF8 */}\r\n <text\r\n x=\"-9.8425188\"\r\n y=\"193.30708\"\r\n fontFamily=\"Verdana, sans-serif\"\r\n fontWeight=\"700\"\r\n fontSize=\"220\"\r\n fill=\"#000000\"\r\n >\r\n Disc\r\n </text>\r\n <g transform=\"matrix(0.94947156 0 0 0.949483 496.94722 33.627248)\">\r\n <path\r\n d=\"m 199.16666,97.588577 a 77.916664,77.916664 0 1 1 -155.833324,0 77.916664,77.916664 0 1 1 155.833324,0 z\"\r\n transform=\"translate(-25.8333 3.33333)\"\r\n fill=\"url(#discoverGradient)\"\r\n />\r\n </g>\r\n {/* \uB450\uBC88\uC9F8 \uC904: ver */}\r\n <text\r\n x=\"200\"\r\n y=\"420\"\r\n fontFamily=\"Verdana, sans-serif\"\r\n fontWeight=\"700\"\r\n fontSize=\"220\"\r\n fill=\"#000000\"\r\n >\r\n ver\r\n </text>\r\n <text\r\n x=\"580\"\r\n y=\"310\"\r\n fontFamily=\"Bitstream Vera Sans, sans-serif\"\r\n fontSize=\"40\"\r\n fill=\"#000000\"\r\n >\r\n \u00AE\r\n </text>\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\n// UnionPay \uB85C\uACE0\r\nexport function UnionPayIcon({ size = 24 }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n // \uC6D0\uBCF8 viewBox: 256 x 160\r\n const logoWidth = 256;\r\n const logoHeight = 160;\r\n const logoScale = Math.min(\r\n (CARD_WIDTH * 0.8) / logoWidth,\r\n (CARD_HEIGHT * 0.85) / logoHeight\r\n );\r\n const offsetX = (CARD_WIDTH - logoWidth * logoScale) / 2;\r\n const offsetY = (CARD_HEIGHT - logoHeight * logoScale) / 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <g\r\n transform={`translate(${offsetX}, ${offsetY}) scale(${logoScale})`}\r\n >\r\n <path\r\n d=\"M50.041631,0.000667563305 L113.820211,0.000667563305 C122.723127,0.000667563305 128.260438,7.25731345 126.183558,16.1897657 L96.4900715,143.675416 C94.3945365,152.576777 85.480739,159.839641 76.571605,159.839641 L12.7992433,159.839641 C3.908764,159.839641 -1.64098444,152.576777 0.435896208,143.675416 L30.1418186,16.1897657 C32.2186993,7.25731345 41.1278333,0.000667563305 50.041631,0.000667563305\"\r\n fill=\"#E21836\"\r\n />\r\n <path\r\n d=\"M108.513283,0.000667563305 L181.857018,0.000667563305 C190.758378,0.000667563305 186.744527,7.25731345 184.650546,16.1897657 L154.961724,143.675416 C152.878625,152.576777 153.528427,159.839641 144.608411,159.839641 L71.2646775,159.839641 C62.3446615,159.839641 56.8244495,152.576777 58.919985,143.675416 L88.6072525,16.1897657 C90.715224,7.25731345 99.6057035,0.000667563305 108.513283,0.000667563305\"\r\n fill=\"#00447C\"\r\n />\r\n <path\r\n d=\"M178.94783,0.000667563305 L242.726409,0.000667563305 C251.641762,0.000667563305 257.179074,7.25731345 255.085093,16.1897657 L225.396271,143.675416 C223.300736,152.576777 214.380719,159.839641 205.466922,159.839641 L141.717879,159.839641 C132.797863,159.839641 127.265215,152.576777 129.354532,143.675416 L159.048017,16.1897657 C161.124899,7.25731345 170.027814,0.000667563305 178.94783,0.000667563305\"\r\n fill=\"#007B84\"\r\n />\r\n <path\r\n d=\"M66.698338,40.8561434 C60.139686,40.9229891 58.202715,40.8561434 57.5840035,40.7100156 C57.346157,41.8401744 52.920349,62.256098 52.9079125,62.273198 C51.9549725,66.403641 51.261643,69.347961 48.9064975,71.2491775 C47.5695833,72.3544635 46.0088137,72.8876745 44.1993159,72.8876745 C41.2907503,72.8876745 39.5962892,71.4434965 39.3118063,68.704377 L39.2573971,67.7638735 C39.2573971,67.7638735 40.1434913,62.231225 40.1434913,62.200134 C40.1434913,62.200134 44.7884909,43.5952629 45.6201759,41.1359627 C45.6637033,40.9960531 45.6761397,40.9229891 45.6870215,40.8561434 C36.6457507,40.9354255 35.0430082,40.8561434 34.9326351,40.7100156 C34.8720075,40.9105527 34.6481522,42.0640298 34.6481522,42.0640298 L29.9052159,63.0333735 L29.4979234,64.8117805 L28.7097659,70.6289115 C28.7097659,72.3544635 29.0486581,73.762887 29.7233334,74.9536735 C31.8841598,78.729679 38.0479561,79.2955355 41.5348148,79.2955355 C46.0274683,79.2955355 50.241857,78.341041 53.089795,76.598389 C58.0332685,73.677387 59.3266555,69.1116695 60.4801325,65.0542905 L61.014898,62.972746 C61.014898,62.972746 65.7998075,43.6496723 66.6128375,41.1359627 C66.643929,40.9960531 66.656365,40.9229891 66.698338,40.8561434 Z M82.9786885,56.444252 C81.825211,56.444252 79.7172395,56.724071 77.823796,57.6521385 C77.1366845,58.0050215 76.486882,58.412314 75.8013245,58.818052 L76.420036,56.5841615 L76.081144,56.20796 C72.0657375,57.0209905 71.167207,57.129809 67.4580475,57.6521385 L67.147137,57.8588935 C66.7165265,61.4296985 66.3341065,64.1144085 64.7375825,71.133208 C64.129753,73.7199815 63.498605,76.331628 62.8659025,78.912183 L63.036903,79.2401935 C66.8377815,79.0396565 67.9912585,79.0396565 71.29468,79.0940655 L71.562063,78.8033645 C71.981792,76.65342 72.036201,76.1497455 72.965823,71.795447 C73.402652,69.7310025 74.313619,65.1948215 74.7628845,63.579643 C75.588351,63.197223 76.402936,62.8210215 77.1802115,62.8210215 C79.0316825,62.8210215 78.8062725,64.4362005 78.734763,65.079785 C78.655481,66.160198 77.9808055,69.68903 77.2890305,72.7188505 L76.8273285,74.674476 C76.5055365,76.1186545 76.152653,77.522414 75.830861,78.954156 L75.9707705,79.2401935 C79.7172395,79.0396565 80.859835,79.0396565 84.0591015,79.0940655 L84.435303,78.8033645 C85.013596,75.4455335 85.183042,74.547003 86.209046,69.6579385 L86.725157,67.411612 C87.727843,63.0153405 88.2315175,60.786114 87.4728965,58.970398 C86.670748,56.93549 84.7462135,56.444252 82.9786885,56.444252 Z M101.165696,61.047123 C99.1743155,61.429543 97.904247,61.684489 96.6419515,61.8492715 C95.3905375,62.049809 94.1702145,62.2316915 92.24568,62.499074 L92.093334,62.637429 L91.9534245,62.7478025 C91.7528875,64.181099 91.6129775,65.420076 91.3471495,66.876691 C91.1217395,68.383051 90.7750745,70.094612 90.2107725,72.5539125 C89.7739435,74.436474 89.5485335,75.092495 89.299805,75.754734 C89.057295,76.4169725 88.7899125,77.060557 88.298674,78.9120275 L88.413711,79.0830285 L88.510093,79.240038 C90.308709,79.1545375 91.4855045,79.09391 92.6949455,79.0830285 C93.902832,79.039501 95.1542455,79.0830285 97.0912165,79.09391 L97.260663,78.955555 L97.4425455,78.803209 C97.7223645,77.133621 97.7643375,76.6843555 97.935338,75.8697705 C98.104784,74.9961125 98.39704,73.786672 99.113688,70.556314 C99.4525805,69.039072 99.8303365,67.5264935 100.181665,65.97816 C100.546985,64.436045 100.929404,62.9172485 101.293169,61.4000065 L101.23876,61.2165695 L101.165696,61.047123 Z M101.208135,54.841043 C99.3986375,53.7730665 96.222689,54.1119585 94.0851805,55.587228 C91.953891,57.0329605 91.711381,59.0849685 93.5146605,60.166936 C95.293067,61.2053765 98.481452,60.896021 100.600305,59.408315 C102.726932,57.9314915 102.99276,55.898138 101.208135,54.841043 Z M112.151399,79.574733 C115.812368,79.574733 119.565055,78.565829 122.389675,75.571763 C124.562938,73.143554 125.559405,69.5307765 125.904516,68.043071 C127.028457,63.112034 126.153244,60.809743 125.054176,59.407538 C123.384588,57.2700295 120.43405,56.5844725 117.373138,56.5844725 C115.532549,56.5844725 111.148714,56.766355 107.724038,59.923649 C105.264737,62.2010665 104.12836,65.291515 103.442803,68.2544895 C102.751028,71.2734285 101.955097,76.70814 106.95298,78.7306115 C108.495095,79.3928505 110.718104,79.574733 112.151399,79.574733 Z M111.865362,68.4798995 C112.709484,64.7458675 113.705951,61.6118915 116.249197,61.6118915 C118.242132,61.6118915 118.386705,63.943719 117.500611,67.6901875 C117.342047,68.5218725 116.614517,71.6138755 115.630486,72.9305805 C114.943374,73.902175 114.130344,74.49135 113.231813,74.49135 C112.96443,74.49135 111.374124,74.49135 111.349251,72.1299865 C111.336815,70.964073 111.574661,69.7732865 111.865362,68.4798995 Z M135.05616,79.094532 L135.342197,78.803831 C135.747935,76.6538865 135.814781,76.148657 136.713312,71.7959135 C137.162577,69.731469 138.092198,65.195288 138.529028,63.580109 C139.356049,63.196135 140.156643,62.8199335 140.958791,62.8199335 C142.797825,62.8199335 142.57397,64.4351125 142.500907,65.0786965 C142.43406,66.1606645 141.759386,69.6879415 141.055173,72.717762 L140.618345,74.673388 C140.284116,76.1191205 139.920351,77.521326 139.598559,78.9546225 L139.738469,79.24066 C143.497374,79.0401225 144.596441,79.0401225 147.814363,79.094532 L148.203001,78.803831 C148.767303,75.4444455 148.919649,74.5459145 149.976744,69.658405 L150.480419,67.410524 C151.487768,63.0142525 151.99766,60.7865805 151.251476,58.9708645 C150.426009,56.9359565 148.489038,56.4447185 146.746386,56.4447185 C145.591354,56.4447185 143.472501,56.722983 141.589939,57.652605 C140.916819,58.005488 140.242143,58.411226 139.579904,58.8185185 L140.156643,56.584628 L139.847287,56.206872 C135.833436,57.021457 134.91625,57.1302755 131.211754,57.652605 L130.927271,57.85936 C130.478006,61.4301645 130.112686,64.1133205 128.516162,71.1336745 C127.908333,73.720448 127.277185,76.332094 126.646037,78.9126495 L126.815483,79.24066 C130.622579,79.0401225 131.758957,79.0401225 135.05616,79.094532 Z M162.673542,79.2398825 C162.909834,78.0864055 164.313594,71.2494885 164.32603,71.2494885 C164.32603,71.2494885 165.52148,66.232951 165.594545,66.0510685 C165.594545,66.0510685 165.970746,65.5287395 166.346947,65.321984 L166.900367,65.321984 C172.122106,65.321984 178.018519,65.321984 182.6402,61.92218 C185.785058,59.590353 187.935002,56.1470215 188.89416,51.9621695 C189.142889,50.9361655 189.326326,49.7158426 189.326326,48.4955199 C189.326326,46.8927774 189.004534,45.3071349 188.074912,44.0681575 C185.718212,40.770954 181.025022,40.7103265 175.60741,40.6854536 C175.59031,40.6854536 172.93669,40.7103265 172.93669,40.7103265 C166.001837,40.7958268 163.220744,40.770954 162.078149,40.6310444 C161.981767,41.1362735 161.799884,42.0348043 161.799884,42.0348043 C161.799884,42.0348043 159.315711,53.547812 159.315711,53.5664665 C159.315711,53.5664665 153.371107,78.0444325 153.091287,79.1979095 C159.146265,79.124846 161.628884,79.124846 162.673542,79.2398825 Z M167.276569,58.7882045 C167.276569,58.7882045 169.917752,47.2985153 169.905316,47.3420427 L169.990815,46.7528678 L170.028125,46.3036024 L171.083665,46.4124209 C171.083665,46.4124209 176.530813,46.8803409 176.658287,46.8927774 C178.808231,47.7244624 179.694325,49.8681887 179.075614,52.666381 C178.511312,55.223618 176.852606,57.373563 174.721316,58.412003 C172.966227,59.291879 170.816282,59.364943 168.601047,59.364943 L167.167751,59.364943 L167.276569,58.7882045 Z M183.721236,68.692718 C183.023242,71.668129 182.221093,77.102841 187.194103,79.039812 C188.779745,79.714487 190.200605,79.915024 191.644784,79.8419605 C193.169799,79.759569 194.582886,78.99473 195.891818,77.8941075 C195.773673,78.346482 195.655527,78.7988565 195.537381,79.2527855 L195.76279,79.5434865 C199.339813,79.392695 200.449763,79.392695 204.325259,79.4222315 L204.676588,79.1548485 C205.242445,75.8281085 205.775656,72.597751 207.246262,66.2334175 C207.962909,63.184942 208.678003,60.1660035 209.413306,57.1299645 L209.29827,56.795736 C205.296854,57.537257 204.227323,57.6958215 200.378253,58.241469 L200.085998,58.479315 C200.047134,58.788671 200.006716,59.08559 199.969406,59.3825095 C199.370904,58.4155785 198.503465,57.590112 197.164996,57.0755555 C195.453434,56.4024345 191.433365,57.269874 187.977597,60.416286 C185.549388,62.662613 184.383475,65.7406245 183.721236,68.692718 Z M192.12514,68.8746005 C192.981698,65.2074135 193.965729,62.104529 196.515194,62.104529 C198.127263,62.104529 198.976048,63.5922345 198.803493,66.1292625 C198.666693,66.761965 198.51901,67.4288675 198.343345,68.182825 C198.0884,69.2725655 197.811689,70.3529785 197.542752,71.4349465 C197.26915,72.174913 196.950468,72.8729065 196.600694,73.3377175 C195.944673,74.267339 194.383904,74.8440775 193.485373,74.8440775 C193.230426,74.8440775 191.65722,74.8440775 191.602811,72.524687 C191.590374,71.3696555 191.828221,70.1804235 192.12514,68.8746005 Z M236.010903,56.766044 L235.701548,56.413161 C231.742105,57.2153095 231.025456,57.3427825 227.387807,57.834021 L227.120423,58.1014035 C227.107988,58.144931 227.097105,58.211777 227.078451,58.2724045 L227.066014,58.211777 C224.357986,64.459519 224.437268,63.111723 222.232914,68.0303235 C222.220477,67.806468 222.220477,67.6665585 222.208042,67.428712 L221.656175,56.766044 L221.30951,56.413161 C217.161968,57.2153095 217.064031,57.3427825 213.233616,57.834021 L212.935143,58.1014035 C212.893169,58.228877 212.893169,58.3687865 212.868297,58.5211325 L212.893169,58.575542 C213.371971,61.022406 213.256934,60.4767585 213.737291,64.338264 C213.961146,66.233262 214.25962,68.139142 214.483475,70.010822 C214.861232,73.143243 215.072651,74.685358 215.534352,79.4656035 C212.947578,83.7344015 212.335085,85.3495805 209.844694,89.0960495 L209.861794,89.1333585 L208.10826,91.906678 C207.907723,92.198934 207.725841,92.399471 207.470894,92.4849715 C207.191075,92.6233265 206.82731,92.648199 206.32208,92.648199 L205.350486,92.648199 L203.906308,97.451763 L208.860663,97.5372635 C211.769228,97.524827 213.597381,96.1645945 214.581412,94.336442 L217.696733,88.9981125 L217.646987,88.9981125 L217.974998,88.621911 C220.070533,84.110603 236.010903,56.766044 236.010903,56.766044 Z M183.72108,119.853625 L181.619326,119.853625 L189.398302,94.1242455 L191.978857,94.1242455 L192.798105,91.4737355 L192.877387,94.421165 C192.781005,96.243099 194.214302,97.858278 197.979425,97.5908955 L202.333723,97.5908955 L203.832311,92.63654 L202.193814,92.63654 C201.251756,92.63654 200.814927,92.3986935 200.869337,91.888801 L200.790054,88.890071 L192.726596,88.890071 L192.726596,88.9056165 C190.119614,88.960026 182.33442,89.1558995 180.758105,89.5756285 C178.850671,90.0668665 176.840635,91.5125995 176.840635,91.5125995 L177.630347,88.85898 L170.087664,88.85898 L168.516013,94.1242455 L160.632883,120.246927 L159.103204,120.246927 L157.603062,125.165528 L172.626247,125.165528 L172.122572,126.805579 L179.525345,126.805579 L180.016584,125.165528 L182.093465,125.165528 L183.72108,119.853625 Z M177.557284,99.352202 C176.349398,99.6864305 174.101516,100.699998 174.101516,100.699998 L176.100669,94.1242455 L182.093465,94.1242455 L180.647732,98.915373 C180.647732,98.915373 178.796261,99.0241915 177.557284,99.352202 Z M177.672321,108.746356 C177.672321,108.746356 175.789759,108.982648 174.550781,109.262467 C173.330458,109.632451 171.042159,110.798364 171.042159,110.798364 L173.106603,103.955229 L179.13049,103.955229 L177.672321,108.746356 Z M174.31449,119.914253 L168.30304,119.914253 L170.045692,114.139095 L176.038487,114.139095 L174.31449,119.914253 Z M188.791404,103.955229 L197.456474,103.955229 L196.211278,107.987735 L187.431173,107.987735 L186.112912,112.396443 L193.795505,112.396443 L187.978375,120.587374 C187.571082,121.188986 187.205762,121.401959 186.800025,121.571405 C186.392732,121.77816 185.857967,122.02067 185.239255,122.02067 L183.107965,122.02067 L181.643577,126.849107 L187.218198,126.849107 C190.115882,126.849107 191.827443,125.530847 193.091294,123.800631 L197.080273,118.341047 L197.936831,123.884578 C198.118713,124.923017 198.864898,125.530847 199.370127,125.767139 C199.928211,126.046958 200.50495,126.527315 201.319535,126.598824 C202.193192,126.636133 202.82434,126.66567 203.244069,126.66567 L205.983189,126.66567 L207.627904,121.262049 L206.547491,121.262049 C205.927224,121.262049 204.859248,121.157894 204.677366,120.963575 C204.495483,120.727283 204.495483,120.363518 204.397546,119.810098 L203.528552,114.254131 L199.970183,114.254131 L201.530954,112.396443 L210.293959,112.396443 L211.641755,107.987735 L203.528552,107.987735 L204.792402,103.955229 L212.880733,103.955229 L214.380875,98.982219 L190.266674,98.982219 L188.791404,103.955229 Z M115.605924,121.037106 L117.628395,114.309008 L125.940582,114.309008 L127.459378,109.304907 L119.139419,109.304907 L120.409488,105.163582 L128.539791,105.163582 L130.046152,100.318045 L109.703292,100.318045 L108.228023,105.163582 L112.849704,105.163582 L111.616945,109.304907 L106.982827,109.304907 L105.446931,114.394508 L110.067057,114.394508 L107.371465,123.295869 C107.0077,124.474219 107.542466,124.923484 107.881358,125.470686 C108.228023,126.003897 108.579352,126.35678 109.369064,126.557317 C110.183649,126.7392 110.741733,126.848018 111.500354,126.848018 L120.87119,126.848018 L122.540778,121.304488 L118.387016,121.875009 C117.584868,121.875009 115.363414,121.778627 115.605924,121.037106 Z M116.55933,88.8286665 L114.452913,92.635763 C114.002093,93.4674475 113.596355,93.983559 113.231036,94.221405 C112.909244,94.4219425 112.271878,94.505888 111.348474,94.505888 L110.249406,94.505888 L108.780355,99.3762975 L112.430442,99.3762975 C114.18553,99.3762975 115.533326,98.7327135 116.176911,98.410921 C116.868686,98.040938 117.050568,98.252357 117.585334,97.736246 L118.818094,96.668269 L130.216064,96.668269 L131.728643,91.5973225 L123.385365,91.5973225 L124.84198,88.8286665 L116.55933,88.8286665 Z M133.386416,121.134887 C133.192097,120.855067 133.332007,120.362275 133.628926,119.336271 L136.744247,109.024932 L147.826644,109.024932 C149.441823,109.001614 150.607736,108.982959 151.366357,108.92855 C152.180942,108.843049 153.067037,108.552348 154.032413,108.030019 C155.028881,107.482817 155.538773,106.906078 155.969384,106.243839 C156.44974,105.583155 157.220798,104.137422 157.883037,101.908196 L161.798952,88.859291 L150.298381,88.926137 C150.298381,88.926137 146.757113,89.448466 145.197898,90.0252045 C143.624692,90.668789 141.37681,92.4658505 141.37681,92.4658505 L142.415251,88.8888275 L135.31095,88.8888275 L125.364931,121.874854 C125.012048,123.155803 124.775756,124.085425 124.721347,124.643509 C124.702692,125.245121 125.479968,125.840514 125.983643,126.289779 C126.579036,126.739045 127.458911,126.665981 128.303033,126.739045 C129.190682,126.805891 130.452978,126.847863 132.195629,126.847863 L137.655214,126.847863 L139.33102,121.189296 L134.443511,121.650998 C133.921182,121.650998 133.543426,121.371178 133.386416,121.134887 Z M138.754282,102.060541 L150.394763,102.060541 L149.654797,104.379932 C149.550642,104.434341 149.301913,104.264895 148.117345,104.404805 L138.037634,104.404805 L138.754282,102.060541 Z M141.086109,94.2815665 L152.824526,94.2815665 L151.980405,97.075095 C151.980405,97.075095 146.447757,97.020686 145.561663,97.1839135 C141.662847,97.858589 139.38543,99.941688 139.38543,99.941688 L141.086109,94.2815665 Z M149.915339,112.146937 C149.818957,112.493602 149.666611,112.705021 149.453638,112.863585 C149.217345,113.015931 148.834926,113.07034 148.264406,113.07034 L146.605699,113.07034 L146.703636,110.245721 L139.804537,110.245721 L139.524718,124.054801 C139.513836,125.051268 139.610218,125.628007 140.339303,126.089709 C141.068387,126.666447 143.314714,126.739511 146.338316,126.739511 L150.661524,126.739511 L152.222294,121.570628 L148.458724,121.777383 L147.207311,121.850447 C147.03631,121.777383 146.873082,121.710537 146.6912,121.528655 C146.532635,121.371645 146.265253,121.468028 146.30878,120.47156 L146.338316,116.931847 L150.285323,116.768619 C152.416613,116.768619 153.32758,116.075288 154.104855,115.414604 C154.846376,114.781902 155.088886,114.054372 155.368706,113.07034 L156.030945,109.936365 L150.607114,109.936365 L149.915339,112.146937 Z\"\r\n fill=\"#FEFEFE\"\r\n />\r\n </g>\r\n </svg>\r\n );\r\n}\r\n\r\n// BC\uCE74\uB4DC \uB85C\uACE0\r\nexport function BcIcon({ size = 24 }: CardIconProps) {\r\n const scale = size / 24;\r\n const width = CARD_WIDTH * scale;\r\n const height = CARD_HEIGHT * scale;\r\n // \uC6D0\uBCF8 viewBox: 160.11 x 160.09 (\uC815\uC0AC\uAC01\uD615)\r\n const logoSize = Math.min(CARD_WIDTH, CARD_HEIGHT) * 0.75;\r\n const offsetX = (CARD_WIDTH - logoSize) / 2;\r\n const offsetY = (CARD_HEIGHT - logoSize) / 2;\r\n\r\n return (\r\n <svg\r\n width={width}\r\n height={height}\r\n viewBox={`0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`}\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <svg\r\n x={offsetX}\r\n y={offsetY}\r\n width={logoSize}\r\n height={logoSize}\r\n viewBox=\"0 0 160.11065 160.09067\"\r\n >\r\n <g transform=\"matrix(1.3333333,0,0,-1.3333333,-218.97066,649.46545)\">\r\n <g>\r\n <g>\r\n <g transform=\"translate(284.311,427.0571)\">\r\n <path\r\n d=\"m 0,0 c 0,-33.144 -26.904,-60.026 -60.042,-60.026 -33.158,0 -60.041,26.882 -60.041,60.026 0,33.164 26.883,60.042 60.041,60.042 C -26.904,60.042 0,33.164 0,0\"\r\n fill=\"#e83e44\"\r\n />\r\n </g>\r\n </g>\r\n </g>\r\n <g>\r\n <g>\r\n <g transform=\"translate(174.2358,433.7524)\">\r\n <path\r\n d=\"M 0,0 C 0,-0.041 0.112,-1.324 0.112,-1.324 0.092,-1.62 0.255,-1.901 0.521,-2.003 0.756,-2.111 1.022,-2.06 1.257,-1.861 3.495,0.02 6.889,1.702 9.618,0.762 11.754,0.02 13.206,-2.183 13.962,-5.796 15.516,-13.37 10.323,-17.02 7.083,-18.506 L 6.971,-18.557 2.82,-20.592 c 0,0 -0.234,-0.101 -0.49,0.021 -0.255,0.133 -0.327,0.297 -0.501,0.746 -2.821,10.411 -3.782,21.348 -2.729,31.559 0.112,0.767 0.46,1.697 1.053,2.454 l 3.485,3.715 0.389,0.424 c 1.891,1.84 3.669,2.76 4.631,2.361 C 9.455,20.351 9.649,19.073 9.659,18.071 9.822,12.644 6.787,7.098 0.429,1.125 0.429,1.125 -0.062,0.726 0,0 m 19.104,7.528 c -1.892,1.13 -4.027,1.451 -6.184,1.139 3.934,4.192 6.072,8.75 6.072,13.35 0,0.419 -0.011,0.838 -0.062,1.268 -0.204,2.861 -1.523,5.008 -3.567,5.734 -2.045,0.766 -5.797,0.378 -11.756,-5.714 L 0.03,19.298 C -0.961,18.092 -4.723,12.399 -5.418,6.47 c -1.165,-10.078 -0.419,-20.136 2.147,-29.054 0.296,-1.042 1.257,-3.558 3.567,-4.489 2.454,-1.001 4.784,0.205 6.849,1.269 l 0.551,0.275 2.126,0.951 2.065,0.91 2.515,1.104 c 1.808,0.736 3.506,1.421 5.161,2.811 2.198,1.876 3.813,4.328 4.641,7.119 0.43,1.441 0.726,3.015 0.879,4.804 0.133,1.39 0.276,4.089 -0.245,6.46 -1.134,5.223 -3.731,7.718 -5.734,8.898\"\r\n fill=\"#ffffff\"\r\n />\r\n </g>\r\n <g transform=\"translate(240.4609,472.9214)\">\r\n <path\r\n d=\"M 0,0 C -1.166,3.996 -3.067,4.834 -3.619,5.019 -8.606,6.613 -13.79,6.94 -18.818,6.062 -26.372,4.671 -32.903,0.706 -37.237,-5.101 c -4.549,-6.107 -6.307,-13.727 -4.958,-21.434 1.37,-7.738 5.275,-14.004 11.346,-18.103 7.114,-4.794 16.579,-6.255 26.699,-4.129 5.979,1.298 10.917,3.623 14.739,6.92 1.707,1.482 2.034,3.368 2.034,4.692 0,0 0.092,1.068 -0.736,4.436 -0.224,0.817 -0.582,1.063 -1.155,1.063 -0.419,0 -0.858,-0.481 -0.94,-0.583 -2.852,-3.302 -7.196,-5.601 -12.624,-6.669 -13.932,-2.678 -24.644,3.827 -27.301,16.584 -1.135,5.525 -0.195,10.824 2.688,14.924 2.893,4.17 7.635,6.93 13.349,7.788 4.354,0.634 8.78,0.098 12.756,-1.564 0,0 1.708,-0.495 1.34,1.176\"\r\n fill=\"#ffffff\"\r\n />\r\n </g>\r\n </g>\r\n </g>\r\n </g>\r\n </svg>\r\n </svg>\r\n );\r\n}\r\n", "/**\r\n * Slider.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback } from \"react\";\r\nimport {\r\n Box,\r\n FormControl,\r\n FormLabel,\r\n Slider as MuiSlider,\r\n} from \"@mui/material\";\r\nimport type { SliderProps } from \"./types\";\r\n\r\nconst SliderBase = forwardRef<HTMLSpanElement, SliderProps>(function SliderBase(\r\n { label, name, value, onChange, readonly, disabled, ...props },\r\n ref,\r\n) {\r\n return (\r\n <FormControl disabled={disabled} sx={{ width: \"100%\" }}>\r\n {label && <FormLabel>{label}</FormLabel>}\r\n <Box sx={{ px: 1 }}>\r\n <MuiSlider\r\n {...props}\r\n ref={ref}\r\n name={name}\r\n value={value ?? 0}\r\n onChange={onChange}\r\n disabled={disabled || readonly}\r\n />\r\n </Box>\r\n </FormControl>\r\n );\r\n});\r\n\r\nconst SliderWithForm = forwardRef<HTMLSpanElement, SliderProps>(\r\n function SliderWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"Slider form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"Slider requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const resolvedValue =\r\n formValue !== undefined && formValue !== null\r\n ? (formValue as number | number[])\r\n : (rest.value ?? 0);\r\n\r\n const handleFormChange = useCallback(\r\n (_event: Event, nextValue: number | number[]) => {\r\n const syntheticEvent = {\r\n target: {\r\n name,\r\n value: nextValue,\r\n },\r\n } as unknown as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n onChange?.(_event, nextValue);\r\n },\r\n [form, name, onChange],\r\n );\r\n\r\n return (\r\n <SliderBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={resolvedValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const Slider = forwardRef<HTMLSpanElement, SliderProps>(\r\n function Slider(props, ref) {\r\n if (props.form) {\r\n return <SliderWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <SliderBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * Stepper.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \u0010a8ud10a8uc601uc9c4 (Kim Young Jin)\r\n * @author \u0010a8ud10a8uc601uc9c4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { forwardRef, useCallback, useEffect } from \"react\";\r\nimport { Stepper as MuiStepper } from \"@mui/material\";\r\nimport type { StepperProps } from \"./types\";\r\n\r\nconst parseStepValue = (value: unknown): number | undefined => {\r\n if (typeof value === \"number\" && Number.isFinite(value)) {\r\n return value;\r\n }\r\n if (typeof value === \"string\" && value.trim() !== \"\") {\r\n const parsed = Number(value);\r\n return Number.isFinite(parsed) ? parsed : undefined;\r\n }\r\n return undefined;\r\n};\r\n\r\nexport const Stepper = forwardRef<HTMLDivElement, StepperProps>(function Stepper(\r\n { form, name, activeStep: activeStepProp, defaultActiveStep = 0, onStepChange, ...props },\r\n ref\r\n) {\r\n if (form && !name) {\r\n throw new Error(\"Stepper requires a name when form prop is provided.\");\r\n }\r\n\r\n const shouldUseForm = Boolean(form && name);\r\n const formValue = shouldUseForm ? form!.useFormValue(name!) : undefined;\r\n const parsedFormValue = parseStepValue(formValue);\r\n\r\n const emitStepChange = useCallback(\r\n (step: number) => {\r\n if (!form || !name) {\r\n onStepChange?.(step);\r\n return;\r\n }\r\n\r\n const eventTarget = {\r\n name,\r\n value: String(step),\r\n } as HTMLInputElement;\r\n const fakeEvent = {\r\n target: eventTarget,\r\n currentTarget: eventTarget,\r\n } as unknown as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(fakeEvent);\r\n onStepChange?.(step);\r\n },\r\n [form, name, onStepChange]\r\n );\r\n\r\n useEffect(() => {\r\n if (!shouldUseForm || activeStepProp === undefined) {\r\n return;\r\n }\r\n\r\n if (activeStepProp !== parsedFormValue) {\r\n emitStepChange(activeStepProp);\r\n }\r\n }, [shouldUseForm, activeStepProp, parsedFormValue, emitStepChange]);\r\n\r\n useEffect(() => {\r\n if (!shouldUseForm || activeStepProp !== undefined) {\r\n return;\r\n }\r\n\r\n if (parsedFormValue === undefined) {\r\n emitStepChange(defaultActiveStep);\r\n }\r\n }, [shouldUseForm, activeStepProp, parsedFormValue, defaultActiveStep, emitStepChange]);\r\n\r\n const resolvedActiveStep = activeStepProp ?? parsedFormValue ?? defaultActiveStep;\r\n\r\n return <MuiStepper ref={ref} activeStep={resolvedActiveStep} {...props} />;\r\n});\r\n", "import * as React from \"react\";\r\nimport { NumberField as BaseNumberField } from \"@base-ui/react/number-field\";\r\nimport type { NumberFieldRoot } from \"@base-ui/react/number-field\";\r\nimport IconButton from \"@mui/material/IconButton\";\r\nimport FormControl from \"@mui/material/FormControl\";\r\nimport FormHelperText from \"@mui/material/FormHelperText\";\r\nimport OutlinedInput from \"@mui/material/OutlinedInput\";\r\nimport InputAdornment from \"@mui/material/InputAdornment\";\r\nimport InputLabel from \"@mui/material/InputLabel\";\r\nimport KeyboardArrowUpIcon from \"@mui/icons-material/KeyboardArrowUp\";\r\nimport KeyboardArrowDownIcon from \"@mui/icons-material/KeyboardArrowDown\";\r\nimport type { FormLike } from \"../types\";\r\n\r\nexport type NumberFieldProps = BaseNumberField.Root.Props & {\r\n label?: React.ReactNode;\r\n size?: \"small\" | \"medium\";\r\n error?: boolean;\r\n fullWidth?: boolean;\r\n form?: FormLike | null;\r\n};\r\n\r\n/**\r\n * This component is a placeholder for FormControl to correctly set the shrink label state on SSR.\r\n */\r\nfunction SSRInitialFilled(_: BaseNumberField.Root.Props) {\r\n return null;\r\n}\r\nSSRInitialFilled.muiName = \"Input\";\r\n\r\nfunction NumberFieldBase({\r\n id: idProp,\r\n label,\r\n error,\r\n size = \"medium\",\r\n step = 1,\r\n fullWidth = true,\r\n form: _form,\r\n ...other\r\n}: NumberFieldProps) {\r\n let id = React.useId();\r\n if (idProp) {\r\n id = idProp;\r\n }\r\n return (\r\n <BaseNumberField.Root\r\n step={step}\r\n {...other}\r\n render={(props, state) => (\r\n <FormControl\r\n size={size}\r\n fullWidth={fullWidth}\r\n sx={fullWidth ? { display: \"flex\" } : undefined}\r\n ref={props.ref}\r\n disabled={state.disabled}\r\n required={state.required}\r\n error={error}\r\n variant=\"outlined\"\r\n >\r\n {props.children}\r\n </FormControl>\r\n )}\r\n >\r\n <SSRInitialFilled {...other} />\r\n <InputLabel htmlFor={id}>{label}</InputLabel>\r\n <BaseNumberField.Input\r\n id={id}\r\n render={(props, state) => (\r\n <OutlinedInput\r\n label={label}\r\n fullWidth={fullWidth}\r\n inputRef={props.ref}\r\n value={state.inputValue}\r\n onBlur={props.onBlur}\r\n onChange={props.onChange}\r\n onKeyUp={props.onKeyUp}\r\n onKeyDown={props.onKeyDown}\r\n onFocus={props.onFocus}\r\n slotProps={{\r\n input: props,\r\n }}\r\n endAdornment={\r\n <InputAdornment\r\n position=\"end\"\r\n sx={{\r\n flexDirection: \"column\",\r\n maxHeight: \"unset\",\r\n alignSelf: \"stretch\",\r\n borderLeft: \"1px solid\",\r\n borderColor: \"divider\",\r\n ml: 0,\r\n \"& button\": {\r\n py: 0,\r\n flex: 1,\r\n borderRadius: 0.5,\r\n },\r\n }}\r\n >\r\n <BaseNumberField.Increment\r\n render={\r\n <IconButton\r\n size={size}\r\n aria-label=\"Increase\"\r\n />\r\n }\r\n >\r\n <KeyboardArrowUpIcon\r\n fontSize={size}\r\n sx={{ transform: \"translateY(2px)\" }}\r\n />\r\n </BaseNumberField.Increment>\r\n\r\n <BaseNumberField.Decrement\r\n render={\r\n <IconButton\r\n size={size}\r\n aria-label=\"Decrease\"\r\n />\r\n }\r\n >\r\n <KeyboardArrowDownIcon\r\n fontSize={size}\r\n sx={{ transform: \"translateY(-2px)\" }}\r\n />\r\n </BaseNumberField.Decrement>\r\n </InputAdornment>\r\n }\r\n sx={{ pr: 0 }}\r\n />\r\n )}\r\n />\r\n </BaseNumberField.Root>\r\n );\r\n}\r\n\r\nfunction NumberFieldWithForm({\r\n form,\r\n name,\r\n onValueChange,\r\n ...rest\r\n}: NumberFieldProps) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"NumberField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"NumberField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormValueChange = React.useCallback(\r\n (\r\n value: number | null,\r\n eventDetails: NumberFieldRoot.ChangeEventDetails,\r\n ) => {\r\n const syntheticEvent = {\r\n target: {\r\n name,\r\n value: value !== null ? String(value) : \"\",\r\n },\r\n currentTarget: {\r\n name,\r\n value: value !== null ? String(value) : \"\",\r\n },\r\n } as unknown as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n onValueChange?.(value, eventDetails);\r\n },\r\n [form, name, onValueChange],\r\n );\r\n\r\n return (\r\n <NumberFieldBase\r\n {...rest}\r\n name={name}\r\n value={formValue as number | null}\r\n onValueChange={handleFormValueChange}\r\n />\r\n );\r\n}\r\n\r\nexport default function NumberField(props: NumberFieldProps) {\r\n if (props.form) {\r\n return <NumberFieldWithForm {...props} />;\r\n }\r\n return <NumberFieldBase {...props} />;\r\n}\r\n", "import * as React from \"react\";\r\nimport { NumberField as BaseNumberField } from \"@base-ui/react/number-field\";\r\nimport Box from \"@mui/material/Box\";\r\nimport Button from \"@mui/material/Button\";\r\nimport FormControl from \"@mui/material/FormControl\";\r\nimport FormLabel from \"@mui/material/FormLabel\";\r\nimport AddIcon from \"@mui/icons-material/Add\";\r\nimport RemoveIcon from \"@mui/icons-material/Remove\";\r\nimport OutlinedInput from \"@mui/material/OutlinedInput\";\r\nimport OpenInFullIcon from \"@mui/icons-material/OpenInFull\";\r\n\r\nexport default function NumberSpinner({\r\n id: idProp,\r\n label,\r\n error,\r\n size = \"medium\",\r\n ...other\r\n}: BaseNumberField.Root.Props & {\r\n label?: React.ReactNode;\r\n size?: \"small\" | \"medium\";\r\n error?: boolean;\r\n}) {\r\n let id = React.useId();\r\n if (idProp) {\r\n id = idProp;\r\n }\r\n return (\r\n <BaseNumberField.Root\r\n {...other}\r\n render={(props, state) => (\r\n <FormControl\r\n size={size}\r\n ref={props.ref}\r\n disabled={state.disabled}\r\n required={state.required}\r\n error={error}\r\n variant=\"outlined\"\r\n sx={{\r\n \"& .MuiButton-root\": {\r\n borderColor: \"divider\",\r\n minWidth: 0,\r\n bgcolor: \"action.hover\",\r\n \"&:not(.Mui-disabled)\": {\r\n color: \"text.primary\",\r\n },\r\n },\r\n }}\r\n >\r\n {props.children}\r\n </FormControl>\r\n )}\r\n >\r\n <BaseNumberField.ScrubArea\r\n render={<Box component=\"span\" sx={{ userSelect: \"none\", width: \"max-content\" }} />}\r\n >\r\n <FormLabel\r\n htmlFor={id}\r\n sx={{\r\n display: \"inline-block\",\r\n cursor: \"ew-resize\",\r\n fontSize: \"0.875rem\",\r\n color: \"text.primary\",\r\n fontWeight: 500,\r\n lineHeight: 1.5,\r\n mb: 0.5,\r\n }}\r\n >\r\n {label}\r\n </FormLabel>\r\n <BaseNumberField.ScrubAreaCursor>\r\n <OpenInFullIcon fontSize=\"small\" sx={{ transform: \"translateY(12.5%) rotate(45deg)\" }} />\r\n </BaseNumberField.ScrubAreaCursor>\r\n </BaseNumberField.ScrubArea>\r\n <Box sx={{ display: \"flex\" }}>\r\n <BaseNumberField.Decrement\r\n render={\r\n <Button\r\n variant=\"outlined\"\r\n aria-label=\"Decrease\"\r\n size={size}\r\n sx={{\r\n borderTopRightRadius: 0,\r\n borderBottomRightRadius: 0,\r\n borderRight: \"0px\",\r\n \"&.Mui-disabled\": {\r\n borderRight: \"0px\",\r\n },\r\n }}\r\n />\r\n }\r\n >\r\n <RemoveIcon fontSize={size} />\r\n </BaseNumberField.Decrement>\r\n\r\n <BaseNumberField.Input\r\n id={id}\r\n render={(props, state) => (\r\n <OutlinedInput\r\n inputRef={props.ref}\r\n value={state.inputValue}\r\n onBlur={props.onBlur}\r\n onChange={props.onChange}\r\n onKeyUp={props.onKeyUp}\r\n onKeyDown={props.onKeyDown}\r\n onFocus={props.onFocus}\r\n slotProps={{\r\n input: {\r\n ...props,\r\n size:\r\n Math.max((other.min?.toString() || \"\").length, state.inputValue.length || 1) +\r\n 1,\r\n sx: {\r\n textAlign: \"center\",\r\n },\r\n },\r\n }}\r\n sx={{ pr: 0, borderRadius: 0, flex: 1 }}\r\n />\r\n )}\r\n />\r\n\r\n <BaseNumberField.Increment\r\n render={\r\n <Button\r\n variant=\"outlined\"\r\n aria-label=\"Increase\"\r\n size={size}\r\n sx={{\r\n borderTopLeftRadius: 0,\r\n borderBottomLeftRadius: 0,\r\n borderLeft: \"0px\",\r\n \"&.Mui-disabled\": {\r\n borderLeft: \"0px\",\r\n },\r\n }}\r\n />\r\n }\r\n >\r\n <AddIcon fontSize={size} />\r\n </BaseNumberField.Increment>\r\n </Box>\r\n </BaseNumberField.Root>\r\n );\r\n}\r\n", "/**\r\n * Autocomplete.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback } from \"react\";\r\nimport { Autocomplete as MuiAutocomplete, TextField } from \"@mui/material\";\r\nimport type { AutocompleteProps, AutocompleteOption } from \"./types\";\r\n\r\nconst AutocompleteBase = forwardRef<HTMLDivElement, AutocompleteProps>(\r\n function AutocompleteBase(\r\n {\r\n name,\r\n label,\r\n options,\r\n value,\r\n onChange,\r\n fullWidth = true,\r\n size,\r\n readonly,\r\n disabled,\r\n textFieldProps,\r\n renderOption,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const selectedOption =\r\n value === null || value === undefined\r\n ? null\r\n : (options.find((option) => option.value === value) ?? null);\r\n\r\n const handleChange = useCallback(\r\n (\r\n _event: React.SyntheticEvent,\r\n option: AutocompleteOption | null,\r\n ) => {\r\n onChange?.(option ? option.value : null);\r\n },\r\n [onChange],\r\n );\r\n\r\n return (\r\n <MuiAutocomplete\r\n {...props}\r\n ref={ref}\r\n options={options}\r\n value={selectedOption}\r\n onChange={handleChange}\r\n fullWidth={fullWidth}\r\n disabled={disabled}\r\n getOptionLabel={(option) => option.label}\r\n isOptionEqualToValue={(option, selected) =>\r\n option.value === selected.value\r\n }\r\n renderOption={\r\n renderOption ??\r\n ((optionProps, option, state) => {\r\n const labelText = option.label;\r\n const query = state.inputValue.trim();\r\n const lowerLabel = labelText.toLowerCase();\r\n const lowerQuery = query.toLowerCase();\r\n const matchIndex = lowerQuery\r\n ? lowerLabel.indexOf(lowerQuery)\r\n : -1;\r\n\r\n if (matchIndex === -1) {\r\n return <li {...optionProps}>{labelText}</li>;\r\n }\r\n\r\n const before = labelText.slice(0, matchIndex);\r\n const match = labelText.slice(\r\n matchIndex,\r\n matchIndex + query.length,\r\n );\r\n const after = labelText.slice(\r\n matchIndex + query.length,\r\n );\r\n\r\n return (\r\n <li {...optionProps}>\r\n {before}\r\n <span style={{ color: \"#1976d2\" }}>\r\n {match}\r\n </span>\r\n {after}\r\n </li>\r\n );\r\n })\r\n }\r\n renderInput={(params) => (\r\n <TextField\r\n {...params}\r\n {...textFieldProps}\r\n name={name}\r\n label={label}\r\n size={size}\r\n InputProps={{\r\n ...params.InputProps,\r\n ...textFieldProps?.InputProps,\r\n readOnly: readonly,\r\n }}\r\n />\r\n )}\r\n />\r\n );\r\n },\r\n);\r\n\r\nconst AutocompleteWithForm = forwardRef<HTMLDivElement, AutocompleteProps>(\r\n function AutocompleteWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"Autocomplete form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"Autocomplete requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name) as string | number | null;\r\n const handleFormChange = useCallback(\r\n (nextValue: string | number | null) => {\r\n const syntheticEvent = {\r\n target: {\r\n name,\r\n value: nextValue ?? \"\",\r\n },\r\n } as unknown as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n onChange?.(nextValue);\r\n },\r\n [form, name, onChange],\r\n );\r\n\r\n return (\r\n <AutocompleteBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const Autocomplete = forwardRef<HTMLDivElement, AutocompleteProps>(\r\n function Autocomplete(props, ref) {\r\n if (props.form) {\r\n return <AutocompleteWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <AutocompleteBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * Select.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 Kim Young Jin\r\n * @author Kim Young Jin (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback, useId } from \"react\";\r\nimport {\r\n FormControl,\r\n MenuItem,\r\n Select as MuiSelect,\r\n SelectChangeEvent,\r\n} from \"@mui/material\";\r\nimport type { SelectProps } from \"./types\";\r\n\r\nconst SelectBase = forwardRef<HTMLDivElement, SelectProps>(function SelectBase(\r\n {\r\n value = \"\",\r\n onChange,\r\n options,\r\n inputProps,\r\n enableWheel = false,\r\n emptyLabel = \"\",\r\n readOnly = false,\r\n showEmptyOption = emptyLabel !== \"\",\r\n fullWidth = true,\r\n size,\r\n formControlProps,\r\n form,\r\n ...selectProps\r\n },\r\n ref,\r\n) {\r\n const generatedId = useId();\r\n const selectId = selectProps.id ?? `select-${generatedId}`;\r\n\r\n const hasValue = value !== undefined && value !== null && value !== \"\";\r\n const safeValue =\r\n hasValue && options.some((option) => option.value === value)\r\n ? value\r\n : \"\";\r\n\r\n const handleSelectWheel = useCallback(\r\n (event: React.WheelEvent) => {\r\n if (!enableWheel || readOnly) return;\r\n event.stopPropagation();\r\n\r\n const optionValues = [\"\", ...options.map((option) => option.value)];\r\n const currentIndex = optionValues.indexOf(safeValue);\r\n if (currentIndex === -1) return;\r\n\r\n const nextIndex =\r\n event.deltaY > 0\r\n ? Math.min(currentIndex + 1, optionValues.length - 1)\r\n : Math.max(currentIndex - 1, 0);\r\n\r\n if (nextIndex !== currentIndex && onChange) {\r\n const nextValue = optionValues[nextIndex];\r\n const syntheticEvent = {\r\n target: {\r\n value: nextValue,\r\n name: selectProps.name ?? \"\",\r\n },\r\n } as SelectChangeEvent<string | number>;\r\n onChange(syntheticEvent);\r\n }\r\n },\r\n [enableWheel, readOnly, options, safeValue, onChange, selectProps],\r\n );\r\n\r\n return (\r\n <FormControl\r\n ref={ref}\r\n fullWidth={fullWidth}\r\n size={size}\r\n {...formControlProps}\r\n sx={{\r\n minWidth: 0,\r\n width: fullWidth ? \"100%\" : undefined,\r\n ...formControlProps?.sx,\r\n }}\r\n >\r\n <MuiSelect\r\n {...selectProps}\r\n id={selectId}\r\n value={safeValue}\r\n onChange={onChange}\r\n fullWidth={fullWidth}\r\n size={size}\r\n inputProps={{\r\n ...inputProps,\r\n readOnly,\r\n }}\r\n onWheel={handleSelectWheel}\r\n displayEmpty={showEmptyOption}\r\n sx={{\r\n width: fullWidth ? \"100%\" : undefined,\r\n minWidth: 0,\r\n \"& .MuiSelect-select\": {\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n },\r\n ...(readOnly && {\r\n pointerEvents: \"none\",\r\n \"&.Mui-focused .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiSelect-icon\": {\r\n display: \"none\",\r\n },\r\n }),\r\n ...selectProps.sx,\r\n }}\r\n renderValue={(selected) => {\r\n if (selected === \"\") {\r\n return (\r\n <span style={{ color: \"#999\" }}>{emptyLabel}</span>\r\n );\r\n }\r\n const option = options.find(\r\n (opt) => opt.value === selected,\r\n );\r\n return (\r\n <span\r\n style={{\r\n display: \"block\",\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n }}\r\n >\r\n {option ? option.label : selected}\r\n </span>\r\n );\r\n }}\r\n >\r\n {showEmptyOption && <MenuItem value=\"\">{emptyLabel}</MenuItem>}\r\n {options.map((option) => (\r\n <MenuItem\r\n key={String(option.value)}\r\n value={option.value as string | number}\r\n >\r\n {option.label}\r\n </MenuItem>\r\n ))}\r\n </MuiSelect>\r\n </FormControl>\r\n );\r\n});\r\n\r\nconst SelectWithForm = forwardRef<HTMLDivElement, SelectProps>(\r\n function SelectWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"Select form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"Select requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name) as\r\n | string\r\n | number\r\n | undefined;\r\n const handleFormChange = useCallback(\r\n (event: SelectChangeEvent<string | number>) => {\r\n form.handleFormChange(\r\n event as React.ChangeEvent<HTMLInputElement>,\r\n );\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <SelectBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const Select = forwardRef<HTMLDivElement, SelectProps>(\r\n function Select(props, ref) {\r\n if (props.form) {\r\n return <SelectWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <SelectBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * LabelSelect.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 Kim Young Jin\r\n * @author Kim Young Jin (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, { forwardRef, useCallback, useId, useState } from \"react\";\r\nimport {\r\n FormControl,\r\n InputLabel,\r\n MenuItem,\r\n Select,\r\n SelectChangeEvent,\r\n} from \"@mui/material\";\r\nimport type { LabelSelectProps } from \"./types\";\r\n\r\nconst LabelSelectBase = forwardRef<HTMLDivElement, LabelSelectProps>(\r\n function LabelSelectBase(\r\n {\r\n label,\r\n value = \"\",\r\n onChange,\r\n options,\r\n inputProps,\r\n enableWheel = false,\r\n showLabel = true,\r\n emptyLabel = \"\uC120\uD0DD\uC548\uD568\",\r\n readOnly = false,\r\n showEmptyOption = true,\r\n fullWidth = true,\r\n size,\r\n formControlProps,\r\n form,\r\n ...selectProps\r\n },\r\n ref,\r\n ) {\r\n const generatedId = useId();\r\n const selectId = selectProps.id ?? `label-select-${generatedId}`;\r\n const labelId = showLabel ? `${selectId}-label` : undefined;\r\n\r\n const hasValue = value !== undefined && value !== null && value !== \"\";\r\n const safeValue =\r\n hasValue && options.some((option) => option.value === value)\r\n ? value\r\n : \"\";\r\n const [isFocused, setIsFocused] = useState(false);\r\n const shouldNotch = showLabel && (safeValue !== \"\" || isFocused);\r\n const displayEmptyValue = showEmptyOption && !showLabel;\r\n\r\n const handleFocus = useCallback(\r\n (event: React.FocusEvent<HTMLInputElement>) => {\r\n setIsFocused(true);\r\n selectProps.onFocus?.(event);\r\n },\r\n [selectProps],\r\n );\r\n\r\n const handleBlur = useCallback(\r\n (event: React.FocusEvent<HTMLInputElement>) => {\r\n setIsFocused(false);\r\n selectProps.onBlur?.(event);\r\n },\r\n [selectProps],\r\n );\r\n\r\n const handleSelectWheel = useCallback(\r\n (event: React.WheelEvent) => {\r\n if (!enableWheel || readOnly) return;\r\n event.stopPropagation();\r\n\r\n const optionValues = [\r\n \"\",\r\n ...options.map((option) => option.value),\r\n ];\r\n const currentIndex = optionValues.indexOf(safeValue);\r\n if (currentIndex === -1) return;\r\n\r\n const nextIndex =\r\n event.deltaY > 0\r\n ? Math.min(currentIndex + 1, optionValues.length - 1)\r\n : Math.max(currentIndex - 1, 0);\r\n\r\n if (nextIndex !== currentIndex && onChange) {\r\n const nextValue = optionValues[nextIndex];\r\n const syntheticEvent = {\r\n target: {\r\n value: nextValue,\r\n name: selectProps.name ?? \"\",\r\n },\r\n } as SelectChangeEvent<string | number>;\r\n onChange(syntheticEvent);\r\n }\r\n },\r\n [enableWheel, readOnly, options, safeValue, onChange, selectProps],\r\n );\r\n\r\n return (\r\n <FormControl\r\n ref={ref}\r\n fullWidth={fullWidth}\r\n size={size}\r\n {...formControlProps}\r\n sx={{\r\n flex: fullWidth ? 1 : undefined,\r\n minWidth: 0,\r\n width: fullWidth ? \"100%\" : undefined,\r\n ...formControlProps?.sx,\r\n }}\r\n >\r\n {showLabel && (\r\n <InputLabel id={labelId} size={size}>\r\n {label}\r\n </InputLabel>\r\n )}\r\n <Select\r\n {...selectProps}\r\n id={selectId}\r\n labelId={labelId}\r\n value={safeValue}\r\n onChange={onChange}\r\n fullWidth={fullWidth}\r\n size={size}\r\n label={showLabel ? label : undefined}\r\n notched={shouldNotch}\r\n inputProps={{\r\n ...inputProps,\r\n readOnly,\r\n }}\r\n onWheel={handleSelectWheel}\r\n onFocus={handleFocus}\r\n onBlur={handleBlur}\r\n displayEmpty={displayEmptyValue}\r\n sx={{\r\n width: fullWidth ? \"100%\" : undefined,\r\n minWidth: 0,\r\n \"& .MuiSelect-select\": {\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n },\r\n ...(readOnly && {\r\n pointerEvents: \"none\",\r\n \"&.Mui-focused .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiSelect-icon\": {\r\n display: \"none\",\r\n },\r\n }),\r\n ...selectProps.sx,\r\n }}\r\n renderValue={(selected) => {\r\n if (selected === \"\") {\r\n return \"\";\r\n }\r\n const option = options.find(\r\n (opt) => opt.value === selected,\r\n );\r\n return (\r\n <span\r\n style={{\r\n display: \"block\",\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n }}\r\n >\r\n {option ? option.label : selected}\r\n </span>\r\n );\r\n }}\r\n >\r\n {showEmptyOption && (\r\n <MenuItem value=\"\">{emptyLabel}</MenuItem>\r\n )}\r\n {options.map((option) => (\r\n <MenuItem\r\n key={String(option.value)}\r\n value={option.value as string | number}\r\n >\r\n {option.label}\r\n </MenuItem>\r\n ))}\r\n </Select>\r\n </FormControl>\r\n );\r\n },\r\n);\r\n\r\nconst LabelSelectWithForm = forwardRef<HTMLDivElement, LabelSelectProps>(\r\n function LabelSelectWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"LabelSelect form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"LabelSelect requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name) as\r\n | string\r\n | number\r\n | undefined;\r\n const handleFormChange = useCallback(\r\n (event: SelectChangeEvent<string | number>) => {\r\n form.handleFormChange(\r\n event as React.ChangeEvent<HTMLInputElement>,\r\n );\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <LabelSelectBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const LabelSelect = forwardRef<HTMLDivElement, LabelSelectProps>(\r\n function LabelSelect(props, ref) {\r\n if (props.form) {\r\n return <LabelSelectWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <LabelSelectBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * PhoneTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n useRef,\r\n ChangeEvent,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport type { PhoneTextFieldProps } from \"./types\";\r\nimport { useDebouncedEmit } from \"./hooks\";\r\nimport { formatPhoneNumber, getPhoneMaxLength } from \"./utils\";\r\n\r\nconst PhoneTextFieldBase = forwardRef<HTMLDivElement, PhoneTextFieldProps>(\r\n function PhoneTextFieldBase(\r\n {\r\n label,\r\n autoFormat = true,\r\n includeDash = false,\r\n prefix,\r\n format,\r\n onValidationChange,\r\n invalidBorderColor,\r\n debounce,\r\n readonly,\r\n slotProps,\r\n sx,\r\n value,\r\n onChange,\r\n onBlur,\r\n inputRef: externalInputRef,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n const [displayValue, setDisplayValue] = useState(\"\");\r\n const [prevNumbers, setPrevNumbers] = useState(\"\");\r\n const [currentMaxLength, setCurrentMaxLength] = useState(13);\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n const cursorPositionRef = useRef<number | null>(null);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLInputElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange, flushOnBlur, lastEmittedValue } = useDebouncedEmit({\r\n name: props.name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n // prefix \uD3EC\uB9F7\uD305 (\uC608: \"010\" -> \"010-\")\r\n const prefixFormatted = prefix ? `${prefix}-` : \"\";\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uC218\uD589\r\n const performValidation = useCallback(\r\n (inputValue: string) => {\r\n const numbers = inputValue.replace(/\\D/g, \"\");\r\n // \uCD5C\uC18C \uAE38\uC774 \uD310\uB2E8\r\n let minLength = 10;\r\n if (/^1[0-9]{3}/.test(numbers)) {\r\n minLength = 8; // \uC804\uAD6D\uB300\uD45C\uBC88\uD638\r\n } else if (numbers.startsWith(\"02\")) {\r\n minLength = 9; // \uC11C\uC6B8\r\n }\r\n\r\n const isComplete = numbers.length >= minLength;\r\n setIsInvalid(isComplete && numbers.length < minLength);\r\n\r\n if (onValidationChange) {\r\n onValidationChange(isComplete);\r\n }\r\n },\r\n [onValidationChange],\r\n );\r\n\r\n // value \uBCC0\uACBD \uC2DC \uC720\uD6A8\uC131 \uAC80\uC0AC \uBC0F displayValue \uC5C5\uB370\uC774\uD2B8 (\uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uACBD\uC6B0\uB9CC)\r\n useEffect(() => {\r\n if (value !== undefined && value !== null) {\r\n const strValue = String(value);\r\n\r\n if (prefix && strValue === \"\") {\r\n if (lastEmittedValue.current !== prefix) {\r\n setDisplayValue(prefixFormatted);\r\n setPrevNumbers(prefix);\r\n lastEmittedValue.current = prefix;\r\n setCurrentMaxLength(getPhoneMaxLength(prefix));\r\n performValidation(prefixFormatted);\r\n }\r\n return;\r\n }\r\n\r\n // \uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uAC12\uC774 \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uD55C \uAC12\uACFC \uB2E4\uB97C \uB54C\uB9CC \uB3D9\uAE30\uD654\r\n if (strValue === lastEmittedValue.current) {\r\n return;\r\n }\r\n\r\n // format\uC774 \uC9C0\uC815\uB418\uC5B4 \uC788\uC73C\uBA74 \uD574\uB2F9 format \uC0AC\uC6A9\r\n let formattedValue = autoFormat\r\n ? formatPhoneNumber(strValue, format)\r\n : strValue;\r\n\r\n // prefix\uAC00 \uC788\uACE0 \uAC12\uC774 \uBE44\uC5B4\uC788\uC73C\uBA74 prefix\uB85C \uCD08\uAE30\uD654\r\n if (prefix && !formattedValue) {\r\n formattedValue = prefixFormatted;\r\n }\r\n // prefix\uAC00 \uC788\uC73C\uBA74 \uD56D\uC0C1 prefix\uB85C \uC2DC\uC791\uD558\uB3C4\uB85D\r\n if (\r\n prefix &&\r\n formattedValue &&\r\n !formattedValue.startsWith(prefixFormatted)\r\n ) {\r\n formattedValue =\r\n prefixFormatted +\r\n formattedValue.replace(/^\\d{3}-?/, \"\");\r\n }\r\n\r\n setDisplayValue(formattedValue);\r\n setPrevNumbers(strValue.replace(/\\D/g, \"\"));\r\n lastEmittedValue.current = strValue;\r\n\r\n // maxLength \uC5C5\uB370\uC774\uD2B8\r\n const numbers = strValue.replace(/\\D/g, \"\");\r\n setCurrentMaxLength(getPhoneMaxLength(numbers));\r\n\r\n performValidation(formattedValue);\r\n } else if (prefix) {\r\n // value\uAC00 \uC5C6\uC73C\uBA74 prefix\uB85C \uCD08\uAE30\uD654\r\n if (lastEmittedValue.current !== prefix) {\r\n setDisplayValue(prefixFormatted);\r\n setPrevNumbers(prefix);\r\n lastEmittedValue.current = prefix;\r\n }\r\n } else {\r\n if (lastEmittedValue.current !== \"\") {\r\n setDisplayValue(\"\");\r\n setPrevNumbers(\"\");\r\n lastEmittedValue.current = \"\";\r\n }\r\n }\r\n }, [\r\n value,\r\n autoFormat,\r\n prefix,\r\n prefixFormatted,\r\n performValidation,\r\n format,\r\n lastEmittedValue,\r\n ]);\r\n\r\n // \uCEE4\uC11C \uC704\uCE58 \uBCF5\uC6D0 effect\r\n useEffect(() => {\r\n if (\r\n cursorPositionRef.current !== null &&\r\n internalInputRef.current\r\n ) {\r\n const pos = cursorPositionRef.current;\r\n internalInputRef.current.setSelectionRange(pos, pos);\r\n cursorPositionRef.current = null;\r\n }\r\n }, [displayValue]);\r\n\r\n // \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\r\n const newValue = e.target.value;\r\n const newNumbers = newValue.replace(/\\D/g, \"\");\r\n const cursorPos = e.target.selectionStart ?? newValue.length;\r\n\r\n // prefix\uAC00 \uC788\uC744 \uB54C prefix \uC0AD\uC81C \uBC29\uC9C0\r\n if (prefix) {\r\n const prefixNumbers = prefix.replace(/\\D/g, \"\");\r\n // prefix\uBCF4\uB2E4 \uC9E7\uC544\uC9C0\uB824\uACE0 \uD558\uBA74 \uBB34\uC2DC (prefix \uC22B\uC790\uB97C \uC9C0\uC6B0\uB824\uACE0 \uD560 \uB54C)\r\n if (newNumbers.length < prefixNumbers.length) {\r\n // \uCEE4\uC11C \uC704\uCE58 \uC720\uC9C0 - \uBC31\uC2A4\uD398\uC774\uC2A4 \uC804 \uC704\uCE58\uB85C \uBCF5\uC6D0\r\n requestAnimationFrame(() => {\r\n const originalPos = cursorPos + 1;\r\n internalInputRef.current?.setSelectionRange(\r\n originalPos,\r\n originalPos,\r\n );\r\n });\r\n return;\r\n }\r\n // prefix\uAC00 \uC544\uB2CC \uB2E4\uB978 \uBC88\uD638\uB85C \uC2DC\uC791\uD558\uBA74 prefix \uC720\uC9C0\r\n if (!newNumbers.startsWith(prefixNumbers)) {\r\n // \uCEE4\uC11C \uC704\uCE58 \uC720\uC9C0 - \uBC31\uC2A4\uD398\uC774\uC2A4 \uC804 \uC704\uCE58\uB85C \uBCF5\uC6D0\r\n requestAnimationFrame(() => {\r\n const originalPos = cursorPos + 1;\r\n internalInputRef.current?.setSelectionRange(\r\n originalPos,\r\n originalPos,\r\n );\r\n });\r\n return;\r\n }\r\n // prefix + dash \uC0AD\uC81C \uBC29\uC9C0: \"010-\" \uC0C1\uD0DC\uC5D0\uC11C \uBC31\uC2A4\uD398\uC774\uC2A4 \uC2DC \uBB34\uC2DC\r\n if (\r\n newNumbers.length === prefixNumbers.length &&\r\n !newValue.endsWith(\"-\")\r\n ) {\r\n // dash\uAC00 \uC9C0\uC6CC\uC84C\uC73C\uBA74 \uB2E4\uC2DC \uCD94\uAC00, \uCEE4\uC11C\uB294 \uBC31\uC2A4\uD398\uC774\uC2A4 \uC804 \uC704\uCE58 (dash \uB4A4 = prefixFormatted.length)\r\n setDisplayValue(prefixFormatted);\r\n requestAnimationFrame(() => {\r\n const originalPos = prefixFormatted.length;\r\n internalInputRef.current?.setSelectionRange(\r\n originalPos,\r\n originalPos,\r\n );\r\n });\r\n return;\r\n }\r\n }\r\n\r\n // \uBC31\uC2A4\uD398\uC774\uC2A4 \uAC10\uC9C0\r\n const isBackspace =\r\n newNumbers.length <= prevNumbers.length &&\r\n newValue.length < displayValue.length;\r\n\r\n let formattedValue: string;\r\n let deletedDigitIndex = -1;\r\n let prefixProtected = false; // prefix \uC601\uC5ED \uBCF4\uD638 \uC5EC\uBD80\r\n\r\n if (autoFormat) {\r\n if (isBackspace && newNumbers.length === prevNumbers.length) {\r\n // dash\uB9CC \uC0AD\uC81C\uB41C \uACBD\uC6B0: \uC22B\uC790\uB3C4 \uD558\uB098 \uC0AD\uC81C\r\n // \uCEE4\uC11C \uC704\uCE58 \uAE30\uC900\uC73C\uB85C \uC0AD\uC81C\uD560 \uC22B\uC790 \uC704\uCE58 \uACC4\uC0B0\r\n const numbersBeforeCursor = newValue\r\n .slice(0, cursorPos)\r\n .replace(/\\D/g, \"\").length;\r\n deletedDigitIndex =\r\n numbersBeforeCursor > 0 ? numbersBeforeCursor - 1 : 0;\r\n\r\n let trimmedNumbers: string;\r\n if (prefix) {\r\n const prefixNumbers = prefix.replace(/\\D/g, \"\");\r\n if (deletedDigitIndex < prefixNumbers.length) {\r\n // prefix \uC601\uC5ED\uC774\uBA74 \uC0AD\uC81C\uD558\uC9C0 \uC54A\uC74C\r\n trimmedNumbers = newNumbers;\r\n prefixProtected = true; // prefix \uBCF4\uD638\uB428\r\n } else {\r\n // \uD574\uB2F9 \uC704\uCE58\uC758 \uC22B\uC790 \uC0AD\uC81C\r\n trimmedNumbers =\r\n newNumbers.slice(0, deletedDigitIndex) +\r\n newNumbers.slice(deletedDigitIndex + 1);\r\n if (trimmedNumbers.length < prefixNumbers.length) {\r\n trimmedNumbers = prefix;\r\n }\r\n }\r\n } else {\r\n // prefix \uC5C6\uB294 \uACBD\uC6B0\r\n trimmedNumbers =\r\n newNumbers.slice(0, deletedDigitIndex) +\r\n newNumbers.slice(deletedDigitIndex + 1);\r\n }\r\n formattedValue = formatPhoneNumber(trimmedNumbers, format);\r\n } else {\r\n formattedValue = formatPhoneNumber(newValue, format);\r\n }\r\n } else {\r\n formattedValue = newValue;\r\n }\r\n\r\n // \uCEE4\uC11C \uC704\uCE58 \uACC4\uC0B0\r\n if (prefixProtected) {\r\n // prefix \uC601\uC5ED\uC774 \uBCF4\uD638\uB41C \uACBD\uC6B0: \uCEE4\uC11C\uB97C prefix \uBC14\uB85C \uB4A4\uB85C (dash \uB4A4)\r\n // formattedValue\uAC00 displayValue\uC640 \uAC19\uC73C\uBA74 useEffect\uAC00 \uD2B8\uB9AC\uAC70\uB418\uC9C0 \uC54A\uC73C\uBBC0\uB85C \uC9C1\uC811 \uC124\uC815\r\n if (formattedValue === displayValue) {\r\n requestAnimationFrame(() => {\r\n internalInputRef.current?.setSelectionRange(\r\n prefixFormatted.length,\r\n prefixFormatted.length,\r\n );\r\n });\r\n } else {\r\n cursorPositionRef.current = prefixFormatted.length;\r\n }\r\n } else if (isBackspace) {\r\n // \uBC31\uC2A4\uD398\uC774\uC2A4\uC778 \uACBD\uC6B0: \uC0AD\uC81C\uB41C \uC22B\uC790 \uC704\uCE58 \uAE30\uC900\uC73C\uB85C \uCEE4\uC11C \uC704\uCE58 \uACC4\uC0B0\r\n if (deletedDigitIndex >= 0) {\r\n // \uC0AD\uC81C\uB41C \uC22B\uC790 \uC55E\uC758 \uC22B\uC790 \uAC1C\uC218\uB97C \uAE30\uC900\uC73C\uB85C \uD3EC\uB9F7\uB41C \uBB38\uC790\uC5F4\uC5D0\uC11C \uC704\uCE58 \uCC3E\uAE30\r\n let targetPos = 0;\r\n let digitCount = 0;\r\n for (let i = 0; i < formattedValue.length; i++) {\r\n if (digitCount === deletedDigitIndex) {\r\n targetPos = i;\r\n break;\r\n }\r\n if (/\\d/.test(formattedValue[i])) {\r\n digitCount++;\r\n }\r\n targetPos = i + 1;\r\n }\r\n cursorPositionRef.current = targetPos;\r\n } else {\r\n // \uC77C\uBC18 \uBC31\uC2A4\uD398\uC774\uC2A4: \uCEE4\uC11C \uC704\uCE58 \uAE30\uC900\uC73C\uB85C \uACC4\uC0B0\r\n const numbersBeforeCursor = newValue\r\n .slice(0, cursorPos)\r\n .replace(/\\D/g, \"\").length;\r\n let targetPos = 0;\r\n let digitCount = 0;\r\n for (\r\n let i = 0;\r\n i < formattedValue.length &&\r\n digitCount < numbersBeforeCursor;\r\n i++\r\n ) {\r\n if (/\\d/.test(formattedValue[i])) {\r\n digitCount++;\r\n }\r\n targetPos = i + 1;\r\n }\r\n // \uC785\uB825 \uB05D\uC5D0\uC11C \uBC31\uC2A4\uD398\uC774\uC2A4: \uC22B\uC790 \uAC1C\uC218\uB9CC \uB9DE\uCD94\uBA74 \uB300\uC2DC(-) \uC55E(targetPos\uAC00 \uAD6C\uBD84\uC790 \uC778\uB371\uC2A4)\uC5D0\r\n // \uCEE4\uC11C\uAC00 \uC11C\uB294 \uACBD\uC6B0\uAC00 \uC788\uC5B4, \uB05D\uC774\uBA74 \uD3EC\uB9F7 \uBB38\uC790\uC5F4 \uB05D\uC73C\uB85C \uB9DE\uCDA4 (\uC608: \"010-\" \u2192 4)\r\n if (cursorPos === newValue.length) {\r\n targetPos = formattedValue.length;\r\n }\r\n cursorPositionRef.current = targetPos;\r\n }\r\n } else {\r\n // \uC785\uB825\uC778 \uACBD\uC6B0: \uCEE4\uC11C \uC704\uCE58 \uC55E\uC758 \uC22B\uC790 \uAC1C\uC218 \uAE30\uC900\uC73C\uB85C \uACC4\uC0B0\r\n const numbersBeforeCursor = newValue\r\n .slice(0, cursorPos)\r\n .replace(/\\D/g, \"\").length;\r\n let targetPos = 0;\r\n let digitCount = 0;\r\n for (let i = 0; i < formattedValue.length; i++) {\r\n if (/\\d/.test(formattedValue[i])) {\r\n digitCount++;\r\n }\r\n if (digitCount === numbersBeforeCursor) {\r\n targetPos = i + 1;\r\n break;\r\n }\r\n }\r\n cursorPositionRef.current = targetPos;\r\n }\r\n\r\n setDisplayValue(formattedValue);\r\n const currentNumbers = formattedValue.replace(/\\D/g, \"\");\r\n setPrevNumbers(currentNumbers);\r\n\r\n // maxLength \uB3D9\uC801 \uC5C5\uB370\uC774\uD2B8\r\n setCurrentMaxLength(getPhoneMaxLength(currentNumbers));\r\n\r\n // onChange\uB85C \uC804\uB2EC\uD560 \uAC12\r\n const outputValue = includeDash\r\n ? formattedValue\r\n : formattedValue.replace(/-/g, \"\");\r\n\r\n // \uB514\uBC14\uC6B4\uC2A4 \uC801\uC6A9\r\n emitChange(e, outputValue);\r\n };\r\n\r\n // blur \uC2DC \uB300\uAE30 \uC911\uC778 \uB514\uBC14\uC6B4\uC2A4 \uC989\uC2DC \uC2E4\uD589\r\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\r\n const outputValue = includeDash\r\n ? displayValue\r\n : displayValue.replace(/-/g, \"\");\r\n flushOnBlur(e, outputValue);\r\n if (onBlur) {\r\n onBlur(e);\r\n }\r\n };\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uC2E4\uD328 \uC2DC \uD14C\uB450\uB9AC \uC2A4\uD0C0\uC77C (invalidBorderColor\uAC00 \uC124\uC815\uB41C \uACBD\uC6B0\uC5D0\uB9CC)\r\n const invalidStyles: SxProps<Theme> =\r\n isInvalid && invalidBorderColor\r\n ? {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n \"&:hover fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n \"&.Mui-focused fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n },\r\n \"& .MuiFilledInput-root\": {\r\n \"&:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:hover:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:after\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n },\r\n \"& .MuiInput-root\": {\r\n \"&:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:hover:before\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n \"&:after\": {\r\n borderBottomColor: invalidBorderColor,\r\n },\r\n },\r\n }\r\n : {};\r\n\r\n // readonly\uC77C \uB54C \uD3EC\uCEE4\uC2A4 \uC2A4\uD0C0\uC77C \uC81C\uAC70\r\n const readonlyStyles = readonly\r\n ? {\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n return (\r\n <TextField\r\n {...props}\r\n ref={ref}\r\n inputRef={internalInputRef}\r\n value={displayValue}\r\n label={label}\r\n type=\"tel\"\r\n onChange={handleChange}\r\n onBlur={handleBlur}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n sx={{\r\n ...invalidStyles,\r\n ...readonlyStyles,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...sx,\r\n }}\r\n slotProps={{\r\n ...slotProps,\r\n input: {\r\n ...slotProps?.input,\r\n readOnly: readonly,\r\n },\r\n htmlInput: {\r\n ...slotProps?.htmlInput,\r\n maxLength: currentMaxLength,\r\n },\r\n }}\r\n />\r\n );\r\n },\r\n);\r\n\r\nconst PhoneTextFieldWithForm = forwardRef<HTMLDivElement, PhoneTextFieldProps>(\r\n function PhoneTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"PhoneTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"PhoneTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <PhoneTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const PhoneTextField = forwardRef<HTMLDivElement, PhoneTextFieldProps>(\r\n function PhoneTextField(props, ref) {\r\n if (props.form) {\r\n return <PhoneTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <PhoneTextFieldBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * AddressTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport {\r\n IconButton,\r\n InputAdornment,\r\n TextField,\r\n Dialog,\r\n DialogContent,\r\n DialogTitle,\r\n} from \"@mui/material\";\r\nimport SearchIcon from \"@mui/icons-material/Search\";\r\nimport CloseIcon from \"@mui/icons-material/Close\";\r\nimport {\r\n useState,\r\n useEffect,\r\n type ChangeEvent,\r\n useCallback,\r\n forwardRef,\r\n useRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport DaumPostcode from \"react-daum-postcode\";\r\nimport type { AddressTextFieldProps, DaumPostcodeData } from \"./types\";\r\nimport { useDebouncedEmit } from \"./hooks\";\r\n\r\nconst AddressTextFieldBase = forwardRef<HTMLDivElement, AddressTextFieldProps>(\r\n function AddressTextFieldBase(\r\n {\r\n value,\r\n onChange,\r\n readonly,\r\n debounce,\r\n onBlur,\r\n size,\r\n spellCheck = false,\r\n inputRef: externalInputRef,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLInputElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n const [address, setAddress] = useState<string>(\r\n typeof value === \"string\" ? value : \"\",\r\n );\r\n const [isPostcodeOpen, setIsPostcodeOpen] = useState(false);\r\n\r\n // size\uC5D0 \uB530\uB978 \uC544\uC774\uCF58 \uD06C\uAE30\r\n const iconSize = size === \"small\" ? 20 : 24;\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange, flushOnBlur, lastEmittedValue } = useDebouncedEmit({\r\n name: props.name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n // value prop\uC774 \uBCC0\uACBD\uB420 \uB54C \uB0B4\uBD80 state \uC5C5\uB370\uC774\uD2B8 (\uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uACBD\uC6B0\uB9CC)\r\n useEffect(() => {\r\n if (value !== undefined && value !== null) {\r\n const strValue = String(value);\r\n // \uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uAC12\uC774 \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uD55C \uAC12\uACFC \uB2E4\uB97C \uB54C\uB9CC \uB3D9\uAE30\uD654\r\n if (strValue !== lastEmittedValue.current) {\r\n setAddress(strValue);\r\n lastEmittedValue.current = strValue;\r\n }\r\n } else if (lastEmittedValue.current !== \"\") {\r\n setAddress(\"\");\r\n lastEmittedValue.current = \"\";\r\n }\r\n }, [value, lastEmittedValue]);\r\n\r\n const handlePostcodeComplete = (data: DaumPostcodeData) => {\r\n let fullAddress = data.address;\r\n let extraAddress = \"\";\r\n\r\n // \uC0AC\uC6A9\uC790\uAC00 \uC120\uD0DD\uD55C \uC8FC\uC18C \uD0C0\uC785\uC5D0 \uB530\uB77C \uD574\uB2F9 \uC8FC\uC18C \uAC12\uC744 \uAC00\uC838\uC628\uB2E4.\r\n if (data.addressType === \"R\") {\r\n // \uB3C4\uB85C\uBA85 \uC8FC\uC18C\uB97C \uC120\uD0DD\uD588\uC744 \uACBD\uC6B0\r\n if (data.bname !== \"\" && /[\uB3D9|\uB85C|\uAC00]$/g.test(data.bname)) {\r\n extraAddress += data.bname;\r\n }\r\n if (data.buildingName !== \"\" && data.apartment === \"Y\") {\r\n extraAddress +=\r\n extraAddress !== \"\"\r\n ? \", \" + data.buildingName\r\n : data.buildingName;\r\n }\r\n if (extraAddress !== \"\") {\r\n extraAddress = \" (\" + extraAddress + \")\";\r\n }\r\n fullAddress += extraAddress;\r\n }\r\n\r\n // \uC8FC\uC18C \uC124\uC815\r\n setAddress(fullAddress);\r\n\r\n // \uC8FC\uC18C \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uBC1C\uC0DD (\uD31D\uC5C5 \uC120\uD0DD\uC740 \uC989\uC2DC \uD638\uCD9C)\r\n emitChange(null, fullAddress, true);\r\n\r\n // \uD31D\uC5C5 \uB2EB\uAE30\r\n setIsPostcodeOpen(false);\r\n };\r\n\r\n const handleSearchButtonClick = () => {\r\n setIsPostcodeOpen(true);\r\n };\r\n\r\n const handleKeyDown = (\r\n event: React.KeyboardEvent<HTMLInputElement>,\r\n ) => {\r\n if (event.key === \"Enter\") {\r\n event.preventDefault();\r\n handleSearchButtonClick();\r\n }\r\n };\r\n\r\n const handlePostcodeClose = () => {\r\n setIsPostcodeOpen(false);\r\n };\r\n\r\n const onClose = () => {\r\n setIsPostcodeOpen(false);\r\n emitChange(null, address as string, true);\r\n };\r\n\r\n // blur \uC2DC \uB300\uAE30 \uC911\uC778 \uB514\uBC14\uC6B4\uC2A4 \uC989\uC2DC \uC2E4\uD589\r\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\r\n flushOnBlur(e, address as string);\r\n if (onBlur) {\r\n onBlur(e);\r\n }\r\n };\r\n\r\n // readonly\uC77C \uB54C \uD3EC\uCEE4\uC2A4 \uC2A4\uD0C0\uC77C \uC81C\uAC70\r\n const readonlyStyles = readonly\r\n ? {\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n return (\r\n <>\r\n <TextField\r\n {...props}\r\n ref={ref}\r\n inputRef={internalInputRef}\r\n size={size}\r\n value={address}\r\n onChange={\r\n readonly\r\n ? undefined\r\n : (e) => {\r\n const newValue = e.target.value;\r\n setAddress(newValue);\r\n emitChange(\r\n e as ChangeEvent<HTMLInputElement>,\r\n newValue,\r\n );\r\n }\r\n }\r\n autoComplete=\"off\"\r\n spellCheck={spellCheck}\r\n onKeyDown={readonly ? undefined : handleKeyDown}\r\n onBlur={readonly ? undefined : handleBlur}\r\n sx={{\r\n ...readonlyStyles,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n }}\r\n slotProps={{\r\n ...props.slotProps,\r\n input: {\r\n ...props.slotProps?.input,\r\n readOnly: readonly,\r\n endAdornment: readonly ? undefined : (\r\n <InputAdornment\r\n position=\"end\"\r\n sx={{ mr: size === \"small\" ? -0.5 : 0.5 }}\r\n >\r\n <IconButton\r\n onClick={handleSearchButtonClick}\r\n edge=\"end\"\r\n aria-label=\"\uC8FC\uC18C \uCC3E\uAE30\"\r\n size={size}\r\n >\r\n <SearchIcon\r\n sx={{ fontSize: iconSize }}\r\n />\r\n </IconButton>\r\n </InputAdornment>\r\n ),\r\n },\r\n }}\r\n />\r\n\r\n <Dialog\r\n open={isPostcodeOpen}\r\n onClose={handlePostcodeClose}\r\n maxWidth=\"sm\"\r\n fullWidth\r\n slotProps={{\r\n paper: {\r\n sx: { height: \"550px\" },\r\n },\r\n }}\r\n >\r\n <DialogTitle\r\n sx={{\r\n display: \"flex\",\r\n justifyContent: \"space-between\",\r\n alignItems: \"center\",\r\n pr: 2,\r\n }}\r\n >\r\n \uC8FC\uC18C \uAC80\uC0C9\r\n <IconButton onClick={onClose} size=\"small\">\r\n <CloseIcon />\r\n </IconButton>\r\n </DialogTitle>\r\n <DialogContent style={{ padding: 0 }} dividers>\r\n <DaumPostcode\r\n onComplete={handlePostcodeComplete}\r\n onClose={handlePostcodeClose}\r\n defaultQuery={address as string}\r\n style={{\r\n width: \"100%\",\r\n height: \"100%\",\r\n }}\r\n />\r\n </DialogContent>\r\n </Dialog>\r\n </>\r\n );\r\n },\r\n);\r\n\r\nconst AddressTextFieldWithForm = forwardRef<\r\n HTMLDivElement,\r\n AddressTextFieldProps\r\n>(function AddressTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"AddressTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"AddressTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <AddressTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const AddressTextField = forwardRef<\r\n HTMLDivElement,\r\n AddressTextFieldProps\r\n>(function AddressTextField(props, ref) {\r\n if (props.form) {\r\n return <AddressTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <AddressTextFieldBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * NumberTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n ChangeEvent,\r\n forwardRef,\r\n useRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField, InputAdornment } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport type { NumberTextFieldProps } from \"./types\";\r\nimport { useDebouncedEmit } from \"./hooks\";\r\nimport { formatNumber, parseNumber } from \"./utils\";\r\n\r\nconst NumberTextFieldBase = forwardRef<HTMLDivElement, NumberTextFieldProps>(\r\n function NumberTextFieldBase(\r\n {\r\n label,\r\n thousandSeparator = true,\r\n decimalLength,\r\n decimalFixed = false,\r\n textAlign = \"right\",\r\n min = -2000000000,\r\n max = 2000000000,\r\n negative = false,\r\n negativeStyles,\r\n prefix,\r\n suffix,\r\n showSuffix = \"always\",\r\n selectOnFocus = true,\r\n debounce,\r\n readonly,\r\n slotProps,\r\n sx,\r\n value,\r\n onChange,\r\n onBlur,\r\n onFocus,\r\n inputRef: externalInputRef,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLInputElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n const [displayValue, setDisplayValue] = useState(\"\");\r\n const [isNegative, setIsNegative] = useState(false);\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange, flushOnBlur, lastEmittedValue } = useDebouncedEmit({\r\n name: props.name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n // value \uBCC0\uACBD \uC2DC displayValue \uC5C5\uB370\uC774\uD2B8 (\uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uACBD\uC6B0\uB9CC)\r\n useEffect(() => {\r\n if (value !== undefined && value !== null) {\r\n const strValue = String(value);\r\n\r\n // \uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uAC12\uC774 \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uD55C \uAC12\uACFC \uB2E4\uB97C \uB54C\uB9CC \uB3D9\uAE30\uD654\r\n if (strValue === lastEmittedValue.current) {\r\n return;\r\n }\r\n\r\n const formattedValue = formatNumber(\r\n strValue,\r\n thousandSeparator,\r\n decimalLength,\r\n );\r\n setDisplayValue(formattedValue);\r\n setIsNegative(\r\n strValue.startsWith(\"-\") || formattedValue.startsWith(\"-\"),\r\n );\r\n lastEmittedValue.current = strValue;\r\n } else {\r\n if (lastEmittedValue.current !== \"\") {\r\n setDisplayValue(\"\");\r\n setIsNegative(false);\r\n lastEmittedValue.current = \"\";\r\n }\r\n }\r\n }, [value, thousandSeparator, decimalLength, lastEmittedValue]);\r\n\r\n // \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleChange = useCallback(\r\n (e: ChangeEvent<HTMLInputElement>) => {\r\n let newValue = e.target.value;\r\n\r\n // \uC74C\uC218 \uD5C8\uC6A9 \uC5EC\uBD80\r\n if (!negative) {\r\n newValue = newValue.replace(/-/g, \"\");\r\n }\r\n\r\n // \uCF64\uB9C8 \uC81C\uAC70 \uD6C4 \uC22B\uC790, \uC18C\uC218\uC810, \uB9C8\uC774\uB108\uC2A4\uB9CC \uD5C8\uC6A9\r\n const withoutComma = newValue.replace(/,/g, \"\");\r\n if (!/^-?\\d*\\.?\\d*$/.test(withoutComma)) {\r\n return; // \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uBB38\uC790\uAC00 \uD3EC\uD568\uB41C \uACBD\uC6B0 \uBB34\uC2DC\r\n }\r\n\r\n // \uC810\uC73C\uB85C \uC2DC\uC791\uD558\uBA74 0. \uC73C\uB85C \uBCC0\uD658\r\n if (withoutComma === \".\") {\r\n newValue = \"0.\";\r\n } else if (withoutComma === \"-.\") {\r\n newValue = \"-0.\";\r\n } else if (withoutComma.startsWith(\".\")) {\r\n newValue = \"0\" + withoutComma;\r\n } else if (withoutComma.startsWith(\"-.\")) {\r\n newValue = \"-0\" + withoutComma.slice(1);\r\n }\r\n\r\n // max \uCD08\uACFC \uAC80\uC99D (\uC785\uB825 \uC911) - max\uB85C \uBCC0\uD658\r\n const numValue = parseFloat(withoutComma);\r\n if (!isNaN(numValue) && max !== undefined && numValue > max) {\r\n const maxFormatted = formatNumber(\r\n String(max),\r\n thousandSeparator,\r\n decimalLength,\r\n );\r\n setDisplayValue(maxFormatted);\r\n setIsNegative(false);\r\n\r\n const emitValue = String(max);\r\n emitChange(e, emitValue);\r\n return;\r\n }\r\n\r\n // min \uBBF8\uB9CC \uAC80\uC99D (\uC785\uB825 \uC911, \uC74C\uC218 \uD5C8\uC6A9 \uC2DC) - min\uC73C\uB85C \uBCC0\uD658\r\n if (!isNaN(numValue) && min !== undefined && numValue < min) {\r\n const minFormatted = formatNumber(\r\n String(min),\r\n thousandSeparator,\r\n decimalLength,\r\n );\r\n setDisplayValue(minFormatted);\r\n setIsNegative(min < 0);\r\n\r\n const emitValue = String(min);\r\n emitChange(e, emitValue);\r\n return;\r\n }\r\n\r\n const formattedValue = formatNumber(\r\n newValue,\r\n thousandSeparator,\r\n decimalLength,\r\n );\r\n setDisplayValue(formattedValue);\r\n setIsNegative(formattedValue.startsWith(\"-\"));\r\n\r\n // onChange\uB85C \uC804\uB2EC\uD560 \uAC12\uC740 \uCF64\uB9C8 \uC81C\uAC70\uB41C \uC2E4\uC81C \uC22B\uC790\r\n const numericValue = parseNumber(formattedValue);\r\n\r\n emitChange(e, numericValue);\r\n },\r\n [thousandSeparator, decimalLength, negative, max, min, emitChange],\r\n );\r\n\r\n // blur \uC2DC min/max \uAC80\uC99D \uBC0F decimalFixed \uC801\uC6A9\r\n const handleBlur = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>) => {\r\n // \uB514\uBC14\uC6B4\uC2A4 \uC989\uC2DC \uC2E4\uD589\r\n const numericValue = parseNumber(displayValue);\r\n flushOnBlur(e, numericValue);\r\n\r\n let num = parseFloat(numericValue);\r\n\r\n // \uAC12\uC774 \uC5C6\uC73C\uBA74 decimalFixed \uC801\uC6A9 \uC548\uD568\r\n if (displayValue === \"\" || displayValue === \"-\") {\r\n if (onBlur) {\r\n onBlur(e);\r\n }\r\n return;\r\n }\r\n\r\n if (!isNaN(num)) {\r\n // min/max \uAC80\uC99D\r\n if (min !== undefined && num < min) {\r\n num = min;\r\n }\r\n if (max !== undefined && num > max) {\r\n num = max;\r\n }\r\n\r\n // \uC18C\uC218\uC810 \uAE38\uC774 \uB9DE\uCD94\uAE30 (decimalFixed \uB610\uB294 decimalLength)\r\n let finalValue: string;\r\n if (decimalFixed && decimalLength !== undefined) {\r\n finalValue = num.toFixed(decimalLength);\r\n } else if (decimalLength !== undefined) {\r\n // decimalLength\uB9CC \uC788\uC744 \uB54C\uB294 \uCD08\uACFC\uBD84\uB9CC \uC790\uB974\uACE0 \uACE0\uC815\uD558\uC9C0 \uC54A\uC74C\r\n finalValue = String(num);\r\n } else {\r\n finalValue = String(num);\r\n }\r\n\r\n const formattedValue = formatNumber(\r\n finalValue,\r\n thousandSeparator,\r\n decimalLength,\r\n );\r\n setDisplayValue(formattedValue);\r\n\r\n // onChange \uD638\uCD9C (\uAC12\uC774 \uBCC0\uACBD\uB418\uC5C8\uC744 \uB54C\uB9CC)\r\n if (finalValue !== lastEmittedValue.current) {\r\n emitChange(e, finalValue, true);\r\n }\r\n }\r\n\r\n if (onBlur) {\r\n onBlur(e);\r\n }\r\n },\r\n [\r\n displayValue,\r\n min,\r\n max,\r\n decimalLength,\r\n decimalFixed,\r\n thousandSeparator,\r\n flushOnBlur,\r\n emitChange,\r\n lastEmittedValue,\r\n onBlur,\r\n ],\r\n );\r\n\r\n // \uD14D\uC2A4\uD2B8 \uC815\uB82C \uBC0F \uC74C\uC218 \uC2A4\uD0C0\uC77C\r\n const inputStyles: SxProps<Theme> = {\r\n \"& .MuiInputBase-input\": {\r\n textAlign: textAlign,\r\n ...(isNegative && negativeStyles ? negativeStyles : {}),\r\n },\r\n };\r\n\r\n // \uD3EC\uCEE4\uC2A4 \uD578\uB4E4\uB7EC (selectOnFocus)\r\n const handleFocus = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>) => {\r\n if (selectOnFocus) {\r\n e.target.select();\r\n }\r\n if (onFocus) {\r\n onFocus(e);\r\n }\r\n },\r\n [selectOnFocus, onFocus],\r\n );\r\n\r\n // readonly\uC77C \uB54C \uD3EC\uCEE4\uC2A4 \uC2A4\uD0C0\uC77C \uC81C\uAC70\r\n const readonlyStyles = readonly\r\n ? {\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n return (\r\n <TextField\r\n {...props}\r\n ref={ref}\r\n inputRef={internalInputRef}\r\n value={displayValue}\r\n label={label}\r\n onChange={handleChange}\r\n onBlur={handleBlur}\r\n onFocus={handleFocus}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n sx={{\r\n ...inputStyles,\r\n ...readonlyStyles,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...(props.fullWidth && { minWidth: 0 }),\r\n ...sx,\r\n }}\r\n slotProps={{\r\n ...slotProps,\r\n input: {\r\n ...slotProps?.input,\r\n readOnly: readonly,\r\n startAdornment: prefix ? (\r\n <InputAdornment position=\"start\">\r\n {prefix}\r\n </InputAdornment>\r\n ) : undefined,\r\n endAdornment:\r\n suffix &&\r\n (showSuffix === \"always\" || displayValue) ? (\r\n <InputAdornment position=\"end\">\r\n {suffix}\r\n </InputAdornment>\r\n ) : undefined,\r\n },\r\n htmlInput: {\r\n ...slotProps?.htmlInput,\r\n inputMode: \"decimal\",\r\n },\r\n }}\r\n />\r\n );\r\n },\r\n);\r\n\r\nconst NumberTextFieldWithForm = forwardRef<\r\n HTMLDivElement,\r\n NumberTextFieldProps\r\n>(function NumberTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"NumberTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"NumberTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <NumberTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const NumberTextField = forwardRef<HTMLDivElement, NumberTextFieldProps>(\r\n function NumberTextField(props, ref) {\r\n if (props.form) {\r\n return <NumberTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <NumberTextFieldBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * JuminTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n useRef,\r\n useMemo,\r\n ChangeEvent,\r\n KeyboardEvent,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField, Box } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport { GroupedInputWrapper } from \"./components\";\r\nimport type { JuminInfo, JuminTextFieldProps } from \"./types\";\r\nimport { DashIcon } from \"./icons\";\r\nimport {\r\n extractJuminInfo,\r\n validateJuminChecksum,\r\n validateJuminBirthDate,\r\n} from \"./utils\";\r\n\r\nconst JuminTextFieldBase = forwardRef<HTMLDivElement, JuminTextFieldProps>(\r\n function JuminTextFieldBase(\r\n {\r\n label,\r\n mask = true,\r\n maskColor = \"rgba(0, 0, 0, 0.7)\",\r\n validateChecksum = true,\r\n fontSize,\r\n fontColor,\r\n fontFamily,\r\n onChange,\r\n onValidationChange,\r\n invalidBorderColor,\r\n debounce,\r\n readonly,\r\n sx,\r\n value,\r\n size,\r\n disabled,\r\n fullWidth = false,\r\n className,\r\n id,\r\n ...props\r\n },\r\n ref,\r\n ) {\r\n const [frontValue, setFrontValue] = useState(\"\"); // \uC55E 6\uC790\uB9AC\r\n const [backValue, setBackValue] = useState(\"\"); // \uB4A4 7\uC790\uB9AC (\uC2E4\uC81C \uAC12)\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n const [isInternalChange, setIsInternalChange] = useState(false); // \uB0B4\uBD80 \uBCC0\uACBD \uD50C\uB798\uADF8\r\n const [focusedField, setFocusedField] = useState<\r\n \"front\" | \"back\" | null\r\n >(null);\r\n const [cursorVisible, setCursorVisible] = useState(false); // \uCEE4\uC11C \uD45C\uC2DC \uC5EC\uBD80\r\n const [renderTrigger, setRenderTrigger] = useState(0); // \uB80C\uB354\uB9C1 \uD2B8\uB9AC\uAC70\r\n const [backComplete, setBackComplete] = useState(false); // \uB4B7\uC790\uB9AC \uC785\uB825 \uC644\uB8CC (\uCEE4\uC11C \uC228\uAE40\uC6A9)\r\n\r\n const frontRef = useRef<HTMLInputElement>(null);\r\n const backRef = useRef<HTMLInputElement>(null);\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const isClickFocusRef = useRef(false); // \uD074\uB9AD\uC73C\uB85C \uC778\uD55C \uD3EC\uCEE4\uC2A4\uC778\uC9C0 \uAD6C\uBD84\r\n const cursorPosRef = useRef(0); // \uCEE4\uC11C \uC704\uCE58 (ref\uB85C \uC989\uC2DC \uBC18\uC601)\r\n\r\n // \uC678\uBD80 ref\uC640 \uB0B4\uBD80 containerRef \uBCD1\uD569\r\n useImperativeHandle(ref, () => containerRef.current!, []);\r\n\r\n // \uB514\uBC14\uC6B4\uC2A4 \uD0C0\uC774\uBA38\r\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(\r\n null,\r\n );\r\n\r\n // \uD0C0\uC774\uBA38 \uC815\uB9AC\r\n useEffect(() => {\r\n return () => {\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n }\r\n };\r\n }, []);\r\n\r\n // value prop \uBCC0\uACBD \uC2DC \uB0B4\uBD80 \uC0C1\uD0DC \uB3D9\uAE30\uD654 (\uC678\uBD80 \uBCC0\uACBD\uC77C \uB54C\uB9CC)\r\n useEffect(() => {\r\n // \uB0B4\uBD80 \uBCC0\uACBD\uC774\uBA74 \uB3D9\uAE30\uD654 \uC2A4\uD0B5\r\n if (isInternalChange) {\r\n setIsInternalChange(false);\r\n return;\r\n }\r\n\r\n if (value !== undefined && value !== null) {\r\n const numbers = String(value).replace(/\\D/g, \"\");\r\n setFrontValue(numbers.slice(0, 6));\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uB4B7\uC790\uB9AC 1\uAE00\uC790\uB9CC \uC800\uC7A5\r\n if (mask) {\r\n setBackValue(numbers.slice(6, 7));\r\n } else {\r\n setBackValue(numbers.slice(6, 13));\r\n }\r\n } else {\r\n setFrontValue(\"\");\r\n setBackValue(\"\");\r\n }\r\n }, [value, mask]);\r\n\r\n // \uB9C8\uC2A4\uD0B9\uB41C \uB4B7\uC790\uB9AC \uD45C\uC2DC\uAC12\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: 1\uAE00\uC790\uB9CC \uD45C\uC2DC\r\n // \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uC804\uCCB4 \uD45C\uC2DC\r\n const displayBackValue = mask ? backValue.slice(0, 1) : backValue;\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uBC0F onChange \uD638\uCD9C\r\n const emitChange = useCallback(\r\n (front: string, back: string) => {\r\n const fullValue = front + back;\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: 7\uC790\uB9AC(6+1) \uC644\uC131, \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: 13\uC790\uB9AC \uC644\uC131\r\n const completeLength = mask ? 7 : 13;\r\n const isLengthComplete = fullValue.length === completeLength;\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC:\r\n // - \uC0DD\uB144\uC6D4\uC77C \uC720\uD6A8\uC131\uC740 \uD56D\uC0C1 \uAC80\uC0AC\r\n // - \uCCB4\uD06C\uC12C \uAC80\uC99D\uC740 \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC + validateChecksum=true\uC77C \uB54C\uB9CC\r\n let isValid = false;\r\n if (mask) {\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: 7\uC790\uB9AC \uC644\uC131 + \uC0DD\uB144\uC6D4\uC77C \uC720\uD6A8\uC131\r\n isValid =\r\n isLengthComplete && validateJuminBirthDate(fullValue);\r\n } else {\r\n // \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: 13\uC790\uB9AC \uC644\uC131 + \uC0DD\uB144\uC6D4\uC77C \uC720\uD6A8\uC131 + (\uC635\uC158) \uCCB4\uD06C\uC12C \uAC80\uC99D\r\n isValid =\r\n isLengthComplete &&\r\n validateJuminBirthDate(fullValue) &&\r\n (validateChecksum\r\n ? validateJuminChecksum(fullValue)\r\n : true);\r\n }\r\n\r\n setIsInvalid(fullValue.length > 0 && !isValid);\r\n\r\n if (onValidationChange) {\r\n onValidationChange(isValid);\r\n }\r\n\r\n const doEmit = () => {\r\n if (onChange) {\r\n setIsInternalChange(true); // \uB0B4\uBD80 \uBCC0\uACBD \uD50C\uB798\uADF8 \uC124\uC815\r\n const info = extractJuminInfo(fullValue);\r\n onChange({ ...info, isValid });\r\n }\r\n };\r\n\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n }\r\n\r\n if (debounce === undefined || debounce === 0) {\r\n doEmit();\r\n } else {\r\n debounceTimer.current = setTimeout(doEmit, debounce);\r\n }\r\n },\r\n [onChange, onValidationChange, mask, validateChecksum, debounce],\r\n );\r\n\r\n // \uC55E\uC790\uB9AC \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleFrontChange = useCallback(\r\n (e: ChangeEvent<HTMLInputElement>) => {\r\n const numbers = e.target.value.replace(/\\D/g, \"\").slice(0, 6);\r\n setFrontValue(numbers);\r\n cursorPosRef.current = numbers.length;\r\n setCursorVisible(true); // \uC785\uB825 \uC2DC \uCEE4\uC11C \uD45C\uC2DC\r\n setRenderTrigger((r) => r + 1);\r\n\r\n // 6\uC790\uB9AC \uC785\uB825 \uC644\uB8CC \uC2DC \uB4B7\uC790\uB9AC\uB85C \uD3EC\uCEE4\uC2A4 \uC774\uB3D9\r\n if (numbers.length === 6) {\r\n setTimeout(() => {\r\n const input = backRef.current;\r\n if (input) {\r\n input.focus();\r\n const len = mask ? 0 : input.value.length;\r\n input.setSelectionRange(len, len);\r\n cursorPosRef.current = len;\r\n setFocusedField(\"back\");\r\n setCursorVisible(true);\r\n }\r\n }, 0);\r\n }\r\n\r\n emitChange(numbers, backValue);\r\n },\r\n [backValue, emitChange, mask],\r\n );\r\n\r\n // \uC55E\uC790\uB9AC \uD3EC\uCEE4\uC2A4 \uD578\uB4E4\uB7EC\r\n const handleFrontFocus = useCallback(() => {\r\n // \uD074\uB9AD\uC73C\uB85C \uC778\uD55C \uD3EC\uCEE4\uC2A4\uBA74 \uD074\uB9AD \uD578\uB4E4\uB7EC\uC5D0\uC11C \uC804\uCCB4 \uC120\uD0DD \uCC98\uB9AC\r\n if (isClickFocusRef.current) {\r\n isClickFocusRef.current = false;\r\n setFocusedField(\"front\");\r\n // \uAC12\uC774 \uC788\uC73C\uBA74 \uC804\uCCB4 \uC120\uD0DD\r\n if (frontRef.current && frontValue.length > 0) {\r\n setTimeout(() => {\r\n frontRef.current?.setSelectionRange(\r\n 0,\r\n frontValue.length,\r\n );\r\n }, 0);\r\n setCursorVisible(false);\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n return;\r\n }\r\n // \uD0ED \uB4F1 \uC77C\uBC18 \uD3EC\uCEE4\uC2A4\uB3C4 \uC804\uCCB4 \uC120\uD0DD\r\n setFocusedField(\"front\");\r\n if (frontRef.current && frontValue.length > 0) {\r\n setTimeout(() => {\r\n frontRef.current?.setSelectionRange(0, frontValue.length);\r\n }, 0);\r\n setCursorVisible(false);\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n }, [frontValue.length]);\r\n\r\n // \uC55E\uC790\uB9AC \uBE14\uB7EC \uD578\uB4E4\uB7EC\r\n const handleFrontBlur = useCallback(() => {\r\n setCursorVisible(false);\r\n setTimeout(() => {\r\n const activeElement = document.activeElement;\r\n if (\r\n activeElement !== frontRef.current &&\r\n activeElement !== backRef.current\r\n ) {\r\n setFocusedField(null);\r\n }\r\n }, 0);\r\n }, []);\r\n\r\n // \uC55E\uC790\uB9AC \uD0A4\uBCF4\uB4DC \uD578\uB4E4\uB7EC\r\n const handleFrontKeyDown = useCallback(\r\n (e: KeyboardEvent<HTMLInputElement>) => {\r\n const input = frontRef.current;\r\n const pos = input?.selectionStart ?? 0;\r\n\r\n if (e.key === \"ArrowLeft\") {\r\n if (pos > 0) {\r\n e.preventDefault();\r\n const newPos = pos - 1;\r\n input?.setSelectionRange(newPos, newPos);\r\n cursorPosRef.current = newPos;\r\n setRenderTrigger((r) => r + 1);\r\n }\r\n } else if (e.key === \"ArrowRight\") {\r\n // 6\uC790\uB9AC \uC644\uC131 \uD6C4 \uB9C8\uC9C0\uB9C9 \uAE00\uC790\uC5D0\uC11C \uC624\uB978\uCABD \uB204\uB974\uBA74 \uBC14\uB85C \uB4B7\uC790\uB9AC\uB85C \uC774\uB3D9\r\n if (\r\n frontValue.length === 6 &&\r\n pos >= frontValue.length - 1\r\n ) {\r\n e.preventDefault();\r\n cursorPosRef.current = 0;\r\n setFocusedField(\"back\");\r\n backRef.current?.focus();\r\n backRef.current?.setSelectionRange(0, 0);\r\n } else if (pos < frontValue.length) {\r\n e.preventDefault();\r\n const newPos = pos + 1;\r\n input?.setSelectionRange(newPos, newPos);\r\n cursorPosRef.current = newPos;\r\n setRenderTrigger((r) => r + 1);\r\n }\r\n } else if (e.key === \"Backspace\") {\r\n if (pos > 0) {\r\n e.preventDefault();\r\n // \uD604\uC7AC \uC704\uCE58 \uC55E\uC758 \uBB38\uC790\uB97C \uC0AD\uC81C\r\n const newValue =\r\n frontValue.slice(0, pos - 1) +\r\n frontValue.slice(pos);\r\n setFrontValue(newValue);\r\n const newPos = pos - 1;\r\n cursorPosRef.current = newPos;\r\n setRenderTrigger((r) => r + 1);\r\n setTimeout(() => {\r\n input?.setSelectionRange(newPos, newPos);\r\n }, 0);\r\n emitChange(newValue, backValue);\r\n }\r\n }\r\n },\r\n [frontValue, backValue, emitChange],\r\n );\r\n\r\n // \uB4B7\uC790\uB9AC \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleBackChange = useCallback(\r\n (e: ChangeEvent<HTMLInputElement>) => {\r\n if (mask) {\r\n const inputVal = e.target.value.replace(/[\u25CF]/g, \"\");\r\n const numbers = inputVal.replace(/\\D/g, \"\").slice(0, 1);\r\n setBackValue(numbers);\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: 1\uAE00\uC790 \uC785\uB825 \uC644\uB8CC \uC2DC \uCEE4\uC11C\uB97C \uC67C\uCABD(0)\uC5D0 \uC704\uCE58\uD558\uACE0 \uCEE4\uC11C \uC228\uAE40\r\n cursorPosRef.current = 0;\r\n if (numbers.length === 1) {\r\n setBackComplete(true); // \uC785\uB825 \uC644\uB8CC \uC2DC \uCEE4\uC11C \uC228\uAE40\r\n } else {\r\n setCursorVisible(true); // \uC785\uB825 \uC911 \uCEE4\uC11C \uD45C\uC2DC\r\n }\r\n setTimeout(() => {\r\n backRef.current?.setSelectionRange(0, 0);\r\n }, 0);\r\n emitChange(frontValue, numbers);\r\n } else {\r\n const numbers = e.target.value\r\n .replace(/\\D/g, \"\")\r\n .slice(0, 7);\r\n setBackValue(numbers);\r\n cursorPosRef.current = numbers.length;\r\n setCursorVisible(true); // \uC785\uB825 \uC2DC \uCEE4\uC11C \uD45C\uC2DC\r\n if (numbers.length === 7) {\r\n setBackComplete(true); // 7\uC790\uB9AC \uC644\uB8CC \uC2DC \uCEE4\uC11C \uC228\uAE40\r\n } else {\r\n setBackComplete(false);\r\n }\r\n setRenderTrigger((r) => r + 1);\r\n emitChange(frontValue, numbers);\r\n }\r\n },\r\n [frontValue, emitChange, mask],\r\n );\r\n\r\n // \uB4B7\uC790\uB9AC \uD0A4\uBCF4\uB4DC \uD578\uB4E4\uB7EC\r\n const handleBackKeyDown = useCallback(\r\n (e: KeyboardEvent<HTMLInputElement>) => {\r\n const input = backRef.current;\r\n const pos = input?.selectionStart ?? 0;\r\n const valLen = mask\r\n ? displayBackValue.length\r\n : backValue.length;\r\n\r\n if (e.key === \"ArrowLeft\") {\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uBC14\uB85C \uC55E\uC790\uB9AC\uB85C \uC774\uB3D9\r\n if (mask || pos === 0) {\r\n e.preventDefault();\r\n frontRef.current?.focus();\r\n // \uC55E\uC790\uB9AC \uB9C8\uC9C0\uB9C9 \uAE00\uC790 '\uC544\uB798'\uB85C \uCEE4\uC11C \uC704\uCE58 (len - 1)\r\n const len = frontValue.length;\r\n const newPos = len > 0 ? len - 1 : 0;\r\n frontRef.current?.setSelectionRange(newPos, newPos);\r\n cursorPosRef.current = newPos;\r\n setRenderTrigger((r) => r + 1);\r\n } else if (pos > 0) {\r\n e.preventDefault();\r\n const newPos = pos - 1;\r\n input?.setSelectionRange(newPos, newPos);\r\n cursorPosRef.current = newPos;\r\n setRenderTrigger((r) => r + 1);\r\n }\r\n } else if (e.key === \"ArrowRight\") {\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC\uC5D0\uC11C\uB294 1\uAE00\uC790 \uC774\uC0C1 \uC624\uB978\uCABD\uC73C\uB85C \uAC00\uBA74 \uC548 \uB428\r\n if (pos < valLen) {\r\n e.preventDefault();\r\n const newPos = pos + 1;\r\n input?.setSelectionRange(newPos, newPos);\r\n cursorPosRef.current = newPos;\r\n setRenderTrigger((r) => r + 1);\r\n }\r\n // pos >= valLen\uC774\uBA74 \uC544\uBB34\uAC83\uB3C4 \uC548 \uD568 (\uB354 \uC774\uC0C1 \uC624\uB978\uCABD\uC73C\uB85C \uAC08 \uC218 \uC5C6\uC74C)\r\n } else if (e.key === \"Backspace\") {\r\n if (mask) {\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uB4B7\uC790\uB9AC \uAC12\uC774 \uC788\uC73C\uBA74 \uC0AD\uC81C, \uC5C6\uC73C\uBA74 \uC55E\uC790\uB9AC\uB85C \uC774\uB3D9\r\n e.preventDefault();\r\n if (backValue.length > 0) {\r\n setBackValue(\"\");\r\n setBackComplete(false);\r\n cursorPosRef.current = 0;\r\n setRenderTrigger((r) => r + 1);\r\n emitChange(frontValue, \"\");\r\n } else if (frontValue.length > 0) {\r\n const newFrontValue = frontValue.slice(0, -1);\r\n setFrontValue(newFrontValue);\r\n cursorPosRef.current = newFrontValue.length;\r\n setRenderTrigger((r) => r + 1);\r\n emitChange(newFrontValue, \"\");\r\n frontRef.current?.focus();\r\n setTimeout(() => {\r\n const len = frontRef.current?.value.length || 0;\r\n frontRef.current?.setSelectionRange(len, len);\r\n }, 0);\r\n }\r\n } else if (pos === 0 && backValue === \"\") {\r\n e.preventDefault();\r\n if (frontValue.length > 0) {\r\n const newFrontValue = frontValue.slice(0, -1);\r\n setFrontValue(newFrontValue);\r\n cursorPosRef.current = newFrontValue.length;\r\n emitChange(newFrontValue, backValue);\r\n }\r\n frontRef.current?.focus();\r\n setTimeout(() => {\r\n const len = frontRef.current?.value.length || 0;\r\n frontRef.current?.setSelectionRange(len, len);\r\n cursorPosRef.current = len;\r\n setRenderTrigger((r) => r + 1);\r\n }, 0);\r\n } else if (!mask && pos > 0) {\r\n // \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uC911\uAC04\uC5D0\uC11C Backspace \uCC98\uB9AC\r\n e.preventDefault();\r\n const newBackValue =\r\n backValue.slice(0, pos - 1) + backValue.slice(pos);\r\n setBackValue(newBackValue);\r\n const newPos = pos - 1;\r\n cursorPosRef.current = newPos;\r\n setRenderTrigger((r) => r + 1);\r\n emitChange(frontValue, newBackValue);\r\n setTimeout(() => {\r\n input?.setSelectionRange(newPos, newPos);\r\n }, 0);\r\n } else if (!mask && pos === 0 && backValue.length > 0) {\r\n // \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uB9E8 \uC55E\uC5D0\uC11C Backspace - \uC55E\uC790\uB9AC\uB85C \uC774\uB3D9\r\n e.preventDefault();\r\n frontRef.current?.focus();\r\n const len = frontValue.length;\r\n const newPos = len > 0 ? len - 1 : 0;\r\n frontRef.current?.setSelectionRange(newPos, newPos);\r\n cursorPosRef.current = newPos;\r\n setRenderTrigger((r) => r + 1);\r\n }\r\n }\r\n },\r\n [backValue, frontValue, displayBackValue, mask, emitChange],\r\n );\r\n\r\n // \uB4B7\uC790\uB9AC \uD3EC\uCEE4\uC2A4 \uD578\uB4E4\uB7EC\r\n const handleBackFocus = useCallback(() => {\r\n // \uD074\uB9AD \uB610\uB294 \uD0ED\uC73C\uB85C \uD3EC\uCEE4\uC2A4 - \uC804\uCCB4 \uC120\uD0DD\r\n isClickFocusRef.current = false;\r\n setFocusedField(\"back\");\r\n setCursorVisible(false); // \uC804\uCCB4 \uC120\uD0DD \uC2DC \uCEE4\uC11C \uC228\uAE40\r\n\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uAC12\uC774 \uC788\uC73C\uBA74 \uC804\uCCB4 \uC120\uD0DD\r\n if (mask) {\r\n if (backValue.length > 0) {\r\n // \uC0C1\uD0DC \uBCC0\uACBD \uD6C4 \uB9AC\uB80C\uB354\uB9C1\uC774 \uC644\uB8CC\uB41C \uB2E4\uC74C\uC5D0 \uC120\uD0DD \uC801\uC6A9\r\n requestAnimationFrame(() => {\r\n backRef.current?.setSelectionRange(0, 1);\r\n });\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n } else {\r\n // \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uAC12\uC774 \uC788\uC73C\uBA74 \uC804\uCCB4 \uC120\uD0DD\r\n if (backValue.length > 0) {\r\n requestAnimationFrame(() => {\r\n backRef.current?.setSelectionRange(0, backValue.length);\r\n });\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n }\r\n }, [backValue.length, mask]);\r\n\r\n // \uB4B7\uC790\uB9AC \uBE14\uB7EC \uD578\uB4E4\uB7EC\r\n const handleBackBlur = useCallback(() => {\r\n setCursorVisible(false);\r\n setTimeout(() => {\r\n const activeElement = document.activeElement;\r\n if (\r\n activeElement !== frontRef.current &&\r\n activeElement !== backRef.current\r\n ) {\r\n setFocusedField(null);\r\n }\r\n }, 0);\r\n }, []);\r\n\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC\uC5D0\uC11C placeholder \uB3D9\uADF8\uB77C\uBBF8 \uAC1C\uC218 (\uCCAB\uBC88\uC9F8 \uC785\uB825\uCE78 + 6\uAC1C = 7\uAC1C \uACE0\uC815)\r\n const placeholderDots = mask ? 7 : 0;\r\n\r\n // \uD3F0\uD2B8 \uD06C\uAE30 \uACC4\uC0B0 (\uAE30\uBCF8\uAC12: small=16px, medium=18px)\r\n const defaultFontSize = size === \"small\" ? 16 : 18;\r\n const computedFontSize = fontSize\r\n ? typeof fontSize === \"number\"\r\n ? fontSize\r\n : parseFloat(fontSize) *\r\n (fontSize.toString().includes(\"rem\") ? 16 : 1)\r\n : defaultFontSize;\r\n\r\n // \uD14D\uC2A4\uD2B8 \uB108\uBE44 \uCE21\uC815 \uD568\uC218\r\n const measureTextWidth = useCallback(\r\n (text: string): number => {\r\n if (typeof document === \"undefined\")\r\n return text.length * computedFontSize * 0.6;\r\n const canvas = document.createElement(\"canvas\");\r\n const ctx = canvas.getContext(\"2d\");\r\n if (!ctx) return text.length * computedFontSize * 0.6;\r\n ctx.font = `${computedFontSize}px ${\r\n fontFamily || \"Roboto, sans-serif\"\r\n }`;\r\n return ctx.measureText(text).width;\r\n },\r\n [computedFontSize, fontFamily],\r\n );\r\n\r\n // \uB3D9\uADF8\uB77C\uBBF8 \uD06C\uAE30: \uD3F0\uD2B8 \uD06C\uAE30\uC5D0 \uBE44\uB840\r\n const dotSize = Math.round(computedFontSize * 0.5); // \uCCAB \uBC88\uC9F8 \uB3D9\uADF8\uB77C\uBBF8 (\uC785\uB825 \uC704\uCE58)\r\n const smallDotSize = Math.round(computedFontSize * 0.35); // \uB4A4 6\uAC1C \uB3D9\uADF8\uB77C\uBBF8\r\n\r\n // \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C \uD06C\uAE30\r\n const cursorHeight = \"1px\";\r\n\r\n // \uCEE4\uC11C \uC704\uCE58 \uACC4\uC0B0 \uACF5\uC6A9 \uD568\uC218\r\n const getCursorLeft = useCallback(\r\n (field: \"front\" | \"back\") => {\r\n if (field === \"front\") {\r\n const textBeforeCursor = frontValue.slice(\r\n 0,\r\n cursorPosRef.current,\r\n );\r\n return measureTextWidth(textBeforeCursor);\r\n } else {\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC\uC5D0\uC11C \uAC12\uC774 \uC5C6\uC744 \uB54C\uB294 \uCCAB \uBC88\uC9F8 \uB3D9\uADF8\uB77C\uBBF8 \uC544\uB798\uC5D0 \uCEE4\uC11C \uC704\uCE58\r\n if (mask && displayBackValue.length === 0) {\r\n return dotSize / 2 - (computedFontSize * 0.55) / 2;\r\n }\r\n const textBeforeCursor = displayBackValue.slice(\r\n 0,\r\n cursorPosRef.current,\r\n );\r\n return measureTextWidth(textBeforeCursor);\r\n }\r\n },\r\n [\r\n frontValue,\r\n displayBackValue,\r\n mask,\r\n dotSize,\r\n computedFontSize,\r\n measureTextWidth,\r\n ],\r\n );\r\n\r\n // \uCEE4\uC11C \uC704\uCE58 (\uB80C\uB354\uB9C1 \uC2DC\uC810\uC5D0 \uACC4\uC0B0)\r\n const cursorLeft = useMemo(() => {\r\n if (!focusedField) return 0;\r\n return getCursorLeft(focusedField);\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [focusedField, cursorVisible, renderTrigger, getCursorLeft]);\r\n\r\n // \uD544\uB4DC \uB108\uBE44: ch \uB2E8\uC704 \uC0AC\uC6A9 (\uD3F0\uD2B8 \uD06C\uAE30\uC5D0 \uC790\uB3D9 \uBE44\uB840)\r\n const frontFieldCh = \"6.2ch\"; // 6\uC790\uB9AC + \uCD5C\uC18C \uC5EC\uC720\r\n const backFieldCh = mask ? \"8.5ch\" : \"7.5ch\"; // \uB9C8\uC2A4\uD0B9: \uC801\uC808\uD55C \uAC04\uACA9, \uBE44\uB9C8\uC2A4\uD0B9: 7\uC790\uB9AC\r\n\r\n // \uAC1C\uBCC4 TextField\uC5D0\uC11C border \uC81C\uAC70\uD558\uB294 \uC2A4\uD0C0\uC77C\r\n const noBorderStyle: SxProps<Theme> = {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": {\r\n border: \"none\",\r\n },\r\n \"&:hover fieldset\": {\r\n border: \"none\",\r\n },\r\n \"&.Mui-focused fieldset\": {\r\n border: \"none\",\r\n },\r\n },\r\n };\r\n\r\n // \uC804\uCCB4 \uC8FC\uBBFC\uBC88\uD638 \uAC12 \uAC00\uC838\uC624\uAE30\r\n const getFullNumber = () => frontValue + backValue;\r\n\r\n // \uADF8\uB8F9 \uC785\uB825 \uB0B4\uBD80 \uCEF4\uD3EC\uB10C\uD2B8 \uB80C\uB354\uB9C1\r\n const renderGroupedInput = () => (\r\n <>\r\n <Box\r\n onClick={() => {\r\n if (disabled || readonly) return;\r\n isClickFocusRef.current = true;\r\n setBackComplete(false);\r\n\r\n // \uCCAB \uBC88\uC9F8 \uBE48 \uCE78 \uCC3E\uAE30, \uC5C6\uC73C\uBA74 \uB9C8\uC9C0\uB9C9 \uCE78 \uC120\uD0DD\r\n const hasFrontValue = frontValue.length > 0;\r\n const hasBackValue = backValue.length > 0;\r\n\r\n if (!hasFrontValue) {\r\n // \uC55E\uCE78\uC774 \uBE44\uC5B4\uC788\uC73C\uBA74 \uC55E\uCE78 \uD3EC\uCEE4\uC2A4\r\n setFocusedField(\"front\");\r\n frontRef.current?.focus();\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n } else if (!hasBackValue) {\r\n // \uC55E\uCE78\uC740 \uC788\uACE0 \uB4B7\uCE78\uC774 \uBE44\uC5B4\uC788\uC73C\uBA74 \uB4B7\uCE78 \uD3EC\uCEE4\uC2A4\r\n setFocusedField(\"back\");\r\n backRef.current?.focus();\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n } else {\r\n // \uB458 \uB2E4 \uAC12\uC774 \uC788\uC73C\uBA74 \uB4B7\uCE78 \uC804\uCCB4 \uC120\uD0DD\r\n setFocusedField(\"back\");\r\n backRef.current?.focus();\r\n if (mask) {\r\n setCursorVisible(false);\r\n setTimeout(() => {\r\n backRef.current?.setSelectionRange(0, 1);\r\n }, 0);\r\n } else {\r\n setCursorVisible(false);\r\n setTimeout(() => {\r\n backRef.current?.setSelectionRange(\r\n 0,\r\n backValue.length,\r\n );\r\n }, 0);\r\n }\r\n }\r\n }}\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: 0.2,\r\n width: \"100%\",\r\n height: \"100%\",\r\n cursor: disabled ? \"default\" : \"text\",\r\n }}\r\n >\r\n <Box\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n if (disabled || readonly) return;\r\n // \uD074\uB9AD \uC2DC \uC804\uCCB4 \uC120\uD0DD\r\n isClickFocusRef.current = true;\r\n setFocusedField(\"front\");\r\n frontRef.current?.focus();\r\n if (frontValue.length > 0) {\r\n setCursorVisible(false);\r\n setTimeout(() => {\r\n frontRef.current?.setSelectionRange(\r\n 0,\r\n frontValue.length,\r\n );\r\n }, 0);\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n }}\r\n sx={{\r\n position: \"relative\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n }}\r\n >\r\n <TextField\r\n {...props}\r\n inputRef={frontRef}\r\n value={frontValue}\r\n onChange={handleFrontChange}\r\n onKeyDown={handleFrontKeyDown}\r\n onFocus={handleFrontFocus}\r\n onBlur={handleFrontBlur}\r\n disabled={disabled}\r\n size={size}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n placeholder=\"000000\"\r\n variant=\"outlined\"\r\n sx={{\r\n width: \"auto\",\r\n minWidth: 0,\r\n ...noBorderStyle,\r\n \"& .MuiInputBase-root\": {\r\n width: \"auto\",\r\n },\r\n \"& .MuiInputBase-input\": {\r\n width: frontFieldCh,\r\n caretColor: \"transparent\",\r\n ...(fontSize && { fontSize }),\r\n ...(fontColor && { color: fontColor }),\r\n ...(fontFamily && { fontFamily }),\r\n },\r\n \"& .MuiInputBase-input::placeholder\": {\r\n color: \"rgba(0, 0, 0, 0.2)\",\r\n opacity: 1,\r\n },\r\n }}\r\n slotProps={{\r\n input: {\r\n readOnly: readonly,\r\n },\r\n htmlInput: {\r\n maxLength: 6,\r\n inputMode: \"numeric\",\r\n style: {\r\n textAlign: \"left\",\r\n padding: \"0 4px\",\r\n },\r\n },\r\n }}\r\n />\r\n {/* \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C - \uC55E\uC790\uB9AC */}\r\n {cursorVisible && focusedField === \"front\" && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n bottom: size === \"small\" ? 1 : 3,\r\n left: `calc(4px + ${cursorLeft}px)`,\r\n width: `${computedFontSize * 0.55}px`,\r\n height: cursorHeight,\r\n backgroundColor:\r\n fontColor || \"text.primary\",\r\n animation: \"blink 1s step-end infinite\",\r\n \"@keyframes blink\": {\r\n \"0%, 100%\": { opacity: 1 },\r\n \"50%\": { opacity: 0 },\r\n },\r\n pointerEvents: \"none\",\r\n }}\r\n />\r\n )}\r\n </Box>\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n color: \"text.secondary\",\r\n mx: size === \"small\" ? 0.5 : 0.75,\r\n userSelect: \"none\",\r\n height: \"100%\",\r\n flexShrink: 0,\r\n }}\r\n >\r\n <DashIcon size={size} />\r\n </Box>\r\n <Box\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n if (disabled || readonly) return;\r\n // \uD074\uB9AD \uC2DC \uC804\uCCB4 \uC120\uD0DD\r\n isClickFocusRef.current = true;\r\n setFocusedField(\"back\");\r\n setBackComplete(false);\r\n backRef.current?.focus();\r\n const len = mask\r\n ? backValue.length > 0\r\n ? 1\r\n : 0\r\n : backValue.length;\r\n if (len > 0) {\r\n setCursorVisible(false);\r\n setTimeout(() => {\r\n backRef.current?.setSelectionRange(0, len);\r\n }, 0);\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n }}\r\n sx={{\r\n position: \"relative\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n }}\r\n >\r\n <TextField\r\n {...props}\r\n inputRef={backRef}\r\n value={displayBackValue}\r\n onChange={handleBackChange}\r\n onKeyDown={handleBackKeyDown}\r\n onFocus={handleBackFocus}\r\n onBlur={handleBackBlur}\r\n onClick={(e) => {\r\n if (disabled || readonly) return;\r\n e.stopPropagation();\r\n\r\n // \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uD074\uB9AD \uC2DC \uC804\uCCB4 \uC120\uD0DD\r\n if (mask) {\r\n setFocusedField(\"back\");\r\n setBackComplete(false);\r\n if (backValue.length > 0) {\r\n setCursorVisible(false);\r\n requestAnimationFrame(() => {\r\n backRef.current?.setSelectionRange(\r\n 0,\r\n 1,\r\n );\r\n });\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n return;\r\n }\r\n\r\n // \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uB4DC\uB798\uADF8 \uC120\uD0DD \uD655\uC778\r\n const input = backRef.current;\r\n const selStart = input?.selectionStart ?? 0;\r\n const selEnd = input?.selectionEnd ?? 0;\r\n\r\n // \uC120\uD0DD \uBC94\uC704\uAC00 \uC788\uC73C\uBA74 \uADF8\uB300\uB85C \uC720\uC9C0\r\n if (selStart !== selEnd) {\r\n setCursorVisible(false);\r\n setFocusedField(\"back\");\r\n return;\r\n }\r\n\r\n // \uBE44\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC: \uD074\uB9AD \uC2DC \uC804\uCCB4 \uC120\uD0DD\r\n setFocusedField(\"back\");\r\n setBackComplete(false);\r\n if (backValue.length > 0) {\r\n setCursorVisible(false);\r\n requestAnimationFrame(() => {\r\n backRef.current?.setSelectionRange(\r\n 0,\r\n backValue.length,\r\n );\r\n });\r\n } else {\r\n cursorPosRef.current = 0;\r\n setCursorVisible(true);\r\n }\r\n }}\r\n disabled={disabled}\r\n size={size}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n placeholder={mask ? \"\" : \"0000000\"}\r\n variant=\"outlined\"\r\n sx={{\r\n width: \"auto\",\r\n minWidth: 0,\r\n ...noBorderStyle,\r\n \"& .MuiInputBase-root\": {\r\n width: \"auto\",\r\n },\r\n \"& .MuiInputBase-input\": {\r\n width: backFieldCh,\r\n caretColor: \"transparent\",\r\n ...(fontSize && { fontSize }),\r\n ...(fontColor && { color: fontColor }),\r\n ...(fontFamily && { fontFamily }),\r\n background: \"transparent\",\r\n position: \"relative\",\r\n zIndex: 1,\r\n },\r\n \"& .MuiInputBase-input::placeholder\": {\r\n color: \"rgba(0, 0, 0, 0.2)\",\r\n opacity: 1,\r\n },\r\n }}\r\n slotProps={{\r\n input: {\r\n readOnly: readonly,\r\n },\r\n htmlInput: {\r\n maxLength: mask ? 1 : 7,\r\n inputMode: \"numeric\",\r\n style: {\r\n textAlign: \"left\",\r\n padding: \"0 4px\",\r\n },\r\n },\r\n }}\r\n />\r\n {/* \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C - \uB4B7\uC790\uB9AC (\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC\uC5D0\uC11C \uC785\uB825 \uC644\uB8CC \uC2DC \uC228\uAE40) */}\r\n {/* \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C - \uB4B7\uC790\uB9AC (\uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC\uC5D0\uC11C \uC785\uB825 \uC644\uB8CC \uD6C4 \uC790\uB3D9 \uC228\uAE40, \uD074\uB9AD \uC2DC \uB2E4\uC2DC \uBCF4\uC784) */}\r\n {cursorVisible &&\r\n focusedField === \"back\" &&\r\n !backComplete && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n bottom: size === \"small\" ? 1 : 3,\r\n left: `calc(4px + ${cursorLeft}px)`,\r\n width: `${computedFontSize * 0.55}px`,\r\n height: cursorHeight,\r\n backgroundColor:\r\n fontColor || \"text.primary\",\r\n animation: \"blink 1s step-end infinite\",\r\n \"@keyframes blink\": {\r\n \"0%, 100%\": { opacity: 1 },\r\n \"50%\": { opacity: 0 },\r\n },\r\n pointerEvents: \"none\",\r\n zIndex: 2,\r\n }}\r\n />\r\n )}\r\n {/* \uB9C8\uC2A4\uD0B9 \uBAA8\uB4DC\uC77C \uB54C \uB4B7\uC790\uB9AC placeholder \u25CF \uD45C\uC2DC */}\r\n {mask && placeholderDots > 0 && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n left: 0,\r\n width: backFieldCh,\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n pointerEvents: \"none\",\r\n fontSize:\r\n fontSize ||\r\n (size === \"small\" ? \"16px\" : \"18px\"),\r\n fontFamily: fontFamily || \"inherit\",\r\n }}\r\n >\r\n {/* \uCCAB \uBC88\uC9F8 \uB3D9\uADF8\uB77C\uBBF8 (\uC785\uB825 \uC704\uCE58) */}\r\n <span\r\n style={{\r\n width: `${dotSize}px`,\r\n height: `${dotSize}px`,\r\n borderRadius: \"50%\",\r\n backgroundColor:\r\n displayBackValue.length > 0\r\n ? \"transparent\"\r\n : maskColor,\r\n opacity: 0.2,\r\n display: \"inline-block\",\r\n flexShrink: 0,\r\n }}\r\n />\r\n {/* \uB4A4 6\uAC1C \uB3D9\uADF8\uB77C\uBBF8 (7ch \uAC04\uACA9) */}\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n justifyContent: \"space-between\",\r\n width: \"7ch\",\r\n marginLeft: \"auto\",\r\n }}\r\n >\r\n {Array.from({ length: 6 }).map((_, i) => (\r\n <span\r\n key={i}\r\n style={{\r\n width: `${smallDotSize}px`,\r\n height: `${smallDotSize}px`,\r\n borderRadius: \"50%\",\r\n backgroundColor: maskColor,\r\n display: \"inline-block\",\r\n flexShrink: 0,\r\n }}\r\n />\r\n ))}\r\n </Box>\r\n </Box>\r\n )}\r\n </Box>\r\n </Box>\r\n </>\r\n );\r\n\r\n // \uD074\uB9AD \uC2DC \uD3EC\uCEE4\uC2A4\uD560 ref \uACB0\uC815\r\n const getTargetRefOnClick = useCallback(() => {\r\n if (frontValue.length === 0) {\r\n return { ref: frontRef, groupIndex: 0 };\r\n } else if (backValue.length === 0) {\r\n return { ref: backRef, groupIndex: 1 };\r\n }\r\n return { ref: backRef, groupIndex: 1 };\r\n }, [frontValue.length, backValue.length]);\r\n\r\n // focusedGroup\uC744 focusedField\uB85C \uB9E4\uD551 (GroupedInputWrapper \uD638\uD658)\r\n const focusedGroup =\r\n focusedField === \"front\" ? 0 : focusedField === \"back\" ? 1 : null;\r\n const setFocusedGroupWrapper = useCallback((group: number | null) => {\r\n if (group === null) {\r\n setFocusedField(null);\r\n setCursorVisible(false);\r\n } else if (group === 0) {\r\n setFocusedField(\"front\");\r\n setCursorVisible(true);\r\n } else if (group === 1) {\r\n setFocusedField(\"back\");\r\n setCursorVisible(true);\r\n }\r\n }, []);\r\n\r\n return (\r\n <GroupedInputWrapper\r\n label={label}\r\n size={size}\r\n disabled={disabled}\r\n readonly={readonly}\r\n focusedGroup={focusedGroup}\r\n setFocusedGroup={setFocusedGroupWrapper}\r\n hasValue={getFullNumber().length > 0}\r\n isInvalid={isInvalid}\r\n invalidBorderColor={invalidBorderColor}\r\n inputRefs={[frontRef, backRef]}\r\n getTargetRefOnClick={getTargetRefOnClick}\r\n fullWidth={fullWidth}\r\n sx={sx}\r\n className={className}\r\n id={id}\r\n >\r\n {renderGroupedInput()}\r\n </GroupedInputWrapper>\r\n );\r\n },\r\n);\r\n\r\nconst JuminTextFieldWithForm = forwardRef<HTMLDivElement, JuminTextFieldProps>(\r\n function JuminTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"JuminTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"JuminTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name) as string | undefined;\r\n const handleFormChange = useCallback(\r\n (info: JuminInfo) => {\r\n const syntheticEvent = {\r\n target: { name, value: info.value },\r\n currentTarget: { name, value: info.value },\r\n } as React.ChangeEvent<HTMLInputElement>;\r\n form.handleFormChange(syntheticEvent);\r\n onChange?.(info);\r\n },\r\n [form, name, onChange],\r\n );\r\n\r\n return (\r\n <JuminTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport const JuminTextField = forwardRef<HTMLDivElement, JuminTextFieldProps>(\r\n function JuminTextField(props, ref) {\r\n if (props.form) {\r\n return <JuminTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <JuminTextFieldBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * GroupedInputWrapper.tsx\r\n *\r\n * \uADF8\uB8F9\uD654\uB41C \uC785\uB825 \uCEF4\uD3EC\uB10C\uD2B8(\uC0AC\uC5C5\uC790\uBC88\uD638, \uC8FC\uBBFC\uBC88\uD638, \uCE74\uB4DC\uBC88\uD638, \uC2DC\uAC04 \uB4F1)\uB97C \uC704\uD55C\r\n * FormControl + OutlinedInput \uB798\uD37C \uCEF4\uD3EC\uB10C\uD2B8\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useCallback,\r\n useRef,\r\n useEffect,\r\n RefObject,\r\n forwardRef,\r\n} from \"react\";\r\nimport { FormControl, InputLabel, OutlinedInput, Box } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\n\r\nexport interface GroupedInputWrapperProps {\r\n label?: React.ReactNode; // \uB77C\uBCA8\r\n size?: \"small\" | \"medium\"; // \uC0AC\uC774\uC988\r\n disabled?: boolean; // \uBE44\uD65C\uC131\uD654\r\n readonly?: boolean; // \uC77D\uAE30 \uC804\uC6A9\r\n focusedGroup: number | null; // \uD3EC\uCEE4\uC2A4\uB41C \uADF8\uB8F9 \uC778\uB371\uC2A4 (null\uC774\uBA74 \uD3EC\uCEE4\uC2A4 \uC5C6\uC74C)\r\n setFocusedGroup: (group: number | null) => void; // \uD3EC\uCEE4\uC2A4 \uADF8\uB8F9 \uC124\uC815 \uD568\uC218\r\n hasValue: boolean; // \uAC12\uC774 \uC788\uB294\uC9C0 \uC5EC\uBD80\r\n isInvalid?: boolean; // \uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uC0C1\uD0DC\r\n invalidBorderColor?: string; // \uC720\uD6A8\uD558\uC9C0 \uC54A\uC744 \uB54C \uD14C\uB450\uB9AC \uC0C9\uC0C1\r\n inputRefs: RefObject<HTMLInputElement | null>[]; // \uB0B4\uBD80 \uC785\uB825 \uD544\uB4DC\uB4E4\uC758 ref \uBC30\uC5F4\r\n getTargetRefOnClick: () => {\r\n ref: RefObject<HTMLInputElement | null>;\r\n groupIndex: number;\r\n }; // \uD074\uB9AD \uC2DC \uD3EC\uCEE4\uC2A4\uD560 ref\uC640 \uADF8\uB8F9 \uC778\uB371\uC2A4 \uACB0\uC815 \uD568\uC218\r\n sx?: SxProps<Theme>; // \uCEE8\uD14C\uC774\uB108 sx\r\n className?: string; // className\r\n id?: string; // id\r\n fullWidth?: boolean; // \uC804\uCCB4 \uB108\uBE44 \uC0AC\uC6A9 \uC5EC\uBD80\r\n children: React.ReactNode; // \uB0B4\uBD80 \uCEE8\uD150\uCE20 \uB80C\uB354\uB9C1\r\n contentSx?: SxProps<Theme>; // \uB0B4\uBD80 Box\uC758 \uCD94\uAC00 sx\r\n endAdornment?: React.ReactNode; // \uC624\uB978\uCABD \uB05D\uC5D0 \uD56D\uC0C1 \uBCF4\uC774\uB294 \uC694\uC18C (\uC544\uC774\uCF58 \uB4F1)\r\n}\r\n\r\n// inputComponent\uB97C \uCEF4\uD3EC\uB10C\uD2B8 \uC678\uBD80\uC5D0\uC11C \uC815\uC758\uD558\uC5EC \uB9AC\uB80C\uB354\uB9C1 \uBC29\uC9C0\r\ninterface CustomInputProps {\r\n showContent: boolean;\r\n inputSize: \"small\" | \"medium\";\r\n contentSx?: SxProps<Theme>;\r\n children: React.ReactNode;\r\n endAdornment?: React.ReactNode;\r\n}\r\n\r\nconst CustomInput = forwardRef<HTMLDivElement, CustomInputProps>(\r\n function CustomInput(\r\n { showContent, inputSize, contentSx, children, endAdornment },\r\n ref,\r\n ) {\r\n return (\r\n <Box\r\n ref={ref}\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n width: \"100%\",\r\n height: \"100%\",\r\n px: inputSize === \"small\" ? 1 : 1.25,\r\n ...contentSx,\r\n }}\r\n >\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n flex: 1,\r\n visibility: showContent ? \"visible\" : \"hidden\",\r\n }}\r\n >\r\n {children}\r\n </Box>\r\n {endAdornment}\r\n </Box>\r\n );\r\n },\r\n);\r\n\r\nexport function GroupedInputWrapper({\r\n label,\r\n size = \"medium\",\r\n disabled,\r\n readonly,\r\n focusedGroup,\r\n setFocusedGroup,\r\n hasValue,\r\n isInvalid,\r\n invalidBorderColor,\r\n inputRefs,\r\n getTargetRefOnClick,\r\n sx,\r\n className,\r\n id,\r\n fullWidth = false,\r\n children,\r\n contentSx,\r\n endAdornment,\r\n}: GroupedInputWrapperProps) {\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n // label\uC774 \uC788\uACE0 focus/\uAC12\uC774 \uC5C6\uC744 \uB54C \uB0B4\uBD80 \uC785\uB825 \uC694\uC18C \uC228\uAE40\r\n const showContent = !label || focusedGroup !== null || hasValue;\r\n const isLabelShrunk = focusedGroup !== null || hasValue;\r\n\r\n // \uD074\uB9AD \uD578\uB4E4\uB7EC - onMouseDown\uC5D0\uC11C \uCC98\uB9AC\uD558\uC5EC OutlinedInput\uC758 \uAE30\uBCF8 \uD3EC\uCEE4\uC2A4 \uB3D9\uC791 \uBC29\uC9C0\r\n const handleMouseDown = useCallback(\r\n (e: React.MouseEvent) => {\r\n if (disabled || readonly) {\r\n return;\r\n }\r\n\r\n // \uC774\uBBF8 input\uC5D0\uC11C \uCC98\uB9AC\uB41C \uD074\uB9AD\uC774\uBA74 \uBB34\uC2DC\r\n const target = e.target as HTMLElement;\r\n if (target.tagName === \"INPUT\") {\r\n return;\r\n }\r\n\r\n // \uAE30\uBCF8 \uD3EC\uCEE4\uC2A4 \uB3D9\uC791 \uBC29\uC9C0\r\n e.preventDefault();\r\n\r\n const { ref: targetRef, groupIndex } = getTargetRefOnClick();\r\n const inputEl = targetRef.current;\r\n\r\n if (inputEl) {\r\n // \uBA3C\uC800 focusedGroup\uC744 \uC124\uC815\uD558\uC5EC visibility\uB97C visible\uB85C \uBCC0\uACBD\r\n setFocusedGroup(groupIndex);\r\n\r\n // \uB2E4\uC74C \uB80C\uB354 \uC0AC\uC774\uD074\uC5D0\uC11C \uD3EC\uCEE4\uC2A4 \uBC0F \uC804\uCCB4 \uC120\uD0DD (visibility\uAC00 visible\uC774 \uB41C \uD6C4)\r\n setTimeout(() => {\r\n inputEl.focus();\r\n inputEl.select(); // \uC804\uCCB4 \uC120\uD0DD\r\n }, 0);\r\n }\r\n },\r\n [disabled, readonly, getTargetRefOnClick, setFocusedGroup],\r\n );\r\n\r\n // blur \uD578\uB4E4\uB7EC - \uC678\uBD80 \uD074\uB9AD \uAC10\uC9C0\r\n useEffect(() => {\r\n if (focusedGroup === null) return;\r\n\r\n const handleDocumentClick = (e: MouseEvent) => {\r\n const target = e.target as Node;\r\n\r\n // \uCEE8\uD14C\uC774\uB108 \uB0B4\uBD80 \uD074\uB9AD\uC774\uBA74 \uBB34\uC2DC\r\n if (containerRef.current?.contains(target)) {\r\n return;\r\n }\r\n\r\n // \uB0B4\uBD80 input \uC911 \uD558\uB098\uAC00 \uD3EC\uCEE4\uC2A4\uB418\uC5B4 \uC788\uB294\uC9C0 \uD655\uC778\r\n const isAnyInputFocused = inputRefs.some(\r\n (ref) => ref.current === document.activeElement,\r\n );\r\n\r\n if (!isAnyInputFocused) {\r\n setFocusedGroup(null);\r\n }\r\n };\r\n\r\n // mousedown\uC73C\uB85C \uCC98\uB9AC (click\uBCF4\uB2E4 \uBA3C\uC800 \uBC1C\uC0DD)\r\n document.addEventListener(\"mousedown\", handleDocumentClick);\r\n return () => {\r\n document.removeEventListener(\"mousedown\", handleDocumentClick);\r\n };\r\n }, [focusedGroup, inputRefs, setFocusedGroup]);\r\n\r\n // \uB0B4\uBD80 input blur \uC2DC \uCC98\uB9AC\r\n const handleBlur = useCallback(() => {\r\n // setTimeout\uC73C\uB85C \uB2E4\uB978 \uB0B4\uBD80 input\uC73C\uB85C \uC774\uB3D9\uD588\uB294\uC9C0 \uD655\uC778\r\n setTimeout(() => {\r\n const activeEl = document.activeElement;\r\n const isStillFocused = inputRefs.some(\r\n (ref) => ref.current === activeEl,\r\n );\r\n if (!isStillFocused) {\r\n setFocusedGroup(null);\r\n }\r\n }, 0);\r\n }, [inputRefs, setFocusedGroup]);\r\n\r\n return (\r\n <FormControl\r\n ref={containerRef}\r\n size={size}\r\n disabled={disabled}\r\n error={isInvalid}\r\n focused={readonly ? false : focusedGroup !== null}\r\n fullWidth={fullWidth}\r\n sx={{\r\n ...(fullWidth && {\r\n width: \"100%\",\r\n flex: 1,\r\n minWidth: 0,\r\n display: \"flex\",\r\n }),\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...sx,\r\n }}\r\n className={className}\r\n >\r\n {label && (\r\n <InputLabel\r\n shrink={isLabelShrunk}\r\n sx={{\r\n ...(isInvalid &&\r\n invalidBorderColor && {\r\n color: invalidBorderColor,\r\n \"&.Mui-focused\": { color: invalidBorderColor },\r\n }),\r\n }}\r\n >\r\n {label}\r\n </InputLabel>\r\n )}\r\n <OutlinedInput\r\n id={id}\r\n label={label}\r\n notched={isLabelShrunk}\r\n fullWidth={fullWidth}\r\n onMouseDown={handleMouseDown}\r\n onBlur={handleBlur}\r\n sx={{\r\n height: size === \"small\" ? 40 : 56,\r\n cursor: disabled ? \"default\" : \"text\",\r\n ...(isInvalid &&\r\n invalidBorderColor && {\r\n \"& .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n \"&:hover .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n \"&.Mui-focused .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n }),\r\n ...(readonly && {\r\n \"&:hover .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n }),\r\n }}\r\n slots={{ input: CustomInput }}\r\n slotProps={{\r\n input: {\r\n showContent,\r\n inputSize: size,\r\n contentSx,\r\n children,\r\n endAdornment,\r\n } as CustomInputProps,\r\n }}\r\n />\r\n </FormControl>\r\n );\r\n}\r\n", "/**\r\n * ColonBox.tsx - \uC2DC\uAC04 \uD544\uB4DC \uC0AC\uC774\uC758 \uCF5C\uB860 \uC544\uC774\uCF58 \uCEF4\uD3EC\uB10C\uD2B8\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport { Box } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport { ColonIcon as ColonSvg } from \"../icons\";\r\n\r\nexport interface ColonBoxProps {\r\n /** \uD06C\uAE30 (small | medium) */\r\n size?: \"small\" | \"medium\";\r\n /** \uAC00\uB85C \uB9C8\uC9C4 */\r\n mx?: number;\r\n /** \uCF5C\uB860 \uD45C\uC2DC \uC5EC\uBD80 */\r\n visible?: boolean;\r\n /** \uCD94\uAC00 \uC2A4\uD0C0\uC77C */\r\n sx?: SxProps<Theme>;\r\n}\r\n\r\n/**\r\n * \uCF5C\uB860 \uC544\uC774\uCF58\uC744 \uAC10\uC2F8\uB294 \uBC15\uC2A4 \uCEF4\uD3EC\uB10C\uD2B8\r\n * TimeTextField\uC640 DateTimeTextField\uC5D0\uC11C \uACF5\uD1B5\uC73C\uB85C \uC0AC\uC6A9\r\n */\r\nexport function ColonBox({ size, mx, visible = true, sx }: ColonBoxProps) {\r\n return (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n userSelect: \"none\",\r\n minWidth: \"6px\",\r\n padding: 0,\r\n flexShrink: 0,\r\n position: \"relative\",\r\n zIndex: 1,\r\n opacity: visible ? 0.8 : 0,\r\n visibility: visible ? \"visible\" : \"hidden\",\r\n mx,\r\n ...sx,\r\n }}\r\n >\r\n <ColonSvg size={size} />\r\n </Box>\r\n );\r\n}\r\n", "/**\r\n * VerificationCodeTextField.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n useRef,\r\n ChangeEvent,\r\n KeyboardEvent,\r\n ClipboardEvent,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { Box, FormControl, InputLabel, OutlinedInput } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport type { VerificationCodeTextFieldProps } from \"./types\";\r\nimport { useDebouncedEmit } from \"./hooks\";\r\n\r\nconst VerificationCodeTextFieldBase = forwardRef<\r\n HTMLDivElement,\r\n VerificationCodeTextFieldProps\r\n>(function VerificationCodeTextFieldBase(\r\n {\r\n label,\r\n length = 6,\r\n type = \"numeric\",\r\n value,\r\n onChange,\r\n onComplete,\r\n debounce,\r\n readonly,\r\n disabled,\r\n size,\r\n name = \"\",\r\n fontSize: fontSizeProp,\r\n fontColor = \"text.primary\",\r\n fontFamily = \"monospace\",\r\n dotSize: dotSizeProp,\r\n caretColor = \"text.primary\",\r\n sx,\r\n invalidBorderColor,\r\n inputRef: externalInputRef,\r\n ...restProps\r\n },\r\n ref,\r\n) {\r\n const [internalValue, setInternalValue] = useState(\"\");\r\n const [isFocused, setIsFocused] = useState(false);\r\n const [isAllSelected, setIsAllSelected] = useState(false);\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(\r\n externalInputRef as React.Ref<HTMLInputElement>,\r\n () => internalInputRef.current!,\r\n [],\r\n );\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange, flushOnBlur, lastEmittedValue } = useDebouncedEmit({\r\n name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n // value prop \uB3D9\uAE30\uD654 (\uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uACBD\uC6B0\uB9CC)\r\n useEffect(() => {\r\n if (value !== undefined && value !== null) {\r\n const strValue = String(value).slice(0, length);\r\n // \uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uAC12\uC774 \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uD55C \uAC12\uACFC \uB2E4\uB97C \uB54C\uB9CC \uB3D9\uAE30\uD654\r\n if (strValue !== lastEmittedValue.current) {\r\n setInternalValue(strValue);\r\n lastEmittedValue.current = strValue;\r\n }\r\n } else if (lastEmittedValue.current !== \"\") {\r\n setInternalValue(\"\");\r\n lastEmittedValue.current = \"\";\r\n }\r\n }, [value, length, lastEmittedValue]);\r\n\r\n // \uC785\uB825 \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n const isValidChar = useCallback(\r\n (char: string): boolean => {\r\n if (type === \"numeric\") {\r\n return /^\\d$/.test(char);\r\n } else if (type === \"alpha\") {\r\n return /^[a-zA-Z]$/.test(char);\r\n } else {\r\n // alphanumeric\r\n return /^[a-zA-Z0-9]$/.test(char);\r\n }\r\n },\r\n [type],\r\n );\r\n\r\n // \uBB38\uC790\uC5F4 \uD544\uD130\uB9C1\r\n const filterValue = useCallback(\r\n (val: string): string => {\r\n let filtered = \"\";\r\n for (const char of val) {\r\n if (isValidChar(char)) {\r\n filtered += type === \"alpha\" ? char.toUpperCase() : char;\r\n }\r\n }\r\n return filtered.slice(0, length);\r\n },\r\n [isValidChar, length, type],\r\n );\r\n\r\n // \uBCC0\uACBD \uD578\uB4E4\uB7EC\r\n const handleChange = useCallback(\r\n (e: ChangeEvent<HTMLInputElement>) => {\r\n const filtered = filterValue(e.target.value);\r\n setInternalValue(filtered);\r\n setIsAllSelected(false); // \uC785\uB825 \uC2DC \uC804\uCCB4 \uC120\uD0DD \uD574\uC81C\r\n\r\n // \uB514\uBC14\uC6B4\uC2A4 \uC801\uC6A9\r\n emitChange(e, filtered);\r\n\r\n // \uC644\uB8CC \uC2DC \uCF5C\uBC31\r\n if (filtered.length === length && onComplete) {\r\n onComplete(filtered);\r\n }\r\n },\r\n [filterValue, length, onComplete, emitChange],\r\n );\r\n\r\n // \uBD99\uC5EC\uB123\uAE30 \uCC98\uB9AC\r\n const handlePaste = useCallback(\r\n (e: ClipboardEvent<HTMLInputElement>) => {\r\n e.preventDefault();\r\n const pastedText = e.clipboardData.getData(\"text\");\r\n const filtered = filterValue(pastedText);\r\n setInternalValue(filtered);\r\n\r\n // \uBD99\uC5EC\uB123\uAE30 \uC2DC \uC989\uC2DC emit\r\n emitChange(null, filtered, true);\r\n\r\n if (filtered.length === length && onComplete) {\r\n onComplete(filtered);\r\n }\r\n },\r\n [filterValue, length, onComplete, emitChange],\r\n );\r\n\r\n // \uD0A4 \uC785\uB825 \uCC98\uB9AC (\uBC31\uC2A4\uD398\uC774\uC2A4 \uB4F1)\r\n const handleKeyDown = useCallback((e: KeyboardEvent<HTMLInputElement>) => {\r\n // \uD2B9\uC218 \uD0A4\uB294 \uD5C8\uC6A9\r\n if (\r\n [\r\n \"Backspace\",\r\n \"Delete\",\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"Tab\",\r\n \"Home\",\r\n \"End\",\r\n ].includes(e.key)\r\n ) {\r\n return;\r\n }\r\n\r\n // Ctrl+A, Ctrl+C, Ctrl+V \uB4F1 \uD5C8\uC6A9\r\n if (e.ctrlKey || e.metaKey) {\r\n return;\r\n }\r\n }, []);\r\n\r\n // \uD074\uB9AD \uC2DC \uC804\uCCB4 \uC120\uD0DD\r\n const handleFocus = useCallback(() => {\r\n setIsFocused(true);\r\n setTimeout(() => {\r\n const input = internalInputRef.current;\r\n if (input && input.value.length > 0) {\r\n input.setSelectionRange(0, input.value.length);\r\n setIsAllSelected(true);\r\n }\r\n }, 0);\r\n }, []);\r\n\r\n // \uC774\uBBF8 \uD3EC\uCEE4\uC2A4\uB41C \uC0C1\uD0DC\uC5D0\uC11C \uD074\uB9AD\uD574\uB3C4 \uC804\uCCB4 \uC120\uD0DD\r\n const handleClick = useCallback(() => {\r\n const input = internalInputRef.current;\r\n if (input && input.value.length > 0) {\r\n input.setSelectionRange(0, input.value.length);\r\n setIsAllSelected(true);\r\n }\r\n }, []);\r\n\r\n // \uD3EC\uCEE4\uC2A4 \uD574\uC81C\r\n const handleBlur = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>) => {\r\n setIsFocused(false);\r\n setIsAllSelected(false);\r\n // blur \uC2DC \uB300\uAE30 \uC911\uC778 \uB514\uBC14\uC6B4\uC2A4 \uC989\uC2DC \uC2E4\uD589\r\n flushOnBlur(e, internalValue);\r\n },\r\n [internalValue, flushOnBlur],\r\n );\r\n\r\n // \uC0AC\uC774\uC988\uBCC4 \uC124\uC815\r\n const defaultFontSize = size === \"small\" ? 18 : 24;\r\n const defaultDotSize = size === \"small\" ? 10 : 14;\r\n const fontSize = fontSizeProp ?? defaultFontSize;\r\n const dotSize = dotSizeProp ?? defaultDotSize;\r\n const charWidth = Math.max(fontSize, size === \"small\" ? 18 : 22); // \uAE00\uC790 \uD558\uB098\uC758 \uB108\uBE44\r\n const gap = size === \"small\" ? 6 : 8; // \uAE00\uC790/dot \uAC04 \uAC04\uACA9\r\n const totalContentWidth = length * charWidth + (length - 1) * gap;\r\n const containerHeight = Math.max(size === \"small\" ? 40 : 56, fontSize + 16);\r\n const containerPadding = size === \"small\" ? 16 : 20;\r\n\r\n // inputMode \uC124\uC815\r\n const inputMode = type === \"numeric\" ? \"numeric\" : \"text\";\r\n\r\n // sx\uC5D0\uC11C width\uAC00 \uC9C0\uC815\uB418\uC5C8\uB294\uC9C0 \uD655\uC778\r\n const hasCustomWidth =\r\n sx &&\r\n typeof sx === \"object\" &&\r\n !Array.isArray(sx) &&\r\n (\"width\" in sx || \"minWidth\" in sx || \"maxWidth\" in sx);\r\n\r\n // showContent: label\uC774 \uC5C6\uAC70\uB098, \uD3EC\uCEE4\uC2A4/\uAC12\uC774 \uC788\uC744 \uB54C\r\n const showContent = !label || isFocused || internalValue.length > 0;\r\n\r\n // FormControl sx \uACC4\uC0B0\r\n const formControlWidth = hasCustomWidth\r\n ? ((sx as Record<string, unknown>)?.width as\r\n | string\r\n | number\r\n | undefined) ||\r\n ((sx as Record<string, unknown>)?.minWidth as\r\n | string\r\n | number\r\n | undefined) ||\r\n ((sx as Record<string, unknown>)?.maxWidth as\r\n | string\r\n | number\r\n | undefined)\r\n : totalContentWidth + containerPadding * 2;\r\n\r\n const formControlSx: SxProps<Theme> = {\r\n display: \"inline-flex\",\r\n width: formControlWidth,\r\n ...(readonly && { pointerEvents: \"none\" }),\r\n ...(sx as Record<string, unknown>),\r\n };\r\n\r\n return (\r\n <FormControl\r\n ref={ref}\r\n variant=\"outlined\"\r\n size={size}\r\n disabled={disabled}\r\n focused={readonly ? false : isFocused}\r\n sx={formControlSx}\r\n >\r\n {label && (\r\n <InputLabel\r\n shrink={isFocused || internalValue.length > 0}\r\n sx={{\r\n backgroundColor: \"background.paper\",\r\n px: 0.5,\r\n ...(readonly && {\r\n \"&.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }),\r\n }}\r\n >\r\n {label}\r\n </InputLabel>\r\n )}\r\n <OutlinedInput\r\n label={label}\r\n notched={\r\n label ? isFocused || internalValue.length > 0 : undefined\r\n }\r\n readOnly={readonly}\r\n onMouseDown={(e) => {\r\n e.preventDefault();\r\n internalInputRef.current?.focus();\r\n }}\r\n sx={{\r\n height: containerHeight,\r\n cursor: disabled ? \"default\" : \"text\",\r\n \"& .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: invalidBorderColor || undefined,\r\n },\r\n \"& .MuiOutlinedInput-input\": {\r\n padding: 0,\r\n height: \"100%\",\r\n },\r\n ...(readonly && {\r\n \"&:hover .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n }),\r\n }}\r\n inputProps={{\r\n style: { display: \"none\" },\r\n }}\r\n />\r\n {/* \uCEE4\uC2A4\uD140 \uB0B4\uC6A9\uBB3C \uB80C\uB354\uB9C1 */}\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n top: 0,\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n width: \"100%\",\r\n height: \"100%\",\r\n px: 1.75,\r\n pointerEvents: \"none\",\r\n }}\r\n >\r\n {/* \uB0B4\uC6A9\uBB3C \uCEE8\uD14C\uC774\uB108 */}\r\n <Box\r\n sx={{\r\n width: hasCustomWidth ? \"100%\" : totalContentWidth,\r\n height: \"100%\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n visibility: showContent ? \"visible\" : \"hidden\",\r\n }}\r\n >\r\n {/* Placeholder dots + \uC785\uB825\uB41C \uAE00\uC790 \uD45C\uC2DC */}\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n gap: hasCustomWidth ? 0 : `${gap}px`,\r\n width: hasCustomWidth ? \"100%\" : undefined,\r\n }}\r\n >\r\n {Array.from({ length }).map((_, i) => (\r\n <Box\r\n key={i}\r\n sx={{\r\n flex: hasCustomWidth ? 1 : undefined,\r\n width: hasCustomWidth\r\n ? undefined\r\n : charWidth,\r\n minWidth: charWidth,\r\n height: charWidth,\r\n display: \"flex\",\r\n justifyContent: \"center\",\r\n alignItems: \"center\",\r\n position: \"relative\",\r\n borderRadius: 0.5,\r\n backgroundColor:\r\n isAllSelected &&\r\n i < internalValue.length\r\n ? \"primary.main\"\r\n : \"transparent\",\r\n transition: \"background-color 0.1s\",\r\n }}\r\n >\r\n {i < internalValue.length ? (\r\n <Box\r\n component=\"span\"\r\n sx={{\r\n fontSize,\r\n fontFamily,\r\n fontWeight: 600,\r\n lineHeight: 1,\r\n color: isAllSelected\r\n ? \"white\"\r\n : fontColor,\r\n transition: \"color 0.1s\",\r\n }}\r\n >\r\n {internalValue[i]}\r\n </Box>\r\n ) : (\r\n <Box\r\n sx={{\r\n width: dotSize,\r\n height: dotSize,\r\n borderRadius: \"50%\",\r\n backgroundColor:\r\n \"rgba(0, 0, 0, 0.08)\",\r\n }}\r\n />\r\n )}\r\n {/* \uAE5C\uBE61\uC774\uB294 \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C */}\r\n {isFocused &&\r\n i === internalValue.length &&\r\n internalValue.length < length && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n bottom: -2,\r\n left: \"50%\",\r\n transform: \"translateX(-50%)\",\r\n width: \"0.6em\",\r\n height: \"1px\",\r\n backgroundColor: caretColor,\r\n animation:\r\n \"blink 1s step-end infinite\",\r\n \"@keyframes blink\": {\r\n \"0%, 100%\": {\r\n opacity: 1,\r\n },\r\n \"50%\": { opacity: 0 },\r\n },\r\n }}\r\n />\r\n )}\r\n </Box>\r\n ))}\r\n </Box>\r\n </Box>\r\n </Box>\r\n {/* \uC228\uACA8\uC9C4 \uC785\uB825 \uD544\uB4DC */}\r\n <input\r\n ref={internalInputRef}\r\n value={internalValue}\r\n onChange={handleChange}\r\n onKeyDown={handleKeyDown}\r\n onPaste={handlePaste}\r\n onFocus={handleFocus}\r\n onClick={handleClick}\r\n onBlur={handleBlur}\r\n disabled={disabled}\r\n readOnly={readonly}\r\n autoComplete=\"one-time-code\"\r\n spellCheck={false}\r\n maxLength={length}\r\n inputMode={inputMode}\r\n style={{\r\n position: \"absolute\",\r\n opacity: 0,\r\n width: 1,\r\n height: 1,\r\n pointerEvents: \"none\",\r\n textTransform:\r\n type === \"alpha\" || type === \"alphanumeric\"\r\n ? \"uppercase\"\r\n : \"none\",\r\n }}\r\n />\r\n </FormControl>\r\n );\r\n});\r\n\r\nconst VerificationCodeTextFieldWithForm = forwardRef<\r\n HTMLDivElement,\r\n VerificationCodeTextFieldProps\r\n>(function VerificationCodeTextFieldWithForm(\r\n { form, name, onChange, ...rest },\r\n ref,\r\n) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"VerificationCodeTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"VerificationCodeTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <VerificationCodeTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const VerificationCodeTextField = forwardRef<\r\n HTMLDivElement,\r\n VerificationCodeTextFieldProps\r\n>(function VerificationCodeTextField(props, ref) {\r\n if (props.form) {\r\n return <VerificationCodeTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <VerificationCodeTextFieldBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * EmailTextField.tsx\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n useRef,\r\n ChangeEvent,\r\n KeyboardEvent,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport {\r\n TextField,\r\n Box,\r\n Popper,\r\n Paper,\r\n List,\r\n ListItemButton,\r\n ListItemText,\r\n ListItemIcon,\r\n ClickAwayListener,\r\n} from \"@mui/material\";\r\nimport type { EmailTextFieldProps } from \"./types\";\r\nimport { getEmailIcon } from \"./icons/email-icons\";\r\nimport { useDebouncedEmit } from \"./hooks\";\r\nimport { DEFAULT_EMAIL_DOMAINS, validateEmail } from \"./utils\";\r\n\r\nconst EmailTextFieldBase = forwardRef<HTMLDivElement, EmailTextFieldProps>(function EmailTextFieldBase(\r\n {\r\n value,\r\n onChange,\r\n onValidationChange,\r\n domains = DEFAULT_EMAIL_DOMAINS,\r\n extraDomains,\r\n suggestions = true,\r\n showLogos = true,\r\n invalidBorderColor,\r\n debounce,\r\n readonly,\r\n sx,\r\n size,\r\n disabled,\r\n name = \"\",\r\n onBlur,\r\n fullWidth,\r\n inputRef: externalInputRef,\r\n ...props\r\n },\r\n ref\r\n) {\r\n // extraDomains\uAC00 \uC788\uC73C\uBA74 \uC55E\uC5D0 \uCD94\uAC00, \uC911\uBCF5 \uC81C\uAC70\r\n // customIcons: \uCEE4\uC2A4\uD140 \uC544\uC774\uCF58 \uB9E4\uD551 (domain -> ReactNode)\r\n const { allDomains, customIcons } = React.useMemo(() => {\r\n const icons: Record<string, React.ReactNode> = {};\r\n\r\n // extraDomains \uCC98\uB9AC (\uBB38\uC790\uC5F4 \uB610\uB294 CustomDomain \uAC1D\uCCB4)\r\n const extraDomainStrings: string[] = [];\r\n if (extraDomains && extraDomains.length > 0) {\r\n extraDomains.forEach((item) => {\r\n if (typeof item === \"string\") {\r\n extraDomainStrings.push(item);\r\n } else {\r\n // CustomDomain \uAC1D\uCCB4\r\n extraDomainStrings.push(item.domain);\r\n if (item.icon) {\r\n icons[item.domain.toLowerCase()] = item.icon;\r\n }\r\n }\r\n });\r\n }\r\n\r\n const combined = [...extraDomainStrings, ...domains];\r\n // \uC911\uBCF5 \uC81C\uAC70 (\uB300\uC18C\uBB38\uC790 \uBB34\uC2DC)\r\n const seen = new Set<string>();\r\n const uniqueDomains = combined.filter((domain) => {\r\n const lower = domain.toLowerCase();\r\n if (seen.has(lower)) return false;\r\n seen.add(lower);\r\n return true;\r\n });\r\n\r\n return { allDomains: uniqueDomains, customIcons: icons };\r\n }, [domains, extraDomains]);\r\n\r\n // \uB3C4\uBA54\uC778\uC5D0 \uD574\uB2F9\uD558\uB294 \uC544\uC774\uCF58 \uAC00\uC838\uC624\uAE30 (\uCEE4\uC2A4\uD140 \uC544\uC774\uCF58 \uC6B0\uC120)\r\n const getDomainIcon = useCallback(\r\n (domain: string, size: number): React.ReactNode => {\r\n const lowerDomain = domain.toLowerCase();\r\n if (customIcons[lowerDomain]) {\r\n return customIcons[lowerDomain];\r\n }\r\n return getEmailIcon(domain, size);\r\n },\r\n [customIcons]\r\n );\r\n\r\n const [inputValue, setInputValue] = useState(\"\");\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n const [localSuggestions, setLocalSuggestions] = useState<string[]>([]);\r\n const [showPopper, setShowPopper] = useState(false);\r\n const [selectedIndex, setSelectedIndex] = useState(-1);\r\n const internalInputRef = useRef<HTMLInputElement>(null);\r\n const anchorRef = useRef<HTMLDivElement>(null);\r\n\r\n // \uC678\uBD80 inputRef\uC640 \uB0B4\uBD80 inputRef \uBCD1\uD569\r\n useImperativeHandle(externalInputRef as React.Ref<HTMLInputElement>, () => internalInputRef.current!, []);\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange, flushOnBlur, lastEmittedValue } = useDebouncedEmit({\r\n name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n // value prop \uB3D9\uAE30\uD654 (\uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uACBD\uC6B0\uB9CC)\r\n useEffect(() => {\r\n if (value !== undefined && value !== null) {\r\n const strValue = String(value);\r\n // \uC678\uBD80\uC5D0\uC11C \uBCC0\uACBD\uB41C \uAC12\uC774 \uB9C8\uC9C0\uB9C9\uC73C\uB85C emit\uD55C \uAC12\uACFC \uB2E4\uB97C \uB54C\uB9CC \uB3D9\uAE30\uD654\r\n if (strValue !== lastEmittedValue.current) {\r\n setInputValue(strValue);\r\n lastEmittedValue.current = strValue;\r\n }\r\n } else if (lastEmittedValue.current !== \"\") {\r\n setInputValue(\"\");\r\n lastEmittedValue.current = \"\";\r\n }\r\n }, [value, lastEmittedValue]);\r\n\r\n // \uB3C4\uBA54\uC778 \uC81C\uC548 \uC0DD\uC131\r\n const generateSuggestions = useCallback(\r\n (input: string) => {\r\n if (!suggestions || !input || disabled || readonly) {\r\n setLocalSuggestions([]);\r\n return;\r\n }\r\n\r\n const atIndex = input.indexOf(\"@\");\r\n if (atIndex === -1) {\r\n // @ \uC5C6\uC73C\uBA74 \uC81C\uC548 \uC548 \uD568\r\n setLocalSuggestions([]);\r\n return;\r\n }\r\n\r\n const localPart = input.slice(0, atIndex);\r\n const domainPart = input.slice(atIndex + 1).toLowerCase();\r\n\r\n if (!localPart) {\r\n setLocalSuggestions([]);\r\n return;\r\n }\r\n\r\n // \uB3C4\uBA54\uC778 \uBD80\uBD84\uC774 \uBE44\uC5B4\uC788\uAC70\uB098 \uBD80\uBD84 \uC785\uB825\uB41C \uACBD\uC6B0\r\n const filteredDomains = allDomains.filter((domain) => domain.toLowerCase().startsWith(domainPart));\r\n\r\n // \uC774\uBBF8 \uC644\uC804\uD788 \uC77C\uCE58\uD558\uB294 \uB3C4\uBA54\uC778\uC774 \uC788\uC73C\uBA74 \uC81C\uC548 \uC548 \uD568\r\n if (filteredDomains.length === 1 && filteredDomains[0].toLowerCase() === domainPart) {\r\n setLocalSuggestions([]);\r\n return;\r\n }\r\n\r\n const newSuggestions = filteredDomains.slice(0, 10).map((domain) => `${localPart}@${domain}`);\r\n\r\n setLocalSuggestions(newSuggestions);\r\n setShowPopper(newSuggestions.length > 0);\r\n // \uCCAB \uBC88\uC9F8 \uD56D\uBAA9 \uC790\uB3D9 \uC120\uD0DD\r\n setSelectedIndex(newSuggestions.length > 0 ? 0 : -1);\r\n },\r\n [allDomains, suggestions, disabled]\r\n );\r\n\r\n // \uC785\uB825 \uBCC0\uACBD \uD578\uB4E4\uB7EC\r\n const handleChange = useCallback(\r\n (e: ChangeEvent<HTMLInputElement>) => {\r\n const newValue = e.target.value;\r\n setInputValue(newValue);\r\n generateSuggestions(newValue);\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n const isValid = validateEmail(newValue);\r\n const hasContent = newValue.length > 0;\r\n setIsInvalid(hasContent && !isValid);\r\n\r\n if (onValidationChange) {\r\n onValidationChange(isValid);\r\n }\r\n\r\n // \uB514\uBC14\uC6B4\uC2A4 \uC801\uC6A9\r\n emitChange(e, newValue);\r\n },\r\n [onValidationChange, generateSuggestions, emitChange]\r\n );\r\n\r\n // \uC81C\uC548 \uC120\uD0DD \uD578\uB4E4\uB7EC\r\n const handleSelectSuggestion = useCallback(\r\n (suggestion: string) => {\r\n setInputValue(suggestion);\r\n setLocalSuggestions([]);\r\n setShowPopper(false);\r\n setSelectedIndex(-1);\r\n\r\n const isValid = validateEmail(suggestion);\r\n setIsInvalid(!isValid);\r\n\r\n if (onValidationChange) {\r\n onValidationChange(isValid);\r\n }\r\n\r\n // \uC81C\uC548 \uC120\uD0DD \uC2DC \uC989\uC2DC emit\r\n emitChange(null, suggestion, true);\r\n\r\n // \uD3EC\uCEE4\uC2A4 \uC720\uC9C0\r\n internalInputRef.current?.focus();\r\n },\r\n [onValidationChange, emitChange]\r\n );\r\n\r\n // \uD0A4\uBCF4\uB4DC \uB124\uBE44\uAC8C\uC774\uC158\r\n const handleKeyDown = useCallback(\r\n (e: KeyboardEvent<HTMLInputElement>) => {\r\n if (!showPopper || localSuggestions.length === 0) return;\r\n\r\n switch (e.key) {\r\n case \"ArrowDown\":\r\n e.preventDefault();\r\n setSelectedIndex((prev) => (prev < localSuggestions.length - 1 ? prev + 1 : 0));\r\n break;\r\n case \"ArrowUp\":\r\n e.preventDefault();\r\n setSelectedIndex((prev) => (prev > 0 ? prev - 1 : localSuggestions.length - 1));\r\n break;\r\n case \"Enter\":\r\n // \uC120\uD0DD\uB41C \uD56D\uBAA9\uC774 \uC788\uC73C\uBA74 \uD574\uB2F9 \uD56D\uBAA9, \uC5C6\uC73C\uBA74 \uCCAB \uBC88\uC9F8 \uD56D\uBAA9 \uC120\uD0DD\r\n e.preventDefault();\r\n if (selectedIndex >= 0) {\r\n handleSelectSuggestion(localSuggestions[selectedIndex]);\r\n } else if (localSuggestions.length > 0) {\r\n handleSelectSuggestion(localSuggestions[0]);\r\n }\r\n break;\r\n case \"Escape\":\r\n e.preventDefault();\r\n setShowPopper(false);\r\n setSelectedIndex(-1);\r\n break;\r\n case \"Tab\":\r\n if (selectedIndex >= 0) {\r\n e.preventDefault();\r\n handleSelectSuggestion(localSuggestions[selectedIndex]);\r\n } else if (localSuggestions.length > 0) {\r\n e.preventDefault();\r\n handleSelectSuggestion(localSuggestions[0]);\r\n }\r\n break;\r\n }\r\n },\r\n [showPopper, localSuggestions, selectedIndex, handleSelectSuggestion]\r\n );\r\n\r\n // \uD074\uB9AD \uC678\uBD80 \uCC98\uB9AC\r\n const handleClickAway = useCallback(() => {\r\n setShowPopper(false);\r\n setSelectedIndex(-1);\r\n }, []);\r\n\r\n // blur \uC2DC \uB300\uAE30 \uC911\uC778 \uB514\uBC14\uC6B4\uC2A4 \uC989\uC2DC \uC2E4\uD589\r\n const handleBlur = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>) => {\r\n flushOnBlur(e, inputValue);\r\n if (onBlur) {\r\n onBlur(e);\r\n }\r\n },\r\n [inputValue, flushOnBlur, onBlur]\r\n );\r\n\r\n // \uD3EC\uCEE4\uC2A4 \uC2DC \uC81C\uC548 \uB2E4\uC2DC \uD45C\uC2DC\r\n const handleFocus = useCallback(() => {\r\n if (localSuggestions.length > 0) {\r\n setShowPopper(true);\r\n } else {\r\n generateSuggestions(inputValue);\r\n }\r\n }, [localSuggestions, inputValue, generateSuggestions]);\r\n\r\n // \uD14C\uB450\uB9AC \uC0C9\uC0C1\r\n const borderColor = isInvalid && invalidBorderColor ? invalidBorderColor : undefined;\r\n\r\n // anchorRef\uC640 \uC678\uBD80 ref\uB97C \uB3D9\uAE30\uD654\r\n const setRefs = useCallback(\r\n (node: HTMLDivElement | null) => {\r\n anchorRef.current = node;\r\n if (typeof ref === \"function\") {\r\n ref(node);\r\n } else if (ref) {\r\n (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\r\n }\r\n },\r\n [ref]\r\n );\r\n\r\n return (\r\n <ClickAwayListener onClickAway={handleClickAway}>\r\n <Box\r\n ref={setRefs}\r\n sx={{\r\n position: \"relative\",\r\n ...(fullWidth && { width: \"100%\" }),\r\n ...sx,\r\n }}\r\n >\r\n <TextField\r\n {...props}\r\n inputRef={internalInputRef}\r\n name={name}\r\n value={inputValue}\r\n onChange={handleChange}\r\n onKeyDown={handleKeyDown}\r\n onFocus={handleFocus}\r\n onBlur={handleBlur}\r\n disabled={disabled}\r\n size={size}\r\n fullWidth={fullWidth}\r\n type=\"email\"\r\n autoComplete=\"email\"\r\n autoCapitalize=\"off\"\r\n autoCorrect=\"off\"\r\n spellCheck=\"false\"\r\n sx={{\r\n width: \"100%\",\r\n ...(borderColor && {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": {\r\n borderColor: borderColor,\r\n },\r\n \"&:hover fieldset\": {\r\n borderColor: borderColor,\r\n },\r\n \"&.Mui-focused fieldset\": {\r\n borderColor: borderColor,\r\n },\r\n },\r\n }),\r\n ...(readonly && {\r\n pointerEvents: \"none\",\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline\": {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }),\r\n }}\r\n slotProps={{\r\n ...props.slotProps,\r\n input: {\r\n ...props.slotProps?.input,\r\n readOnly: readonly,\r\n },\r\n htmlInput: {\r\n ...props.slotProps?.htmlInput,\r\n inputMode: \"email\",\r\n },\r\n }}\r\n />\r\n <Popper\r\n open={showPopper && localSuggestions.length > 0}\r\n anchorEl={anchorRef.current}\r\n placement=\"bottom-start\"\r\n style={{\r\n zIndex: 1300,\r\n width: anchorRef.current?.offsetWidth,\r\n }}\r\n >\r\n <Paper elevation={3} sx={{ mt: 0.5 }}>\r\n <List dense disablePadding>\r\n {localSuggestions.map((suggestion, index) => {\r\n const domain = suggestion.split(\"@\")[1];\r\n const iconSize = size === \"small\" ? 16 : 20;\r\n return (\r\n <ListItemButton\r\n key={suggestion}\r\n selected={index === selectedIndex}\r\n onClick={() => handleSelectSuggestion(suggestion)}\r\n sx={{\r\n py: 0.5,\r\n \"&.Mui-selected\": {\r\n backgroundColor: \"action.selected\",\r\n },\r\n }}\r\n >\r\n {showLogos && (\r\n <ListItemIcon sx={{ minWidth: 32 }}>\r\n {getDomainIcon(domain, iconSize)}\r\n </ListItemIcon>\r\n )}\r\n <ListItemText\r\n primary={suggestion}\r\n primaryTypographyProps={{\r\n fontSize: size === \"small\" ? 14 : 16,\r\n }}\r\n />\r\n </ListItemButton>\r\n );\r\n })}\r\n </List>\r\n </Paper>\r\n </Popper>\r\n </Box>\r\n </ClickAwayListener>\r\n );\r\n});\r\n\r\nconst EmailTextFieldWithForm = forwardRef<HTMLDivElement, EmailTextFieldProps>(function EmailTextFieldWithForm(\r\n { form, name, onChange, ...rest },\r\n ref\r\n) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\"EmailTextField form prop is missing. Provide a form from useForm or useGlobalForm.\");\r\n }\r\n if (!name) {\r\n throw new Error(\"EmailTextField requires a name when form prop is provided.\");\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange]\r\n );\r\n\r\n return <EmailTextFieldBase {...rest} ref={ref} name={name} value={formValue} onChange={handleFormChange} />;\r\n});\r\n\r\nexport const EmailTextField = forwardRef<HTMLDivElement, EmailTextFieldProps>(function EmailTextField(props, ref) {\r\n if (props.form) {\r\n return <EmailTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <EmailTextFieldBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * email-icons.tsx\r\n *\r\n * \uC774\uBA54\uC77C \uB3C4\uBA54\uC778 \uC544\uC774\uCF58 \uCEF4\uD3EC\uB10C\uD2B8\r\n *\r\n * @license MIT\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React from \"react\";\r\n\r\ninterface IconProps {\r\n size?: number;\r\n}\r\n\r\n// Gmail - \uACF5\uC2DD Gmail \uB85C\uACE0\r\nexport const GmailIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"52 42 88 66\" fill=\"none\">\r\n <path fill=\"#4285f4\" d=\"M58 108h14V74L52 59v43c0 3.32 2.69 6 6 6\" />\r\n <path fill=\"#34a853\" d=\"M120 108h14c3.32 0 6-2.69 6-6V59l-20 15\" />\r\n <path\r\n fill=\"#fbbc04\"\r\n d=\"M120 48v26l20-15v-8c0-7.42-8.47-11.65-14.4-7.2\"\r\n />\r\n <path fill=\"#ea4335\" d=\"M72 74V48l24 18 24-18v26L96 92\" />\r\n <path\r\n fill=\"#c5221f\"\r\n d=\"M52 51v8l20 15V48l-5.6-4.2c-5.94-4.45-14.4-.22-14.4 7.2\"\r\n />\r\n </svg>\r\n);\r\n\r\n// Naver\r\nexport const NaverIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\">\r\n <rect width=\"24\" height=\"24\" rx=\"4\" fill=\"#03C75A\" />\r\n <path\r\n d=\"M14.4 12.6L9.3 5.4H6v13.2h3.6v-7.2l5.1 7.2H18V5.4h-3.6v7.2z\"\r\n fill=\"white\"\r\n />\r\n </svg>\r\n);\r\n\r\n// Daum / Hanmail - \uB2E4\uC74C \uACF5\uC2DD \uB85C\uACE0 (\uBC30\uACBD + \uD770\uC0C9 D)\r\nexport const DaumIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 52 52\" fill=\"none\">\r\n {/* \uB124\uC774\uBE44 \uBC30\uACBD */}\r\n <rect width=\"52\" height=\"52\" rx=\"8\" fill=\"#273552\" />\r\n {/* \uD770\uC0C9 D \uAE00\uC790 */}\r\n <path\r\n d=\"m 25.52,20.36 c 3.1152,0 5.6352,2.712 5.5152,5.8536 -0.1128,2.988 -2.6616,5.4264 -5.652,5.4264 h -3.9456 c -0.264,0 -0.48,-0.216 -0.48,-0.48 V 20.84 c 0,-0.264 0.216,-0.48 0.48,-0.48 h 4.08 M 25.52,14 h -9.6 c -0.7944,0 -1.44,0.6456 -1.44,1.44 v 21.12 c 0,0.7944 0.6456,1.44 1.44,1.44 H 25.52 C 32.1464,38 37.52,32.6264 37.52,26 37.52,19.3736 32.1464,14 25.52,14 Z\"\r\n fill=\"white\"\r\n />\r\n </svg>\r\n);\r\n\r\n// Kakao\r\nexport const KakaoIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\">\r\n <rect width=\"24\" height=\"24\" rx=\"4\" fill=\"#FEE500\" />\r\n <path\r\n d=\"M12 5C7.58 5 4 7.79 4 11.15c0 2.13 1.42 4.01 3.58 5.08-.16.57-.57 2.07-.65 2.39-.1.4.15.39.31.28.13-.08 2.04-1.38 2.87-1.94.6.09 1.23.14 1.89.14 4.42 0 8-2.79 8-6.15S16.42 5 12 5z\"\r\n fill=\"#3C1E1E\"\r\n />\r\n </svg>\r\n);\r\n\r\n// Nate\r\n// Nate - \uB124\uC774\uD2B8 \uB85C\uACE0 (\uBE68\uAC04\uC0C9 \uBC30\uACBD + \uD770\uC0C9 n)\r\nexport const NateIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\">\r\n {/* \uBE68\uAC04\uC0C9 \uB465\uADFC \uBC30\uACBD */}\r\n <rect width=\"24\" height=\"24\" rx=\"4\" fill=\"#FF2F1A\" />\r\n {/* \uD770\uC0C9 n \uAE00\uC790 */}\r\n <path\r\n d=\"M6 8V18H9V13C9 11.5 10 10.5 12 10.5C14 10.5 15 11.5 15 13V18H18V12C18 9 15.5 7 12 7C10 7 8 7.8 6 8Z\"\r\n fill=\"white\"\r\n />\r\n </svg>\r\n);\r\n\r\n// Hotmail / Outlook - Microsoft \uB85C\uACE0\r\nexport const OutlookIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 48 48\" fill=\"none\">\r\n <path fill=\"#ff5722\" d=\"M6 6H22V22H6z\" transform=\"rotate(-180 14 14)\" />\r\n <path\r\n fill=\"#4caf50\"\r\n d=\"M26 6H42V22H26z\"\r\n transform=\"rotate(-180 34 14)\"\r\n />\r\n <path\r\n fill=\"#ffc107\"\r\n d=\"M26 26H42V42H26z\"\r\n transform=\"rotate(-180 34 34)\"\r\n />\r\n <path\r\n fill=\"#03a9f4\"\r\n d=\"M6 26H22V42H6z\"\r\n transform=\"rotate(-180 14 34)\"\r\n />\r\n </svg>\r\n);\r\n\r\n// Yahoo - \uACF5\uC2DD \uB85C\uACE0\r\nexport const YahooIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 48 48\" fill=\"none\">\r\n <polygon\r\n fill=\"#5e35b1\"\r\n points=\"4.209,14.881 11.632,14.881 16.189,26.715 20.966,14.881 28.315,14.881 17.07,42 9.501,42 12.587,34.96\"\r\n />\r\n <circle cx=\"29.276\" cy=\"30.522\" r=\"4.697\" fill=\"#5e35b1\" />\r\n <polygon\r\n fill=\"#5e35b1\"\r\n points=\"34.693,6 27.213,24.042 35.444,24.042 42.925,6\"\r\n />\r\n </svg>\r\n);\r\n\r\n// iCloud - Apple \uAD6C\uB984 \uB85C\uACE0\r\nexport const ICloudIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 48 48\" fill=\"none\">\r\n {/* \uD558\uB298\uC0C9 \uADF8\uB77C\uB370\uC774\uC158 \uAD6C\uB984 - \uD06C\uAC8C, \uC911\uC559 \uC815\uB82C */}\r\n <path\r\n d=\"M44 26c0-4.42-3.58-8-8-8-.43 0-.85.04-1.27.1C33.57 11.77 28.03 7 21.5 7 13.49 7 7 13.49 7 21.5c0 .42.01.83.05 1.23-.04 0-.07-.01-.11-.01C3.63 22.72 1 25.35 1 28.66 1 32.16 3.84 35 7.34 35H36c4.42 0 8-3.58 8-8v-1z\"\r\n fill=\"url(#icloud_gradient)\"\r\n />\r\n <defs>\r\n <linearGradient\r\n id=\"icloud_gradient\"\r\n x1=\"24\"\r\n y1=\"7\"\r\n x2=\"24\"\r\n y2=\"35\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n >\r\n <stop stopColor=\"#6AC4F7\" />\r\n <stop offset=\"1\" stopColor=\"#3693F3\" />\r\n </linearGradient>\r\n </defs>\r\n </svg>\r\n);\r\n\r\n// \uAE30\uBCF8 \uC774\uBA54\uC77C \uC544\uC774\uCF58 (\uC54C \uC218 \uC5C6\uB294 \uB3C4\uBA54\uC778\uC6A9) - \uC9C4\uD68C\uC0C9 \uC544\uC6C3\uB77C\uC778\r\nexport const DefaultEmailIcon: React.FC<IconProps> = ({ size = 16 }) => (\r\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\">\r\n {/* \uBD09\uD22C \uBCF8\uCCB4 */}\r\n <rect\r\n x=\"2\"\r\n y=\"4\"\r\n width=\"20\"\r\n height=\"16\"\r\n rx=\"2\"\r\n stroke=\"#666666\"\r\n strokeWidth=\"2\"\r\n fill=\"none\"\r\n />\r\n {/* \uBD09\uD22C \uB36E\uAC1C */}\r\n <path\r\n d=\"M2 6l10 7 10-7\"\r\n stroke=\"#666666\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n fill=\"none\"\r\n />\r\n </svg>\r\n);\r\n\r\n/**\r\n * \uB3C4\uBA54\uC778\uC5D0 \uD574\uB2F9\uD558\uB294 \uC544\uC774\uCF58 \uCEF4\uD3EC\uB10C\uD2B8 \uBC18\uD658\r\n */\r\nexport function getEmailIcon(\r\n domain: string,\r\n size: number = 16\r\n): React.ReactNode {\r\n const lowerDomain = domain.toLowerCase();\r\n\r\n switch (lowerDomain) {\r\n case \"gmail.com\":\r\n return <GmailIcon size={size} />;\r\n case \"naver.com\":\r\n return <NaverIcon size={size} />;\r\n case \"daum.net\":\r\n case \"hanmail.net\":\r\n return <DaumIcon size={size} />;\r\n case \"kakao.com\":\r\n return <KakaoIcon size={size} />;\r\n case \"nate.com\":\r\n return <NateIcon size={size} />;\r\n case \"hotmail.com\":\r\n case \"outlook.com\":\r\n return <OutlookIcon size={size} />;\r\n case \"yahoo.com\":\r\n return <YahooIcon size={size} />;\r\n case \"icloud.com\":\r\n return <ICloudIcon size={size} />;\r\n default:\r\n return <DefaultEmailIcon size={size} />;\r\n }\r\n}\r\n", "/**\r\n * TimeTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n useRef,\r\n useMemo,\r\n ChangeEvent,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField, Box } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport type { TimeTextFieldProps } from \"./types\";\r\nimport { ClockIcon } from \"./icons\";\r\nimport { ColonBox, GroupedInputWrapper } from \"./components\";\r\nimport { useGroupedInput, GroupConfig } from \"./hooks/useGroupedInput\";\r\nimport { TimePicker } from \"@ehfuse/mui-datetime-picker\";\r\nimport { getTimeFieldCount, validateTime } from \"./utils\";\r\n\r\nconst TimeTextFieldBase = forwardRef<HTMLDivElement, TimeTextFieldProps>(function TimeTextFieldBase(\r\n {\r\n label,\r\n format = \"HH:mm\",\r\n minTime,\r\n maxTime,\r\n clockIcon = true,\r\n minuteStep = 1,\r\n secondStep = 1,\r\n hideDisabledTime = false,\r\n invalidBorderColor,\r\n debounce,\r\n sx,\r\n value,\r\n onChange,\r\n onBlur,\r\n name = \"\",\r\n disabled,\r\n readonly = false,\r\n size,\r\n fullWidth = false,\r\n className,\r\n id,\r\n fontSize,\r\n fontColor,\r\n fontFamily,\r\n },\r\n ref\r\n) {\r\n const [hourValue, setHourValue] = useState(\"\");\r\n const [minuteValue, setMinuteValue] = useState(\"\");\r\n const [secondValue, setSecondValue] = useState(\"\");\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n const [isInternalChange, setIsInternalChange] = useState(false);\r\n const [pickerOpen, setPickerOpen] = useState(false);\r\n\r\n const hourRef = useRef<HTMLInputElement>(null);\r\n const minuteRef = useRef<HTMLInputElement>(null);\r\n const secondRef = useRef<HTMLInputElement>(null);\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n // \uC678\uBD80 ref\uC640 \uB0B4\uBD80 containerRef \uBCD1\uD569\r\n useImperativeHandle(ref, () => containerRef.current!, []);\r\n\r\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n const fieldCount = getTimeFieldCount(format);\r\n const hasSecond = fieldCount === 3;\r\n\r\n // \uD3F0\uD2B8 \uD06C\uAE30 \uACC4\uC0B0\r\n const defaultFontSize = size === \"small\" ? 16 : 18;\r\n const computedFontSize = fontSize\r\n ? typeof fontSize === \"number\"\r\n ? fontSize\r\n : parseFloat(fontSize) * (fontSize.toString().includes(\"rem\") ? 16 : 1)\r\n : defaultFontSize;\r\n const cursorHeight = \"1px\";\r\n const cursorWidth = `${computedFontSize * 0.55}px`;\r\n\r\n // useGroupedInput \uD6C5 \uC0AC\uC6A9\r\n const groups: GroupConfig[] = useMemo(\r\n () =>\r\n hasSecond\r\n ? [\r\n {\r\n maxLength: 2,\r\n ref: hourRef,\r\n value: hourValue,\r\n setValue: setHourValue,\r\n },\r\n {\r\n maxLength: 2,\r\n ref: minuteRef,\r\n value: minuteValue,\r\n setValue: setMinuteValue,\r\n },\r\n {\r\n maxLength: 2,\r\n ref: secondRef,\r\n value: secondValue,\r\n setValue: setSecondValue,\r\n },\r\n ]\r\n : [\r\n {\r\n maxLength: 2,\r\n ref: hourRef,\r\n value: hourValue,\r\n setValue: setHourValue,\r\n },\r\n {\r\n maxLength: 2,\r\n ref: minuteRef,\r\n value: minuteValue,\r\n setValue: setMinuteValue,\r\n },\r\n ],\r\n [hourValue, minuteValue, secondValue, hasSecond]\r\n );\r\n\r\n const {\r\n focusedGroup,\r\n setFocusedGroup,\r\n cursorVisible,\r\n inputComplete,\r\n getCursorLeft,\r\n createMouseDownHandler,\r\n createClickHandler,\r\n createFocusHandler,\r\n createBlurHandler,\r\n createKeyDownHandler,\r\n createChangeHandler: createGroupChangeHandler,\r\n } = useGroupedInput({\r\n groups,\r\n fontSize: computedFontSize,\r\n disabled,\r\n readonly,\r\n });\r\n\r\n useEffect(() => {\r\n return () => {\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n }\r\n };\r\n }, []);\r\n\r\n // value prop \uBCC0\uACBD \uC2DC \uB0B4\uBD80 \uC0C1\uD0DC \uB3D9\uAE30\uD654\r\n useEffect(() => {\r\n if (isInternalChange) {\r\n setIsInternalChange(false);\r\n return;\r\n }\r\n\r\n if (value !== undefined && value !== null) {\r\n const strValue = String(value).replace(/[^\\d:]/g, \"\");\r\n const parts = strValue.split(\":\");\r\n\r\n if (parts.length >= 2) {\r\n setHourValue(parts[0].slice(0, 2));\r\n setMinuteValue(parts[1].slice(0, 2));\r\n if (hasSecond && parts[2]) {\r\n setSecondValue(parts[2].slice(0, 2));\r\n }\r\n } else {\r\n const numbers = strValue.replace(/\\D/g, \"\");\r\n setHourValue(numbers.slice(0, 2));\r\n setMinuteValue(numbers.slice(2, 4));\r\n if (hasSecond) {\r\n setSecondValue(numbers.slice(4, 6));\r\n }\r\n }\r\n } else {\r\n setHourValue(\"\");\r\n setMinuteValue(\"\");\r\n setSecondValue(\"\");\r\n }\r\n }, [value, hasSecond, isInternalChange]);\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uBC0F onChange \uD638\uCD9C\r\n const emitChange = useCallback(\r\n (hour: string, minute: string, second: string) => {\r\n const isComplete = hasSecond\r\n ? hour.length === 2 && minute.length === 2 && second.length === 2\r\n : hour.length === 2 && minute.length === 2;\r\n\r\n const isValid = isComplete ? validateTime(hour, minute, second, format, minTime, maxTime) : true;\r\n\r\n setIsInvalid(isComplete && !isValid);\r\n\r\n const doEmit = () => {\r\n if (onChange) {\r\n setIsInternalChange(true);\r\n const timeString = hasSecond ? `${hour}:${minute}:${second}` : `${hour}:${minute}`;\r\n\r\n const event = {\r\n target: { name, value: timeString },\r\n } as ChangeEvent<HTMLInputElement>;\r\n onChange(event);\r\n }\r\n };\r\n\r\n if (debounceTimer.current) {\r\n clearTimeout(debounceTimer.current);\r\n }\r\n\r\n if (debounce === undefined || debounce === 0) {\r\n doEmit();\r\n } else {\r\n debounceTimer.current = setTimeout(doEmit, debounce);\r\n }\r\n },\r\n [onChange, name, hasSecond, format, minTime, maxTime, debounce]\r\n );\r\n\r\n // \uC2DC\uAC04 \uAC12 \uC81C\uD55C (\uC2DC: 0-23 \uB610\uB294 0-12, \uBD84/\uCD08: 0-59)\r\n // 24\uC2DC\uAC04 \uD615\uC2DD\uC5D0\uC11C 24 \uC774\uC0C1\uC744 \uC785\uB825\uD558\uBA74 24\uB97C \uBE7C\uC11C \uBCC0\uD658 (24\u219200, 25\u219201, ...)\r\n const clampTimeValue = useCallback(\r\n (value: string, type: \"hour\" | \"minute\" | \"second\"): string => {\r\n if (value.length === 0) return value;\r\n\r\n // \uCCAB \uBC88\uC9F8 \uC790\uB9AC \uC785\uB825 \uC2DC: \uC720\uD6A8 \uBC94\uC704 \uCD08\uACFC\uD558\uBA74 \uC55E\uC5D0 0\uC744 \uBD99\uC5EC\uC11C \uB450 \uC790\uB9AC\uB85C\r\n if (value.length === 1) {\r\n const digit = parseInt(value, 10);\r\n if (type === \"hour\") {\r\n // \uC2DC: 12\uC2DC\uAC04 \uD615\uC2DD\uC774\uBA74 1\uAE4C\uC9C0, 24\uC2DC\uAC04 \uD615\uC2DD\uC774\uBA74 2\uAE4C\uC9C0\r\n const maxFirstDigit = format.startsWith(\"hh\") ? 1 : 2;\r\n // \uCCAB \uC790\uB9AC\uAC00 \uBC94\uC704 \uCD08\uACFC\uD558\uBA74 \uC55E\uC5D0 0\uC744 \uBD99\uC5EC\uC11C \uB450 \uC790\uB9AC\uB85C \uB9CC\uB4E6\r\n if (digit > maxFirstDigit) return `0${digit}`;\r\n } else {\r\n // \uBD84/\uCD08: \uCCAB \uC790\uB9AC\uB294 0-5\uB9CC \uAC00\uB2A5, 6-9\uBA74 \uC55E\uC5D0 0 \uBD99\uC784\r\n if (digit > 5) return `0${digit}`;\r\n }\r\n return value;\r\n }\r\n\r\n // \uB450 \uBC88\uC9F8 \uC790\uB9AC\uAE4C\uC9C0 \uC785\uB825 \uC644\uB8CC \uC2DC \uC81C\uD55C\r\n const num = parseInt(value, 10);\r\n if (isNaN(num)) return value;\r\n\r\n if (type === \"hour\") {\r\n const is12Hour = format.startsWith(\"hh\");\r\n // 24\uC2DC\uAC04 \uD615\uC2DD\uC5D0\uC11C 24 \uC774\uC0C1\uC744 \uC785\uB825\uD558\uBA74 24\uB97C \uBE7C\uC11C \uBCC0\uD658\r\n if (!is12Hour && num >= 24) {\r\n return String(num - 24).padStart(2, \"0\");\r\n }\r\n const maxHour = is12Hour ? 12 : 23;\r\n if (num > maxHour) return String(maxHour).padStart(2, \"0\");\r\n } else {\r\n // minute or second\r\n if (num > 59) return \"59\";\r\n }\r\n return value;\r\n },\r\n [format]\r\n );\r\n\r\n // \uC785\uB825 \uD578\uB4E4\uB7EC (\uD6C5\uC758 \uD578\uB4E4\uB7EC + \uCEE4\uC2A4\uD140 \uB85C\uC9C1)\r\n const handleChange = (groupIndex: number) => {\r\n return createGroupChangeHandler(groupIndex, (newValue, idx) => {\r\n // \uAC12 \uC81C\uD55C \uC801\uC6A9\r\n let clampedValue = newValue;\r\n if (idx === 0) {\r\n clampedValue = clampTimeValue(newValue, \"hour\");\r\n } else if (idx === 1) {\r\n clampedValue = clampTimeValue(newValue, \"minute\");\r\n } else if (idx === 2) {\r\n clampedValue = clampTimeValue(newValue, \"second\");\r\n }\r\n\r\n // \uAC12\uC774 \uBCC0\uACBD\uB418\uC5C8\uC73C\uBA74 \uC0C1\uD0DC \uC5C5\uB370\uC774\uD2B8\r\n if (clampedValue !== newValue) {\r\n groups[idx].setValue(clampedValue);\r\n\r\n // clamp\uB85C \uC778\uD574 2\uC790\uB9AC\uAC00 \uB418\uC5C8\uC73C\uBA74 \uB2E4\uC74C \uD544\uB4DC\uB85C \uC774\uB3D9\r\n if (clampedValue.length === 2 && newValue.length === 1 && idx < groups.length - 1) {\r\n const refs = [hourRef, minuteRef, secondRef];\r\n setTimeout(() => {\r\n refs[idx + 1].current?.focus();\r\n refs[idx + 1].current?.setSelectionRange(0, 0);\r\n }, 0);\r\n }\r\n }\r\n\r\n const newValues = [hourValue, minuteValue, secondValue];\r\n newValues[idx] = clampedValue;\r\n emitChange(newValues[0], newValues[1], newValues[2] || \"\");\r\n });\r\n };\r\n\r\n // \uD0A4 \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleKeyDown = (groupIndex: number) => {\r\n return createKeyDownHandler(groupIndex, (newValue, idx) => {\r\n const newValues = [hourValue, minuteValue, secondValue];\r\n newValues[idx] = newValue;\r\n emitChange(newValues[0], newValues[1], newValues[2] || \"\");\r\n });\r\n };\r\n\r\n // blur \uD578\uB4E4\uB7EC\r\n const handleBlur = useCallback(() => {\r\n const blurHandler = createBlurHandler();\r\n blurHandler();\r\n\r\n // \uC2DC\uAC04 \uADF8\uB8F9 \uB0B4 \uB2E4\uB978 \uD544\uB4DC\uB85C \uD3EC\uCEE4\uC2A4 \uC774\uB3D9 \uC2DC \uD328\uB529\uD558\uC9C0 \uC54A\uC74C\r\n setTimeout(() => {\r\n const activeElement = document.activeElement;\r\n const isStillInTimeGroup =\r\n activeElement === hourRef.current ||\r\n activeElement === minuteRef.current ||\r\n activeElement === secondRef.current;\r\n\r\n if (!isStillInTimeGroup) {\r\n // 1\uC790\uB9AC \uC2DC\uAC04 \uAC12\uC744 2\uC790\uB9AC\uB85C \uD328\uB529\r\n if (hourValue.length === 1) {\r\n setHourValue(hourValue.padStart(2, \"0\"));\r\n }\r\n if (minuteValue.length === 1) {\r\n setMinuteValue(minuteValue.padStart(2, \"0\"));\r\n }\r\n if (secondValue.length === 1) {\r\n setSecondValue(secondValue.padStart(2, \"0\"));\r\n }\r\n }\r\n }, 0);\r\n\r\n if (onBlur) {\r\n const paddedHour = hourValue.length === 1 ? hourValue.padStart(2, \"0\") : hourValue;\r\n const paddedMinute = minuteValue.length === 1 ? minuteValue.padStart(2, \"0\") : minuteValue;\r\n const paddedSecond = secondValue.length === 1 ? secondValue.padStart(2, \"0\") : secondValue;\r\n const timeString = hasSecond\r\n ? `${paddedHour}:${paddedMinute}:${paddedSecond}`\r\n : `${paddedHour}:${paddedMinute}`;\r\n const event = {\r\n target: { name, value: timeString },\r\n } as React.FocusEvent<HTMLInputElement>;\r\n onBlur(event);\r\n }\r\n }, [createBlurHandler, onBlur, hasSecond, hourValue, minuteValue, secondValue, name]);\r\n\r\n // \uD074\uB9AD \uC2DC \uD3EC\uCEE4\uC2A4\uD560 ref \uACB0\uC815\r\n const getTargetRefOnClick = useCallback(() => {\r\n const values = hasSecond ? [hourValue, minuteValue, secondValue] : [hourValue, minuteValue];\r\n const refs = hasSecond ? [hourRef, minuteRef, secondRef] : [hourRef, minuteRef];\r\n\r\n // \uB9C8\uC9C0\uB9C9\uC73C\uB85C \uAC12\uC774 \uC788\uB294 \uADF8\uB8F9 \uCC3E\uAE30\r\n let lastFilledIndex = -1;\r\n for (let i = values.length - 1; i >= 0; i--) {\r\n if (values[i].length > 0) {\r\n lastFilledIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n if (lastFilledIndex >= 0) {\r\n return {\r\n ref: refs[lastFilledIndex],\r\n groupIndex: lastFilledIndex,\r\n };\r\n }\r\n // \uBAA8\uB450 \uBE44\uC5B4\uC788\uC73C\uBA74 \uCCAB \uBC88\uC9F8 \uCE78\r\n return { ref: hourRef, groupIndex: 0 };\r\n }, [hourValue, minuteValue, secondValue, hasSecond]);\r\n\r\n // useGroupedInput \uD6C5\uC5D0\uC11C \uBC18\uD658\uB41C setFocusedGroup \uC0AC\uC6A9\r\n // (GroupedInputWrapper\uAC00 \uD638\uCD9C\uD560 \uB54C \uD6C5 \uB0B4\uBD80 \uC0C1\uD0DC\uB3C4 \uC5C5\uB370\uC774\uD2B8\uB428)\r\n\r\n // \uC2DC\uACC4 \uC544\uC774\uCF58 \uD074\uB9AD \uD578\uB4E4\uB7EC\r\n const handleClockIconClick = useCallback(\r\n (e: React.MouseEvent<HTMLElement>) => {\r\n e.stopPropagation();\r\n if (disabled || readonly) return;\r\n\r\n // \uD604\uC7AC \uD3EC\uCEE4\uC2A4\uB41C \uC694\uC18C blur \uCC98\uB9AC\r\n const activeElement = document.activeElement as HTMLElement;\r\n if (activeElement && typeof activeElement.blur === \"function\") {\r\n activeElement.blur();\r\n }\r\n setFocusedGroup(null);\r\n\r\n setPickerOpen(true);\r\n },\r\n [disabled, readonly, setFocusedGroup]\r\n );\r\n\r\n // TimePicker\uC5D0\uC11C \uC2DC\uAC04 \uC120\uD0DD \uC2DC\r\n const handlePickerChange = useCallback(\r\n (hour: string, minute: string, second?: string) => {\r\n setHourValue(hour);\r\n setMinuteValue(minute);\r\n if (hasSecond && second) {\r\n setSecondValue(second);\r\n }\r\n emitChange(hour, minute, second || \"\");\r\n\r\n // \uD3EC\uCEE4\uC2A4\uAC00 \uB2E4\uC2DC \uB4E4\uC5B4\uAC00\uC9C0 \uC54A\uB3C4\uB85D\r\n setFocusedGroup(null);\r\n },\r\n [hasSecond, emitChange, setFocusedGroup]\r\n );\r\n\r\n // TimePicker \uB2EB\uAE30\r\n const handlePickerClose = useCallback(() => {\r\n setPickerOpen(false);\r\n }, []);\r\n\r\n const noBorderStyle: SxProps<Theme> = {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": { border: \"none\" },\r\n \"&:hover fieldset\": { border: \"none\" },\r\n \"&.Mui-focused fieldset\": { border: \"none\" },\r\n },\r\n };\r\n\r\n // \uCEE4\uC2A4\uD140 \uD3F0\uD2B8 \uD06C\uAE30\uC5D0 \uB530\uB978 fieldWidth \uACC4\uC0B0\r\n // ch \uB2E8\uC704\uB294 \uD3F0\uD2B8\uB9C8\uB2E4 \uB2E4\uB974\uBBC0\uB85C, fontSize \uAE30\uC900\uC73C\uB85C px \uACC4\uC0B0\r\n const fieldWidth = fontSize ? `${computedFontSize * 1.25}px` : \"2.5ch\";\r\n\r\n // \uADF8\uB8F9 \uB80C\uB354\uB9C1\r\n const renderGroup = (groupIndex: number, groupValue: string, placeholder: string) => {\r\n const isFocused = focusedGroup === groupIndex;\r\n const showCursor = cursorVisible && isFocused && !inputComplete;\r\n const refs = [hourRef, minuteRef, secondRef];\r\n\r\n return (\r\n <Box\r\n onMouseDown={createMouseDownHandler(groupIndex)}\r\n onClick={createClickHandler(groupIndex)}\r\n sx={{\r\n position: \"relative\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n }}\r\n >\r\n <TextField\r\n inputRef={refs[groupIndex]}\r\n value={groupValue}\r\n onChange={handleChange(groupIndex)}\r\n onKeyDown={handleKeyDown(groupIndex)}\r\n onFocus={createFocusHandler(groupIndex)}\r\n onBlur={handleBlur}\r\n disabled={disabled}\r\n size={size}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n placeholder={placeholder}\r\n variant=\"outlined\"\r\n sx={{\r\n width: fieldWidth,\r\n maxWidth: fieldWidth,\r\n minWidth: fieldWidth,\r\n ...noBorderStyle,\r\n \"& .MuiInputBase-root\": {\r\n width: fieldWidth,\r\n maxWidth: fieldWidth,\r\n minWidth: fieldWidth,\r\n },\r\n \"& .MuiInputBase-input\": {\r\n width: fieldWidth,\r\n minWidth: fieldWidth,\r\n maxWidth: fieldWidth,\r\n textAlign: \"left\",\r\n caretColor: \"transparent\",\r\n ...(fontSize && { fontSize }),\r\n ...(fontColor && { color: fontColor }),\r\n ...(fontFamily && { fontFamily }),\r\n },\r\n \"& .MuiInputBase-input::placeholder\": {\r\n color: \"rgba(0, 0, 0, 0.3)\",\r\n opacity: 1,\r\n },\r\n }}\r\n slotProps={{\r\n input: { readOnly: readonly },\r\n htmlInput: {\r\n maxLength: 2,\r\n inputMode: \"numeric\",\r\n style: { padding: \"0 2px\", textAlign: \"left\" },\r\n },\r\n }}\r\n />\r\n {showCursor && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n bottom: size === \"small\" ? 1 : 3,\r\n left: `calc(2px + ${getCursorLeft(groupIndex)}px)`,\r\n width: cursorWidth,\r\n height: cursorHeight,\r\n backgroundColor: \"text.primary\",\r\n animation: \"blink 1s step-end infinite\",\r\n \"@keyframes blink\": {\r\n \"0%, 100%\": { opacity: 1 },\r\n \"50%\": { opacity: 0 },\r\n },\r\n pointerEvents: \"none\",\r\n }}\r\n />\r\n )}\r\n </Box>\r\n );\r\n };\r\n\r\n // \uC804\uCCB4 \uC2DC\uAC04 \uAC12 \uD655\uC778\r\n const getFullTime = useCallback(() => {\r\n return hourValue + minuteValue + (hasSecond ? secondValue : \"\");\r\n }, [hourValue, minuteValue, secondValue, hasSecond]);\r\n\r\n // \uCF5C\uB860 \uD45C\uC2DC \uC5EC\uBD80 (\uAC12\uC774 \uC788\uAC70\uB098 \uD3EC\uCEE4\uC2A4\uAC00 \uC788\uC744 \uB54C)\r\n const showColon = getFullTime().length > 0 || focusedGroup !== null;\r\n\r\n // \uB0B4\uBD80 \uADF8\uB8F9 \uB80C\uB354\uB9C1\r\n const renderGroupedInput = () => (\r\n <>\r\n {/* \uC2DC\uAC04 \uD544\uB4DC */}\r\n {renderGroup(0, hourValue, \"00\")}\r\n\r\n <ColonBox size={size} visible={showColon} />\r\n\r\n {/* \uBD84 \uD544\uB4DC */}\r\n {renderGroup(1, minuteValue, \"00\")}\r\n\r\n {/* \uCD08 \uD544\uB4DC */}\r\n {hasSecond && (\r\n <>\r\n <ColonBox size={size} visible={showColon} />\r\n\r\n {renderGroup(2, secondValue, \"00\")}\r\n </>\r\n )}\r\n\r\n {/* Spacer - flex \uD655\uC7A5\uC744 \uC704\uD55C \uBE48 \uACF5\uAC04 */}\r\n <Box sx={{ flex: 1 }} />\r\n </>\r\n );\r\n\r\n // \uC2DC\uACC4 \uC544\uC774\uCF58 (endAdornment)\r\n const clockIconElement =\r\n clockIcon && !readonly ? (\r\n <Box\r\n onMouseDown={(e) => {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n }}\r\n onClick={handleClockIconClick}\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n ml: size === \"small\" ? 0.5 : 1,\r\n mr: size === \"small\" ? -0.5 : 0,\r\n color: \"text.secondary\",\r\n opacity: 0.5,\r\n cursor: disabled ? \"default\" : \"pointer\",\r\n borderRadius: \"50%\",\r\n p: 0.5,\r\n transition: \"opacity 0.2s, color 0.2s, background-color 0.2s\",\r\n \"&:hover\": {\r\n opacity: disabled ? 0.5 : 1,\r\n color: disabled ? \"text.secondary\" : \"text.primary\",\r\n backgroundColor: disabled ? \"transparent\" : \"action.hover\",\r\n },\r\n }}\r\n >\r\n <ClockIcon size={size === \"small\" ? 18 : 22} />\r\n </Box>\r\n ) : null;\r\n\r\n return (\r\n <Box\r\n ref={containerRef}\r\n sx={{\r\n ...(fullWidth && { width: \"100%\" }),\r\n ...sx,\r\n }}\r\n className={className}\r\n >\r\n <GroupedInputWrapper\r\n label={label}\r\n size={size}\r\n disabled={disabled}\r\n readonly={readonly}\r\n focusedGroup={focusedGroup}\r\n setFocusedGroup={setFocusedGroup}\r\n hasValue={getFullTime().length > 0}\r\n isInvalid={isInvalid}\r\n invalidBorderColor={invalidBorderColor}\r\n inputRefs={hasSecond ? [hourRef, minuteRef, secondRef] : [hourRef, minuteRef]}\r\n getTargetRefOnClick={getTargetRefOnClick}\r\n fullWidth={fullWidth}\r\n id={id}\r\n endAdornment={clockIconElement}\r\n contentSx={{ pl: 1.75 }}\r\n >\r\n {renderGroupedInput()}\r\n </GroupedInputWrapper>\r\n\r\n {/* TimePicker Popover */}\r\n <TimePicker\r\n anchorEl={containerRef}\r\n open={pickerOpen}\r\n onClose={handlePickerClose}\r\n value={{\r\n hour: hourValue,\r\n minute: minuteValue,\r\n second: hasSecond ? secondValue : undefined,\r\n }}\r\n onChange={handlePickerChange}\r\n format={format}\r\n minTime={minTime}\r\n maxTime={maxTime}\r\n minuteStep={minuteStep}\r\n secondStep={secondStep}\r\n hideDisabledTime={hideDisabledTime}\r\n />\r\n </Box>\r\n );\r\n});\r\n\r\nconst TimeTextFieldWithForm = forwardRef<HTMLDivElement, TimeTextFieldProps>(function TimeTextFieldWithForm(\r\n { form, name, onChange, ...rest },\r\n ref\r\n) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\"TimeTextField form prop is missing. Provide a form from useForm or useGlobalForm.\");\r\n }\r\n if (!name) {\r\n throw new Error(\"TimeTextField requires a name when form prop is provided.\");\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange]\r\n );\r\n\r\n return <TimeTextFieldBase {...rest} ref={ref} name={name} value={formValue} onChange={handleFormChange} />;\r\n});\r\n\r\nexport const TimeTextField = forwardRef<HTMLDivElement, TimeTextFieldProps>(function TimeTextField(props, ref) {\r\n if (props.form) {\r\n return <TimeTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <TimeTextFieldBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * DateTimeTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n ChangeEvent,\r\n useMemo,\r\n useRef,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField, InputAdornment, IconButton, Box } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport type { DateTimeTextFieldProps } from \"./types\";\r\nimport { DateTimePicker } from \"@ehfuse/mui-datetime-picker\";\r\nimport { ColonBox } from \"./components\";\r\nimport { CalendarIcon } from \"./icons\";\r\nimport { useDebouncedEmit, useGroupedInput, GroupConfig } from \"./hooks\";\r\nimport {\r\n getSeparator,\r\n getMaxLength,\r\n getCompleteLength,\r\n validateDate,\r\n validateTime,\r\n clampTimeValue,\r\n is12HourFormat,\r\n extractDateFormat,\r\n hasSecondField,\r\n formatDateValue,\r\n formatToPlaceholder,\r\n getSegmentRange,\r\n hasYearInFormat,\r\n parseDateWithInternalYear,\r\n buildDateOutputValue,\r\n dateToNumbers,\r\n} from \"./utils\";\r\n\r\nconst DateTimeTextFieldBase = forwardRef<\r\n HTMLDivElement,\r\n DateTimeTextFieldProps\r\n>(function DateTimeTextFieldBase(\r\n {\r\n label,\r\n format = \"YYYY-MM-DD HH:mm\",\r\n dateSeparator = \"-\",\r\n minDateTime,\r\n maxDateTime,\r\n minTime,\r\n maxTime,\r\n holidays = [],\r\n holidayColor = \"red\",\r\n calendarIcon = true,\r\n selectedColor,\r\n showToday = true,\r\n minuteStep = 1,\r\n secondStep = 1,\r\n hideDisabledTime = false,\r\n invalidBorderColor,\r\n debounce,\r\n sx,\r\n value,\r\n onChange,\r\n onBlur,\r\n name = \"\",\r\n disabled,\r\n readonly = false,\r\n size,\r\n fullWidth = false,\r\n className,\r\n id,\r\n },\r\n ref,\r\n) {\r\n // \uB0A0\uC9DC \uD544\uB4DC \uC0C1\uD0DC\r\n const [dateDisplayValue, setDateDisplayValue] = useState(\"\");\r\n const [prevDateNumbers, setPrevDateNumbers] = useState(\"\");\r\n const [internalYear, setInternalYear] = useState<number | null>(null); // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC6A9\r\n\r\n // \uC2DC\uAC04 \uD544\uB4DC \uC0C1\uD0DC\r\n const [hourValue, setHourValue] = useState(\"\");\r\n const [minuteValue, setMinuteValue] = useState(\"\");\r\n const [secondValue, setSecondValue] = useState(\"\");\r\n\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n const [isDateFocused, setIsDateFocused] = useState(false);\r\n\r\n // \uD31D\uC624\uBC84 \uC0C1\uD0DC\r\n const [calendarOpen, setCalendarOpen] = useState(false);\r\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);\r\n\r\n // refs\r\n const dateInputRef = useRef<HTMLInputElement>(null);\r\n const hourRef = useRef<HTMLInputElement>(null);\r\n const minuteRef = useRef<HTMLInputElement>(null);\r\n const secondRef = useRef<HTMLInputElement>(null);\r\n const selectionRangeRef = useRef<{ start: number; end: number } | null>(\r\n null,\r\n );\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n // \uC678\uBD80 ref\uC640 \uB0B4\uBD80 containerRef \uBCD1\uD569\r\n useImperativeHandle(ref, () => containerRef.current!, []);\r\n\r\n const hasSecond = hasSecondField(format);\r\n const is12Hour = is12HourFormat(format);\r\n const dateFormat = extractDateFormat(format);\r\n const displayDateSeparator = getSeparator(dateFormat);\r\n const dateMaxLength = getMaxLength(dateFormat);\r\n const dateCompleteLength = getCompleteLength(dateFormat);\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC778\uC9C0 \uD655\uC778 (YYYY, YY\uAC00 \uC5C6\uB294 \uD3EC\uB9F7)\r\n const isYearlessFormat = !hasYearInFormat(dateFormat);\r\n\r\n // \uD3F0\uD2B8 \uD06C\uAE30 \uACC4\uC0B0 (\uC2DC\uAC04 \uD544\uB4DC\uC6A9)\r\n const computedFontSize = size === \"small\" ? 16 : 18;\r\n const cursorHeight = \"1px\";\r\n const cursorWidth = `${computedFontSize * 0.55}px`;\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange, flushOnBlur, lastEmittedValue } = useDebouncedEmit({\r\n name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n // \uC2DC\uAC04 \uADF8\uB8F9 \uC124\uC815\r\n const timeGroups: GroupConfig[] = useMemo(() => {\r\n const baseGroups: GroupConfig[] = [\r\n {\r\n maxLength: 2,\r\n ref: hourRef,\r\n value: hourValue,\r\n setValue: setHourValue,\r\n },\r\n {\r\n maxLength: 2,\r\n ref: minuteRef,\r\n value: minuteValue,\r\n setValue: setMinuteValue,\r\n },\r\n ];\r\n\r\n if (hasSecond) {\r\n baseGroups.push({\r\n maxLength: 2,\r\n ref: secondRef,\r\n value: secondValue,\r\n setValue: setSecondValue,\r\n });\r\n }\r\n\r\n return baseGroups;\r\n }, [hourValue, minuteValue, secondValue, hasSecond]);\r\n\r\n const {\r\n focusedGroup,\r\n cursorVisible,\r\n inputComplete,\r\n getCursorLeft,\r\n createMouseDownHandler,\r\n createClickHandler,\r\n createFocusHandler,\r\n createBlurHandler,\r\n createKeyDownHandler,\r\n createChangeHandler: createGroupChangeHandler,\r\n } = useGroupedInput({\r\n groups: timeGroups,\r\n fontSize: computedFontSize,\r\n disabled,\r\n readonly,\r\n });\r\n\r\n // \uC804\uCCB4 \uB0A0\uC9DC\uC2DC\uAC04 \uBB38\uC790\uC5F4 \uC0DD\uC131 (\uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC774\uC5B4\uB3C4 \uC5F0\uB3C4 \uD3EC\uD568)\r\n const buildDateTimeString = useCallback(\r\n (\r\n dateStr: string,\r\n hour: string,\r\n minute: string,\r\n second: string,\r\n yearOverride?: number,\r\n ) => {\r\n // \uB0A0\uC9DC \uBD80\uBD84 \uCD9C\uB825\uAC12 \uC0DD\uC131 (yearless \uD3EC\uB9F7 \uC9C0\uC6D0)\r\n const outputDateStr = buildDateOutputValue(\r\n dateStr,\r\n dateFormat,\r\n dateSeparator,\r\n yearOverride ?? internalYear,\r\n );\r\n const timeStr = hasSecond\r\n ? `${hour}:${minute}:${second}`\r\n : `${hour}:${minute}`;\r\n return `${outputDateStr} ${timeStr}`;\r\n },\r\n [dateFormat, dateSeparator, hasSecond, internalYear],\r\n );\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n const performValidation = useCallback(\r\n (dateStr: string, hour: string, minute: string, second: string) => {\r\n const dateNumbers = dateStr.replace(/\\D/g, \"\");\r\n const dateComplete = dateNumbers.length === dateCompleteLength;\r\n const timeComplete = hasSecond\r\n ? hour.length === 2 &&\r\n minute.length === 2 &&\r\n second.length === 2\r\n : hour.length === 2 && minute.length === 2;\r\n\r\n if (dateComplete && timeComplete) {\r\n const dateValid = validateDate(\r\n dateStr,\r\n dateFormat,\r\n minDateTime,\r\n maxDateTime,\r\n );\r\n const timeValid = validateTime(\r\n hour,\r\n minute,\r\n second,\r\n is12Hour,\r\n minTime,\r\n maxTime,\r\n );\r\n setIsInvalid(!dateValid || !timeValid);\r\n } else {\r\n setIsInvalid(false);\r\n }\r\n },\r\n [\r\n dateCompleteLength,\r\n hasSecond,\r\n dateFormat,\r\n minDateTime,\r\n maxDateTime,\r\n is12Hour,\r\n minTime,\r\n maxTime,\r\n ],\r\n );\r\n\r\n // value prop \uBCC0\uACBD \uC2DC \uB3D9\uAE30\uD654\r\n useEffect(() => {\r\n if (value !== undefined && value !== null) {\r\n const strValue = String(value);\r\n const [datePart, timePart] = strValue.split(\" \");\r\n\r\n if (strValue !== lastEmittedValue.current) {\r\n if (datePart) {\r\n const formatted = formatDateValue(datePart, dateFormat);\r\n setDateDisplayValue(formatted);\r\n setPrevDateNumbers(formatted.replace(/\\D/g, \"\"));\r\n }\r\n\r\n if (timePart) {\r\n const timeParts = timePart.split(\":\");\r\n setHourValue(timeParts[0]?.slice(0, 2) || \"\");\r\n setMinuteValue(timeParts[1]?.slice(0, 2) || \"\");\r\n if (hasSecond && timeParts[2]) {\r\n setSecondValue(timeParts[2].slice(0, 2));\r\n }\r\n }\r\n\r\n lastEmittedValue.current = strValue;\r\n }\r\n } else {\r\n if (lastEmittedValue.current !== \"\") {\r\n setDateDisplayValue(\"\");\r\n setPrevDateNumbers(\"\");\r\n setHourValue(\"\");\r\n setMinuteValue(\"\");\r\n setSecondValue(\"\");\r\n lastEmittedValue.current = \"\";\r\n }\r\n }\r\n }, [value, hasSecond, dateFormat, lastEmittedValue]);\r\n\r\n // \uB0A0\uC9DC \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleDateChange = useCallback(\r\n (e: ChangeEvent<HTMLInputElement>) => {\r\n const input = e.target;\r\n const newValue = input.value;\r\n const newNumbers = newValue.replace(/\\D/g, \"\");\r\n const selection = selectionRangeRef.current;\r\n\r\n // \uC601\uC5ED \uC120\uD0DD \uC0C1\uD0DC\uC5D0\uC11C \uC785\uB825\uD55C \uACBD\uC6B0\r\n if (\r\n selection &&\r\n selection.start !== selection.end &&\r\n selection.start >= 0 &&\r\n selection.end <= dateDisplayValue.length &&\r\n dateDisplayValue.length > 0 &&\r\n selection.start < selection.end\r\n ) {\r\n const beforeSelection = dateDisplayValue.slice(\r\n 0,\r\n selection.start,\r\n );\r\n const afterSelection = dateDisplayValue.slice(selection.end);\r\n const beforeNumbers = beforeSelection.replace(/\\D/g, \"\");\r\n const afterNumbers = afterSelection.replace(/\\D/g, \"\");\r\n const inputChar = newValue\r\n .slice(selection.start, selection.start + 1)\r\n .replace(/\\D/g, \"\");\r\n\r\n if (inputChar) {\r\n const combinedNumbers =\r\n beforeNumbers + inputChar + afterNumbers;\r\n const formattedValue = formatDateValue(\r\n combinedNumbers,\r\n dateFormat,\r\n );\r\n\r\n setDateDisplayValue(formattedValue);\r\n setPrevDateNumbers(formattedValue.replace(/\\D/g, \"\"));\r\n performValidation(\r\n formattedValue,\r\n hourValue,\r\n minuteValue,\r\n secondValue,\r\n );\r\n\r\n const newCursorPos = selection.start + 1;\r\n let adjustedPos = newCursorPos;\r\n if (formattedValue[adjustedPos] === displayDateSeparator) {\r\n adjustedPos++;\r\n }\r\n\r\n requestAnimationFrame(() => {\r\n input.setSelectionRange(adjustedPos, adjustedPos);\r\n });\r\n\r\n const outputValue = buildDateTimeString(\r\n formattedValue,\r\n hourValue,\r\n minuteValue,\r\n secondValue,\r\n );\r\n emitChange(e, outputValue);\r\n\r\n selectionRangeRef.current = null;\r\n return;\r\n }\r\n }\r\n\r\n selectionRangeRef.current = null;\r\n\r\n // \uBC31\uC2A4\uD398\uC774\uC2A4 \uAC10\uC9C0\r\n const isBackspace =\r\n newNumbers.length <= prevDateNumbers.length &&\r\n newValue.length < dateDisplayValue.length;\r\n\r\n let formattedValue: string;\r\n\r\n if (isBackspace && newNumbers.length === prevDateNumbers.length) {\r\n const trimmedNumbers = newNumbers.slice(0, -1);\r\n formattedValue = formatDateValue(trimmedNumbers, dateFormat);\r\n } else {\r\n formattedValue = formatDateValue(newValue, dateFormat);\r\n }\r\n\r\n setDateDisplayValue(formattedValue);\r\n setPrevDateNumbers(formattedValue.replace(/\\D/g, \"\"));\r\n performValidation(\r\n formattedValue,\r\n hourValue,\r\n minuteValue,\r\n secondValue,\r\n );\r\n\r\n const outputValue = buildDateTimeString(\r\n formattedValue,\r\n hourValue,\r\n minuteValue,\r\n secondValue,\r\n );\r\n emitChange(e, outputValue);\r\n\r\n // \uB0A0\uC9DC \uC785\uB825 \uC644\uB8CC \uC2DC \uC2DC\uAC04 \uD544\uB4DC\uB85C \uD3EC\uCEE4\uC2A4 \uC774\uB3D9\r\n const numbers = formattedValue.replace(/\\D/g, \"\");\r\n if (numbers.length === dateCompleteLength) {\r\n setTimeout(() => {\r\n hourRef.current?.focus();\r\n }, 0);\r\n }\r\n },\r\n [\r\n dateDisplayValue,\r\n prevDateNumbers,\r\n dateFormat,\r\n displayDateSeparator,\r\n dateCompleteLength,\r\n hourValue,\r\n minuteValue,\r\n secondValue,\r\n performValidation,\r\n buildDateTimeString,\r\n emitChange,\r\n ],\r\n );\r\n\r\n // \uD14D\uC2A4\uD2B8 \uB108\uBE44 \uCE21\uC815\r\n const measureTextWidth = useCallback(\r\n (text: string, input: HTMLInputElement): number => {\r\n const style = window.getComputedStyle(input);\r\n const canvas = document.createElement(\"canvas\");\r\n const ctx = canvas.getContext(\"2d\");\r\n if (!ctx) return text.length * 10;\r\n ctx.font = `${style.fontSize} ${style.fontFamily}`;\r\n return ctx.measureText(text).width;\r\n },\r\n [],\r\n );\r\n\r\n // \uB0A0\uC9DC \uD074\uB9AD \uD578\uB4E4\uB7EC (\uC601\uC5ED \uC120\uD0DD)\r\n const handleDateClick = useCallback(\r\n (e: React.MouseEvent<HTMLInputElement>) => {\r\n if (disabled || readonly) return;\r\n\r\n // dateInputRef\uB97C \uC0AC\uC6A9\uD558\uC5EC \uC2E4\uC81C input \uC694\uC18C \uCC38\uC870\r\n const input = dateInputRef.current;\r\n if (!input) return;\r\n\r\n const cursorPos = input.selectionStart || 0;\r\n\r\n if (dateDisplayValue.length > 0) {\r\n // \uD074\uB9AD\uD55C X \uC88C\uD45C\uAC00 \uD14D\uC2A4\uD2B8 \uB108\uBE44\uBCF4\uB2E4 \uD070\uC9C0 \uD655\uC778 (\uC678\uACFD \uD074\uB9AD)\r\n const rect = input.getBoundingClientRect();\r\n const clickX = e.clientX - rect.left;\r\n const paddingLeft = parseFloat(\r\n window.getComputedStyle(input).paddingLeft,\r\n );\r\n const textWidth = measureTextWidth(dateDisplayValue, input);\r\n const isOutsideText = clickX > paddingLeft + textWidth;\r\n\r\n // \uC678\uACFD \uD074\uB9AD\uC774\uAC70\uB098 \uCEE4\uC11C\uAC00 \uAC12 \uAE38\uC774 \uB05D\uC774\uBA74 \uC804\uCCB4 \uC120\uD0DD\r\n if (isOutsideText || cursorPos >= dateDisplayValue.length) {\r\n selectionRangeRef.current = {\r\n start: 0,\r\n end: dateDisplayValue.length,\r\n };\r\n requestAnimationFrame(() => {\r\n input?.setSelectionRange?.(0, dateDisplayValue.length);\r\n });\r\n } else {\r\n // \uB144/\uC6D4/\uC77C \uAC01 \uCE78 \uD074\uB9AD\uC2DC \uD574\uB2F9 \uCE78\uB9CC \uC120\uD0DD\r\n const { start, end } = getSegmentRange(\r\n cursorPos,\r\n dateFormat,\r\n );\r\n const actualEnd = Math.min(end, dateDisplayValue.length);\r\n const actualStart = Math.min(\r\n start,\r\n dateDisplayValue.length,\r\n );\r\n\r\n selectionRangeRef.current = {\r\n start: actualStart,\r\n end: actualEnd,\r\n };\r\n\r\n requestAnimationFrame(() => {\r\n input?.setSelectionRange?.(actualStart, actualEnd);\r\n });\r\n }\r\n } else {\r\n selectionRangeRef.current = null;\r\n }\r\n },\r\n [disabled, readonly, dateDisplayValue, dateFormat, measureTextWidth],\r\n );\r\n\r\n // \uB0A0\uC9DC \uD0A4 \uC785\uB825 \uC81C\uD55C (\uC5F0\uB3C4 \uCCAB \uC790\uB9AC)\r\n const handleDateKeyDown = useCallback(\r\n (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n if (!/^\\d$/.test(e.key)) return;\r\n\r\n const currentNumbers = dateDisplayValue.replace(/\\D/g, \"\");\r\n const numLen = currentNumbers.length;\r\n\r\n if (dateFormat.startsWith(\"YYYY\") && numLen === 0) {\r\n if (e.key !== \"1\" && e.key !== \"2\") {\r\n e.preventDefault();\r\n return;\r\n }\r\n }\r\n },\r\n [dateDisplayValue, dateFormat],\r\n );\r\n\r\n // \uC2DC\uAC04 \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleTimeChange = (groupIndex: number) => {\r\n return createGroupChangeHandler(groupIndex, (newValue, idx) => {\r\n let clampedValue = clampTimeValue(\r\n newValue,\r\n idx === 0 ? \"hour\" : idx === 1 ? \"minute\" : \"second\",\r\n is12Hour,\r\n );\r\n\r\n if (clampedValue !== newValue) {\r\n timeGroups[idx].setValue(clampedValue);\r\n\r\n // clamp\uB85C \uC778\uD574 2\uC790\uB9AC\uAC00 \uB418\uC5C8\uC73C\uBA74 \uB2E4\uC74C \uD544\uB4DC\uB85C \uC774\uB3D9\r\n if (\r\n clampedValue.length === 2 &&\r\n newValue.length === 1 &&\r\n idx < timeGroups.length - 1\r\n ) {\r\n const refs = [hourRef, minuteRef, secondRef];\r\n setTimeout(() => {\r\n refs[idx + 1].current?.focus();\r\n refs[idx + 1].current?.setSelectionRange(0, 0);\r\n }, 0);\r\n }\r\n }\r\n\r\n const newHour = idx === 0 ? clampedValue : hourValue;\r\n const newMinute = idx === 1 ? clampedValue : minuteValue;\r\n const newSecond = idx === 2 ? clampedValue : secondValue;\r\n\r\n performValidation(dateDisplayValue, newHour, newMinute, newSecond);\r\n\r\n const outputValue = buildDateTimeString(\r\n dateDisplayValue,\r\n newHour,\r\n newMinute,\r\n newSecond,\r\n );\r\n emitChange(null, outputValue);\r\n });\r\n };\r\n\r\n // \uC2DC\uAC04 \uD0A4 \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleTimeKeyDown = (groupIndex: number) => {\r\n return createKeyDownHandler(groupIndex, (newValue, idx) => {\r\n const newHour = idx === 0 ? newValue : hourValue;\r\n const newMinute = idx === 1 ? newValue : minuteValue;\r\n const newSecond = idx === 2 ? newValue : secondValue;\r\n\r\n const outputValue = buildDateTimeString(\r\n dateDisplayValue,\r\n newHour,\r\n newMinute,\r\n newSecond,\r\n );\r\n emitChange(null, outputValue);\r\n });\r\n };\r\n\r\n // blur \uD578\uB4E4\uB7EC\r\n const handleBlur = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>) => {\r\n setIsDateFocused(false);\r\n\r\n // 1\uC790\uB9AC \uC2DC\uAC04 \uAC12\uC744 2\uC790\uB9AC\uB85C \uD328\uB529\r\n const paddedHour =\r\n hourValue.length === 1 ? hourValue.padStart(2, \"0\") : hourValue;\r\n const paddedMinute =\r\n minuteValue.length === 1\r\n ? minuteValue.padStart(2, \"0\")\r\n : minuteValue;\r\n const paddedSecond =\r\n secondValue.length === 1\r\n ? secondValue.padStart(2, \"0\")\r\n : secondValue;\r\n\r\n // \uD328\uB529\uB41C \uAC12\uC73C\uB85C \uC0C1\uD0DC \uC5C5\uB370\uC774\uD2B8\r\n if (hourValue.length === 1) setHourValue(paddedHour);\r\n if (minuteValue.length === 1) setMinuteValue(paddedMinute);\r\n if (secondValue.length === 1) setSecondValue(paddedSecond);\r\n\r\n const outputValue = buildDateTimeString(\r\n dateDisplayValue,\r\n paddedHour,\r\n paddedMinute,\r\n paddedSecond,\r\n );\r\n flushOnBlur(e, outputValue);\r\n if (onBlur) {\r\n onBlur(e);\r\n }\r\n },\r\n [\r\n dateDisplayValue,\r\n hourValue,\r\n minuteValue,\r\n secondValue,\r\n buildDateTimeString,\r\n flushOnBlur,\r\n onBlur,\r\n ],\r\n );\r\n\r\n // \uC2DC\uAC04 \uD544\uB4DC blur \uD578\uB4E4\uB7EC (\uD328\uB529 \uCC98\uB9AC \uD3EC\uD568)\r\n const handleTimeBlur = useCallback(() => {\r\n // \uAE30\uC874 createBlurHandler \uB85C\uC9C1 \uC2E4\uD589\r\n const baseBlurHandler = createBlurHandler();\r\n baseBlurHandler();\r\n\r\n // \uC2DC\uAC04 \uADF8\uB8F9 \uB0B4 \uB2E4\uB978 \uD544\uB4DC\uB85C \uD3EC\uCEE4\uC2A4 \uC774\uB3D9 \uC2DC \uD328\uB529\uD558\uC9C0 \uC54A\uC74C\r\n setTimeout(() => {\r\n const activeElement = document.activeElement;\r\n const isStillInTimeGroup =\r\n activeElement === hourRef.current ||\r\n activeElement === minuteRef.current ||\r\n activeElement === secondRef.current;\r\n\r\n if (!isStillInTimeGroup) {\r\n // 1\uC790\uB9AC \uC2DC\uAC04 \uAC12\uC744 2\uC790\uB9AC\uB85C \uD328\uB529\r\n if (hourValue.length === 1) {\r\n setHourValue(hourValue.padStart(2, \"0\"));\r\n }\r\n if (minuteValue.length === 1) {\r\n setMinuteValue(minuteValue.padStart(2, \"0\"));\r\n }\r\n if (secondValue.length === 1) {\r\n setSecondValue(secondValue.padStart(2, \"0\"));\r\n }\r\n }\r\n }, 0);\r\n }, [createBlurHandler, hourValue, minuteValue, secondValue]);\r\n\r\n // focus \uD578\uB4E4\uB7EC\r\n const handleDateFocus = useCallback(() => {\r\n setIsDateFocused(true);\r\n }, []);\r\n\r\n // \uB2EC\uB825\uC5D0\uC11C \uB0A0\uC9DC \uC120\uD0DD\r\n const handleCalendarSelect = useCallback(\r\n (date: Date) => {\r\n const year = date.getFullYear();\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC758 \uACBD\uC6B0 internalYear\uC5D0 \uC800\uC7A5\r\n if (isYearlessFormat) {\r\n setInternalYear(year);\r\n }\r\n\r\n // \uD3EC\uB9F7\uC5D0 \uB9DE\uAC8C \uC22B\uC790 \uBB38\uC790\uC5F4 \uC0DD\uC131\r\n const numbers = dateToNumbers(date, dateFormat);\r\n\r\n const formatted = formatDateValue(numbers, dateFormat);\r\n\r\n setDateDisplayValue(formatted);\r\n setPrevDateNumbers(numbers);\r\n performValidation(formatted, hourValue, minuteValue, secondValue);\r\n\r\n const outputValue = buildDateTimeString(\r\n formatted,\r\n hourValue,\r\n minuteValue,\r\n secondValue,\r\n year,\r\n );\r\n emitChange(null, outputValue, true);\r\n setCalendarOpen(false);\r\n setAnchorEl(null);\r\n\r\n // \uD3EC\uCEE4\uC2A4 \uD574\uC81C (blur)\r\n setTimeout(() => {\r\n dateInputRef.current?.blur();\r\n hourRef.current?.blur();\r\n minuteRef.current?.blur();\r\n secondRef.current?.blur();\r\n }, 0);\r\n },\r\n [\r\n dateFormat,\r\n isYearlessFormat,\r\n hourValue,\r\n minuteValue,\r\n secondValue,\r\n performValidation,\r\n buildDateTimeString,\r\n emitChange,\r\n ],\r\n );\r\n\r\n // \uB2EC\uB825 \uD31D\uC624\uBC84 \uB0B4 \uC2DC\uAC04 \uC120\uD0DD \uD578\uB4E4\uB7EC\r\n const handleCalendarTimeChange = useCallback(\r\n (hour: number, minute: number, second?: number) => {\r\n const h = String(hour).padStart(2, \"0\");\r\n const m = String(minute).padStart(2, \"0\");\r\n const s =\r\n second !== undefined ? String(second).padStart(2, \"0\") : \"\";\r\n\r\n setHourValue(h);\r\n setMinuteValue(m);\r\n if (hasSecond && s) {\r\n setSecondValue(s);\r\n }\r\n\r\n performValidation(dateDisplayValue, h, m, s);\r\n\r\n const outputValue = buildDateTimeString(dateDisplayValue, h, m, s);\r\n emitChange(null, outputValue, true);\r\n },\r\n [\r\n hasSecond,\r\n dateDisplayValue,\r\n performValidation,\r\n buildDateTimeString,\r\n emitChange,\r\n ],\r\n );\r\n\r\n // \uC120\uD0DD\uB41C \uB0A0\uC9DC \uACC4\uC0B0 (\uB2EC\uB825\uC6A9)\r\n const selectedDate = useMemo((): Date | null => {\r\n const parsed = parseDateWithInternalYear(\r\n dateDisplayValue,\r\n dateFormat,\r\n internalYear,\r\n );\r\n if (!parsed) return null;\r\n return new Date(parsed.year, parsed.month - 1, parsed.day);\r\n }, [dateDisplayValue, dateFormat, internalYear]);\r\n\r\n // \uB2EC\uB825\uC5D0 \uC804\uB2EC\uD560 \uB0A0\uC9DC \uACC4\uC0B0\r\n const calendarSelectedDate = useMemo((): Date => {\r\n // \uC120\uD0DD\uB41C \uB0A0\uC9DC\uAC00 \uC788\uC73C\uBA74 \uADF8\uB300\uB85C \uC0AC\uC6A9\r\n if (selectedDate) return selectedDate;\r\n\r\n // \uC5F0\uB3C4\uAC00 \uC5C6\uB294 \uD3EC\uB9F7\uC758 \uACBD\uC6B0 internalYear \uB610\uB294 \uD604\uC7AC \uC5F0\uB3C4 \uC0AC\uC6A9\r\n if (isYearlessFormat) {\r\n const yearToUse = internalYear || new Date().getFullYear();\r\n const parsed = parseDateWithInternalYear(\r\n dateDisplayValue,\r\n dateFormat,\r\n yearToUse,\r\n );\r\n if (\r\n parsed &&\r\n parsed.month >= 1 &&\r\n parsed.month <= 12 &&\r\n parsed.day >= 1 &&\r\n parsed.day <= 31\r\n ) {\r\n return new Date(yearToUse, parsed.month - 1, parsed.day);\r\n }\r\n return new Date(\r\n yearToUse,\r\n new Date().getMonth(),\r\n new Date().getDate(),\r\n );\r\n }\r\n\r\n return new Date();\r\n }, [\r\n selectedDate,\r\n dateDisplayValue,\r\n dateFormat,\r\n isYearlessFormat,\r\n internalYear,\r\n ]);\r\n\r\n // \uC2A4\uD0C0\uC77C\r\n const invalidStyles: SxProps<Theme> =\r\n isInvalid && invalidBorderColor\r\n ? {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": { borderColor: invalidBorderColor },\r\n \"&:hover fieldset\": { borderColor: invalidBorderColor },\r\n \"&.Mui-focused fieldset\": {\r\n borderColor: invalidBorderColor,\r\n },\r\n },\r\n }\r\n : {};\r\n\r\n const readonlyStyles: SxProps<Theme> = readonly\r\n ? {\r\n pointerEvents: \"none\",\r\n \"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline\":\r\n {\r\n borderColor: \"rgba(0, 0, 0, 0.23)\",\r\n borderWidth: 1,\r\n },\r\n \"& .MuiInputLabel-root.Mui-focused\": {\r\n color: \"rgba(0, 0, 0, 0.6)\",\r\n },\r\n }\r\n : {};\r\n\r\n const noBorderStyle: SxProps<Theme> = {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": { border: \"none\" },\r\n \"&:hover fieldset\": { border: \"none\" },\r\n \"&.Mui-focused fieldset\": { border: \"none\" },\r\n },\r\n };\r\n\r\n // \uB0A0\uC9DC \uD544\uB4DC width \uACC4\uC0B0\r\n // placeholder '____-__-__' \uC5D0\uC11C \uBC11\uC904\uC740 \uC22B\uC790\uC640 \uBE44\uC2B7\uD55C \uB108\uBE44\r\n const dateFieldWidth = useMemo(() => {\r\n // dateMaxLength = 10 (YYYY-MM-DD)\r\n return `${dateMaxLength}ch`;\r\n }, [dateMaxLength]);\r\n\r\n // \uB0A0\uC9DC placeholder (____-__-__)\r\n const datePlaceholder = useMemo(() => {\r\n return formatToPlaceholder(dateFormat);\r\n }, [dateFormat]);\r\n\r\n // \uC2DC\uAC04 \uD544\uB4DC width (TimeTextField\uC640 \uB3D9\uC77C\uD558\uAC8C)\r\n const timeFieldWidth = \"2.5ch\";\r\n\r\n // \uC2DC\uAC04 \uADF8\uB8F9 \uB80C\uB354\uB9C1\r\n const renderTimeGroup = (\r\n groupIndex: number,\r\n groupValue: string,\r\n placeholder: string,\r\n ) => {\r\n const isFocusedGroup = focusedGroup === groupIndex;\r\n const showCursor = cursorVisible && isFocusedGroup && !inputComplete;\r\n const refs = [hourRef, minuteRef, secondRef];\r\n\r\n return (\r\n <Box\r\n key={groupIndex}\r\n onMouseDown={createMouseDownHandler(groupIndex)}\r\n onClick={createClickHandler(groupIndex)}\r\n sx={{\r\n position: \"relative\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n }}\r\n >\r\n <TextField\r\n inputRef={refs[groupIndex]}\r\n value={groupValue}\r\n onChange={handleTimeChange(groupIndex)}\r\n onKeyDown={handleTimeKeyDown(groupIndex)}\r\n onFocus={createFocusHandler(groupIndex)}\r\n onBlur={handleTimeBlur}\r\n disabled={disabled}\r\n size={size}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n placeholder={placeholder}\r\n variant=\"outlined\"\r\n sx={{\r\n width: timeFieldWidth,\r\n maxWidth: timeFieldWidth,\r\n minWidth: timeFieldWidth,\r\n ...noBorderStyle,\r\n \"& .MuiInputBase-root\": {\r\n width: timeFieldWidth,\r\n maxWidth: timeFieldWidth,\r\n minWidth: timeFieldWidth,\r\n },\r\n \"& .MuiInputBase-input\": {\r\n width: timeFieldWidth,\r\n minWidth: timeFieldWidth,\r\n maxWidth: timeFieldWidth,\r\n textAlign: \"left\",\r\n caretColor: \"transparent\",\r\n },\r\n \"& .MuiInputBase-input::placeholder\": {\r\n color: \"rgba(0, 0, 0, 0.3)\",\r\n opacity: 1,\r\n },\r\n }}\r\n slotProps={{\r\n input: { readOnly: readonly },\r\n htmlInput: {\r\n maxLength: 2,\r\n inputMode: \"numeric\",\r\n tabIndex: -1,\r\n style: { padding: \"0 2px\", textAlign: \"left\" },\r\n },\r\n }}\r\n />\r\n {showCursor && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n bottom: size === \"small\" ? 1 : 3,\r\n left: `calc(2px + ${getCursorLeft(groupIndex)}px)`,\r\n width: cursorWidth,\r\n height: cursorHeight,\r\n backgroundColor: \"text.primary\",\r\n animation: \"blink 1s step-end infinite\",\r\n \"@keyframes blink\": {\r\n \"0%, 100%\": { opacity: 1 },\r\n \"50%\": { opacity: 0 },\r\n },\r\n pointerEvents: \"none\",\r\n }}\r\n />\r\n )}\r\n </Box>\r\n );\r\n };\r\n\r\n // \uC2DC\uAC04 \uD544\uB4DC \uD45C\uC2DC \uC5EC\uBD80 (\uAC12\uC774 \uC788\uAC70\uB098 \uD3EC\uCEE4\uC2A4\uAC00 \uC788\uC744 \uB54C\uB9CC)\r\n const hasAnyValue =\r\n dateDisplayValue.length > 0 ||\r\n hourValue.length > 0 ||\r\n minuteValue.length > 0 ||\r\n secondValue.length > 0;\r\n const showTimeFields =\r\n hasAnyValue || isDateFocused || focusedGroup !== null;\r\n\r\n // endAdornment (\uC2DC\uAC04 \uD544\uB4DC + \uC544\uC774\uCF58)\r\n const endAdornmentElement = (\r\n <InputAdornment\r\n position=\"end\"\r\n sx={{ ml: 0, mr: size === \"small\" ? -0.5 : 0, flexGrow: 1 }}\r\n >\r\n <Box sx={{ display: \"flex\", alignItems: \"center\", width: \"100%\" }}>\r\n {/* \uC2DC\uAC04 \uD544\uB4DC\uB4E4 - \uAC12\uC774 \uC788\uAC70\uB098 \uD3EC\uCEE4\uC2A4\uAC00 \uC788\uC744 \uB54C\uB9CC \uD45C\uC2DC */}\r\n {showTimeFields && (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n flexShrink: 0,\r\n }}\r\n >\r\n {renderTimeGroup(0, hourValue, \"00\")}\r\n <ColonBox size={size} />\r\n {renderTimeGroup(1, minuteValue, \"00\")}\r\n {hasSecond && (\r\n <>\r\n <ColonBox size={size} />\r\n {renderTimeGroup(2, secondValue, \"00\")}\r\n </>\r\n )}\r\n </Box>\r\n )}\r\n\r\n {/* Spacer - \uC544\uC774\uCF58\uC744 \uC624\uB978\uCABD \uB05D\uC73C\uB85C \uBC00\uAE30, \uD074\uB9AD \uC2DC \uB0A0\uC9DC \uD544\uB4DC \uD3EC\uCEE4\uC2A4 */}\r\n <Box\r\n sx={{ flexGrow: 1, height: \"100%\", minHeight: 24 }}\r\n onClick={() => {\r\n if (!disabled && !readonly) {\r\n dateInputRef.current?.focus();\r\n }\r\n }}\r\n />\r\n\r\n {/* \uC544\uC774\uCF58 \uB610\uB294 \uB3D9\uC77C \uD06C\uAE30 \uBE48 \uACF5\uAC04 */}\r\n {calendarIcon &&\r\n (readonly ? (\r\n // readonly\uC77C \uB54C \uC544\uC774\uCF58\uACFC \uB3D9\uC77C\uD55C \uD06C\uAE30\uC758 \uBE48 \uACF5\uAC04\r\n <Box\r\n sx={{\r\n width: size === \"small\" ? 28 : 32,\r\n height: size === \"small\" ? 28 : 32,\r\n ml: 0.5,\r\n }}\r\n />\r\n ) : (\r\n <IconButton\r\n onClick={(e) => {\r\n setAnchorEl(e.currentTarget);\r\n setCalendarOpen(true);\r\n }}\r\n edge=\"end\"\r\n size=\"small\"\r\n disabled={disabled}\r\n sx={{\r\n ml: 0.5,\r\n color: \"text.secondary\",\r\n opacity: 0.5,\r\n transition: \"opacity 0.2s, color 0.2s\",\r\n \"&:hover\": {\r\n opacity: 1,\r\n color: \"text.primary\",\r\n },\r\n }}\r\n >\r\n <CalendarIcon size={size === \"small\" ? 16 : 18} />\r\n </IconButton>\r\n ))}\r\n </Box>\r\n </InputAdornment>\r\n );\r\n\r\n return (\r\n <>\r\n <TextField\r\n inputRef={dateInputRef}\r\n value={dateDisplayValue}\r\n onChange={handleDateChange}\r\n onClick={handleDateClick}\r\n onKeyDown={handleDateKeyDown}\r\n onFocus={handleDateFocus}\r\n onBlur={handleBlur}\r\n label={label}\r\n placeholder={datePlaceholder}\r\n disabled={disabled}\r\n size={size}\r\n fullWidth={fullWidth}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n className={className}\r\n id={id}\r\n sx={{\r\n ...invalidStyles,\r\n ...readonlyStyles,\r\n ...sx,\r\n \"& .MuiInputBase-input\": {\r\n width: dateFieldWidth,\r\n minWidth: dateFieldWidth,\r\n },\r\n }}\r\n slotProps={{\r\n input: {\r\n readOnly: readonly,\r\n endAdornment: endAdornmentElement,\r\n },\r\n htmlInput: {\r\n maxLength: dateMaxLength,\r\n inputMode: \"numeric\",\r\n },\r\n }}\r\n />\r\n\r\n {/* Calendar Popup */}\r\n <DateTimePicker\r\n open={calendarOpen}\r\n anchorEl={anchorEl}\r\n onClose={() => {\r\n setCalendarOpen(false);\r\n setAnchorEl(null);\r\n }}\r\n anchorOrigin={{\r\n vertical: \"bottom\",\r\n horizontal: \"right\",\r\n }}\r\n transformOrigin={{\r\n vertical: \"top\",\r\n horizontal: \"right\",\r\n }}\r\n selectedDate={calendarSelectedDate}\r\n onDateChange={handleCalendarSelect}\r\n timeValue={{\r\n hour: hourValue,\r\n minute: minuteValue,\r\n second: hasSecond ? secondValue : undefined,\r\n }}\r\n onTimeChange={(hour, minute, second) => {\r\n handleCalendarTimeChange(\r\n parseInt(hour, 10),\r\n parseInt(minute, 10),\r\n second ? parseInt(second, 10) : undefined,\r\n );\r\n }}\r\n minDate={minDateTime}\r\n maxDate={maxDateTime}\r\n holidays={holidays}\r\n styles={{ selectedColor, holidayColor }}\r\n showToday={showToday}\r\n timeFormat={\r\n hasSecond\r\n ? is12Hour\r\n ? \"hh:mm:ss\"\r\n : \"HH:mm:ss\"\r\n : is12Hour\r\n ? \"hh:mm\"\r\n : \"HH:mm\"\r\n }\r\n minTime={minTime}\r\n maxTime={maxTime}\r\n minuteStep={minuteStep}\r\n secondStep={secondStep}\r\n hideDisabledTime={hideDisabledTime}\r\n />\r\n </>\r\n );\r\n});\r\n\r\nconst DateTimeTextFieldWithForm = forwardRef<\r\n HTMLDivElement,\r\n DateTimeTextFieldProps\r\n>(function DateTimeTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"DateTimeTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"DateTimeTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name);\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <DateTimeTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const DateTimeTextField = forwardRef<\r\n HTMLDivElement,\r\n DateTimeTextFieldProps\r\n>(function DateTimeTextField(props, ref) {\r\n if (props.form) {\r\n return <DateTimeTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <DateTimeTextFieldBase {...props} ref={ref} />;\r\n});\r\n", "/**\r\n * BizNumTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n useRef,\r\n useMemo,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField, Box, IconButton } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport { InfoAlert } from \"@ehfuse/alerts\";\r\nimport type { BizNumTextFieldProps } from \"./types\";\r\nimport { DashIcon, CopyIcon } from \"./icons\";\r\nimport { useGroupedInput, GroupConfig } from \"./hooks/useGroupedInput\";\r\nimport { useDebouncedEmit } from \"./hooks\";\r\nimport { GroupedInputWrapper } from \"./components\";\r\nimport { validateBusinessNumber } from \"./utils\";\r\n\r\nconst BizNumTextFieldBase = forwardRef<HTMLDivElement, BizNumTextFieldProps>(\r\n function BizNumTextFieldBase(\r\n {\r\n label,\r\n includeDash = false,\r\n validate = false,\r\n copyIcon = true,\r\n fontSize,\r\n fontColor,\r\n fontFamily,\r\n onValidationChange,\r\n invalidBorderColor,\r\n debounce,\r\n readonly,\r\n sx,\r\n value,\r\n onChange,\r\n size,\r\n disabled,\r\n className,\r\n id,\r\n autoFocus,\r\n name,\r\n fullWidth = false,\r\n },\r\n ref,\r\n ) {\r\n // 3\uAC1C \uADF8\uB8F9: 000-00-00000\r\n const [group1, setGroup1] = useState(\"\"); // 3\uC790\uB9AC\r\n const [group2, setGroup2] = useState(\"\"); // 2\uC790\uB9AC\r\n const [group3, setGroup3] = useState(\"\"); // 5\uC790\uB9AC\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n const [isInternalChange, setIsInternalChange] = useState(false);\r\n\r\n const ref1 = useRef<HTMLInputElement>(null);\r\n const ref2 = useRef<HTMLInputElement>(null);\r\n const ref3 = useRef<HTMLInputElement>(null);\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n // \uC678\uBD80 ref\uC640 \uB0B4\uBD80 containerRef \uBCD1\uD569\r\n useImperativeHandle(ref, () => containerRef.current!, []);\r\n\r\n // \uADF8\uB8F9\uBCC4 \uCD5C\uB300 \uAE38\uC774\r\n const maxLengths = [3, 2, 5];\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange: debouncedEmit, flushOnBlur } = useDebouncedEmit({\r\n name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n // \uD3F0\uD2B8 \uD06C\uAE30 \uACC4\uC0B0\r\n const defaultFontSize = size === \"small\" ? 16 : 18;\r\n const computedFontSize = fontSize\r\n ? typeof fontSize === \"number\"\r\n ? fontSize\r\n : parseFloat(fontSize) *\r\n (fontSize.toString().includes(\"rem\") ? 16 : 1)\r\n : defaultFontSize;\r\n\r\n // useGroupedInput \uD6C5 \uC0AC\uC6A9\r\n const groups: GroupConfig[] = useMemo(\r\n () => [\r\n { maxLength: 3, ref: ref1, value: group1, setValue: setGroup1 },\r\n { maxLength: 2, ref: ref2, value: group2, setValue: setGroup2 },\r\n { maxLength: 5, ref: ref3, value: group3, setValue: setGroup3 },\r\n ],\r\n [group1, group2, group3],\r\n );\r\n\r\n const {\r\n focusedGroup,\r\n setFocusedGroup,\r\n cursorVisible,\r\n inputComplete,\r\n getCursorLeft,\r\n createMouseDownHandler,\r\n createClickHandler,\r\n createFocusHandler,\r\n createBlurHandler,\r\n createKeyDownHandler,\r\n createChangeHandler: createGroupChangeHandler,\r\n } = useGroupedInput({\r\n groups,\r\n fontFamily,\r\n fontSize: computedFontSize,\r\n disabled,\r\n readonly,\r\n });\r\n\r\n // value prop \uBCC0\uACBD \uC2DC \uB0B4\uBD80 \uC0C1\uD0DC \uB3D9\uAE30\uD654\r\n useEffect(() => {\r\n if (isInternalChange) {\r\n setIsInternalChange(false);\r\n return;\r\n }\r\n\r\n if (value !== undefined && value !== null) {\r\n const numbers = String(value).replace(/\\D/g, \"\").slice(0, 10);\r\n setGroup1(numbers.slice(0, 3));\r\n setGroup2(numbers.slice(3, 5));\r\n setGroup3(numbers.slice(5, 10));\r\n } else {\r\n setGroup1(\"\");\r\n setGroup2(\"\");\r\n setGroup3(\"\");\r\n }\r\n }, [value, isInternalChange]);\r\n\r\n // \uC804\uCCB4 \uBC88\uD638 \uAC00\uC838\uC624\uAE30\r\n const getFullNumber = useCallback(() => {\r\n return group1 + group2 + group3;\r\n }, [group1, group2, group3]);\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uBC0F onChange \uD638\uCD9C\r\n const emitChange = useCallback(\r\n (g1: string, g2: string, g3: string) => {\r\n const fullNumber = g1 + g2 + g3;\r\n const isComplete = fullNumber.length === 10;\r\n let isValid = isComplete;\r\n\r\n if (validate && isComplete) {\r\n isValid = validateBusinessNumber(fullNumber);\r\n }\r\n\r\n setIsInvalid(isComplete && !isValid);\r\n\r\n if (onValidationChange) {\r\n onValidationChange(isValid);\r\n }\r\n\r\n setIsInternalChange(true);\r\n const outputValue = includeDash\r\n ? `${g1}-${g2}-${g3}`\r\n : fullNumber;\r\n debouncedEmit(null, outputValue);\r\n },\r\n [validate, onValidationChange, includeDash, debouncedEmit],\r\n );\r\n\r\n // \uC785\uB825 \uD578\uB4E4\uB7EC (\uD6C5\uC758 \uD578\uB4E4\uB7EC + \uCEE4\uC2A4\uD140 \uB85C\uC9C1)\r\n const handleChange = (groupIndex: number) => {\r\n return createGroupChangeHandler(groupIndex, (newValue, idx) => {\r\n const newValues = [group1, group2, group3];\r\n newValues[idx] = newValue;\r\n emitChange(newValues[0], newValues[1], newValues[2]);\r\n });\r\n };\r\n\r\n // \uD0A4 \uC785\uB825 \uD578\uB4E4\uB7EC (\uD6C5\uC758 \uD578\uB4E4\uB7EC + \uCEE4\uC2A4\uD140 \uB85C\uC9C1)\r\n const handleKeyDown = (groupIndex: number) => {\r\n return createKeyDownHandler(groupIndex, (newValue, idx) => {\r\n const newValues = [group1, group2, group3];\r\n newValues[idx] = newValue;\r\n emitChange(newValues[0], newValues[1], newValues[2]);\r\n });\r\n };\r\n\r\n // blur \uD578\uB4E4\uB7EC\r\n const handleBlur = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>) => {\r\n const blurHandler = createBlurHandler();\r\n blurHandler();\r\n\r\n const fullNumber = getFullNumber();\r\n const outputValue = includeDash\r\n ? `${group1}-${group2}-${group3}`\r\n : fullNumber;\r\n setIsInternalChange(true);\r\n flushOnBlur(e, outputValue);\r\n },\r\n [\r\n createBlurHandler,\r\n getFullNumber,\r\n includeDash,\r\n group1,\r\n group2,\r\n group3,\r\n flushOnBlur,\r\n ],\r\n );\r\n\r\n // \uBCF5\uC0AC \uD578\uB4E4\uB7EC\r\n const handleCopy = useCallback(() => {\r\n const fullNumber = getFullNumber();\r\n const copyValue = includeDash\r\n ? `${group1}-${group2}-${group3}`\r\n : fullNumber;\r\n navigator.clipboard.writeText(copyValue);\r\n InfoAlert(\"\uC0AC\uC5C5\uC790\uBC88\uD638\uAC00 \uBCF5\uC0AC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\");\r\n }, [getFullNumber, includeDash, group1, group2, group3]);\r\n\r\n // \uD544\uB4DC \uB108\uBE44\r\n const fieldWidths = [\"3ch\", \"2ch\", \"5.5ch\"];\r\n\r\n // \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C \uD06C\uAE30\r\n const cursorWidth = \"0.6em\";\r\n const cursorHeight = \"1px\";\r\n\r\n // TextField border \uC81C\uAC70 \uC2A4\uD0C0\uC77C\r\n const noBorderStyle: SxProps<Theme> = {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": { border: \"none\" },\r\n \"&:hover fieldset\": { border: \"none\" },\r\n \"&.Mui-focused fieldset\": { border: \"none\" },\r\n },\r\n };\r\n\r\n // \uADF8\uB8F9 \uB80C\uB354\uB9C1\r\n const renderGroup = (\r\n groupIndex: number,\r\n groupValue: string,\r\n placeholder: string,\r\n ) => {\r\n const isFocused = focusedGroup === groupIndex;\r\n const showCursor = cursorVisible && isFocused && !inputComplete;\r\n const refs = [ref1, ref2, ref3];\r\n\r\n return (\r\n <Box\r\n onMouseDown={createMouseDownHandler(groupIndex)}\r\n onClick={createClickHandler(groupIndex)}\r\n sx={{\r\n position: \"relative\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n }}\r\n >\r\n <TextField\r\n inputRef={refs[groupIndex]}\r\n value={groupValue}\r\n onChange={handleChange(groupIndex)}\r\n onKeyDown={handleKeyDown(groupIndex)}\r\n onFocus={createFocusHandler(groupIndex)}\r\n onBlur={handleBlur}\r\n disabled={disabled}\r\n size={size}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n placeholder={placeholder}\r\n variant=\"outlined\"\r\n autoFocus={groupIndex === 0 && autoFocus}\r\n sx={{\r\n width: \"auto\",\r\n minWidth: 0,\r\n ...noBorderStyle,\r\n \"& .MuiInputBase-root\": { width: \"auto\" },\r\n \"& .MuiInputBase-input\": {\r\n width: fieldWidths[groupIndex],\r\n userSelect: \"none\",\r\n ...(fontSize && { fontSize }),\r\n ...(fontColor && { color: fontColor }),\r\n ...(fontFamily && { fontFamily }),\r\n },\r\n \"& .MuiInputBase-input::placeholder\": {\r\n color: \"rgba(0, 0, 0, 0.2)\",\r\n opacity: 1,\r\n },\r\n }}\r\n slotProps={{\r\n input: {\r\n readOnly: readonly,\r\n },\r\n htmlInput: {\r\n maxLength: maxLengths[groupIndex],\r\n inputMode: \"numeric\",\r\n style: { textAlign: \"left\", padding: \"0 4px\" },\r\n },\r\n }}\r\n />\r\n {/* \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C */}\r\n {showCursor && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n bottom: size === \"small\" ? 0 : -2,\r\n left: `calc(4px + ${getCursorLeft(\r\n groupIndex,\r\n )}px)`,\r\n width: cursorWidth,\r\n height: cursorHeight,\r\n backgroundColor: fontColor || \"text.primary\",\r\n animation: \"blink 1s step-end infinite\",\r\n \"@keyframes blink\": {\r\n \"0%, 100%\": { opacity: 1 },\r\n \"50%\": { opacity: 0 },\r\n },\r\n pointerEvents: \"none\",\r\n }}\r\n />\r\n )}\r\n </Box>\r\n );\r\n };\r\n\r\n // Dash \uB798\uD37C \uCEF4\uD3EC\uB10C\uD2B8\r\n const Dash = () => (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n color: \"text.secondary\",\r\n mx: size === \"small\" ? 0.25 : 0.5,\r\n userSelect: \"none\",\r\n }}\r\n >\r\n <DashIcon size={size} />\r\n </Box>\r\n );\r\n\r\n // \uD074\uB9AD \uC2DC \uD3EC\uCEE4\uC2A4\uD560 ref \uACB0\uC815 (\uC678\uACFD \uD074\uB9AD \uC2DC \uCCAB \uBC88\uC9F8 \uCE78\uC73C\uB85C)\r\n const getTargetRefOnClick = useCallback(() => {\r\n return { ref: ref1, groupIndex: 0 };\r\n }, []);\r\n\r\n return (\r\n <Box\r\n ref={containerRef}\r\n sx={{\r\n ...(fullWidth && { width: \"100%\" }),\r\n ...sx,\r\n }}\r\n className={className}\r\n >\r\n <GroupedInputWrapper\r\n label={label}\r\n size={size}\r\n disabled={disabled}\r\n readonly={readonly}\r\n focusedGroup={focusedGroup}\r\n setFocusedGroup={setFocusedGroup}\r\n hasValue={getFullNumber().length > 0}\r\n isInvalid={isInvalid}\r\n invalidBorderColor={invalidBorderColor}\r\n inputRefs={[ref1, ref2, ref3]}\r\n getTargetRefOnClick={getTargetRefOnClick}\r\n fullWidth={fullWidth}\r\n id={id}\r\n contentSx={{\r\n pr:\r\n copyIcon && getFullNumber().length === 10\r\n ? 0.5\r\n : 1.5,\r\n }}\r\n >\r\n {renderGroup(0, group1, \"000\")}\r\n <Dash />\r\n {renderGroup(1, group2, \"00\")}\r\n <Dash />\r\n {renderGroup(2, group3, \"00000\")}\r\n {copyIcon && getFullNumber().length === 10 && (\r\n <>\r\n <Box sx={{ flexGrow: 1 }} />\r\n <IconButton\r\n onClick={(e) => {\r\n e.stopPropagation();\r\n handleCopy();\r\n }}\r\n onMouseDown={(e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n }}\r\n disabled={disabled}\r\n size={size}\r\n sx={{\r\n p: size === \"small\" ? 0.5 : 1,\r\n mr: 0.5,\r\n color: \"text.secondary\",\r\n \"&:hover\": {\r\n color: \"text.primary\",\r\n },\r\n }}\r\n >\r\n <CopyIcon size={size} />\r\n </IconButton>\r\n </>\r\n )}\r\n </GroupedInputWrapper>\r\n </Box>\r\n );\r\n },\r\n);\r\n\r\nconst BizNumTextFieldWithForm = forwardRef<\r\n HTMLDivElement,\r\n BizNumTextFieldProps\r\n>(function BizNumTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"BizNumTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"BizNumTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name) as string | undefined;\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <BizNumTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const BizNumTextField = forwardRef<HTMLDivElement, BizNumTextFieldProps>(\r\n function BizNumTextField(props, ref) {\r\n if (props.form) {\r\n return <BizNumTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <BizNumTextFieldBase {...props} ref={ref} />;\r\n },\r\n);\r\n", "/**\r\n * CardNumTextField.tsx\r\n *\r\n * @license MIT\r\n form,\r\n * @copyright 2025 \uAE40\uC601\uC9C4 (Kim Young Jin)\r\n * @author \uAE40\uC601\uC9C4 (ehfuse@gmail.com)\r\n */\r\n\r\nimport React, {\r\n useState,\r\n useEffect,\r\n useCallback,\r\n useRef,\r\n useMemo,\r\n forwardRef,\r\n useImperativeHandle,\r\n} from \"react\";\r\nimport { TextField, Box } from \"@mui/material\";\r\nimport type { SxProps, Theme } from \"@mui/material/styles\";\r\nimport type { CardNumTextFieldProps } from \"./types\";\r\nimport { useDebouncedEmit } from \"./hooks\";\r\nimport { useGroupedInput, GroupConfig } from \"./hooks/useGroupedInput\";\r\nimport { GroupedInputWrapper } from \"./components\";\r\nimport {\r\n DashIcon,\r\n CardIcon,\r\n VisaIcon,\r\n MastercardIcon,\r\n AmexIcon,\r\n JcbIcon,\r\n DinersIcon,\r\n DiscoverIcon,\r\n UnionPayIcon,\r\n BcIcon,\r\n} from \"./icons\";\r\nimport { CardBrand, validateCardNumber, detectCardBrand } from \"./utils\";\r\n\r\nconst CardNumTextFieldBase = forwardRef<HTMLDivElement, CardNumTextFieldProps>(\r\n function CardNumTextFieldBase(\r\n {\r\n label,\r\n maskColor = \"rgba(0, 0, 0, 0.7)\",\r\n fontSize,\r\n fontColor,\r\n fontFamily,\r\n onChange,\r\n onValidationChange,\r\n onCardBrandChange,\r\n invalidBorderColor,\r\n validate = false,\r\n debounce,\r\n readonly,\r\n sx,\r\n value,\r\n size,\r\n disabled,\r\n logoIcon = true,\r\n name = \"\",\r\n className,\r\n id,\r\n fullWidth = false,\r\n },\r\n ref,\r\n ) {\r\n // 4\uAC1C \uADF8\uB8F9 \uAC01\uAC01\uC758 \uAC12\r\n const [group1, setGroup1] = useState(\"\"); // \uCCAB 4\uC790\uB9AC (\uBCF4\uC784)\r\n const [group2, setGroup2] = useState(\"\"); // \uB458\uC9F8 4\uC790\uB9AC (\uB9C8\uC2A4\uD0B9)\r\n const [group3, setGroup3] = useState(\"\"); // \uC14B\uC9F8 4\uC790\uB9AC (\uB9C8\uC2A4\uD0B9)\r\n const [group4, setGroup4] = useState(\"\"); // \uB137\uC9F8 4\uC790\uB9AC (\uBCF4\uC784)\r\n const [isInvalid, setIsInvalid] = useState(false);\r\n const [isInternalChange, setIsInternalChange] = useState(false);\r\n const [cardBrand, setCardBrand] = useState<CardBrand>(null);\r\n // \uB9C8\uC9C0\uB9C9 \uC785\uB825\uB41C \uADF8\uB8F9\uACFC \uC778\uB371\uC2A4 \uCD94\uC801 (\uB9C8\uC2A4\uD0B9 \uADF8\uB8F9\uC5D0\uC11C \uB9C8\uC9C0\uB9C9 \uC22B\uC790 \uD45C\uC2DC\uC6A9)\r\n const [lastInputInfo, setLastInputInfo] = useState<{\r\n groupIndex: number;\r\n charIndex: number;\r\n } | null>(null);\r\n\r\n const ref1 = useRef<HTMLInputElement>(null);\r\n const ref2 = useRef<HTMLInputElement>(null);\r\n const ref3 = useRef<HTMLInputElement>(null);\r\n const ref4 = useRef<HTMLInputElement>(null);\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n // \uC678\uBD80 ref\uC640 \uB0B4\uBD80 containerRef \uBCD1\uD569\r\n useImperativeHandle(ref, () => containerRef.current!, []);\r\n\r\n // \uD3F0\uD2B8 \uD06C\uAE30 \uACC4\uC0B0\r\n const defaultFontSize = size === \"small\" ? 16 : 18;\r\n const computedFontSize = fontSize\r\n ? typeof fontSize === \"number\"\r\n ? fontSize\r\n : parseFloat(fontSize) *\r\n (fontSize.toString().includes(\"rem\") ? 16 : 1)\r\n : defaultFontSize;\r\n\r\n // useGroupedInput \uD6C5 \uC0AC\uC6A9\r\n const groups: GroupConfig[] = useMemo(\r\n () => [\r\n { maxLength: 4, ref: ref1, value: group1, setValue: setGroup1 },\r\n { maxLength: 4, ref: ref2, value: group2, setValue: setGroup2 },\r\n { maxLength: 4, ref: ref3, value: group3, setValue: setGroup3 },\r\n { maxLength: 4, ref: ref4, value: group4, setValue: setGroup4 },\r\n ],\r\n [group1, group2, group3, group4],\r\n );\r\n\r\n const {\r\n focusedGroup,\r\n setFocusedGroup,\r\n cursorVisible,\r\n cursorPosRef,\r\n inputComplete,\r\n renderTrigger,\r\n getCursorLeft,\r\n createMouseDownHandler,\r\n createClickHandler,\r\n createFocusHandler,\r\n createBlurHandler,\r\n createKeyDownHandler,\r\n createChangeHandler: createGroupChangeHandler,\r\n } = useGroupedInput({\r\n groups,\r\n fontSize: computedFontSize,\r\n disabled,\r\n readonly,\r\n });\r\n\r\n // useDebouncedEmit \uD6C5 \uC0AC\uC6A9\r\n const { emitChange, flushOnBlur } = useDebouncedEmit({\r\n name,\r\n debounce,\r\n onChange,\r\n });\r\n\r\n // \uC804\uCCB4 \uCE74\uB4DC\uBC88\uD638 \uC870\uD569\r\n const getFullNumber = useCallback(() => {\r\n return group1 + group2 + group3 + group4;\r\n }, [group1, group2, group3, group4]);\r\n\r\n // \uC720\uD6A8\uC131 \uAC80\uC0AC \uBC0F onChange \uD638\uCD9C\r\n const emitCardChange = useCallback(\r\n (g1: string, g2: string, g3: string, g4: string) => {\r\n const fullValue = g1 + g2 + g3 + g4;\r\n const isComplete = fullValue.length === 16;\r\n let isValid = isComplete;\r\n\r\n // validate\uAC00 true\uC77C \uB54C\uB9CC Luhn \uC54C\uACE0\uB9AC\uC998 \uC801\uC6A9\r\n if (validate && isComplete) {\r\n isValid = validateCardNumber(fullValue);\r\n }\r\n\r\n setIsInvalid(isComplete && !isValid);\r\n\r\n if (onValidationChange) {\r\n onValidationChange(isValid);\r\n }\r\n\r\n // \uCE74\uB4DC \uBE0C\uB79C\uB4DC \uAC10\uC9C0\r\n const brand = detectCardBrand(fullValue);\r\n setCardBrand(brand);\r\n if (onCardBrandChange) {\r\n onCardBrandChange(brand);\r\n }\r\n\r\n setIsInternalChange(true);\r\n emitChange(null, fullValue, true);\r\n },\r\n [validate, onValidationChange, onCardBrandChange, emitChange],\r\n );\r\n\r\n // value prop \uBCC0\uACBD \uC2DC \uB0B4\uBD80 \uC0C1\uD0DC \uB3D9\uAE30\uD654\r\n useEffect(() => {\r\n if (isInternalChange) {\r\n setIsInternalChange(false);\r\n return;\r\n }\r\n\r\n // uncontrolled \uC0AC\uC6A9 \uC2DC \uB3D9\uAE30\uD654 \uC2A4\uD0B5\r\n if (value === undefined) {\r\n return;\r\n }\r\n\r\n if (value !== null) {\r\n const numbers = String(value).replace(/\\D/g, \"\").slice(0, 16);\r\n setGroup1(numbers.slice(0, 4));\r\n setGroup2(numbers.slice(4, 8));\r\n setGroup3(numbers.slice(8, 12));\r\n setGroup4(numbers.slice(12, 16));\r\n } else {\r\n setGroup1(\"\");\r\n setGroup2(\"\");\r\n setGroup3(\"\");\r\n setGroup4(\"\");\r\n }\r\n }, [value, isInternalChange]);\r\n\r\n // \uC785\uB825 \uD578\uB4E4\uB7EC (\uD6C5\uC758 \uD578\uB4E4\uB7EC + \uCEE4\uC2A4\uD140 \uB85C\uC9C1)\r\n const handleChange = (groupIndex: number) => {\r\n return createGroupChangeHandler(groupIndex, (newValue, idx) => {\r\n const newValues = [group1, group2, group3, group4];\r\n newValues[idx] = newValue;\r\n\r\n // \uB9C8\uC2A4\uD0B9 \uADF8\uB8F9(1, 2)\uC5D0\uC11C \uC785\uB825 \uC2DC \uB9C8\uC9C0\uB9C9 \uC785\uB825 \uBB38\uC790 \uCD94\uC801\r\n if ((idx === 1 || idx === 2) && newValue.length > 0) {\r\n setLastInputInfo({\r\n groupIndex: idx,\r\n charIndex: newValue.length - 1,\r\n });\r\n // \uC7A0\uC2DC \uD6C4 \uC228\uAE40 (500ms)\r\n setTimeout(() => {\r\n setLastInputInfo(null);\r\n }, 500);\r\n }\r\n\r\n emitCardChange(\r\n newValues[0],\r\n newValues[1],\r\n newValues[2],\r\n newValues[3],\r\n );\r\n });\r\n };\r\n\r\n // \uD0A4 \uC785\uB825 \uD578\uB4E4\uB7EC\r\n const handleKeyDown = (groupIndex: number) => {\r\n return createKeyDownHandler(groupIndex, (newValue, idx) => {\r\n const newValues = [group1, group2, group3, group4];\r\n newValues[idx] = newValue;\r\n emitCardChange(\r\n newValues[0],\r\n newValues[1],\r\n newValues[2],\r\n newValues[3],\r\n );\r\n });\r\n };\r\n\r\n // blur \uD578\uB4E4\uB7EC\r\n const handleBlur = useCallback(\r\n (e: React.FocusEvent<HTMLInputElement>) => {\r\n const blurHandler = createBlurHandler();\r\n blurHandler();\r\n\r\n const fullValue = getFullNumber();\r\n flushOnBlur(e, fullValue);\r\n },\r\n [createBlurHandler, getFullNumber, flushOnBlur],\r\n );\r\n\r\n // 2-2. \uC678\uACFD \uC601\uC5ED \uD074\uB9AD \uC2DC \uB9C8\uC9C0\uB9C9 \uAC12\uC774 \uC788\uB294 \uCE78\uC758 \uB9C8\uC9C0\uB9C9\uC73C\uB85C \uCEE4\uC11C \uC774\uB3D9\r\n const handleContainerClick = useCallback(\r\n (e: React.MouseEvent) => {\r\n if (disabled || readonly) return;\r\n\r\n // \uC774\uBBF8 input\uC5D0\uC11C \uCC98\uB9AC\uB41C \uD074\uB9AD\uC774\uBA74 \uBB34\uC2DC\r\n const target = e.target as HTMLElement;\r\n if (target.tagName === \"INPUT\") return;\r\n\r\n const values = [group1, group2, group3, group4];\r\n const refs = [ref1, ref2, ref3, ref4];\r\n\r\n // \uB9C8\uC9C0\uB9C9\uC73C\uB85C \uAC12\uC774 \uC788\uB294 \uADF8\uB8F9 \uCC3E\uAE30\r\n let lastFilledIndex = -1;\r\n for (let i = values.length - 1; i >= 0; i--) {\r\n if (values[i].length > 0) {\r\n lastFilledIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n if (lastFilledIndex >= 0) {\r\n // \uB9C8\uC9C0\uB9C9 \uAC12\uC774 \uC788\uB294 \uCE78\uC758 \uB9C8\uC9C0\uB9C9\uC73C\uB85C \uC774\uB3D9\r\n const targetRef = refs[lastFilledIndex];\r\n const targetValue = values[lastFilledIndex];\r\n const newPos = targetValue.length;\r\n cursorPosRef.current = newPos;\r\n targetRef.current?.focus();\r\n targetRef.current?.setSelectionRange(newPos, newPos);\r\n } else {\r\n // \uBAA8\uB450 \uBE44\uC5B4\uC788\uC73C\uBA74 \uCCAB \uBC88\uC9F8 \uCE78\uC73C\uB85C\r\n cursorPosRef.current = 0;\r\n ref1.current?.focus();\r\n ref1.current?.setSelectionRange(0, 0);\r\n }\r\n },\r\n [disabled, readonly, group1, group2, group3, group4, cursorPosRef],\r\n );\r\n\r\n // \uB3D9\uADF8\uB77C\uBBF8 \uD06C\uAE30 (\uB9C8\uC2A4\uD0B9\uC6A9)\r\n const dotSize = Math.round(computedFontSize * 0.5);\r\n\r\n // \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C \uD06C\uAE30\r\n const cursorWidthPx = `${computedFontSize * 0.55}px`;\r\n const cursorHeightPx = \"1px\";\r\n\r\n // \uD544\uB4DC \uB108\uBE44 - \uC77C\uBC18 \uADF8\uB8F9\uC6A9 (\uC22B\uC790 4\uC790\uB9AC)\r\n const normalFieldWidth = \"4ch\";\r\n // \uD544\uB4DC \uB108\uBE44 - \uB9C8\uC2A4\uD0B9 \uADF8\uB8F9\uC6A9 (\uB3D9\uADF8\uB77C\uBBF8 \uAC04\uACA9 \uACE0\uB824)\r\n const maskedFieldWidth = \"5.5ch\";\r\n\r\n // \uB9C8\uC2A4\uD0B9 \uADF8\uB8F9\uC758 \uB3D9\uADF8\uB77C\uBBF8 \uAC04\uACA9 \uACC4\uC0B0 (px \uB2E8\uC704)\r\n // maskedFieldWidth = 5.5ch, padding px: 0.25 * 8 = 2px \uC591\uCABD\r\n // \uB3D9\uADF8\uB77C\uBBF8 4\uAC1C\uAC00 space-between\uC73C\uB85C \uBC30\uCE58\uB428\r\n const getMaskedCursorLeft = (cursorPos: number): number => {\r\n // 5.5ch\uB97C px\uB85C \uBCC0\uD658 (1ch \u2248 0.45em)\r\n const chToPx = computedFontSize * 0.45;\r\n const fieldWidthPx = 5.5 * chToPx;\r\n const paddingPx = 2; // px: 0.25 * 8\r\n const contentWidth = fieldWidthPx - paddingPx * 2;\r\n // space-between: \uCCAB \uBC88\uC9F8 \uC694\uC18C\uB294 \uC2DC\uC791, \uB9C8\uC9C0\uB9C9 \uC694\uC18C\uB294 \uB05D, \uB098\uBA38\uC9C0\uB294 \uADE0\uB4F1 \uBD84\uBC30\r\n // 4\uAC1C \uC694\uC18C\uC758 \uACBD\uC6B0: 0, 1/3, 2/3, 1 \uC704\uCE58\uC5D0 \uBC30\uCE58\r\n const gap = contentWidth / 3; // 4\uAC1C \uB3D9\uADF8\uB77C\uBBF8 \uC0AC\uC774 3\uAC1C \uAC04\uACA9\r\n return paddingPx + cursorPos * gap;\r\n };\r\n\r\n // TextField border \uC81C\uAC70 \uC2A4\uD0C0\uC77C\r\n const noBorderStyle: SxProps<Theme> = {\r\n \"& .MuiOutlinedInput-root\": {\r\n \"& fieldset\": { border: \"none\" },\r\n \"&:hover fieldset\": { border: \"none\" },\r\n \"&.Mui-focused fieldset\": { border: \"none\" },\r\n },\r\n };\r\n\r\n // \uB9C8\uC2A4\uD0B9\uB41C \uADF8\uB8F9 \uB80C\uB354\uB9C1 (2, 3\uBC88\uC9F8 \uADF8\uB8F9)\r\n // renderTrigger\uB97C \uC758\uC874\uC131\uC73C\uB85C \uC0AC\uC6A9\uD558\uC5EC \uCEE4\uC11C \uC704\uCE58 \uBCC0\uACBD \uC2DC \uB9AC\uB80C\uB354\uB9C1\r\n const renderMaskedGroup = (groupIndex: number, groupValue: string) => {\r\n const isFocused = focusedGroup === groupIndex;\r\n const showCursor = cursorVisible && isFocused && !inputComplete;\r\n const refs = [ref1, ref2, ref3, ref4];\r\n // renderTrigger \uBCC0\uACBD \uC2DC \uCEE4\uC11C \uC704\uCE58 \uC5C5\uB370\uC774\uD2B8\uB97C \uC704\uD574 \uCC38\uC870\r\n void renderTrigger;\r\n\r\n return (\r\n <Box\r\n onMouseDown={createMouseDownHandler(groupIndex)}\r\n onClick={createClickHandler(groupIndex)}\r\n sx={{\r\n position: \"relative\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n userSelect: \"none\",\r\n }}\r\n >\r\n <TextField\r\n inputRef={refs[groupIndex]}\r\n value={groupValue}\r\n onChange={handleChange(groupIndex)}\r\n onKeyDown={handleKeyDown(groupIndex)}\r\n onFocus={createFocusHandler(groupIndex)}\r\n onBlur={handleBlur}\r\n disabled={disabled}\r\n size={size}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n variant=\"outlined\"\r\n sx={{\r\n width: \"auto\",\r\n minWidth: 0,\r\n ...noBorderStyle,\r\n \"& .MuiInputBase-root\": { width: \"auto\" },\r\n \"& .MuiInputBase-input\": {\r\n width: maskedFieldWidth,\r\n color: \"transparent\",\r\n caretColor: \"transparent\",\r\n userSelect: \"none\",\r\n ...(fontSize && { fontSize }),\r\n ...(fontFamily && { fontFamily }),\r\n },\r\n }}\r\n slotProps={{\r\n input: {\r\n readOnly: readonly,\r\n },\r\n htmlInput: {\r\n maxLength: 4,\r\n inputMode: \"numeric\",\r\n style: { textAlign: \"left\", padding: 0 },\r\n },\r\n }}\r\n />\r\n {/* \uB9C8\uC2A4\uD0B9 \uC624\uBC84\uB808\uC774 - \uB3D9\uADF8\uB77C\uBBF8 + \uB9C8\uC9C0\uB9C9 \uC785\uB825 \uC22B\uC790 */}\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n left: 0,\r\n width: maskedFieldWidth,\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"space-between\",\r\n pointerEvents: \"none\",\r\n userSelect: \"none\",\r\n px: 0.25,\r\n }}\r\n >\r\n {Array.from({ length: 4 }).map((_, i) => {\r\n const isEntered = i < groupValue.length;\r\n // \uD3EC\uCEE4\uC2A4 \uC911\uC77C \uB54C \uCEE4\uC11C \uC704\uCE58\uC758 \uBB38\uC790 \uD45C\uC2DC (\uBC29\uD5A5\uD0A4 \uC774\uB3D9 \uC9C0\uC6D0)\r\n const cursorPos = cursorPosRef.current;\r\n const isAtCursor =\r\n isFocused &&\r\n i === cursorPos &&\r\n i < groupValue.length;\r\n\r\n // \uB9C8\uC9C0\uB9C9 \uC785\uB825\uB41C \uBB38\uC790 \uD45C\uC2DC (\uC785\uB825 \uC9C1\uD6C4 \uC7A0\uAE50)\r\n const isLastInput =\r\n lastInputInfo !== null &&\r\n lastInputInfo.groupIndex === groupIndex &&\r\n lastInputInfo.charIndex === i;\r\n\r\n if (isAtCursor || isLastInput) {\r\n // \uD3EC\uCEE4\uC2A4 \uC911\uC774\uACE0 \uCEE4\uC11C \uC704\uCE58\uC758 \uBB38\uC790\uAC70\uB098, \uB9C8\uC9C0\uB9C9 \uC785\uB825\uB41C \uBB38\uC790\uBA74 \uC22B\uC790 \uD45C\uC2DC\r\n return (\r\n <span\r\n key={i}\r\n style={{\r\n fontSize:\r\n fontSize ||\r\n (size === \"small\" ? 16 : 18),\r\n fontFamily: fontFamily || \"inherit\",\r\n color: fontColor || \"inherit\",\r\n display: \"inline-block\",\r\n width: `${dotSize}px`,\r\n textAlign: \"center\",\r\n }}\r\n >\r\n {groupValue[i]}\r\n </span>\r\n );\r\n }\r\n\r\n // \uB3D9\uADF8\uB77C\uBBF8 \uD45C\uC2DC (\uC785\uB825\uB428: \uC9C4\uD558\uAC8C, \uBBF8\uC785\uB825: \uD750\uB9AC\uAC8C)\r\n return (\r\n <span\r\n key={i}\r\n style={{\r\n width: `${dotSize}px`,\r\n height: `${dotSize}px`,\r\n borderRadius: \"50%\",\r\n backgroundColor: maskColor,\r\n opacity: isEntered ? 1 : 0.15,\r\n display: \"inline-block\",\r\n }}\r\n />\r\n );\r\n })}\r\n </Box>\r\n {/* \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C */}\r\n {showCursor && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n bottom: size === \"small\" ? 1 : 3,\r\n left: `${getMaskedCursorLeft(\r\n cursorPosRef.current,\r\n )}px`,\r\n width: cursorWidthPx,\r\n height: cursorHeightPx,\r\n backgroundColor: fontColor || \"text.primary\",\r\n animation: \"blink 1s step-end infinite\",\r\n \"@keyframes blink\": {\r\n \"0%, 100%\": { opacity: 1 },\r\n \"50%\": { opacity: 0 },\r\n },\r\n pointerEvents: \"none\",\r\n }}\r\n />\r\n )}\r\n </Box>\r\n );\r\n };\r\n\r\n // \uC77C\uBC18 \uADF8\uB8F9 \uB80C\uB354\uB9C1 (1, 4\uBC88\uC9F8 \uADF8\uB8F9)\r\n const renderNormalGroup = (groupIndex: number, groupValue: string) => {\r\n const isFocused = focusedGroup === groupIndex;\r\n const showCursor = cursorVisible && isFocused && !inputComplete;\r\n const refs = [ref1, ref2, ref3, ref4];\r\n\r\n return (\r\n <Box\r\n onMouseDown={createMouseDownHandler(groupIndex)}\r\n onClick={createClickHandler(groupIndex)}\r\n sx={{\r\n position: \"relative\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n }}\r\n >\r\n <TextField\r\n inputRef={refs[groupIndex]}\r\n value={groupValue}\r\n onChange={handleChange(groupIndex)}\r\n onKeyDown={handleKeyDown(groupIndex)}\r\n onFocus={createFocusHandler(groupIndex)}\r\n onBlur={handleBlur}\r\n disabled={disabled}\r\n size={size}\r\n autoComplete=\"off\"\r\n spellCheck=\"false\"\r\n placeholder=\"0000\"\r\n variant=\"outlined\"\r\n sx={{\r\n width: \"auto\",\r\n minWidth: 0,\r\n ...noBorderStyle,\r\n \"& .MuiInputBase-root\": { width: \"auto\" },\r\n \"& .MuiInputBase-input\": {\r\n width: normalFieldWidth,\r\n userSelect: \"none\",\r\n caretColor: \"transparent\",\r\n ...(fontSize && { fontSize }),\r\n ...(fontColor && { color: fontColor }),\r\n ...(fontFamily && { fontFamily }),\r\n },\r\n \"& .MuiInputBase-input::placeholder\": {\r\n color: \"rgba(0, 0, 0, 0.2)\",\r\n opacity: 1,\r\n },\r\n }}\r\n slotProps={{\r\n input: {\r\n readOnly: readonly,\r\n },\r\n htmlInput: {\r\n maxLength: 4,\r\n inputMode: \"numeric\",\r\n style: { textAlign: \"left\", padding: \"0 4px\" },\r\n },\r\n }}\r\n />\r\n {/* \uC5B8\uB354\uC2A4\uCF54\uC5B4 \uCEE4\uC11C */}\r\n {showCursor && (\r\n <Box\r\n sx={{\r\n position: \"absolute\",\r\n bottom: size === \"small\" ? 1 : 3,\r\n left: `${getCursorLeft(groupIndex) + 4}px`,\r\n width: cursorWidthPx,\r\n height: cursorHeightPx,\r\n backgroundColor: fontColor || \"text.primary\",\r\n animation: \"blink 1s step-end infinite\",\r\n \"@keyframes blink\": {\r\n \"0%, 100%\": { opacity: 1 },\r\n \"50%\": { opacity: 0 },\r\n },\r\n pointerEvents: \"none\",\r\n }}\r\n />\r\n )}\r\n </Box>\r\n );\r\n };\r\n\r\n // Dash \uB798\uD37C \uCEF4\uD3EC\uB10C\uD2B8\r\n const Dash = () => (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n color: \"text.secondary\",\r\n mx: size === \"small\" ? 0.5 : 0.75,\r\n userSelect: \"none\",\r\n }}\r\n >\r\n <DashIcon size={size} />\r\n </Box>\r\n );\r\n\r\n // \uCE74\uB4DC \uBE0C\uB79C\uB4DC \uC544\uC774\uCF58 \uB80C\uB354\uB9C1\r\n const renderCardIcon = () => {\r\n const iconSize = size === \"small\" ? 22 : 26;\r\n\r\n switch (cardBrand) {\r\n case \"visa\":\r\n return <VisaIcon size={iconSize} />;\r\n case \"mastercard\":\r\n return <MastercardIcon size={iconSize} />;\r\n case \"amex\":\r\n return <AmexIcon size={iconSize} />;\r\n case \"jcb\":\r\n return <JcbIcon size={iconSize} />;\r\n case \"diners\":\r\n return <DinersIcon size={iconSize} />;\r\n case \"discover\":\r\n return <DiscoverIcon size={iconSize} />;\r\n case \"unionpay\":\r\n return <UnionPayIcon size={iconSize} />;\r\n case \"bc\":\r\n return <BcIcon size={iconSize} />;\r\n default:\r\n return <CardIcon size={iconSize} />;\r\n }\r\n };\r\n\r\n // \uADF8\uB8F9 \uC785\uB825 \uB0B4\uBD80 \uCEF4\uD3EC\uB10C\uD2B8 \uB80C\uB354\uB9C1\r\n const renderGroupedInput = () => (\r\n <Box\r\n onClick={handleContainerClick}\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n width: \"100%\",\r\n height: \"100%\",\r\n cursor: disabled ? \"default\" : \"text\",\r\n ...(logoIcon && { pl: 1 }),\r\n }}\r\n >\r\n {/* \uCE74\uB4DC \uBE0C\uB79C\uB4DC \uC544\uC774\uCF58 */}\r\n {logoIcon && (\r\n <Box\r\n sx={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n mr: 0,\r\n flexShrink: 0,\r\n }}\r\n >\r\n {renderCardIcon()}\r\n </Box>\r\n )}\r\n {/* \uADF8\uB8F9 1: \uC77C\uBC18 */}\r\n {renderNormalGroup(0, group1)}\r\n <Dash />\r\n {/* \uADF8\uB8F9 2: \uB9C8\uC2A4\uD0B9 */}\r\n {renderMaskedGroup(1, group2)}\r\n <Dash />\r\n {/* \uADF8\uB8F9 3: \uB9C8\uC2A4\uD0B9 */}\r\n {renderMaskedGroup(2, group3)}\r\n <Dash />\r\n {/* \uADF8\uB8F9 4: \uC77C\uBC18 */}\r\n {renderNormalGroup(3, group4)}\r\n </Box>\r\n );\r\n\r\n // \uD074\uB9AD \uC2DC \uD3EC\uCEE4\uC2A4\uD560 ref \uACB0\uC815\r\n const getTargetRefOnClick = useCallback(() => {\r\n const values = [group1, group2, group3, group4];\r\n const refs = [ref1, ref2, ref3, ref4];\r\n\r\n // \uB9C8\uC9C0\uB9C9\uC73C\uB85C \uAC12\uC774 \uC788\uB294 \uADF8\uB8F9 \uCC3E\uAE30\r\n let lastFilledIndex = -1;\r\n for (let i = values.length - 1; i >= 0; i--) {\r\n if (values[i].length > 0) {\r\n lastFilledIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n if (lastFilledIndex >= 0) {\r\n return {\r\n ref: refs[lastFilledIndex],\r\n groupIndex: lastFilledIndex,\r\n };\r\n }\r\n // \uBAA8\uB450 \uBE44\uC5B4\uC788\uC73C\uBA74 \uCCAB \uBC88\uC9F8 \uCE78\r\n return { ref: ref1, groupIndex: 0 };\r\n }, [group1, group2, group3, group4]);\r\n\r\n return (\r\n <GroupedInputWrapper\r\n label={label}\r\n size={size}\r\n disabled={disabled}\r\n readonly={readonly}\r\n focusedGroup={focusedGroup}\r\n setFocusedGroup={setFocusedGroup}\r\n hasValue={getFullNumber().length > 0}\r\n isInvalid={isInvalid}\r\n invalidBorderColor={invalidBorderColor}\r\n inputRefs={[ref1, ref2, ref3, ref4]}\r\n getTargetRefOnClick={getTargetRefOnClick}\r\n fullWidth={fullWidth}\r\n sx={sx}\r\n className={className}\r\n id={id}\r\n contentSx={logoIcon ? { pl: 0 } : undefined}\r\n >\r\n {renderGroupedInput()}\r\n </GroupedInputWrapper>\r\n );\r\n },\r\n);\r\n\r\nconst CardNumTextFieldWithForm = forwardRef<\r\n HTMLDivElement,\r\n CardNumTextFieldProps\r\n>(function CardNumTextFieldWithForm({ form, name, onChange, ...rest }, ref) {\r\n if (!form || typeof form.useFormValue !== \"function\") {\r\n throw new Error(\r\n \"CardNumTextField form prop is missing. Provide a form from useForm or useGlobalForm.\",\r\n );\r\n }\r\n if (!name) {\r\n throw new Error(\r\n \"CardNumTextField requires a name when form prop is provided.\",\r\n );\r\n }\r\n\r\n const formValue = form.useFormValue(name) as string | undefined;\r\n const handleFormChange = useCallback(\r\n (event: React.ChangeEvent<HTMLInputElement>) => {\r\n form.handleFormChange(event);\r\n onChange?.(event);\r\n },\r\n [form, onChange],\r\n );\r\n\r\n return (\r\n <CardNumTextFieldBase\r\n {...rest}\r\n ref={ref}\r\n name={name}\r\n value={formValue}\r\n onChange={handleFormChange}\r\n />\r\n );\r\n});\r\n\r\nexport const CardNumTextField = forwardRef<\r\n HTMLDivElement,\r\n CardNumTextFieldProps\r\n>(function CardNumTextField(props, ref) {\r\n if (props.form) {\r\n return <CardNumTextFieldWithForm {...props} ref={ref} />;\r\n }\r\n\r\n return <CardNumTextFieldBase {...props} ref={ref} />;\r\n});\r\n"],
5
+ "mappings": "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AW,EACA,sBAAAnC,EACA,YAAAc,CACJ,CACJ,CC7gBA,IAAM2B,GAA2B,CAC7B,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,GACJ,EAEMC,GAA4B,CAC9B,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,KACA,KACA,KACA,IACA,IACA,KACA,KACA,KACA,IACA,IACA,KACA,GACJ,EAEMC,GAA4B,CAC9B,GACA,IACA,IACA,KACA,IACA,KACA,KACA,IACA,IACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,IACA,IACA,KACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,GACJ,EAEMC,GAA6D,CAC/D,OAAG,IACH,OAAG,IACH,OAAG,KACH,OAAG,IACH,OAAG,KACH,OAAG,KACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,KACH,OAAG,KACH,OAAG,KACH,OAAG,KACH,OAAG,KACH,OAAG,KACH,OAAG,KACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,KACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,KACH,OAAG,KACH,OAAG,KACH,OAAG,IACH,OAAG,IACH,OAAG,KACH,OAAG,KACH,OAAG,KACH,OAAG,IACH,OAAG,IACH,OAAG,KACH,OAAG,GACP,EAEMC,GAA0D,CAC5D,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,IACH,OAAG,GACP,EAEMC,GAA2D,CAC7D,OAAG,IA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",
6
6
  "names": ["forwardRef", "useCallback", "useEffect", "useRef", "useImperativeHandle", "useState", "TextField", "IconButton", "InputAdornment", "CircularProgress", "ClearIcon", "SearchIcon", "useState", "useRef", "useEffect", "useCallback", "useTextFieldBase", "value", "name", "debounce", "onChange", "onBlur", "transformValue", "internalValue", "setInternalValue", "lastEmittedValue", "debounceTimer", "prevExternalValue", "newValue", "emitChange", "e", "immediate", "doEmit", "syntheticEvent", "handleChange", "inputValue", "displayValue", "emitValue", "handleBlur", "useDebouncedEmit", "flushOnBlur", "currentValue", "useState", "useEffect", "useCallback", "STORAGE_KEY_PREFIX", "useKoreanHolidays", "apiKey", "year", "targetYear", "holidays", "setHolidays", "loading", "setLoading", "error", "setError", "getCachedHolidays", "cached", "data", "oneYearMs", "dateStr", "y", "m", "d", "setCachedHolidays", "fetchHolidays", "baseUrl", "params", "response", "items", "itemArray", "holidayDates", "item", "holidayStrings", "dates", "err", "useKoreanHolidaysRange", "startYear", "endYear", "currentYear", "start", "end", "years", "storageKey", "cacheData", "results", "allHolidays", "useRef", "useState", "useCallback", "useGroupedInput", "groups", "fontFamily", "fontSize", "onComplete", "disabled", "readonly", "focusedGroup", "setFocusedGroup", "cursorVisible", "setCursorVisible", "inputComplete", "setInputComplete", "renderTrigger", "setRenderTrigger", "cursorPosRef", "isClickFocusRef", "isArrowFocusRef", "arrowTargetPosRef", "measureTextWidth", "text", "ctx", "getCursorPosFromClick", "e", "value", "inputRef", "input", "rect", "clickX", "newPos", "i", "textWidth", "getCursorLeft", "groupIndex", "group", "textBeforeCursor", "forceRender", "prev", "createMouseDownHandler", "createClickHandler", "createContainerClickHandler", "targetIndex", "targetGroup", "createFocusHandler", "createBlurHandler", "activeElement", "createKeyDownHandler", "onValueChange", "selectionStart", "selectionEnd", "hasSelection", "prevGroup", "nextGroup", "newValue", "prevLen", "newPrevValue", "finalPos", "createChangeHandler", "onAfterChange", "numbers", "isGroupComplete", "allComplete", "g", "CHOSEONG_TO_ENGLISH_KEYS", "JUNGSEONG_TO_ENGLISH_KEYS", "JONGSEONG_TO_ENGLISH_KEYS", "COMPATIBILITY_JAMO_TO_ENGLISH_KEYS", "MODERN_CHOSEONG_TO_ENGLISH_KEYS", "MODERN_JUNGSEONG_TO_ENGLISH_KEYS", "MODERN_JONGSEONG_TO_ENGLISH_KEYS", "KOREAN_CHAR_RE", "KOREAN_IME_QUERY_RE", "convertCompatibilityJamoToEnglish", "char", "convertModernJamoToEnglish", "convertHangulSyllableToEnglish", "codePoint", "syllableIndex", "choseongIndex", "jungseongIndex", "jongseongIndex", "convertMistypedKoreanImeToEnglish", "value", "compatibilityJamo", "modernJamo", "syllable", "shouldAutoConvertKoreanImeQuery", "trimmed", "jsx", "SearchTextFieldBase", "forwardRef", "value", "form", "loading", "searchIcon", "searchIconColor", "clearIcon", "clearIconColor", "debounce", "readonly", "spellCheck", "autoConvertKoreanImeToEnglish", "autoConvertKoreanImeDelay", "minLength", "onChange", "onBlur", "onFocus", "onCompositionStart", "onCompositionEnd", "onClear", "onSearch", "slotProps", "size", "externalInputRef", "props", "ref", "internalValue", "setInternalValue", "handleChange", "handleBlur", "emitChange", "useTextFieldBase", "isFocused", "setIsFocused", "useState", "forceShrink", "setForceShrink", "internalLoading", "setInternalLoading", "isClearingRef", "useRef", "onSearchTimer", "autoConvertTimer", "lastSearchValueRef", "restoreFocusAfterAutoConvertRef", "isComposingRef", "compositionTaskIdRef", "forcedAutoConvertTaskRef", "suppressBlurRef", "internalInputRef", "useEffect", "useImperativeHandle", "iconSize", "clearAutoConvertTimer", "useCallback", "getResolvedInputValue", "fallbackValue", "createSyntheticChangeEvent", "nextValue", "handleClear", "fakeEvent", "triggerSearch", "immediate", "normalizedValue", "shouldReset", "shouldSearch", "runSearch", "applyImmediateValue", "selectionStart", "commitAutoConvertedValue", "length", "scheduleAutoConvert", "rawValue", "input", "taskId", "composingValue", "resolvedValue", "converted", "convertMistypedKoreanImeToEnglish", "resolvedLoading", "handleManualDelete", "deleteDirection", "currentValue", "selectionEnd", "hasSelection", "nextSelectionStart", "ownerDocument", "handleNativeDelete", "handleNativeKeyDownCapture", "event", "handleNativeBeforeInputCapture", "handleKeyDown", "handleInputChange", "e", "shouldAutoConvertKoreanImeQuery", "handleFocus", "handleBlurWithFocus", "handleCompositionStartInternal", "handleCompositionEndInternal", "compositionTaskId", "readonlyStyles", "shouldShrink", "hasLabel", "labelOffsetSx", "resolveInputLabelSlotProps", "ownerState", "baseInputLabel", "resolvedInputLabel", "resolvedSx", "mergedSx", "TextField", "InputAdornment", "SearchIcon", "CircularProgress", "IconButton", "ClearIcon", "SearchTextFieldWithForm", "name", "rest", "formValue", "handleFormChange", "SearchTextField", "forwardRef", "useCallback", "useRef", "useImperativeHandle", "useState", "TextField", "IconButton", "InputAdornment", "ClearIcon", "jsx", "ClearTextFieldBase", "forwardRef", "value", "clearIcon", "debounce", "readonly", "spellCheck", "onChange", "onBlur", "onFocus", "onClear", "slotProps", "size", "externalInputRef", "props", "ref", "internalValue", "setInternalValue", "handleChange", "handleBlur", "emitChange", "lastEmittedValue", "debounceTimer", "useTextFieldBase", "isFocused", "setIsFocused", "useState", "forceShrink", "setForceShrink", "isClearingRef", "useRef", "internalInputRef", "useImperativeHandle", "iconSize", "handleClear", "eventTarget", "handleFocus", "event", "handleBlurWithFocus", "readonlyStyles", "shouldShrink", "resolveInputLabelSlotProps", "ownerState", "baseInputLabel", "resolvedInputLabel", "TextField", "InputAdornment", "IconButton", "ClearIcon", "ClearTextFieldWithForm", "form", "name", "rest", "formValue", "handleFormChange", "useCallback", "ClearTextField", "useState", "useEffect", "useCallback", "forwardRef", "useRef", "useImperativeHandle", "TextField", "IconButton", "InputAdornment", "Visibility", "VisibilityOff", "isLeapYear", "year", "getDaysInMonth", "month", "getSeparator", "format", "formatDate", "value", "rawNumbers", "separator", "numbers", "constrainDateNumbers", "getMaxLength", "getCompleteLength", "parseDateParts", "completeLength", "day", "yy", "validateDate", "minDate", "maxDate", "parts", "daysInMonth", "date", "extractDateFormat", "format", "hasSecondField", "constrainDateNumbers", "numbers", "result", "year", "month", "firstDigit", "monthStr", "dayStr", "day", "maxDay", "getDaysInMonth", "yearStr", "formatDateValue", "value", "rawNumbers", "separator", "getSeparator", "formatToPlaceholder", "getSegmentRange", "cursorPos", "hasYearInFormat", "has2DigitYear", "convertYY2YYYY", "yy", "parseDateWithInternalYear", "formattedValue", "internalYear", "completeLength", "getCompleteLength", "buildDateOutputValue", "formatSeparator", "yearToUse", "dateToNumbers", "date", "year2", "getTimeFieldCount", "format", "is12HourFormat", "validateTime", "hour", "minute", "second", "formatOrIs12Hour", "minTime", "maxTime", "is12Hour", "h", "m", "s", "timeValue", "minParts", "minH", "minM", "minS", "minValue", "maxParts", "maxH", "maxM", "maxS", "maxValue", "clampTimeValue", "value", "type", "digit", "num", "maxHour", "formatNumber", "value", "thousandSeparator", "decimalLength", "cleaned", "isNegative", "parts", "integerPart", "decimalPart", "result", "parseNumber", "displayValue", "DEFAULT_EMAIL_DOMAINS", "validateEmail", "email", "formatPhoneNumber", "value", "customFormat", "numbers", "getPhoneMaxLength", "DEFAULT_SPECIAL_CHARS", "DEFAULT_PASSWORD_VALIDATION_RULES", "validatePassword", "value", "rules", "mergedRules", "errors", "escapedChars", "validateBusinessNumber", "value", "numbers", "checkKey", "sum", "i", "validateCardNumber", "value", "numbers", "sum", "isEven", "i", "digit", "detectCardBrand", "REGION_MAP", "extractJuminInfo", "value", "numbers", "result", "genderCode", "yy", "mm", "dd", "century", "year", "regionCode", "regionNum", "validateJuminChecksum", "weights", "sum", "i", "checkDigit", "lastDigit", "validateJuminBirthDate", "daysInMonth", "jsx", "PasswordTextFieldBase", "forwardRef", "showToggle", "label", "validationRules", "onValidationChange", "invalidBorderColor", "debounce", "readonly", "slotProps", "sx", "size", "value", "onChange", "onBlur", "externalInputRef", "props", "ref", "internalInputRef", "useRef", "useImperativeHandle", "showPassword", "setShowPassword", "useState", "isInvalid", "setIsInvalid", "internalValue", "handleChange", "handleBlur", "useTextFieldBase", "iconSize", "handleTogglePassword", "prev", "performValidation", "useCallback", "inputValue", "mergedRules", "DEFAULT_PASSWORD_VALIDATION_RULES", "result", "validatePassword", "minLength", "useEffect", "TextField", "InputAdornment", "IconButton", "VisibilityOff", "Visibility", "PasswordTextFieldWithForm", "form", "name", "rest", "formValue", "handleFormChange", "event", "PasswordTextField", "forwardRef", "useRef", "useImperativeHandle", "MuiTextField", "jsx", "TextFieldBase", "forwardRef", "value", "onChange", "onBlur", "debounce", "readonly", "slotProps", "externalInputRef", "sx", "props", "ref", "resolvedValue", "internalValue", "handleChange", "handleBlur", "useTextFieldBase", "internalInputRef", "useRef", "useImperativeHandle", "MuiTextField", "TextFieldWithForm", "form", "name", "rest", "formValue", "event", "TextField", "forwardRef", "useCallback", "useImperativeHandle", "useRef", "useState", "Box", "FormControl", "InputLabel", "TextareaAutosize", "jsx", "jsxs", "TextAreaBase", "forwardRef", "label", "value", "name", "onChange", "onBlur", "onFocus", "minRows", "maxRows", "placeholder", "disabled", "readonly", "fullWidth", "externalInputRef", "sx", "inputProps", "debounce", "form", "rest", "ref", "internalInputRef", "useRef", "isFocused", "setIsFocused", "useState", "useImperativeHandle", "internalValue", "setInternalValue", "emitChange", "handleBlur", "useTextFieldBase", "handleChange", "useCallback", "event", "newValue", "handleFocus", "handleBlurWithFocus", "FormControl", "InputLabel", "Box", "TextareaAutosize", "node", "TextAreaWithForm", "formValue", "handleFormChange", "TextArea", "props", "forwardRef", "useCallback", "MuiCheckbox", "FormControlLabel", "jsx", "CheckboxBase", "label", "name", "checked", "onChange", "readonly", "disabled", "form", "props", "ref", "CheckboxWithForm", "rest", "formValue", "handleFormChange", "event", "nextChecked", "syntheticEvent", "Checkbox", "forwardRef", "useCallback", "FormControl", "FormLabel", "MuiRadioGroup", "FormControlLabel", "Radio", "jsx", "jsxs", "RadioGroupBase", "label", "name", "value", "options", "onChange", "readonly", "disabled", "props", "ref", "option", "RadioGroupWithForm", "form", "rest", "formValue", "handleFormChange", "event", "nextValue", "syntheticEvent", "RadioGroup", "forwardRef", "useCallback", "MuiSwitch", "FormControlLabel", "jsx", "SwitchBase", "label", "name", "checked", "onChange", "readonly", "disabled", "form", "props", "ref", "switchNode", "SwitchWithForm", "rest", "formValue", "handleFormChange", "event", "nextChecked", "syntheticEvent", "Switch", "forwardRef", "useCallback", "MuiRating", "jsx", "RatingBase", "name", "value", "onChange", "readonly", "disabled", "props", "ref", "RatingWithForm", "form", "rest", "formValue", "resolvedValue", "handleFormChange", "event", "nextValue", "syntheticEvent", "Rating", "forwardRef", "useCallback", "MuiToggleButton", "jsx", "ToggleButtonBase", "name", "value", "selected", "onChange", "readonly", "disabled", "props", "ref", "ToggleButtonWithForm", "form", "rest", "formValue", "resolvedSelected", "handleFormChange", "event", "nextSelected", "syntheticEvent", "ToggleButton", "forwardRef", "useCallback", "MuiToggleButton", "MuiToggleButtonGroup", "jsx", "ToggleButtonGroupBase", "options", "value", "onChange", "fullWidth", "readonly", "disabled", "form", "onDeselect", "props", "ref", "option", "ToggleButtonGroupWithForm", "name", "exclusive", "rest", "formValue", "handleFormChange", "event", "nextValue", "resolvedValue", "syntheticEvent", "ToggleButtonGroup", "forwardRef", "MuiButtonGroup", "jsx", "ButtonGroup", "props", "ref", "Box", "useState", "useEffect", "useCallback", "useMemo", "useRef", "forwardRef", "useImperativeHandle", "TextField", "InputAdornment", "IconButton", "useState", "useMemo", "useEffect", "useRef", "useCallback", "Box", "Typography", "IconButton", "Button", "jsx", "jsxs", "OverlayScrollbar", "Fragment", "Popover", "getWeekInfo", "date", "dayOfWeek", "startDate", "endDate", "firstDayOfWeek", "isSameWeek", "date1", "date2", "week1", "week2", "isSameDay", "d1", "d2", "resolveFooterAndAutoApply", "showFooter", "autoApply", "koLocale", "enLocale", "jaLocale", "zhCNLocale", "zhTWLocale", "esLocale", "frLocale", "deLocale", "ptLocale", "ruLocale", "itLocale", "arLocale", "hiLocale", "viLocale", "thLocale", "idLocale", "nlLocale", "plLocale", "trLocale", "defaultLocale", "locales", "resolveLocale", "locale", "getSizeValue", "size", "ChevronLeft", "color", "s", "ChevronRight", "ColonIcon", "TimeSelector", "value", "onChange", "format", "minTime", "maxTime", "minuteStep", "secondStep", "showHeader", "hideDisabledTime", "selectedHour", "setSelectedHour", "h", "selectedMinute", "setSelectedMinute", "m", "selectedSecond", "setSelectedSecond", "initialScrollDone", "hourRef", "minuteRef", "secondRef", "hasSeconds", "is12Hour", "maxHour", "minHourValue", "hours", "_", "i", "minutes", "seconds", "scrollToCenter", "scrollbarRef", "val", "scrollContainer", "element", "containerHeight", "elementTop", "elementHeight", "scrollTop", "timer", "isTimeInRange", "timeValue", "minParts", "minH", "minM", "minS", "minValue", "maxParts", "maxH", "maxM", "maxS", "maxValue", "handleHourSelect", "hour", "handleMinuteSelect", "minute", "handleSecondSelect", "second", "renderItem", "selected", "disabled", "onClick", "renderColumn", "ref", "items", "selectedValue", "onSelect", "checkDisabled", "item", "isDisabled", "isHourDisabled", "isMinuteDisabled", "isSecondDisabled", "HEADER_HEIGHT", "FOOTER_HEIGHT", "SimpleCalendar", "selectedDate", "minDate", "maxDate", "holidays", "styles", "onClose", "showToday", "showFooterProp", "autoApplyProp", "monthOnly", "yearOnly", "onMonthChange", "onYearChange", "onWeekChange", "showTimePicker", "onTimeChange", "timeFormat", "texts", "footerOn", "applyImmediate", "selectedColor", "todayBorderColor", "holidayColor", "saturdayColor", "resolvedLocale", "mergedLocale", "validHolidays", "d", "today", "viewDate", "setViewDate", "viewMode", "setViewMode", "tempYear", "setTempYear", "tempMonth", "setTempMonth", "tempSelectedYear", "setTempSelectedYear", "tempSelectedDate", "setTempSelectedDate", "tempTime", "setTempTime", "now", "year", "month", "yearScrollRef", "contentRef", "calendarDays", "firstDay", "lastDay", "startPadding", "daysInMonth", "days", "prevMonthDays", "nextDay", "yearList", "currentYear", "years", "y", "isDateDisabled", "dateOnly", "min", "max", "isTimeChanged", "isYearChanged", "newYear", "isMonthChanged", "newMonth", "compareDate", "isWeekChanged", "goToPrevMonth", "newDate", "goToNextMonth", "handleWheel", "e", "handleDateClick", "weekInfo", "handleTodayClick", "todayYear", "todayMonth", "handleConfirm", "handleTempTimeChange", "handleTitleClick", "handleYearSelect", "selectedYear", "handleYearConfirm", "handleMonthSelect", "selectedMonth", "handleMonthConfirm", "yearIndex", "gridElement", "firstYearItem", "rowHeight", "rowIndex", "visibleRows", "centerRowOffset", "renderHeader", "renderContent", "isSelected", "isCurrent", "monthName", "index", "day", "isToday", "isCurrentMonth", "isHoliday", "renderFooter", "calendarContent", "footerContent", "resolveAnchorEl", "anchorEl", "TimePicker", "open", "resolvedAnchorEl", "tempHour", "setTempHour", "tempMinute", "setTempMinute", "tempSecond", "setTempSecond", "handleTimeChange", "DatePicker", "onDateChange", "anchorOrigin", "transformOrigin", "slotProps", "popoverProps", "mergedPaperProps", "tempDate", "setTempDate", "prevYear", "prevMonth", "handleDateSelect", "DateTimePicker", "handleCalendarTimeChange", "newTime", "width", "height", "jsx", "jsxs", "CalendarIcon", "size", "jsx", "jsx", "jsx", "jsxs", "ClockIcon", "size", "color", "jsx", "jsxs", "ColonIcon", "size", "color", "height", "dotRadius", "width", "centerX", "jsx", "DashIcon", "size", "width", "height", "jsx", "jsxs", "CopyIcon", "size", "iconSize", "jsx", "jsxs", "CARD_WIDTH", "CARD_HEIGHT", "CardIcon", "size", "color", "scale", "width", "height", "VisaIcon", "logoWidth", "logoHeight", "logoScale", "offsetX", "offsetY", "MastercardIcon", "AmexIcon", "JcbIcon", "DinersIcon", "DiscoverIcon", "UnionPayIcon", "BcIcon", "logoSize", "Fragment", "jsx", "jsxs", "DateTextFieldBase", "forwardRef", "label", "format", "separator", "minDate", "maxDate", "holidays", "holidayColor", "calendarIcon", "selectedColor", "showToday", "invalidBorderColor", "debounce", "slotProps", "sx", "value", "onChange", "onBlur", "placeholder", "onCalendarDismiss", "onCalendarOpen", "onCalendarClose", "name", "disabled", "readonly", "size", "externalInputRef", "calendarAnchorOrigin", "calendarTransformOrigin", "props", "ref", "isInvalid", "setIsInvalid", "useState", "displayValue", "setDisplayValue", "prevNumbers", "setPrevNumbers", "calendarOpen", "setCalendarOpen", "calendarAnchorPos", "setCalendarAnchorPos", "calendarCloseReasonRef", "useRef", "internalYear", "setInternalYear", "internalInputRef", "useImperativeHandle", "emitChange", "flushOnBlur", "lastEmittedValue", "useDebouncedEmit", "maxLength", "getMaxLength", "completeLength", "getCompleteLength", "isYearlessFormat", "hasYearInFormat", "selectedDate", "useMemo", "parsed", "parseDateWithInternalYear", "calendarSelectedDate", "yearToUse", "buildOutputValue", "useCallback", "formattedValue", "buildDateOutputValue", "performValidation", "inputValue", "isValid", "validateDate", "useEffect", "strValue", "formatDate", "currentNumbers", "handleChange", "e", "input", "newValue", "newNumbers", "isBackspace", "trimmedNumbers", "limitedNumbers", "formatSep", "getSeparator", "cursorPos", "targetNumberCount", "numberCount", "i", "inputNumberCount", "outputValue", "handleBlur", "handleClick", "handleKeyDown", "numLen", "handleCalendarSelect", "date", "year", "numbers", "dateToNumbers", "activeElement", "inputRoot", "handleOpenCalendar", "inputEl", "rect", "handleCloseCalendar", "isSelectClose", "isCalendarOpen", "invalidStyles", "readonlyStyles", "TextField", "formatToPlaceholder", "InputAdornment", "IconButton", "CalendarIcon", "Dt", "DateTextFieldWithForm", "form", "rest", "formValue", "handleFormChange", "event", "DateTextField", "jsx", "jsxs", "DateRange", "form", "startName", "endName", "startLabel", "endLabel", "startValue", "endValue", "onStartChange", "onEndChange", "fullWidth", "size", "readonly", "gap", "startProps", "endProps", "Box", "DateTextField", "forwardRef", "useCallback", "Box", "FormControl", "FormLabel", "MuiSlider", "jsx", "jsxs", "SliderBase", "label", "name", "value", "onChange", "readonly", "disabled", "props", "ref", "SliderWithForm", "form", "rest", "formValue", "resolvedValue", "handleFormChange", "_event", "nextValue", "syntheticEvent", "Slider", "forwardRef", "useCallback", "useEffect", "MuiStepper", "jsx", "parseStepValue", "value", "parsed", "Stepper", "form", "name", "activeStepProp", "defaultActiveStep", "onStepChange", "props", "ref", "shouldUseForm", "formValue", "parsedFormValue", "emitStepChange", "step", "eventTarget", "fakeEvent", "React", "BaseNumberField", "IconButton", "FormControl", "OutlinedInput", "InputAdornment", "InputLabel", "KeyboardArrowUpIcon", "KeyboardArrowDownIcon", "jsx", "jsxs", "SSRInitialFilled", "_", "NumberFieldBase", "idProp", "label", "error", "size", "step", "fullWidth", "_form", "other", "id", "props", "state", "NumberFieldWithForm", "form", "name", "onValueChange", "rest", "formValue", "handleFormValueChange", "value", "eventDetails", "syntheticEvent", "NumberField", "React", "BaseNumberField", "Box", "Button", "FormControl", "FormLabel", "AddIcon", "RemoveIcon", "OutlinedInput", "OpenInFullIcon", "jsx", "jsxs", "NumberSpinner", "idProp", "label", "error", "size", "other", "id", "props", "state", "forwardRef", "useCallback", "MuiAutocomplete", "TextField", "jsx", "jsxs", "AutocompleteBase", "name", "label", "options", "value", "onChange", "fullWidth", "size", "readonly", "disabled", "textFieldProps", "renderOption", "props", "ref", "selectedOption", "option", "handleChange", "_event", "selected", "optionProps", "state", "labelText", "query", "lowerLabel", "lowerQuery", "matchIndex", "before", "match", "after", "params", "AutocompleteWithForm", "form", "rest", "formValue", "handleFormChange", "nextValue", "syntheticEvent", "Autocomplete", "forwardRef", "useCallback", "useId", "FormControl", "MenuItem", "MuiSelect", "jsx", "jsxs", "SelectBase", "value", "onChange", "options", "inputProps", "enableWheel", "emptyLabel", "readOnly", "showEmptyOption", "fullWidth", "size", "formControlProps", "form", "selectProps", "ref", "generatedId", "selectId", "safeValue", "option", "handleSelectWheel", "event", "optionValues", "currentIndex", "nextIndex", "syntheticEvent", "selected", "opt", "SelectWithForm", "name", "rest", "formValue", "handleFormChange", "Select", "props", "forwardRef", "useCallback", "useId", "useState", "FormControl", "InputLabel", "MenuItem", "Select", "jsx", "jsxs", "LabelSelectBase", "label", "value", "onChange", "options", "inputProps", "enableWheel", "showLabel", "emptyLabel", "readOnly", "showEmptyOption", "fullWidth", "size", "formControlProps", "form", "selectProps", "ref", "generatedId", "selectId", "labelId", "safeValue", "option", "isFocused", "setIsFocused", "shouldNotch", "displayEmptyValue", "handleFocus", "event", "handleBlur", "handleSelectWheel", "optionValues", "currentIndex", "nextIndex", "syntheticEvent", "selected", "opt", "LabelSelectWithForm", "name", "rest", "formValue", "handleFormChange", "LabelSelect", "props", "useState", "useEffect", "useCallback", "useRef", "forwardRef", "useImperativeHandle", "TextField", "jsx", "PhoneTextFieldBase", "forwardRef", "label", "autoFormat", "includeDash", "prefix", "format", "onValidationChange", "invalidBorderColor", "debounce", "readonly", "slotProps", "sx", "value", "onChange", "onBlur", "externalInputRef", "props", "ref", "isInvalid", "setIsInvalid", "useState", "displayValue", "setDisplayValue", "prevNumbers", "setPrevNumbers", "currentMaxLength", "setCurrentMaxLength", "internalInputRef", "useRef", "cursorPositionRef", "useImperativeHandle", "emitChange", "flushOnBlur", "lastEmittedValue", "useDebouncedEmit", "prefixFormatted", "performValidation", "useCallback", "inputValue", "numbers", "minLength", "isComplete", "useEffect", "strValue", "getPhoneMaxLength", "formattedValue", "formatPhoneNumber", "pos", "TextField", "e", "newValue", "newNumbers", "cursorPos", "prefixNumbers", "originalPos", "isBackspace", "deletedDigitIndex", "prefixProtected", "numbersBeforeCursor", "trimmedNumbers", "targetPos", "digitCount", "i", "currentNumbers", "outputValue", "PhoneTextFieldWithForm", "form", "name", "rest", "formValue", "handleFormChange", "event", "PhoneTextField", "IconButton", "InputAdornment", "TextField", "Dialog", "DialogContent", "DialogTitle", "SearchIcon", "CloseIcon", "useState", "useEffect", "useCallback", "forwardRef", "useRef", "useImperativeHandle", "DaumPostcode", "Fragment", "jsx", "jsxs", "AddressTextFieldBase", "forwardRef", "value", "onChange", "readonly", "debounce", "onBlur", "size", "spellCheck", "externalInputRef", "props", "ref", "internalInputRef", "useRef", "useImperativeHandle", "address", "setAddress", "useState", "isPostcodeOpen", "setIsPostcodeOpen", "iconSize", "emitChange", "flushOnBlur", "lastEmittedValue", "useDebouncedEmit", "useEffect", "strValue", "handlePostcodeComplete", "data", "fullAddress", "extraAddress", "handleSearchButtonClick", "handleKeyDown", "event", "handlePostcodeClose", "onClose", "TextField", "e", "newValue", "InputAdornment", "IconButton", "SearchIcon", "Dialog", "DialogTitle", "CloseIcon", "DialogContent", "DaumPostcode", "AddressTextFieldWithForm", "form", "name", "rest", "formValue", "handleFormChange", "useCallback", "AddressTextField", "useState", "useEffect", "useCallback", "forwardRef", "useRef", "useImperativeHandle", "TextField", "InputAdornment", "jsx", "NumberTextFieldBase", "forwardRef", "label", "thousandSeparator", "decimalLength", "decimalFixed", "textAlign", "min", "max", "negative", "negativeStyles", "prefix", "suffix", "showSuffix", "selectOnFocus", "debounce", "readonly", "slotProps", "sx", "value", "onChange", "onBlur", "onFocus", "externalInputRef", "props", "ref", "internalInputRef", "useRef", "useImperativeHandle", "displayValue", "setDisplayValue", "useState", "isNegative", "setIsNegative", "emitChange", "flushOnBlur", "lastEmittedValue", "useDebouncedEmit", "useEffect", "strValue", "formattedValue", "formatNumber", "handleChange", "useCallback", "e", "newValue", "withoutComma", "numValue", "maxFormatted", "emitValue", "minFormatted", "numericValue", "parseNumber", "handleBlur", "num", "finalValue", "inputStyles", "handleFocus", "TextField", "InputAdornment", "NumberTextFieldWithForm", "form", "name", "rest", "formValue", "handleFormChange", "event", "NumberTextField", "useState", "useEffect", "useCallback", "useRef", "useMemo", "forwardRef", "useImperativeHandle", "TextField", "Box", "useCallback", "useRef", "useEffect", "forwardRef", "FormControl", "InputLabel", "OutlinedInput", "Box", "jsx", "jsxs", "CustomInput", "showContent", "inputSize", "contentSx", "children", "endAdornment", "ref", "GroupedInputWrapper", "label", "size", "disabled", "readonly", "focusedGroup", "setFocusedGroup", "hasValue", "isInvalid", "invalidBorderColor", "inputRefs", "getTargetRefOnClick", "sx", "className", "id", "fullWidth", "containerRef", "isLabelShrunk", "handleMouseDown", "e", "targetRef", "groupIndex", "inputEl", "handleDocumentClick", "target", "handleBlur", "activeEl", "Box", "jsx", "ColonBox", "size", "mx", "visible", "sx", "Box", "ColonIcon", "Fragment", "jsx", "jsxs", "JuminTextFieldBase", "forwardRef", "label", "mask", "maskColor", "validateChecksum", "fontSize", "fontColor", "fontFamily", "onChange", "onValidationChange", "invalidBorderColor", "debounce", "readonly", "sx", "value", "size", "disabled", "fullWidth", "className", "id", "props", "ref", "frontValue", "setFrontValue", "useState", "backValue", "setBackValue", "isInvalid", "setIsInvalid", "isInternalChange", "setIsInternalChange", "focusedField", "setFocusedField", "cursorVisible", "setCursorVisible", "renderTrigger", "setRenderTrigger", "backComplete", "setBackComplete", "frontRef", "useRef", "backRef", "containerRef", "isClickFocusRef", "cursorPosRef", "useImperativeHandle", "debounceTimer", "useEffect", "numbers", "displayBackValue", "emitChange", "useCallback", "front", "back", "fullValue", "completeLength", "isLengthComplete", "isValid", "validateJuminBirthDate", "validateJuminChecksum", "doEmit", "info", "extractJuminInfo", "handleFrontChange", "e", "r", "input", "len", "handleFrontFocus", "handleFrontBlur", "activeElement", "handleFrontKeyDown", "pos", "newPos", "newValue", "handleBackChange", "handleBackKeyDown", "valLen", "newFrontValue", "newBackValue", "handleBackFocus", "handleBackBlur", "placeholderDots", "computedFontSize", "measureTextWidth", "text", "ctx", "dotSize", "smallDotSize", "cursorHeight", "getCursorLeft", "field", "textBeforeCursor", "cursorLeft", "useMemo", "frontFieldCh", "backFieldCh", "noBorderStyle", "getFullNumber", "renderGroupedInput", "Box", "hasFrontValue", "hasBackValue", "TextField", "DashIcon", "selStart", "selEnd", "_", "i", "getTargetRefOnClick", "focusedGroup", "setFocusedGroupWrapper", "group", "GroupedInputWrapper", "JuminTextFieldWithForm", "form", "name", "rest", "formValue", "handleFormChange", "syntheticEvent", "JuminTextField", "useState", "useEffect", "useCallback", "useRef", "forwardRef", "useImperativeHandle", "Box", "FormControl", "InputLabel", "OutlinedInput", "jsx", "jsxs", "VerificationCodeTextFieldBase", "forwardRef", "label", "length", "type", "value", "onChange", "onComplete", "debounce", "readonly", "disabled", "size", "name", "fontSizeProp", "fontColor", "fontFamily", "dotSizeProp", "caretColor", "sx", "invalidBorderColor", "externalInputRef", "restProps", "ref", "internalValue", "setInternalValue", "useState", "isFocused", "setIsFocused", "isAllSelected", "setIsAllSelected", "internalInputRef", "useRef", "useImperativeHandle", "emitChange", "flushOnBlur", "lastEmittedValue", "useDebouncedEmit", "useEffect", "strValue", "isValidChar", "useCallback", "char", "filterValue", "val", "filtered", "handleChange", "e", "handlePaste", "pastedText", "handleKeyDown", "handleFocus", "input", "handleClick", "handleBlur", "defaultFontSize", "defaultDotSize", "fontSize", "dotSize", "charWidth", "gap", "totalContentWidth", "containerHeight", "containerPadding", "inputMode", "hasCustomWidth", "showContent", "formControlSx", "FormControl", "InputLabel", "OutlinedInput", "Box", "_", "i", "VerificationCodeTextFieldWithForm", "form", "rest", "formValue", "handleFormChange", "event", "VerificationCodeTextField", "props", "React", "useState", "useEffect", "useCallback", "useRef", "forwardRef", "useImperativeHandle", "TextField", "Box", "Popper", "Paper", "List", "ListItemButton", "ListItemText", "ListItemIcon", "ClickAwayListener", "jsx", "jsxs", "GmailIcon", "size", "NaverIcon", "DaumIcon", "KakaoIcon", "NateIcon", "OutlookIcon", "YahooIcon", "ICloudIcon", "DefaultEmailIcon", "getEmailIcon", "domain", "jsx", "jsxs", "EmailTextFieldBase", "forwardRef", "value", "onChange", "onValidationChange", "domains", "DEFAULT_EMAIL_DOMAINS", "extraDomains", "suggestions", "showLogos", "invalidBorderColor", "debounce", "readonly", "sx", "size", "disabled", "name", "onBlur", "fullWidth", "externalInputRef", "props", "ref", "allDomains", "customIcons", "React", "icons", "extraDomainStrings", "item", "combined", "seen", "domain", "lower", "getDomainIcon", "useCallback", "lowerDomain", "getEmailIcon", "inputValue", "setInputValue", "useState", "isInvalid", "setIsInvalid", "localSuggestions", "setLocalSuggestions", "showPopper", "setShowPopper", "selectedIndex", "setSelectedIndex", "internalInputRef", "useRef", "anchorRef", "useImperativeHandle", "emitChange", "flushOnBlur", "lastEmittedValue", "useDebouncedEmit", "useEffect", "strValue", "generateSuggestions", "input", "atIndex", "localPart", "domainPart", "filteredDomains", "newSuggestions", "handleChange", "e", "newValue", "isValid", "validateEmail", "hasContent", "handleSelectSuggestion", "suggestion", "handleKeyDown", "prev", "handleClickAway", "handleBlur", "handleFocus", "borderColor", "setRefs", "node", "ClickAwayListener", "Box", "TextField", "Popper", "Paper", "List", "index", "ListItemButton", "ListItemIcon", "ListItemText", "EmailTextFieldWithForm", "form", "rest", "formValue", "handleFormChange", "event", "EmailTextField", "useState", "useEffect", "useCallback", "useRef", "useMemo", "forwardRef", "useImperativeHandle", "TextField", "Box", "Fragment", "jsx", "jsxs", "TimeTextFieldBase", "forwardRef", "label", "format", "minTime", "maxTime", "clockIcon", "minuteStep", "secondStep", "hideDisabledTime", "invalidBorderColor", "debounce", "sx", "value", "onChange", "onBlur", "name", "disabled", "readonly", "size", "fullWidth", "className", "id", "fontSize", "fontColor", "fontFamily", "ref", "hourValue", "setHourValue", "useState", "minuteValue", "setMinuteValue", "secondValue", "setSecondValue", "isInvalid", "setIsInvalid", "isInternalChange", "setIsInternalChange", "pickerOpen", "setPickerOpen", "hourRef", "useRef", "minuteRef", "secondRef", "containerRef", "useImperativeHandle", "debounceTimer", "hasSecond", "getTimeFieldCount", "computedFontSize", "cursorHeight", "cursorWidth", "groups", "useMemo", "focusedGroup", "setFocusedGroup", "cursorVisible", "inputComplete", "getCursorLeft", "createMouseDownHandler", "createClickHandler", "createFocusHandler", "createBlurHandler", "createKeyDownHandler", "createGroupChangeHandler", "useGroupedInput", "useEffect", "strValue", "parts", "numbers", "emitChange", "useCallback", "hour", "minute", "second", "isComplete", "isValid", "validateTime", "doEmit", "timeString", "clampTimeValue", "type", "digit", "maxFirstDigit", "num", "is12Hour", "maxHour", "handleChange", "groupIndex", "newValue", "idx", "clampedValue", "refs", "newValues", "handleKeyDown", "handleBlur", "activeElement", "paddedHour", "paddedMinute", "paddedSecond", "getTargetRefOnClick", "values", "lastFilledIndex", "i", "handleClockIconClick", "e", "handlePickerChange", "handlePickerClose", "noBorderStyle", "fieldWidth", "renderGroup", "groupValue", "placeholder", "showCursor", "Box", "TextField", "getFullTime", "showColon", "renderGroupedInput", "ColonBox", "clockIconElement", "ClockIcon", "GroupedInputWrapper", "oo", "TimeTextFieldWithForm", "form", "rest", "formValue", "handleFormChange", "event", "TimeTextField", "props", "useState", "useEffect", "useCallback", "useMemo", "useRef", "forwardRef", "useImperativeHandle", "TextField", "InputAdornment", "IconButton", "Box", "Fragment", "jsx", "jsxs", "DateTimeTextFieldBase", "forwardRef", "label", "format", "dateSeparator", "minDateTime", "maxDateTime", "minTime", "maxTime", "holidays", "holidayColor", "calendarIcon", "selectedColor", "showToday", "minuteStep", "secondStep", "hideDisabledTime", "invalidBorderColor", "debounce", "sx", "value", "onChange", "onBlur", "name", "disabled", "readonly", "size", "fullWidth", "className", "id", "ref", "dateDisplayValue", "setDateDisplayValue", "useState", "prevDateNumbers", "setPrevDateNumbers", "internalYear", "setInternalYear", "hourValue", "setHourValue", "minuteValue", "setMinuteValue", "secondValue", "setSecondValue", "isInvalid", "setIsInvalid", "isDateFocused", "setIsDateFocused", "calendarOpen", "setCalendarOpen", "anchorEl", "setAnchorEl", "dateInputRef", "useRef", "hourRef", "minuteRef", "secondRef", "selectionRangeRef", "containerRef", "useImperativeHandle", "hasSecond", "hasSecondField", "is12Hour", "is12HourFormat", "dateFormat", "extractDateFormat", "displayDateSeparator", "getSeparator", "dateMaxLength", "getMaxLength", "dateCompleteLength", "getCompleteLength", "isYearlessFormat", "hasYearInFormat", "computedFontSize", "cursorHeight", "cursorWidth", "emitChange", "flushOnBlur", "lastEmittedValue", "useDebouncedEmit", "timeGroups", "useMemo", "baseGroups", "focusedGroup", "cursorVisible", "inputComplete", "getCursorLeft", "createMouseDownHandler", "createClickHandler", "createFocusHandler", "createBlurHandler", "createKeyDownHandler", "createGroupChangeHandler", "useGroupedInput", "buildDateTimeString", "useCallback", "dateStr", "hour", "minute", "second", "yearOverride", "outputDateStr", "buildDateOutputValue", "timeStr", "performValidation", "dateComplete", "timeComplete", "dateValid", "validateDate", "timeValid", "validateTime", "useEffect", "strValue", "datePart", "timePart", "formatted", "formatDateValue", "timeParts", "handleDateChange", "e", "input", "newValue", "newNumbers", "selection", "beforeSelection", "afterSelection", "beforeNumbers", "afterNumbers", "inputChar", "combinedNumbers", "formattedValue", "adjustedPos", "outputValue", "isBackspace", "trimmedNumbers", "measureTextWidth", "text", "style", "ctx", "handleDateClick", "cursorPos", "rect", "clickX", "paddingLeft", "textWidth", "start", "end", "getSegmentRange", "actualEnd", "actualStart", "handleDateKeyDown", "numLen", "handleTimeChange", "groupIndex", "idx", "clampedValue", "clampTimeValue", "refs", "newHour", "newMinute", "newSecond", "handleTimeKeyDown", "handleBlur", "paddedHour", "paddedMinute", "paddedSecond", "handleTimeBlur", "activeElement", "handleDateFocus", "handleCalendarSelect", "date", "year", "numbers", "dateToNumbers", "handleCalendarTimeChange", "h", "m", "s", "selectedDate", "parsed", "parseDateWithInternalYear", "calendarSelectedDate", "yearToUse", "invalidStyles", "readonlyStyles", "noBorderStyle", "dateFieldWidth", "datePlaceholder", "formatToPlaceholder", "timeFieldWidth", "renderTimeGroup", "groupValue", "placeholder", "showCursor", "Box", "TextField", "showTimeFields", "endAdornmentElement", "InputAdornment", "ColonBox", "IconButton", "CalendarIcon", "mo", "DateTimeTextFieldWithForm", "form", "rest", "formValue", "handleFormChange", "event", "DateTimeTextField", "props", "useState", "useEffect", "useCallback", "useRef", "useMemo", "forwardRef", "useImperativeHandle", "TextField", "Box", "IconButton", "InfoAlert", "Fragment", "jsx", "jsxs", "BizNumTextFieldBase", "forwardRef", "label", "includeDash", "validate", "copyIcon", "fontSize", "fontColor", "fontFamily", "onValidationChange", "invalidBorderColor", "debounce", "readonly", "sx", "value", "onChange", "size", "disabled", "className", "id", "autoFocus", "name", "fullWidth", "ref", "group1", "setGroup1", "useState", "group2", "setGroup2", "group3", "setGroup3", "isInvalid", "setIsInvalid", "isInternalChange", "setIsInternalChange", "ref1", "useRef", "ref2", "ref3", "containerRef", "useImperativeHandle", "maxLengths", "debouncedEmit", "flushOnBlur", "useDebouncedEmit", "computedFontSize", "groups", "useMemo", "focusedGroup", "setFocusedGroup", "cursorVisible", "inputComplete", "getCursorLeft", "createMouseDownHandler", "createClickHandler", "createFocusHandler", "createBlurHandler", "createKeyDownHandler", "createGroupChangeHandler", "useGroupedInput", "useEffect", "numbers", "getFullNumber", "useCallback", "emitChange", "g1", "g2", "g3", "fullNumber", "isComplete", "isValid", "validateBusinessNumber", "outputValue", "handleChange", "groupIndex", "newValue", "idx", "newValues", "handleKeyDown", "handleBlur", "e", "handleCopy", "copyValue", "InfoAlert", "fieldWidths", "cursorWidth", "cursorHeight", "noBorderStyle", "renderGroup", "groupValue", "placeholder", "showCursor", "refs", "Box", "TextField", "Dash", "DashIcon", "getTargetRefOnClick", "GroupedInputWrapper", "IconButton", "CopyIcon", "BizNumTextFieldWithForm", "form", "rest", "formValue", "handleFormChange", "event", "BizNumTextField", "props", "useState", "useEffect", "useCallback", "useRef", "useMemo", "forwardRef", "useImperativeHandle", "TextField", "Box", "jsx", "jsxs", "CardNumTextFieldBase", "forwardRef", "label", "maskColor", "fontSize", "fontColor", "fontFamily", "onChange", "onValidationChange", "onCardBrandChange", "invalidBorderColor", "validate", "debounce", "readonly", "sx", "value", "size", "disabled", "logoIcon", "name", "className", "id", "fullWidth", "ref", "group1", "setGroup1", "useState", "group2", "setGroup2", "group3", "setGroup3", "group4", "setGroup4", "isInvalid", "setIsInvalid", "isInternalChange", "setIsInternalChange", "cardBrand", "setCardBrand", "lastInputInfo", "setLastInputInfo", "ref1", "useRef", "ref2", "ref3", "ref4", "containerRef", "useImperativeHandle", "computedFontSize", "groups", "useMemo", "focusedGroup", "setFocusedGroup", "cursorVisible", "cursorPosRef", "inputComplete", "renderTrigger", "getCursorLeft", "createMouseDownHandler", "createClickHandler", "createFocusHandler", "createBlurHandler", "createKeyDownHandler", "createGroupChangeHandler", "useGroupedInput", "emitChange", "flushOnBlur", "useDebouncedEmit", "getFullNumber", "useCallback", "emitCardChange", "g1", "g2", "g3", "g4", "fullValue", "isComplete", "isValid", "validateCardNumber", "brand", "detectCardBrand", "useEffect", "numbers", "handleChange", "groupIndex", "newValue", "idx", "newValues", "handleKeyDown", "handleBlur", "e", "handleContainerClick", "values", "refs", "lastFilledIndex", "i", "targetRef", "newPos", "dotSize", "cursorWidthPx", "cursorHeightPx", "normalFieldWidth", "maskedFieldWidth", "getMaskedCursorLeft", "cursorPos", "fieldWidthPx", "paddingPx", "gap", "noBorderStyle", "renderMaskedGroup", "groupValue", "isFocused", "showCursor", "Box", "TextField", "_", "isEntered", "isAtCursor", "isLastInput", "renderNormalGroup", "Dash", "DashIcon", "renderCardIcon", "iconSize", "VisaIcon", "MastercardIcon", "AmexIcon", "JcbIcon", "DinersIcon", "DiscoverIcon", "UnionPayIcon", "BcIcon", "CardIcon", "renderGroupedInput", "getTargetRefOnClick", "GroupedInputWrapper", "CardNumTextFieldWithForm", "form", "rest", "formValue", "handleFormChange", "event", "CardNumTextField", "props"]
7
7
  }