@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.
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../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 * @ehfuse/mui-form-controls\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\nexport { SearchTextField } from \"./SearchTextField\";\r\nexport { ClearTextField } from \"./ClearTextField\";\r\nexport { PasswordTextField } from \"./PasswordTextField\";\r\nexport { TextField } from \"./TextField\";\r\nexport { TextArea } from \"./TextArea\";\r\nexport { Checkbox } from \"./Checkbox\";\r\nexport { RadioGroup } from \"./RadioGroup\";\r\nexport { Switch } from \"./Switch\";\r\nexport { Rating } from \"./Rating\";\r\nexport { ToggleButton } from \"./ToggleButton\";\r\nexport { ToggleButtonGroup } from \"./ToggleButtonGroup\";\r\nexport { ButtonGroup } from \"./ButtonGroup\";\r\nexport { DateRange } from \"./DateRange\";\r\nexport { Slider } from \"./Slider\";\r\nexport { Stepper } from \"./Stepper\";\r\nexport { NumberField, NumberSpinner } from \"./NumberField\";\r\nexport type { NumberFieldProps } from \"./NumberField\";\r\nexport { Autocomplete } from \"./Autocomplete\";\r\nexport { Select } from \"./Select\";\r\nexport { LabelSelect } from \"./LabelSelect\";\r\nexport { PhoneTextField } from \"./PhoneTextField\";\r\nexport { AddressTextField } from \"./AddressTextField\";\r\nexport { NumberTextField } from \"./NumberTextField\";\r\nexport { JuminTextField } from \"./JuminTextField\";\r\nexport { VerificationCodeTextField } from \"./VerificationCodeTextField\";\r\nexport { EmailTextField } from \"./EmailTextField\";\r\nexport { DateTextField } from \"./DateTextField\";\r\nexport { TimeTextField } from \"./TimeTextField\";\r\nexport { DateTimeTextField } from \"./DateTimeTextField\";\r\nexport { BizNumTextField } from \"./BizNumTextField\";\r\nexport { CardNumTextField } from \"./CardNumTextField\";\r\nexport { useKoreanHolidays, useKoreanHolidaysRange } from \"./hooks\";\r\nexport {\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\nexport type {\r\n SearchTextFieldProps,\r\n ClearTextFieldProps,\r\n PasswordTextFieldProps,\r\n TextFieldProps,\r\n TextAreaProps,\r\n CheckboxProps,\r\n SwitchProps,\r\n RadioGroupProps,\r\n RadioOption,\r\n DateRangeProps,\r\n SliderProps,\r\n RatingProps,\r\n ToggleButtonProps,\r\n ToggleButtonGroupProps,\r\n ToggleButtonGroupOption,\r\n ButtonGroupProps,\r\n StepperProps,\r\n AutocompleteProps,\r\n AutocompleteOption,\r\n SelectProps,\r\n SelectOption,\r\n LabelSelectProps,\r\n LabelSelectOption,\r\n PasswordValidationRules,\r\n PasswordValidationResult,\r\n PhoneTextFieldProps,\r\n PhoneFormat,\r\n AddressTextFieldProps,\r\n DaumPostcodeData,\r\n NumberTextFieldProps,\r\n JuminTextFieldProps,\r\n JuminInfo,\r\n VerificationCodeTextFieldProps,\r\n VerificationCodeType,\r\n EmailTextFieldProps,\r\n CustomDomain,\r\n DateTextFieldProps,\r\n DateFormat,\r\n TimeTextFieldProps,\r\n TimeFormat,\r\n DateTimeTextFieldProps,\r\n DateTimeFormat,\r\n BizNumTextFieldProps,\r\n CardNumTextFieldProps,\r\n SelectChangeEvent,\r\n} from \"./types\";\r\n", "/**\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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AAS1B,EAAY4B,CAAW,CACpD,EAEJ,CAAC5D,EAAQG,CAAU,CACvB,EAEA,MAAO,CACH,aAAAG,EACA,gBAAAC,EACA,cAAAC,EACA,iBAAAC,EACA,aAAAK,EACA,gBAAAC,EACA,cAAAL,EACA,iBAAAC,EACA,cAAAC,EACA,iBAAAM,EACA,cAAAa,EACA,uBAAAM,EACA,mBAAAC,EACA,4BAAAC,EACA,mBAAAG,EACA,kBAAAC,EACA,qBAAAE,EACA,oBAAAW,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,OAA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",
4
+ "sourcesContent": ["/**\r\n * @ehfuse/mui-form-controls\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\nexport { SearchTextField } from \"./SearchTextField\";\r\nexport { ClearTextField } from \"./ClearTextField\";\r\nexport { PasswordTextField } from \"./PasswordTextField\";\r\nexport { TextField } from \"./TextField\";\r\nexport { TextArea } from \"./TextArea\";\r\nexport { Checkbox } from \"./Checkbox\";\r\nexport { RadioGroup } from \"./RadioGroup\";\r\nexport { Switch } from \"./Switch\";\r\nexport { Rating } from \"./Rating\";\r\nexport { ToggleButton } from \"./ToggleButton\";\r\nexport { ToggleButtonGroup } from \"./ToggleButtonGroup\";\r\nexport { ButtonGroup } from \"./ButtonGroup\";\r\nexport { DateRange } from \"./DateRange\";\r\nexport { Slider } from \"./Slider\";\r\nexport { Stepper } from \"./Stepper\";\r\nexport { NumberField, NumberSpinner } from \"./NumberField\";\r\nexport type { NumberFieldProps } from \"./NumberField\";\r\nexport { Autocomplete } from \"./Autocomplete\";\r\nexport { Select } from \"./Select\";\r\nexport { LabelSelect } from \"./LabelSelect\";\r\nexport { PhoneTextField } from \"./PhoneTextField\";\r\nexport { AddressTextField } from \"./AddressTextField\";\r\nexport { NumberTextField } from \"./NumberTextField\";\r\nexport { JuminTextField } from \"./JuminTextField\";\r\nexport { VerificationCodeTextField } from \"./VerificationCodeTextField\";\r\nexport { EmailTextField } from \"./EmailTextField\";\r\nexport { DateTextField } from \"./DateTextField\";\r\nexport { TimeTextField } from \"./TimeTextField\";\r\nexport { DateTimeTextField } from \"./DateTimeTextField\";\r\nexport { BizNumTextField } from \"./BizNumTextField\";\r\nexport { CardNumTextField } from \"./CardNumTextField\";\r\nexport { useKoreanHolidays, useKoreanHolidaysRange } from \"./hooks\";\r\nexport {\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\nexport type {\r\n SearchTextFieldProps,\r\n ClearTextFieldProps,\r\n PasswordTextFieldProps,\r\n TextFieldProps,\r\n TextAreaProps,\r\n CheckboxProps,\r\n SwitchProps,\r\n RadioGroupProps,\r\n RadioOption,\r\n DateRangeProps,\r\n SliderProps,\r\n RatingProps,\r\n ToggleButtonProps,\r\n ToggleButtonGroupProps,\r\n ToggleButtonGroupOption,\r\n ButtonGroupProps,\r\n StepperProps,\r\n AutocompleteProps,\r\n AutocompleteOption,\r\n SelectProps,\r\n SelectOption,\r\n LabelSelectProps,\r\n LabelSelectOption,\r\n PasswordValidationRules,\r\n PasswordValidationResult,\r\n PhoneTextFieldProps,\r\n PhoneFormat,\r\n AddressTextFieldProps,\r\n DaumPostcodeData,\r\n NumberTextFieldProps,\r\n JuminTextFieldProps,\r\n JuminInfo,\r\n VerificationCodeTextFieldProps,\r\n VerificationCodeType,\r\n EmailTextFieldProps,\r\n CustomDomain,\r\n DateTextFieldProps,\r\n DateFormat,\r\n TimeTextFieldProps,\r\n TimeFormat,\r\n DateTimeTextFieldProps,\r\n DateTimeFormat,\r\n BizNumTextFieldProps,\r\n CardNumTextFieldProps,\r\n SelectChangeEvent,\r\n} from \"./types\";\r\n", "/**\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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AAS1B,EAAY4B,CAAW,CACpD,EAEJ,CAAC5D,EAAQG,CAAU,CACvB,EAEA,MAAO,CACH,aAAAG,EACA,gBAAAC,EACA,cAAAC,EACA,iBAAAC,EACA,aAAAK,EACA,gBAAAC,EACA,cAAAL,EACA,iBAAAC,EACA,cAAAC,EACA,iBAAAM,EACA,cAAAa,EACA,uBAAAM,EACA,mBAAAC,EACA,4BAAAC,EACA,mBAAAG,EACA,kBAAAC,EACA,qBAAAE,EACA,oBAAAW,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,OAA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",
6
6
  "names": ["index_exports", "__export", "AddressTextField", "AmexIcon", "Autocomplete", "BcIcon", "BizNumTextField", "ButtonGroup", "CardIcon", "CardNumTextField", "Checkbox", "ClearTextField", "DateRange", "DateTextField", "DateTimeTextField", "DinersIcon", "DiscoverIcon", "EmailTextField", "JcbIcon", "JuminTextField", "LabelSelect", "MastercardIcon", "NumberField", "NumberSpinner", "NumberTextField", "PasswordTextField", "PhoneTextField", "RadioGroup", "Rating", "SearchTextField", "Select", "Slider", "Stepper", "Switch", "TextArea", "TextField", "TimeTextField", "ToggleButton", "ToggleButtonGroup", "UnionPayIcon", "VerificationCodeTextField", "VisaIcon", "useKoreanHolidays", "useKoreanHolidaysRange", "__toCommonJS", "import_react", "import_material", "import_Clear", "import_Search", "import_react", "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", "import_react", "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", "import_react", "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", "import_jsx_runtime", "SearchTextFieldBase", "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", "forceShrink", "setForceShrink", "internalLoading", "setInternalLoading", "isClearingRef", "onSearchTimer", "autoConvertTimer", "lastSearchValueRef", "restoreFocusAfterAutoConvertRef", "isComposingRef", "compositionTaskIdRef", "forcedAutoConvertTaskRef", "suppressBlurRef", "internalInputRef", "iconSize", "clearAutoConvertTimer", "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", "SearchIcon", "ClearIcon", "SearchTextFieldWithForm", "name", "rest", "formValue", "handleFormChange", "SearchTextField", "import_react", "import_material", "import_Clear", "import_jsx_runtime", "ClearTextFieldBase", "value", "clearIcon", "debounce", "readonly", "spellCheck", "onChange", "onBlur", "onFocus", "onClear", "slotProps", "size", "externalInputRef", "props", "ref", "internalValue", "setInternalValue", "handleChange", "handleBlur", "emitChange", "lastEmittedValue", "debounceTimer", "useTextFieldBase", "isFocused", "setIsFocused", "forceShrink", "setForceShrink", "isClearingRef", "internalInputRef", "iconSize", "handleClear", "eventTarget", "handleFocus", "event", "handleBlurWithFocus", "readonlyStyles", "shouldShrink", "resolveInputLabelSlotProps", "ownerState", "baseInputLabel", "resolvedInputLabel", "ClearIcon", "ClearTextFieldWithForm", "form", "name", "rest", "formValue", "handleFormChange", "ClearTextField", "import_react", "import_material", "import_Visibility", "import_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", "import_jsx_runtime", "PasswordTextFieldBase", "showToggle", "label", "validationRules", "onValidationChange", "invalidBorderColor", "debounce", "readonly", "slotProps", "sx", "size", "value", "onChange", "onBlur", "externalInputRef", "props", "ref", "internalInputRef", "showPassword", "setShowPassword", "isInvalid", "setIsInvalid", "internalValue", "handleChange", "handleBlur", "useTextFieldBase", "iconSize", "handleTogglePassword", "prev", "performValidation", "inputValue", "mergedRules", "DEFAULT_PASSWORD_VALIDATION_RULES", "result", "validatePassword", "minLength", "VisibilityOff", "Visibility", "PasswordTextFieldWithForm", "form", "name", "rest", "formValue", "handleFormChange", "event", "PasswordTextField", "import_react", "import_material", "import_jsx_runtime", "TextFieldBase", "value", "onChange", "onBlur", "debounce", "readonly", "slotProps", "externalInputRef", "sx", "props", "ref", "resolvedValue", "internalValue", "handleChange", "handleBlur", "useTextFieldBase", "internalInputRef", "MuiTextField", "TextFieldWithForm", "form", "name", "rest", "formValue", "event", "TextField", "import_react", "import_material", "import_jsx_runtime", "TextAreaBase", "label", "value", "name", "onChange", "onBlur", "onFocus", "minRows", "maxRows", "placeholder", "disabled", "readonly", "fullWidth", "externalInputRef", "sx", "inputProps", "debounce", "form", "rest", "ref", "internalInputRef", "isFocused", "setIsFocused", "internalValue", "setInternalValue", "emitChange", "handleBlur", "useTextFieldBase", "handleChange", "event", "newValue", "handleFocus", "handleBlurWithFocus", "node", "TextAreaWithForm", "formValue", "handleFormChange", "TextArea", "props", "import_react", "import_material", "import_jsx_runtime", "CheckboxBase", "label", "name", "checked", "onChange", "readonly", "disabled", "form", "props", "ref", "MuiCheckbox", "CheckboxWithForm", "rest", "formValue", "handleFormChange", "event", "nextChecked", "syntheticEvent", "Checkbox", "import_react", "import_material", "import_jsx_runtime", "RadioGroupBase", "label", "name", "value", "options", "onChange", "readonly", "disabled", "props", "ref", "MuiRadioGroup", "option", "RadioGroupWithForm", "form", "rest", "formValue", "handleFormChange", "event", "nextValue", "syntheticEvent", "RadioGroup", "import_react", "import_material", "import_jsx_runtime", "SwitchBase", "label", "name", "checked", "onChange", "readonly", "disabled", "form", "props", "ref", "switchNode", "MuiSwitch", "SwitchWithForm", "rest", "formValue", "handleFormChange", "event", "nextChecked", "syntheticEvent", "Switch", "import_react", "import_material", "import_jsx_runtime", "RatingBase", "name", "value", "onChange", "readonly", "disabled", "props", "ref", "MuiRating", "RatingWithForm", "form", "rest", "formValue", "resolvedValue", "handleFormChange", "event", "nextValue", "syntheticEvent", "Rating", "import_react", "import_material", "import_jsx_runtime", "ToggleButtonBase", "name", "value", "selected", "onChange", "readonly", "disabled", "props", "ref", "MuiToggleButton", "ToggleButtonWithForm", "form", "rest", "formValue", "resolvedSelected", "handleFormChange", "event", "nextSelected", "syntheticEvent", "ToggleButton", "import_react", "import_material", "import_jsx_runtime", "ToggleButtonGroupBase", "options", "value", "onChange", "fullWidth", "readonly", "disabled", "form", "onDeselect", "props", "ref", "MuiToggleButtonGroup", "option", "MuiToggleButton", "ToggleButtonGroupWithForm", "name", "exclusive", "rest", "formValue", "handleFormChange", "event", "nextValue", "resolvedValue", "syntheticEvent", "ToggleButtonGroup", "import_react", "import_material", "import_jsx_runtime", "ButtonGroup", "props", "ref", "MuiButtonGroup", "import_material", "import_react", "import_material", "import_react", "import_material", "import_jsx_runtime", "import_overlay_scrollbar", "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", "jsx", "ChevronRight", "ColonIcon", "jsxs", "TimeSelector", "value", "onChange", "format", "minTime", "maxTime", "minuteStep", "secondStep", "showHeader", "hideDisabledTime", "selectedHour", "setSelectedHour", "useState", "h", "selectedMinute", "setSelectedMinute", "m", "selectedSecond", "setSelectedSecond", "initialScrollDone", "useRef", "hourRef", "minuteRef", "secondRef", "hasSeconds", "is12Hour", "maxHour", "minHourValue", "hours", "_", "i", "minutes", "seconds", "scrollToCenter", "useCallback", "scrollbarRef", "val", "scrollContainer", "element", "containerHeight", "elementTop", "elementHeight", "scrollTop", "useEffect", "timer", "isTimeInRange", "timeValue", "minParts", "minH", "minM", "minS", "minValue", "maxParts", "maxH", "maxM", "maxS", "maxValue", "handleHourSelect", "hour", "handleMinuteSelect", "minute", "handleSecondSelect", "second", "renderItem", "selected", "disabled", "onClick", "Box", "Typography", "renderColumn", "ref", "items", "selectedValue", "onSelect", "checkDisabled", "OverlayScrollbar", "item", "isDisabled", "isHourDisabled", "isMinuteDisabled", "isSecondDisabled", "Fragment", "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", "useMemo", "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", "IconButton", "renderContent", "isSelected", "isCurrent", "monthName", "index", "day", "isToday", "isCurrentMonth", "isHoliday", "renderFooter", "Button", "calendarContent", "footerContent", "resolveAnchorEl", "anchorEl", "TimePicker", "open", "resolvedAnchorEl", "tempHour", "setTempHour", "tempMinute", "setTempMinute", "tempSecond", "setTempSecond", "handleTimeChange", "Popover", "DatePicker", "onDateChange", "anchorOrigin", "transformOrigin", "slotProps", "popoverProps", "mergedPaperProps", "tempDate", "setTempDate", "prevYear", "prevMonth", "handleDateSelect", "DateTimePicker", "handleCalendarTimeChange", "newTime", "width", "height", "import_jsx_runtime", "CalendarIcon", "size", "import_jsx_runtime", "import_jsx_runtime", "import_jsx_runtime", "ClockIcon", "size", "color", "import_jsx_runtime", "ColonIcon", "size", "color", "height", "dotRadius", "width", "centerX", "import_jsx_runtime", "DashIcon", "size", "width", "height", "import_jsx_runtime", "CopyIcon", "size", "iconSize", "import_jsx_runtime", "CARD_WIDTH", "CARD_HEIGHT", "CardIcon", "size", "color", "scale", "width", "height", "VisaIcon", "logoWidth", "logoHeight", "logoScale", "offsetX", "offsetY", "MastercardIcon", "AmexIcon", "JcbIcon", "DinersIcon", "DiscoverIcon", "UnionPayIcon", "BcIcon", "logoSize", "import_jsx_runtime", "DateTextFieldBase", "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", "displayValue", "setDisplayValue", "prevNumbers", "setPrevNumbers", "calendarOpen", "setCalendarOpen", "calendarAnchorPos", "setCalendarAnchorPos", "calendarCloseReasonRef", "internalYear", "setInternalYear", "internalInputRef", "emitChange", "flushOnBlur", "lastEmittedValue", "useDebouncedEmit", "maxLength", "getMaxLength", "completeLength", "getCompleteLength", "isYearlessFormat", "hasYearInFormat", "selectedDate", "parsed", "parseDateWithInternalYear", "calendarSelectedDate", "yearToUse", "buildOutputValue", "formattedValue", "buildDateOutputValue", "performValidation", "inputValue", "isValid", "validateDate", "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", "formatToPlaceholder", "CalendarIcon", "Dt", "DateTextFieldWithForm", "form", "rest", "formValue", "handleFormChange", "event", "DateTextField", "import_jsx_runtime", "DateRange", "form", "startName", "endName", "startLabel", "endLabel", "startValue", "endValue", "onStartChange", "onEndChange", "fullWidth", "size", "readonly", "gap", "startProps", "endProps", "DateTextField", "import_react", "import_material", "import_jsx_runtime", "SliderBase", "label", "name", "value", "onChange", "readonly", "disabled", "props", "ref", "MuiSlider", "SliderWithForm", "form", "rest", "formValue", "resolvedValue", "handleFormChange", "_event", "nextValue", "syntheticEvent", "Slider", "import_react", "import_material", "import_jsx_runtime", "parseStepValue", "value", "parsed", "Stepper", "form", "name", "activeStepProp", "defaultActiveStep", "onStepChange", "props", "ref", "shouldUseForm", "formValue", "parsedFormValue", "emitStepChange", "step", "eventTarget", "fakeEvent", "MuiStepper", "React", "import_number_field", "import_IconButton", "import_FormControl", "import_OutlinedInput", "import_InputAdornment", "import_InputLabel", "import_KeyboardArrowUp", "import_KeyboardArrowDown", "import_jsx_runtime", "SSRInitialFilled", "_", "NumberFieldBase", "idProp", "label", "error", "size", "step", "fullWidth", "_form", "other", "id", "BaseNumberField", "props", "state", "FormControl", "InputLabel", "OutlinedInput", "InputAdornment", "IconButton", "KeyboardArrowUpIcon", "KeyboardArrowDownIcon", "NumberFieldWithForm", "form", "name", "onValueChange", "rest", "formValue", "handleFormValueChange", "value", "eventDetails", "syntheticEvent", "NumberField", "React", "import_number_field", "import_Box", "import_Button", "import_FormControl", "import_FormLabel", "import_Add", "import_Remove", "import_OutlinedInput", "import_OpenInFull", "import_jsx_runtime", "NumberSpinner", "idProp", "label", "error", "size", "other", "id", "BaseNumberField", "props", "state", "FormControl", "Box", "FormLabel", "OpenInFullIcon", "Button", "RemoveIcon", "OutlinedInput", "AddIcon", "import_react", "import_material", "import_jsx_runtime", "AutocompleteBase", "name", "label", "options", "value", "onChange", "fullWidth", "size", "readonly", "disabled", "textFieldProps", "renderOption", "props", "ref", "selectedOption", "option", "handleChange", "_event", "MuiAutocomplete", "selected", "optionProps", "state", "labelText", "query", "lowerLabel", "lowerQuery", "matchIndex", "before", "match", "after", "params", "AutocompleteWithForm", "form", "rest", "formValue", "handleFormChange", "nextValue", "syntheticEvent", "Autocomplete", "import_react", "import_material", "import_jsx_runtime", "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", "MuiSelect", "selected", "opt", "SelectWithForm", "name", "rest", "formValue", "handleFormChange", "Select", "props", "import_react", "import_material", "import_jsx_runtime", "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", "import_react", "import_material", "import_jsx_runtime", "PhoneTextFieldBase", "label", "autoFormat", "includeDash", "prefix", "format", "onValidationChange", "invalidBorderColor", "debounce", "readonly", "slotProps", "sx", "value", "onChange", "onBlur", "externalInputRef", "props", "ref", "isInvalid", "setIsInvalid", "displayValue", "setDisplayValue", "prevNumbers", "setPrevNumbers", "currentMaxLength", "setCurrentMaxLength", "internalInputRef", "cursorPositionRef", "emitChange", "flushOnBlur", "lastEmittedValue", "useDebouncedEmit", "prefixFormatted", "performValidation", "inputValue", "numbers", "minLength", "isComplete", "strValue", "getPhoneMaxLength", "formattedValue", "formatPhoneNumber", "pos", "e", "newValue", "newNumbers", "cursorPos", "prefixNumbers", "originalPos", "isBackspace", "deletedDigitIndex", "prefixProtected", "numbersBeforeCursor", "trimmedNumbers", "targetPos", "digitCount", "i", "currentNumbers", "outputValue", "PhoneTextFieldWithForm", "form", "name", "rest", "formValue", "handleFormChange", "event", "PhoneTextField", "import_material", "import_Search", "import_Close", "import_react", "import_react_daum_postcode", "import_jsx_runtime", "AddressTextFieldBase", "value", "onChange", "readonly", "debounce", "onBlur", "size", "spellCheck", "externalInputRef", "props", "ref", "internalInputRef", "address", "setAddress", "isPostcodeOpen", "setIsPostcodeOpen", "iconSize", "emitChange", "flushOnBlur", "lastEmittedValue", "useDebouncedEmit", "strValue", "handlePostcodeComplete", "data", "fullAddress", "extraAddress", "handleSearchButtonClick", "handleKeyDown", "event", "handlePostcodeClose", "onClose", "e", "newValue", "SearchIcon", "CloseIcon", "DaumPostcode", "AddressTextFieldWithForm", "form", "name", "rest", "formValue", "handleFormChange", "AddressTextField", "import_react", "import_material", "import_jsx_runtime", "NumberTextFieldBase", "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", "displayValue", "setDisplayValue", "isNegative", "setIsNegative", "emitChange", "flushOnBlur", "lastEmittedValue", "useDebouncedEmit", "strValue", "formattedValue", "formatNumber", "handleChange", "e", "newValue", "withoutComma", "numValue", "maxFormatted", "emitValue", "minFormatted", "numericValue", "parseNumber", "handleBlur", "num", "finalValue", "inputStyles", "handleFocus", "NumberTextFieldWithForm", "form", "name", "rest", "formValue", "handleFormChange", "event", "NumberTextField", "import_react", "import_material", "import_react", "import_material", "import_jsx_runtime", "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", "import_material", "import_jsx_runtime", "ColonBox", "size", "mx", "visible", "sx", "ColonIcon", "import_jsx_runtime", "JuminTextFieldBase", "label", "mask", "maskColor", "validateChecksum", "fontSize", "fontColor", "fontFamily", "onChange", "onValidationChange", "invalidBorderColor", "debounce", "readonly", "sx", "value", "size", "disabled", "fullWidth", "className", "id", "props", "ref", "frontValue", "setFrontValue", "backValue", "setBackValue", "isInvalid", "setIsInvalid", "isInternalChange", "setIsInternalChange", "focusedField", "setFocusedField", "cursorVisible", "setCursorVisible", "renderTrigger", "setRenderTrigger", "backComplete", "setBackComplete", "frontRef", "backRef", "containerRef", "isClickFocusRef", "cursorPosRef", "debounceTimer", "numbers", "displayBackValue", "emitChange", "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", "frontFieldCh", "backFieldCh", "noBorderStyle", "getFullNumber", "renderGroupedInput", "hasFrontValue", "hasBackValue", "DashIcon", "selStart", "selEnd", "_", "i", "getTargetRefOnClick", "focusedGroup", "setFocusedGroupWrapper", "group", "GroupedInputWrapper", "JuminTextFieldWithForm", "form", "name", "rest", "formValue", "handleFormChange", "syntheticEvent", "JuminTextField", "import_react", "import_material", "import_jsx_runtime", "VerificationCodeTextFieldBase", "label", "length", "type", "value", "onChange", "onComplete", "debounce", "readonly", "disabled", "size", "name", "fontSizeProp", "fontColor", "fontFamily", "dotSizeProp", "caretColor", "sx", "invalidBorderColor", "externalInputRef", "restProps", "ref", "internalValue", "setInternalValue", "isFocused", "setIsFocused", "isAllSelected", "setIsAllSelected", "internalInputRef", "emitChange", "flushOnBlur", "lastEmittedValue", "useDebouncedEmit", "strValue", "isValidChar", "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", "_", "i", "VerificationCodeTextFieldWithForm", "form", "rest", "formValue", "handleFormChange", "event", "VerificationCodeTextField", "props", "import_react", "import_material", "import_jsx_runtime", "GmailIcon", "size", "NaverIcon", "DaumIcon", "KakaoIcon", "NateIcon", "OutlookIcon", "YahooIcon", "ICloudIcon", "DefaultEmailIcon", "getEmailIcon", "domain", "import_jsx_runtime", "EmailTextFieldBase", "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", "lowerDomain", "getEmailIcon", "inputValue", "setInputValue", "isInvalid", "setIsInvalid", "localSuggestions", "setLocalSuggestions", "showPopper", "setShowPopper", "selectedIndex", "setSelectedIndex", "internalInputRef", "anchorRef", "emitChange", "flushOnBlur", "lastEmittedValue", "useDebouncedEmit", "strValue", "generateSuggestions", "input", "atIndex", "localPart", "domainPart", "filteredDomains", "newSuggestions", "handleChange", "e", "newValue", "isValid", "validateEmail", "hasContent", "handleSelectSuggestion", "suggestion", "handleKeyDown", "prev", "handleClickAway", "handleBlur", "handleFocus", "borderColor", "setRefs", "node", "index", "EmailTextFieldWithForm", "form", "rest", "formValue", "handleFormChange", "event", "EmailTextField", "import_react", "import_material", "import_jsx_runtime", "TimeTextFieldBase", "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", "minuteValue", "setMinuteValue", "secondValue", "setSecondValue", "isInvalid", "setIsInvalid", "isInternalChange", "setIsInternalChange", "pickerOpen", "setPickerOpen", "hourRef", "minuteRef", "secondRef", "containerRef", "debounceTimer", "hasSecond", "getTimeFieldCount", "computedFontSize", "cursorHeight", "cursorWidth", "groups", "focusedGroup", "setFocusedGroup", "cursorVisible", "inputComplete", "getCursorLeft", "createMouseDownHandler", "createClickHandler", "createFocusHandler", "createBlurHandler", "createKeyDownHandler", "createGroupChangeHandler", "useGroupedInput", "strValue", "parts", "numbers", "emitChange", "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", "getFullTime", "showColon", "renderGroupedInput", "ColonBox", "clockIconElement", "ClockIcon", "GroupedInputWrapper", "oo", "TimeTextFieldWithForm", "form", "rest", "formValue", "handleFormChange", "event", "TimeTextField", "props", "import_react", "import_material", "import_jsx_runtime", "DateTimeTextFieldBase", "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", "prevDateNumbers", "setPrevDateNumbers", "internalYear", "setInternalYear", "hourValue", "setHourValue", "minuteValue", "setMinuteValue", "secondValue", "setSecondValue", "isInvalid", "setIsInvalid", "isDateFocused", "setIsDateFocused", "calendarOpen", "setCalendarOpen", "anchorEl", "setAnchorEl", "dateInputRef", "hourRef", "minuteRef", "secondRef", "selectionRangeRef", "containerRef", "hasSecond", "hasSecondField", "is12Hour", "is12HourFormat", "dateFormat", "extractDateFormat", "displayDateSeparator", "getSeparator", "dateMaxLength", "getMaxLength", "dateCompleteLength", "getCompleteLength", "isYearlessFormat", "hasYearInFormat", "computedFontSize", "cursorHeight", "cursorWidth", "emitChange", "flushOnBlur", "lastEmittedValue", "useDebouncedEmit", "timeGroups", "baseGroups", "focusedGroup", "cursorVisible", "inputComplete", "getCursorLeft", "createMouseDownHandler", "createClickHandler", "createFocusHandler", "createBlurHandler", "createKeyDownHandler", "createGroupChangeHandler", "useGroupedInput", "buildDateTimeString", "dateStr", "hour", "minute", "second", "yearOverride", "outputDateStr", "buildDateOutputValue", "timeStr", "performValidation", "dateComplete", "timeComplete", "dateValid", "validateDate", "timeValid", "validateTime", "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", "showTimeFields", "endAdornmentElement", "ColonBox", "CalendarIcon", "mo", "DateTimeTextFieldWithForm", "form", "rest", "formValue", "handleFormChange", "event", "DateTimeTextField", "props", "import_react", "import_material", "import_alerts", "import_jsx_runtime", "BizNumTextFieldBase", "label", "includeDash", "validate", "copyIcon", "fontSize", "fontColor", "fontFamily", "onValidationChange", "invalidBorderColor", "debounce", "readonly", "sx", "value", "onChange", "size", "disabled", "className", "id", "autoFocus", "name", "fullWidth", "ref", "group1", "setGroup1", "group2", "setGroup2", "group3", "setGroup3", "isInvalid", "setIsInvalid", "isInternalChange", "setIsInternalChange", "ref1", "ref2", "ref3", "containerRef", "maxLengths", "debouncedEmit", "flushOnBlur", "useDebouncedEmit", "computedFontSize", "groups", "focusedGroup", "setFocusedGroup", "cursorVisible", "inputComplete", "getCursorLeft", "createMouseDownHandler", "createClickHandler", "createFocusHandler", "createBlurHandler", "createKeyDownHandler", "createGroupChangeHandler", "useGroupedInput", "numbers", "getFullNumber", "emitChange", "g1", "g2", "g3", "fullNumber", "isComplete", "isValid", "validateBusinessNumber", "outputValue", "handleChange", "groupIndex", "newValue", "idx", "newValues", "handleKeyDown", "handleBlur", "e", "handleCopy", "copyValue", "fieldWidths", "cursorWidth", "cursorHeight", "noBorderStyle", "renderGroup", "groupValue", "placeholder", "showCursor", "refs", "Dash", "DashIcon", "getTargetRefOnClick", "GroupedInputWrapper", "CopyIcon", "BizNumTextFieldWithForm", "form", "rest", "formValue", "handleFormChange", "event", "BizNumTextField", "props", "import_react", "import_material", "import_jsx_runtime", "CardNumTextFieldBase", "label", "maskColor", "fontSize", "fontColor", "fontFamily", "onChange", "onValidationChange", "onCardBrandChange", "invalidBorderColor", "validate", "debounce", "readonly", "sx", "value", "size", "disabled", "logoIcon", "name", "className", "id", "fullWidth", "ref", "group1", "setGroup1", "group2", "setGroup2", "group3", "setGroup3", "group4", "setGroup4", "isInvalid", "setIsInvalid", "isInternalChange", "setIsInternalChange", "cardBrand", "setCardBrand", "lastInputInfo", "setLastInputInfo", "ref1", "ref2", "ref3", "ref4", "containerRef", "computedFontSize", "groups", "focusedGroup", "setFocusedGroup", "cursorVisible", "cursorPosRef", "inputComplete", "renderTrigger", "getCursorLeft", "createMouseDownHandler", "createClickHandler", "createFocusHandler", "createBlurHandler", "createKeyDownHandler", "createGroupChangeHandler", "useGroupedInput", "emitChange", "flushOnBlur", "useDebouncedEmit", "getFullNumber", "emitCardChange", "g1", "g2", "g3", "g4", "fullValue", "isComplete", "isValid", "validateCardNumber", "brand", "detectCardBrand", "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", "_", "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
  }