@alfalab/core-components-date-input 6.0.4 → 6.0.5
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/Component.d.ts +6 -6
- package/Component.js.map +1 -1
- package/cssm/Component.d.ts +6 -6
- package/cssm/Component.js.map +1 -1
- package/esm/Component.d.ts +6 -6
- package/esm/Component.js.map +1 -1
- package/esm/index.css +3 -3
- package/esm/index.module.css.js +1 -1
- package/esm/index.module.css.js.map +1 -1
- package/index.css +3 -3
- package/index.module.css.js +1 -1
- package/index.module.css.js.map +1 -1
- package/modern/Component.d.ts +6 -6
- package/modern/Component.js.map +1 -1
- package/modern/index.css +3 -3
- package/modern/index.module.css.js +1 -1
- package/modern/index.module.css.js.map +1 -1
- package/moderncssm/Component.d.ts +6 -6
- package/moderncssm/Component.js.map +1 -1
- package/package.json +3 -3
- package/src/index.module.css +1 -1
package/Component.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { type ChangeEvent } from 'react';
|
|
2
2
|
import { type InputProps } from '@alfalab/core-components-input';
|
|
3
|
-
export
|
|
3
|
+
export type DateInputProps = Omit<InputProps, 'onChange'> & {
|
|
4
4
|
/**
|
|
5
5
|
* Управление нативным режимом на мобильных устройствах
|
|
6
6
|
*/
|
|
@@ -28,19 +28,19 @@ export declare const DateInput: React.ForwardRefExoticComponent<Omit<InputProps,
|
|
|
28
28
|
/**
|
|
29
29
|
* Управление нативным режимом на мобильных устройствах
|
|
30
30
|
*/
|
|
31
|
-
mobileMode?: "input" | "native"
|
|
31
|
+
mobileMode?: "input" | "native";
|
|
32
32
|
/**
|
|
33
33
|
* Обработчик изменения значения
|
|
34
34
|
*/
|
|
35
|
-
onChange?: (
|
|
35
|
+
onChange?: (event: ChangeEvent<HTMLInputElement>, payload: {
|
|
36
36
|
date: Date;
|
|
37
37
|
value: string;
|
|
38
|
-
}) => void
|
|
38
|
+
}) => void;
|
|
39
39
|
/**
|
|
40
40
|
* Обработчик окончания ввода
|
|
41
41
|
*/
|
|
42
|
-
onComplete?: (
|
|
42
|
+
onComplete?: (event: ChangeEvent<HTMLInputElement>, payload: {
|
|
43
43
|
date: Date;
|
|
44
44
|
value: string;
|
|
45
|
-
}) => void
|
|
45
|
+
}) => void;
|
|
46
46
|
} & React.RefAttributes<HTMLInputElement>>;
|
package/Component.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Component.js","sources":["src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n type FocusEvent,\n forwardRef,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\n\nimport { Input, type InputProps } from '@alfalab/core-components-input';\n\nimport {\n format,\n formatDate,\n isCompleteDateInput,\n isInputDateSupported,\n isValid,\n NATIVE_DATE_FORMAT,\n parseDateString,\n} from './utils';\n\nimport styles from './index.module.css';\n\nexport type DateInputProps = Omit<InputProps, 'onChange'> & {\n /**\n * Управление нативным режимом на мобильных устройствах\n */\n mobileMode?: 'input' | 'native';\n\n /**\n * Обработчик изменения значения\n */\n onChange?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n\n /**\n * Обработчик окончания ввода\n */\n onComplete?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n};\n\n/**\n * @deprecated\n * use UniversalDateInput instead\n */\nexport const DateInput = forwardRef<HTMLInputElement, DateInputProps>(\n (\n {\n mobileMode = 'input',\n defaultValue = '',\n rightAddons,\n error,\n value: propValue,\n onBlur,\n onChange,\n onComplete,\n ...restProps\n },\n ref,\n ) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [shouldRenderNative, setShouldRenderNative] = useState(false);\n\n const [value, setValue] = useState(propValue || defaultValue);\n\n const moveCaretTo = (pos: number) => {\n requestAnimationFrame(() => {\n inputRef.current?.setSelectionRange(pos, pos);\n });\n };\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const { value: newValue } = event.target;\n const caretPos = event.target.selectionStart || 0;\n\n // Позволяем вводить только цифры и точки\n if (/[^\\d.]/.test(newValue)) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Не даем вводить больше, чем 2 точки\n if (getDotsCount(newValue) > 2) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Форматируем введенное значение (добавляем точки)\n const formattedValue = format(newValue);\n const date = parseDateString(formattedValue);\n\n // Управляем кареткой, если она находится не в конце инпута\n if (caretPos !== newValue.length) {\n if (formattedValue === value) {\n moveCaretTo(caretPos);\n } else if (newValue.length - formattedValue.length === 1) {\n moveCaretTo(caretPos);\n } else if (\n formattedValue.length - newValue.length === 1 &&\n getDotsCount(formattedValue) > getDotsCount(newValue)\n ) {\n moveCaretTo(caretPos);\n }\n }\n\n setValue(formattedValue);\n\n if (onChange) onChange(event, { date, value: formattedValue });\n\n if (isCompleteDateInput(formattedValue)) {\n const valid = formattedValue.length > 0 && isValid(formattedValue);\n\n if (!valid) return;\n\n if (onComplete) onComplete(event, { date, value: formattedValue });\n }\n };\n\n const handleNativeInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const newDate = parseDateString(event.target.value, NATIVE_DATE_FORMAT);\n const newValue = event.target.value === '' ? '' : formatDate(newDate);\n\n setValue(newValue);\n\n if (onComplete) onComplete(event, { date: newDate, value: newValue });\n if (onChange) onChange(event, { date: newDate, value: newValue });\n };\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n if (onBlur) onBlur(event);\n };\n\n useEffect(() => {\n if (mobileMode === 'native' && isInputDateSupported()) {\n setShouldRenderNative(true);\n }\n }, [mobileMode]);\n\n useEffect(() => {\n if (typeof propValue !== 'undefined') {\n setValue(propValue);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [propValue]);\n\n return (\n <Input\n {...restProps}\n ref={mergeRefs([ref, inputRef])}\n value={value}\n inputMode='decimal'\n pattern='[0-9\\.]*'\n onChange={handleChange}\n onBlur={handleBlur}\n placeholder='ДД.ММ.ГГГГ'\n error={error}\n rightAddons={\n <React.Fragment>\n {rightAddons}\n\n {shouldRenderNative && (\n <input\n type='date'\n ref={ref}\n defaultValue={defaultValue}\n onChange={handleNativeInputChange}\n className={styles.nativeInput}\n />\n )}\n </React.Fragment>\n }\n />\n );\n },\n);\n\nfunction getDotsCount(value: string) {\n return (value.match(/\\./g) || []).length;\n}\n"],"names":["forwardRef","__rest","useRef","useState","format","parseDateString","isCompleteDateInput","isValid","NATIVE_DATE_FORMAT","formatDate","useEffect","isInputDateSupported","React","Input","__assign","mergeRefs","styles"],"mappings":";;;;;;;;;;;;;;;;;AA+CA;;;AAGG;IACU,SAAS,GAAGA,gBAAU,CAC/B,UACI,EAUC,EACD,GAAG,EAAA;AAVC,IAAA,IAAA,EAAoB,GAAA,EAAA,CAAA,UAAA,EAApB,UAAU,GAAA,EAAA,KAAA,MAAA,GAAG,OAAO,GAAA,EAAA,EACpB,EAAiB,GAAA,EAAA,CAAA,YAAA,EAAjB,YAAY,GAAG,EAAA,KAAA,MAAA,GAAA,EAAE,GAAA,EAAA,EACjB,WAAW,GAAA,EAAA,CAAA,WAAA,EACX,KAAK,GAAA,EAAA,CAAA,KAAA,EACE,SAAS,GAAA,EAAA,CAAA,KAAA,EAChB,MAAM,YAAA,EACN,QAAQ,GAAA,EAAA,CAAA,QAAA,EACR,UAAU,GAAA,EAAA,CAAA,UAAA,EACP,SAAS,GAAAC,YAAA,CAAA,EAAA,EAThB,mGAUC,CADe;AAIhB,IAAA,IAAM,QAAQ,GAAGC,YAAM,CAAmB,IAAI,CAAC;IAEzC,IAAA,EAAA,GAA8CC,cAAQ,CAAC,KAAK,CAAC,EAA5D,kBAAkB,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,qBAAqB,GAAA,EAAA,CAAA,CAAA,CAAmB;AAE7D,IAAA,IAAA,EAAoB,GAAAA,cAAQ,CAAC,SAAS,IAAI,YAAY,CAAC,EAAtD,KAAK,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,QAAQ,QAAuC;IAE7D,IAAM,WAAW,GAAG,UAAC,GAAW,EAAA;AAC5B,QAAA,qBAAqB,CAAC,YAAA;;YAClB,CAAA,EAAA,GAAA,QAAQ,CAAC,OAAO,MAAE,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAA,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC;AACjD,SAAC,CAAC;AACN,KAAC;IAED,IAAM,YAAY,GAAG,UAAC,KAAoC,EAAA;AAC9C,QAAA,IAAO,QAAQ,GAAK,KAAK,CAAC,MAAM,MAAjB;QACvB,IAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC;;AAGjD,QAAA,IAAI,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AACzB,YAAA,WAAW,CAAC,QAAQ,GAAG,CAAC,CAAC;YAEzB
|
|
1
|
+
{"version":3,"file":"Component.js","sources":["src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n type FocusEvent,\n forwardRef,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\n\nimport { Input, type InputProps } from '@alfalab/core-components-input';\n\nimport {\n format,\n formatDate,\n isCompleteDateInput,\n isInputDateSupported,\n isValid,\n NATIVE_DATE_FORMAT,\n parseDateString,\n} from './utils';\n\nimport styles from './index.module.css';\n\nexport type DateInputProps = Omit<InputProps, 'onChange'> & {\n /**\n * Управление нативным режимом на мобильных устройствах\n */\n mobileMode?: 'input' | 'native';\n\n /**\n * Обработчик изменения значения\n */\n onChange?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n\n /**\n * Обработчик окончания ввода\n */\n onComplete?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n};\n\n/**\n * @deprecated\n * use UniversalDateInput instead\n */\nexport const DateInput = forwardRef<HTMLInputElement, DateInputProps>(\n (\n {\n mobileMode = 'input',\n defaultValue = '',\n rightAddons,\n error,\n value: propValue,\n onBlur,\n onChange,\n onComplete,\n ...restProps\n },\n ref,\n ) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [shouldRenderNative, setShouldRenderNative] = useState(false);\n\n const [value, setValue] = useState(propValue || defaultValue);\n\n const moveCaretTo = (pos: number) => {\n requestAnimationFrame(() => {\n inputRef.current?.setSelectionRange(pos, pos);\n });\n };\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const { value: newValue } = event.target;\n const caretPos = event.target.selectionStart || 0;\n\n // Позволяем вводить только цифры и точки\n if (/[^\\d.]/.test(newValue)) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Не даем вводить больше, чем 2 точки\n if (getDotsCount(newValue) > 2) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Форматируем введенное значение (добавляем точки)\n const formattedValue = format(newValue);\n const date = parseDateString(formattedValue);\n\n // Управляем кареткой, если она находится не в конце инпута\n if (caretPos !== newValue.length) {\n if (formattedValue === value) {\n moveCaretTo(caretPos);\n } else if (newValue.length - formattedValue.length === 1) {\n moveCaretTo(caretPos);\n } else if (\n formattedValue.length - newValue.length === 1 &&\n getDotsCount(formattedValue) > getDotsCount(newValue)\n ) {\n moveCaretTo(caretPos);\n }\n }\n\n setValue(formattedValue);\n\n if (onChange) onChange(event, { date, value: formattedValue });\n\n if (isCompleteDateInput(formattedValue)) {\n const valid = formattedValue.length > 0 && isValid(formattedValue);\n\n if (!valid) return;\n\n if (onComplete) onComplete(event, { date, value: formattedValue });\n }\n };\n\n const handleNativeInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const newDate = parseDateString(event.target.value, NATIVE_DATE_FORMAT);\n const newValue = event.target.value === '' ? '' : formatDate(newDate);\n\n setValue(newValue);\n\n if (onComplete) onComplete(event, { date: newDate, value: newValue });\n if (onChange) onChange(event, { date: newDate, value: newValue });\n };\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n if (onBlur) onBlur(event);\n };\n\n useEffect(() => {\n if (mobileMode === 'native' && isInputDateSupported()) {\n setShouldRenderNative(true);\n }\n }, [mobileMode]);\n\n useEffect(() => {\n if (typeof propValue !== 'undefined') {\n setValue(propValue);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [propValue]);\n\n return (\n <Input\n {...restProps}\n ref={mergeRefs([ref, inputRef])}\n value={value}\n inputMode='decimal'\n pattern='[0-9\\.]*'\n onChange={handleChange}\n onBlur={handleBlur}\n placeholder='ДД.ММ.ГГГГ'\n error={error}\n rightAddons={\n <React.Fragment>\n {rightAddons}\n\n {shouldRenderNative && (\n <input\n type='date'\n ref={ref}\n defaultValue={defaultValue}\n onChange={handleNativeInputChange}\n className={styles.nativeInput}\n />\n )}\n </React.Fragment>\n }\n />\n );\n },\n);\n\nfunction getDotsCount(value: string) {\n return (value.match(/\\./g) || []).length;\n}\n"],"names":["forwardRef","__rest","useRef","useState","format","parseDateString","isCompleteDateInput","isValid","NATIVE_DATE_FORMAT","formatDate","useEffect","isInputDateSupported","React","Input","__assign","mergeRefs","styles"],"mappings":"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"}
|
package/cssm/Component.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { type ChangeEvent } from 'react';
|
|
2
2
|
import { type InputProps } from '@alfalab/core-components-input/cssm';
|
|
3
|
-
export
|
|
3
|
+
export type DateInputProps = Omit<InputProps, 'onChange'> & {
|
|
4
4
|
/**
|
|
5
5
|
* Управление нативным режимом на мобильных устройствах
|
|
6
6
|
*/
|
|
@@ -28,19 +28,19 @@ export declare const DateInput: React.ForwardRefExoticComponent<Omit<InputProps,
|
|
|
28
28
|
/**
|
|
29
29
|
* Управление нативным режимом на мобильных устройствах
|
|
30
30
|
*/
|
|
31
|
-
mobileMode?: "input" | "native"
|
|
31
|
+
mobileMode?: "input" | "native";
|
|
32
32
|
/**
|
|
33
33
|
* Обработчик изменения значения
|
|
34
34
|
*/
|
|
35
|
-
onChange?: (
|
|
35
|
+
onChange?: (event: ChangeEvent<HTMLInputElement>, payload: {
|
|
36
36
|
date: Date;
|
|
37
37
|
value: string;
|
|
38
|
-
}) => void
|
|
38
|
+
}) => void;
|
|
39
39
|
/**
|
|
40
40
|
* Обработчик окончания ввода
|
|
41
41
|
*/
|
|
42
|
-
onComplete?: (
|
|
42
|
+
onComplete?: (event: ChangeEvent<HTMLInputElement>, payload: {
|
|
43
43
|
date: Date;
|
|
44
44
|
value: string;
|
|
45
|
-
}) => void
|
|
45
|
+
}) => void;
|
|
46
46
|
} & React.RefAttributes<HTMLInputElement>>;
|
package/cssm/Component.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n type FocusEvent,\n forwardRef,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\n\nimport { Input, type InputProps } from '@alfalab/core-components-input';\n\nimport {\n format,\n formatDate,\n isCompleteDateInput,\n isInputDateSupported,\n isValid,\n NATIVE_DATE_FORMAT,\n parseDateString,\n} from './utils';\n\nimport styles from './index.module.css';\n\nexport type DateInputProps = Omit<InputProps, 'onChange'> & {\n /**\n * Управление нативным режимом на мобильных устройствах\n */\n mobileMode?: 'input' | 'native';\n\n /**\n * Обработчик изменения значения\n */\n onChange?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n\n /**\n * Обработчик окончания ввода\n */\n onComplete?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n};\n\n/**\n * @deprecated\n * use UniversalDateInput instead\n */\nexport const DateInput = forwardRef<HTMLInputElement, DateInputProps>(\n (\n {\n mobileMode = 'input',\n defaultValue = '',\n rightAddons,\n error,\n value: propValue,\n onBlur,\n onChange,\n onComplete,\n ...restProps\n },\n ref,\n ) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [shouldRenderNative, setShouldRenderNative] = useState(false);\n\n const [value, setValue] = useState(propValue || defaultValue);\n\n const moveCaretTo = (pos: number) => {\n requestAnimationFrame(() => {\n inputRef.current?.setSelectionRange(pos, pos);\n });\n };\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const { value: newValue } = event.target;\n const caretPos = event.target.selectionStart || 0;\n\n // Позволяем вводить только цифры и точки\n if (/[^\\d.]/.test(newValue)) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Не даем вводить больше, чем 2 точки\n if (getDotsCount(newValue) > 2) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Форматируем введенное значение (добавляем точки)\n const formattedValue = format(newValue);\n const date = parseDateString(formattedValue);\n\n // Управляем кареткой, если она находится не в конце инпута\n if (caretPos !== newValue.length) {\n if (formattedValue === value) {\n moveCaretTo(caretPos);\n } else if (newValue.length - formattedValue.length === 1) {\n moveCaretTo(caretPos);\n } else if (\n formattedValue.length - newValue.length === 1 &&\n getDotsCount(formattedValue) > getDotsCount(newValue)\n ) {\n moveCaretTo(caretPos);\n }\n }\n\n setValue(formattedValue);\n\n if (onChange) onChange(event, { date, value: formattedValue });\n\n if (isCompleteDateInput(formattedValue)) {\n const valid = formattedValue.length > 0 && isValid(formattedValue);\n\n if (!valid) return;\n\n if (onComplete) onComplete(event, { date, value: formattedValue });\n }\n };\n\n const handleNativeInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const newDate = parseDateString(event.target.value, NATIVE_DATE_FORMAT);\n const newValue = event.target.value === '' ? '' : formatDate(newDate);\n\n setValue(newValue);\n\n if (onComplete) onComplete(event, { date: newDate, value: newValue });\n if (onChange) onChange(event, { date: newDate, value: newValue });\n };\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n if (onBlur) onBlur(event);\n };\n\n useEffect(() => {\n if (mobileMode === 'native' && isInputDateSupported()) {\n setShouldRenderNative(true);\n }\n }, [mobileMode]);\n\n useEffect(() => {\n if (typeof propValue !== 'undefined') {\n setValue(propValue);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [propValue]);\n\n return (\n <Input\n {...restProps}\n ref={mergeRefs([ref, inputRef])}\n value={value}\n inputMode='decimal'\n pattern='[0-9\\.]*'\n onChange={handleChange}\n onBlur={handleBlur}\n placeholder='ДД.ММ.ГГГГ'\n error={error}\n rightAddons={\n <React.Fragment>\n {rightAddons}\n\n {shouldRenderNative && (\n <input\n type='date'\n ref={ref}\n defaultValue={defaultValue}\n onChange={handleNativeInputChange}\n className={styles.nativeInput}\n />\n )}\n </React.Fragment>\n }\n />\n );\n },\n);\n\nfunction getDotsCount(value: string) {\n return (value.match(/\\./g) || []).length;\n}\n"],"names":["forwardRef","__rest","useRef","useState","format","parseDateString","isCompleteDateInput","isValid","NATIVE_DATE_FORMAT","formatDate","useEffect","isInputDateSupported","React","Input","__assign","mergeRefs","styles"],"mappings":";;;;;;;;;;;;;;;;;;AA+CA;;;AAGG;IACU,SAAS,GAAGA,gBAAU,CAC/B,UACI,EAUC,EACD,GAAG,EAAA;AAVC,IAAA,IAAA,EAAoB,GAAA,EAAA,CAAA,UAAA,EAApB,UAAU,GAAA,EAAA,KAAA,MAAA,GAAG,OAAO,GAAA,EAAA,EACpB,EAAiB,GAAA,EAAA,CAAA,YAAA,EAAjB,YAAY,GAAG,EAAA,KAAA,MAAA,GAAA,EAAE,GAAA,EAAA,EACjB,WAAW,GAAA,EAAA,CAAA,WAAA,EACX,KAAK,GAAA,EAAA,CAAA,KAAA,EACE,SAAS,GAAA,EAAA,CAAA,KAAA,EAChB,MAAM,YAAA,EACN,QAAQ,GAAA,EAAA,CAAA,QAAA,EACR,UAAU,GAAA,EAAA,CAAA,UAAA,EACP,SAAS,GAAAC,YAAA,CAAA,EAAA,EAThB,mGAUC,CADe;AAIhB,IAAA,IAAM,QAAQ,GAAGC,YAAM,CAAmB,IAAI,CAAC;IAEzC,IAAA,EAAA,GAA8CC,cAAQ,CAAC,KAAK,CAAC,EAA5D,kBAAkB,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,qBAAqB,GAAA,EAAA,CAAA,CAAA,CAAmB;AAE7D,IAAA,IAAA,EAAoB,GAAAA,cAAQ,CAAC,SAAS,IAAI,YAAY,CAAC,EAAtD,KAAK,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,QAAQ,QAAuC;IAE7D,IAAM,WAAW,GAAG,UAAC,GAAW,EAAA;AAC5B,QAAA,qBAAqB,CAAC,YAAA;;YAClB,CAAA,EAAA,GAAA,QAAQ,CAAC,OAAO,MAAE,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAA,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC;AACjD,SAAC,CAAC;AACN,KAAC;IAED,IAAM,YAAY,GAAG,UAAC,KAAoC,EAAA;AAC9C,QAAA,IAAO,QAAQ,GAAK,KAAK,CAAC,MAAM,MAAjB;QACvB,IAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC;;AAGjD,QAAA,IAAI,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AACzB,YAAA,WAAW,CAAC,QAAQ,GAAG,CAAC,CAAC;YAEzB
|
|
1
|
+
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n type FocusEvent,\n forwardRef,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\n\nimport { Input, type InputProps } from '@alfalab/core-components-input';\n\nimport {\n format,\n formatDate,\n isCompleteDateInput,\n isInputDateSupported,\n isValid,\n NATIVE_DATE_FORMAT,\n parseDateString,\n} from './utils';\n\nimport styles from './index.module.css';\n\nexport type DateInputProps = Omit<InputProps, 'onChange'> & {\n /**\n * Управление нативным режимом на мобильных устройствах\n */\n mobileMode?: 'input' | 'native';\n\n /**\n * Обработчик изменения значения\n */\n onChange?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n\n /**\n * Обработчик окончания ввода\n */\n onComplete?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n};\n\n/**\n * @deprecated\n * use UniversalDateInput instead\n */\nexport const DateInput = forwardRef<HTMLInputElement, DateInputProps>(\n (\n {\n mobileMode = 'input',\n defaultValue = '',\n rightAddons,\n error,\n value: propValue,\n onBlur,\n onChange,\n onComplete,\n ...restProps\n },\n ref,\n ) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [shouldRenderNative, setShouldRenderNative] = useState(false);\n\n const [value, setValue] = useState(propValue || defaultValue);\n\n const moveCaretTo = (pos: number) => {\n requestAnimationFrame(() => {\n inputRef.current?.setSelectionRange(pos, pos);\n });\n };\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const { value: newValue } = event.target;\n const caretPos = event.target.selectionStart || 0;\n\n // Позволяем вводить только цифры и точки\n if (/[^\\d.]/.test(newValue)) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Не даем вводить больше, чем 2 точки\n if (getDotsCount(newValue) > 2) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Форматируем введенное значение (добавляем точки)\n const formattedValue = format(newValue);\n const date = parseDateString(formattedValue);\n\n // Управляем кареткой, если она находится не в конце инпута\n if (caretPos !== newValue.length) {\n if (formattedValue === value) {\n moveCaretTo(caretPos);\n } else if (newValue.length - formattedValue.length === 1) {\n moveCaretTo(caretPos);\n } else if (\n formattedValue.length - newValue.length === 1 &&\n getDotsCount(formattedValue) > getDotsCount(newValue)\n ) {\n moveCaretTo(caretPos);\n }\n }\n\n setValue(formattedValue);\n\n if (onChange) onChange(event, { date, value: formattedValue });\n\n if (isCompleteDateInput(formattedValue)) {\n const valid = formattedValue.length > 0 && isValid(formattedValue);\n\n if (!valid) return;\n\n if (onComplete) onComplete(event, { date, value: formattedValue });\n }\n };\n\n const handleNativeInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const newDate = parseDateString(event.target.value, NATIVE_DATE_FORMAT);\n const newValue = event.target.value === '' ? '' : formatDate(newDate);\n\n setValue(newValue);\n\n if (onComplete) onComplete(event, { date: newDate, value: newValue });\n if (onChange) onChange(event, { date: newDate, value: newValue });\n };\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n if (onBlur) onBlur(event);\n };\n\n useEffect(() => {\n if (mobileMode === 'native' && isInputDateSupported()) {\n setShouldRenderNative(true);\n }\n }, [mobileMode]);\n\n useEffect(() => {\n if (typeof propValue !== 'undefined') {\n setValue(propValue);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [propValue]);\n\n return (\n <Input\n {...restProps}\n ref={mergeRefs([ref, inputRef])}\n value={value}\n inputMode='decimal'\n pattern='[0-9\\.]*'\n onChange={handleChange}\n onBlur={handleBlur}\n placeholder='ДД.ММ.ГГГГ'\n error={error}\n rightAddons={\n <React.Fragment>\n {rightAddons}\n\n {shouldRenderNative && (\n <input\n type='date'\n ref={ref}\n defaultValue={defaultValue}\n onChange={handleNativeInputChange}\n className={styles.nativeInput}\n />\n )}\n </React.Fragment>\n }\n />\n );\n },\n);\n\nfunction getDotsCount(value: string) {\n return (value.match(/\\./g) || []).length;\n}\n"],"names":["forwardRef","__rest","useRef","useState","format","parseDateString","isCompleteDateInput","isValid","NATIVE_DATE_FORMAT","formatDate","useEffect","isInputDateSupported","React","Input","__assign","mergeRefs","styles"],"mappings":";;;;;;;;;;;;;;;;;;AA+CA;;;AAGG;IACU,SAAS,GAAGA,gBAAU,CAC/B,UACI,EAUC,EACD,GAAG,EAAA;AAVC,IAAA,IAAA,EAAoB,GAAA,EAAA,CAAA,UAAA,EAApB,UAAU,GAAA,EAAA,KAAA,MAAA,GAAG,OAAO,GAAA,EAAA,EACpB,EAAiB,GAAA,EAAA,CAAA,YAAA,EAAjB,YAAY,GAAG,EAAA,KAAA,MAAA,GAAA,EAAE,GAAA,EAAA,EACjB,WAAW,GAAA,EAAA,CAAA,WAAA,EACX,KAAK,GAAA,EAAA,CAAA,KAAA,EACE,SAAS,GAAA,EAAA,CAAA,KAAA,EAChB,MAAM,YAAA,EACN,QAAQ,GAAA,EAAA,CAAA,QAAA,EACR,UAAU,GAAA,EAAA,CAAA,UAAA,EACP,SAAS,GAAAC,YAAA,CAAA,EAAA,EAThB,mGAUC,CADe;AAIhB,IAAA,IAAM,QAAQ,GAAGC,YAAM,CAAmB,IAAI,CAAC;IAEzC,IAAA,EAAA,GAA8CC,cAAQ,CAAC,KAAK,CAAC,EAA5D,kBAAkB,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,qBAAqB,GAAA,EAAA,CAAA,CAAA,CAAmB;AAE7D,IAAA,IAAA,EAAoB,GAAAA,cAAQ,CAAC,SAAS,IAAI,YAAY,CAAC,EAAtD,KAAK,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,QAAQ,QAAuC;IAE7D,IAAM,WAAW,GAAG,UAAC,GAAW,EAAA;AAC5B,QAAA,qBAAqB,CAAC,YAAA;;YAClB,CAAA,EAAA,GAAA,QAAQ,CAAC,OAAO,MAAE,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAA,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC;AACjD,SAAC,CAAC;AACN,KAAC;IAED,IAAM,YAAY,GAAG,UAAC,KAAoC,EAAA;AAC9C,QAAA,IAAO,QAAQ,GAAK,KAAK,CAAC,MAAM,MAAjB;QACvB,IAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC;;AAGjD,QAAA,IAAI,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AACzB,YAAA,WAAW,CAAC,QAAQ,GAAG,CAAC,CAAC;YAEzB;;;AAIJ,QAAA,IAAI,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AAC5B,YAAA,WAAW,CAAC,QAAQ,GAAG,CAAC,CAAC;YAEzB;;;AAIJ,QAAA,IAAM,cAAc,GAAGC,aAAM,CAAC,QAAQ,CAAC;AACvC,QAAA,IAAM,IAAI,GAAGC,sBAAe,CAAC,cAAc,CAAC;;AAG5C,QAAA,IAAI,QAAQ,KAAK,QAAQ,CAAC,MAAM,EAAE;AAC9B,YAAA,IAAI,cAAc,KAAK,KAAK,EAAE;gBAC1B,WAAW,CAAC,QAAQ,CAAC;;iBAClB,IAAI,QAAQ,CAAC,MAAM,GAAG,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE;gBACtD,WAAW,CAAC,QAAQ,CAAC;;iBAClB,IACH,cAAc,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAC7C,YAAY,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC,QAAQ,CAAC,EACvD;gBACE,WAAW,CAAC,QAAQ,CAAC;;;QAI7B,QAAQ,CAAC,cAAc,CAAC;AAExB,QAAA,IAAI,QAAQ;AAAE,YAAA,QAAQ,CAAC,KAAK,EAAE,EAAE,IAAI,EAAA,IAAA,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;AAE9D,QAAA,IAAIC,0BAAmB,CAAC,cAAc,CAAC,EAAE;AACrC,YAAA,IAAM,KAAK,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,IAAIC,cAAO,CAAC,cAAc,CAAC;AAElE,YAAA,IAAI,CAAC,KAAK;gBAAE;AAEZ,YAAA,IAAI,UAAU;AAAE,gBAAA,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,EAAA,IAAA,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;;AAE1E,KAAC;IAED,IAAM,uBAAuB,GAAG,UAAC,KAAoC,EAAA;AACjE,QAAA,IAAM,OAAO,GAAGF,sBAAe,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAEG,yBAAkB,CAAC;QACvE,IAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,KAAK,EAAE,GAAG,EAAE,GAAGC,iBAAU,CAAC,OAAO,CAAC;QAErE,QAAQ,CAAC,QAAQ,CAAC;AAElB,QAAA,IAAI,UAAU;AAAE,YAAA,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AACrE,QAAA,IAAI,QAAQ;AAAE,YAAA,QAAQ,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AACrE,KAAC;IAED,IAAM,UAAU,GAAG,UAAC,KAAmC,EAAA;AACnD,QAAA,IAAI,MAAM;YAAE,MAAM,CAAC,KAAK,CAAC;AAC7B,KAAC;AAED,IAAAC,eAAS,CAAC,YAAA;AACN,QAAA,IAAI,UAAU,KAAK,QAAQ,IAAIC,mCAAoB,EAAE,EAAE;YACnD,qBAAqB,CAAC,IAAI,CAAC;;AAEnC,KAAC,EAAE,CAAC,UAAU,CAAC,CAAC;AAEhB,IAAAD,eAAS,CAAC,YAAA;AACN,QAAA,IAAI,OAAO,SAAS,KAAK,WAAW,EAAE;YAClC,QAAQ,CAAC,SAAS,CAAC;;;AAG3B,KAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IAEf,QACIE,qCAACC,UAAK,EAAAC,cAAA,CAAA,EAAA,EACE,SAAS,EACb,EAAA,GAAG,EAAEC,0BAAS,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,EAC/B,KAAK,EAAE,KAAK,EACZ,SAAS,EAAC,SAAS,EACnB,OAAO,EAAC,WAAU,EAClB,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,UAAU,EAClB,WAAW,EAAC,oDAAY,EACxB,KAAK,EAAE,KAAK,EACZ,WAAW,EACPH,sBAAA,CAAA,aAAA,CAACA,sBAAK,CAAC,QAAQ,EAAA,IAAA;YACV,WAAW;AAEX,YAAA,kBAAkB,KACfA,sBACI,CAAA,aAAA,CAAA,OAAA,EAAA,EAAA,IAAI,EAAC,MAAM,EACX,GAAG,EAAE,GAAG,EACR,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,uBAAuB,EACjC,SAAS,EAAEI,uBAAM,CAAC,WAAW,EAC/B,CAAA,CACL,CACY,EAAA,CAAA,CAEvB;AAEV,CAAC;AAGL,SAAS,YAAY,CAAC,KAAa,EAAA;AAC/B,IAAA,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,MAAM;AAC5C;;;;"}
|
package/esm/Component.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { type ChangeEvent } from 'react';
|
|
2
2
|
import { type InputProps } from '@alfalab/core-components-input/esm';
|
|
3
|
-
export
|
|
3
|
+
export type DateInputProps = Omit<InputProps, 'onChange'> & {
|
|
4
4
|
/**
|
|
5
5
|
* Управление нативным режимом на мобильных устройствах
|
|
6
6
|
*/
|
|
@@ -28,19 +28,19 @@ export declare const DateInput: React.ForwardRefExoticComponent<Omit<InputProps,
|
|
|
28
28
|
/**
|
|
29
29
|
* Управление нативным режимом на мобильных устройствах
|
|
30
30
|
*/
|
|
31
|
-
mobileMode?: "input" | "native"
|
|
31
|
+
mobileMode?: "input" | "native";
|
|
32
32
|
/**
|
|
33
33
|
* Обработчик изменения значения
|
|
34
34
|
*/
|
|
35
|
-
onChange?: (
|
|
35
|
+
onChange?: (event: ChangeEvent<HTMLInputElement>, payload: {
|
|
36
36
|
date: Date;
|
|
37
37
|
value: string;
|
|
38
|
-
}) => void
|
|
38
|
+
}) => void;
|
|
39
39
|
/**
|
|
40
40
|
* Обработчик окончания ввода
|
|
41
41
|
*/
|
|
42
|
-
onComplete?: (
|
|
42
|
+
onComplete?: (event: ChangeEvent<HTMLInputElement>, payload: {
|
|
43
43
|
date: Date;
|
|
44
44
|
value: string;
|
|
45
|
-
}) => void
|
|
45
|
+
}) => void;
|
|
46
46
|
} & React.RefAttributes<HTMLInputElement>>;
|
package/esm/Component.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n type FocusEvent,\n forwardRef,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\n\nimport { Input, type InputProps } from '@alfalab/core-components-input';\n\nimport {\n format,\n formatDate,\n isCompleteDateInput,\n isInputDateSupported,\n isValid,\n NATIVE_DATE_FORMAT,\n parseDateString,\n} from './utils';\n\nimport styles from './index.module.css';\n\nexport type DateInputProps = Omit<InputProps, 'onChange'> & {\n /**\n * Управление нативным режимом на мобильных устройствах\n */\n mobileMode?: 'input' | 'native';\n\n /**\n * Обработчик изменения значения\n */\n onChange?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n\n /**\n * Обработчик окончания ввода\n */\n onComplete?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n};\n\n/**\n * @deprecated\n * use UniversalDateInput instead\n */\nexport const DateInput = forwardRef<HTMLInputElement, DateInputProps>(\n (\n {\n mobileMode = 'input',\n defaultValue = '',\n rightAddons,\n error,\n value: propValue,\n onBlur,\n onChange,\n onComplete,\n ...restProps\n },\n ref,\n ) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [shouldRenderNative, setShouldRenderNative] = useState(false);\n\n const [value, setValue] = useState(propValue || defaultValue);\n\n const moveCaretTo = (pos: number) => {\n requestAnimationFrame(() => {\n inputRef.current?.setSelectionRange(pos, pos);\n });\n };\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const { value: newValue } = event.target;\n const caretPos = event.target.selectionStart || 0;\n\n // Позволяем вводить только цифры и точки\n if (/[^\\d.]/.test(newValue)) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Не даем вводить больше, чем 2 точки\n if (getDotsCount(newValue) > 2) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Форматируем введенное значение (добавляем точки)\n const formattedValue = format(newValue);\n const date = parseDateString(formattedValue);\n\n // Управляем кареткой, если она находится не в конце инпута\n if (caretPos !== newValue.length) {\n if (formattedValue === value) {\n moveCaretTo(caretPos);\n } else if (newValue.length - formattedValue.length === 1) {\n moveCaretTo(caretPos);\n } else if (\n formattedValue.length - newValue.length === 1 &&\n getDotsCount(formattedValue) > getDotsCount(newValue)\n ) {\n moveCaretTo(caretPos);\n }\n }\n\n setValue(formattedValue);\n\n if (onChange) onChange(event, { date, value: formattedValue });\n\n if (isCompleteDateInput(formattedValue)) {\n const valid = formattedValue.length > 0 && isValid(formattedValue);\n\n if (!valid) return;\n\n if (onComplete) onComplete(event, { date, value: formattedValue });\n }\n };\n\n const handleNativeInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const newDate = parseDateString(event.target.value, NATIVE_DATE_FORMAT);\n const newValue = event.target.value === '' ? '' : formatDate(newDate);\n\n setValue(newValue);\n\n if (onComplete) onComplete(event, { date: newDate, value: newValue });\n if (onChange) onChange(event, { date: newDate, value: newValue });\n };\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n if (onBlur) onBlur(event);\n };\n\n useEffect(() => {\n if (mobileMode === 'native' && isInputDateSupported()) {\n setShouldRenderNative(true);\n }\n }, [mobileMode]);\n\n useEffect(() => {\n if (typeof propValue !== 'undefined') {\n setValue(propValue);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [propValue]);\n\n return (\n <Input\n {...restProps}\n ref={mergeRefs([ref, inputRef])}\n value={value}\n inputMode='decimal'\n pattern='[0-9\\.]*'\n onChange={handleChange}\n onBlur={handleBlur}\n placeholder='ДД.ММ.ГГГГ'\n error={error}\n rightAddons={\n <React.Fragment>\n {rightAddons}\n\n {shouldRenderNative && (\n <input\n type='date'\n ref={ref}\n defaultValue={defaultValue}\n onChange={handleNativeInputChange}\n className={styles.nativeInput}\n />\n )}\n </React.Fragment>\n }\n />\n );\n },\n);\n\nfunction getDotsCount(value: string) {\n return (value.match(/\\./g) || []).length;\n}\n"],"names":[],"mappings":";;;;;;;;AA+CA;;;AAGG;IACU,SAAS,GAAG,UAAU,CAC/B,UACI,EAUC,EACD,GAAG,EAAA;AAVC,IAAA,IAAA,EAAoB,GAAA,EAAA,CAAA,UAAA,EAApB,UAAU,GAAA,EAAA,KAAA,MAAA,GAAG,OAAO,GAAA,EAAA,EACpB,EAAiB,GAAA,EAAA,CAAA,YAAA,EAAjB,YAAY,GAAG,EAAA,KAAA,MAAA,GAAA,EAAE,GAAA,EAAA,EACjB,WAAW,GAAA,EAAA,CAAA,WAAA,EACX,KAAK,GAAA,EAAA,CAAA,KAAA,EACE,SAAS,GAAA,EAAA,CAAA,KAAA,EAChB,MAAM,YAAA,EACN,QAAQ,GAAA,EAAA,CAAA,QAAA,EACR,UAAU,GAAA,EAAA,CAAA,UAAA,EACP,SAAS,GAAA,MAAA,CAAA,EAAA,EAThB,mGAUC,CADe;AAIhB,IAAA,IAAM,QAAQ,GAAG,MAAM,CAAmB,IAAI,CAAC;IAEzC,IAAA,EAAA,GAA8C,QAAQ,CAAC,KAAK,CAAC,EAA5D,kBAAkB,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,qBAAqB,GAAA,EAAA,CAAA,CAAA,CAAmB;AAE7D,IAAA,IAAA,EAAoB,GAAA,QAAQ,CAAC,SAAS,IAAI,YAAY,CAAC,EAAtD,KAAK,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,QAAQ,QAAuC;IAE7D,IAAM,WAAW,GAAG,UAAC,GAAW,EAAA;AAC5B,QAAA,qBAAqB,CAAC,YAAA;;YAClB,CAAA,EAAA,GAAA,QAAQ,CAAC,OAAO,MAAE,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAA,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC;AACjD,SAAC,CAAC;AACN,KAAC;IAED,IAAM,YAAY,GAAG,UAAC,KAAoC,EAAA;AAC9C,QAAA,IAAO,QAAQ,GAAK,KAAK,CAAC,MAAM,MAAjB;QACvB,IAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC;;AAGjD,QAAA,IAAI,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AACzB,YAAA,WAAW,CAAC,QAAQ,GAAG,CAAC,CAAC;YAEzB
|
|
1
|
+
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n type FocusEvent,\n forwardRef,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\n\nimport { Input, type InputProps } from '@alfalab/core-components-input';\n\nimport {\n format,\n formatDate,\n isCompleteDateInput,\n isInputDateSupported,\n isValid,\n NATIVE_DATE_FORMAT,\n parseDateString,\n} from './utils';\n\nimport styles from './index.module.css';\n\nexport type DateInputProps = Omit<InputProps, 'onChange'> & {\n /**\n * Управление нативным режимом на мобильных устройствах\n */\n mobileMode?: 'input' | 'native';\n\n /**\n * Обработчик изменения значения\n */\n onChange?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n\n /**\n * Обработчик окончания ввода\n */\n onComplete?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n};\n\n/**\n * @deprecated\n * use UniversalDateInput instead\n */\nexport const DateInput = forwardRef<HTMLInputElement, DateInputProps>(\n (\n {\n mobileMode = 'input',\n defaultValue = '',\n rightAddons,\n error,\n value: propValue,\n onBlur,\n onChange,\n onComplete,\n ...restProps\n },\n ref,\n ) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [shouldRenderNative, setShouldRenderNative] = useState(false);\n\n const [value, setValue] = useState(propValue || defaultValue);\n\n const moveCaretTo = (pos: number) => {\n requestAnimationFrame(() => {\n inputRef.current?.setSelectionRange(pos, pos);\n });\n };\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const { value: newValue } = event.target;\n const caretPos = event.target.selectionStart || 0;\n\n // Позволяем вводить только цифры и точки\n if (/[^\\d.]/.test(newValue)) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Не даем вводить больше, чем 2 точки\n if (getDotsCount(newValue) > 2) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Форматируем введенное значение (добавляем точки)\n const formattedValue = format(newValue);\n const date = parseDateString(formattedValue);\n\n // Управляем кареткой, если она находится не в конце инпута\n if (caretPos !== newValue.length) {\n if (formattedValue === value) {\n moveCaretTo(caretPos);\n } else if (newValue.length - formattedValue.length === 1) {\n moveCaretTo(caretPos);\n } else if (\n formattedValue.length - newValue.length === 1 &&\n getDotsCount(formattedValue) > getDotsCount(newValue)\n ) {\n moveCaretTo(caretPos);\n }\n }\n\n setValue(formattedValue);\n\n if (onChange) onChange(event, { date, value: formattedValue });\n\n if (isCompleteDateInput(formattedValue)) {\n const valid = formattedValue.length > 0 && isValid(formattedValue);\n\n if (!valid) return;\n\n if (onComplete) onComplete(event, { date, value: formattedValue });\n }\n };\n\n const handleNativeInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const newDate = parseDateString(event.target.value, NATIVE_DATE_FORMAT);\n const newValue = event.target.value === '' ? '' : formatDate(newDate);\n\n setValue(newValue);\n\n if (onComplete) onComplete(event, { date: newDate, value: newValue });\n if (onChange) onChange(event, { date: newDate, value: newValue });\n };\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n if (onBlur) onBlur(event);\n };\n\n useEffect(() => {\n if (mobileMode === 'native' && isInputDateSupported()) {\n setShouldRenderNative(true);\n }\n }, [mobileMode]);\n\n useEffect(() => {\n if (typeof propValue !== 'undefined') {\n setValue(propValue);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [propValue]);\n\n return (\n <Input\n {...restProps}\n ref={mergeRefs([ref, inputRef])}\n value={value}\n inputMode='decimal'\n pattern='[0-9\\.]*'\n onChange={handleChange}\n onBlur={handleBlur}\n placeholder='ДД.ММ.ГГГГ'\n error={error}\n rightAddons={\n <React.Fragment>\n {rightAddons}\n\n {shouldRenderNative && (\n <input\n type='date'\n ref={ref}\n defaultValue={defaultValue}\n onChange={handleNativeInputChange}\n className={styles.nativeInput}\n />\n )}\n </React.Fragment>\n }\n />\n );\n },\n);\n\nfunction getDotsCount(value: string) {\n return (value.match(/\\./g) || []).length;\n}\n"],"names":[],"mappings":"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"}
|
package/esm/index.css
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
:root {
|
|
2
2
|
--gap-0: 0px;
|
|
3
3
|
}
|
|
4
|
-
.date-
|
|
4
|
+
.date-input__nativeInput_1pf6x {
|
|
5
5
|
opacity: 0;
|
|
6
6
|
position: absolute;
|
|
7
7
|
top: var(--gap-0);
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
appearance: none;
|
|
14
14
|
z-index: 1;
|
|
15
15
|
}
|
|
16
|
-
.date-
|
|
16
|
+
.date-input__nativeInput_1pf6x::-webkit-calendar-picker-indicator {
|
|
17
17
|
display: none;
|
|
18
18
|
}
|
|
19
|
-
.date-
|
|
19
|
+
.date-input__nativeInput_1pf6x::-webkit-inner-spin-button {
|
|
20
20
|
display: none;
|
|
21
21
|
}
|
package/esm/index.module.css.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/
|
|
1
|
+
{"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n.nativeInput {\n opacity: 0;\n position: absolute;\n top: var(--gap-0);\n left: var(--gap-0);\n width: 100%;\n height: 100%;\n appearance: none;\n z-index: 1;\n\n &::-webkit-calendar-picker-indicator {\n display: none;\n }\n &::-webkit-inner-spin-button {\n display: none;\n }\n}\n"],"names":[],"mappings":";;AAEgB,aAAe,CAAC,aAAa,CAAC,+BAA+B,CAAC;;;;"}
|
package/index.css
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
:root {
|
|
2
2
|
--gap-0: 0px;
|
|
3
3
|
}
|
|
4
|
-
.date-
|
|
4
|
+
.date-input__nativeInput_1pf6x {
|
|
5
5
|
opacity: 0;
|
|
6
6
|
position: absolute;
|
|
7
7
|
top: var(--gap-0);
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
appearance: none;
|
|
14
14
|
z-index: 1;
|
|
15
15
|
}
|
|
16
|
-
.date-
|
|
16
|
+
.date-input__nativeInput_1pf6x::-webkit-calendar-picker-indicator {
|
|
17
17
|
display: none;
|
|
18
18
|
}
|
|
19
|
-
.date-
|
|
19
|
+
.date-input__nativeInput_1pf6x::-webkit-inner-spin-button {
|
|
20
20
|
display: none;
|
|
21
21
|
}
|
package/index.module.css.js
CHANGED
package/index.module.css.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/
|
|
1
|
+
{"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n.nativeInput {\n opacity: 0;\n position: absolute;\n top: var(--gap-0);\n left: var(--gap-0);\n width: 100%;\n height: 100%;\n appearance: none;\n z-index: 1;\n\n &::-webkit-calendar-picker-indicator {\n display: none;\n }\n &::-webkit-inner-spin-button {\n display: none;\n }\n}\n"],"names":[],"mappings":";;;;AAEgB,aAAe,CAAC,aAAa,CAAC,+BAA+B,CAAC;;;;"}
|
package/modern/Component.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { type ChangeEvent } from 'react';
|
|
2
2
|
import { type InputProps } from '@alfalab/core-components-input/modern';
|
|
3
|
-
export
|
|
3
|
+
export type DateInputProps = Omit<InputProps, 'onChange'> & {
|
|
4
4
|
/**
|
|
5
5
|
* Управление нативным режимом на мобильных устройствах
|
|
6
6
|
*/
|
|
@@ -28,19 +28,19 @@ export declare const DateInput: React.ForwardRefExoticComponent<Omit<InputProps,
|
|
|
28
28
|
/**
|
|
29
29
|
* Управление нативным режимом на мобильных устройствах
|
|
30
30
|
*/
|
|
31
|
-
mobileMode?: "input" | "native"
|
|
31
|
+
mobileMode?: "input" | "native";
|
|
32
32
|
/**
|
|
33
33
|
* Обработчик изменения значения
|
|
34
34
|
*/
|
|
35
|
-
onChange?: (
|
|
35
|
+
onChange?: (event: ChangeEvent<HTMLInputElement>, payload: {
|
|
36
36
|
date: Date;
|
|
37
37
|
value: string;
|
|
38
|
-
}) => void
|
|
38
|
+
}) => void;
|
|
39
39
|
/**
|
|
40
40
|
* Обработчик окончания ввода
|
|
41
41
|
*/
|
|
42
|
-
onComplete?: (
|
|
42
|
+
onComplete?: (event: ChangeEvent<HTMLInputElement>, payload: {
|
|
43
43
|
date: Date;
|
|
44
44
|
value: string;
|
|
45
|
-
}) => void
|
|
45
|
+
}) => void;
|
|
46
46
|
} & React.RefAttributes<HTMLInputElement>>;
|
package/modern/Component.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n type FocusEvent,\n forwardRef,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\n\nimport { Input, type InputProps } from '@alfalab/core-components-input';\n\nimport {\n format,\n formatDate,\n isCompleteDateInput,\n isInputDateSupported,\n isValid,\n NATIVE_DATE_FORMAT,\n parseDateString,\n} from './utils';\n\nimport styles from './index.module.css';\n\nexport type DateInputProps = Omit<InputProps, 'onChange'> & {\n /**\n * Управление нативным режимом на мобильных устройствах\n */\n mobileMode?: 'input' | 'native';\n\n /**\n * Обработчик изменения значения\n */\n onChange?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n\n /**\n * Обработчик окончания ввода\n */\n onComplete?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n};\n\n/**\n * @deprecated\n * use UniversalDateInput instead\n */\nexport const DateInput = forwardRef<HTMLInputElement, DateInputProps>(\n (\n {\n mobileMode = 'input',\n defaultValue = '',\n rightAddons,\n error,\n value: propValue,\n onBlur,\n onChange,\n onComplete,\n ...restProps\n },\n ref,\n ) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [shouldRenderNative, setShouldRenderNative] = useState(false);\n\n const [value, setValue] = useState(propValue || defaultValue);\n\n const moveCaretTo = (pos: number) => {\n requestAnimationFrame(() => {\n inputRef.current?.setSelectionRange(pos, pos);\n });\n };\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const { value: newValue } = event.target;\n const caretPos = event.target.selectionStart || 0;\n\n // Позволяем вводить только цифры и точки\n if (/[^\\d.]/.test(newValue)) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Не даем вводить больше, чем 2 точки\n if (getDotsCount(newValue) > 2) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Форматируем введенное значение (добавляем точки)\n const formattedValue = format(newValue);\n const date = parseDateString(formattedValue);\n\n // Управляем кареткой, если она находится не в конце инпута\n if (caretPos !== newValue.length) {\n if (formattedValue === value) {\n moveCaretTo(caretPos);\n } else if (newValue.length - formattedValue.length === 1) {\n moveCaretTo(caretPos);\n } else if (\n formattedValue.length - newValue.length === 1 &&\n getDotsCount(formattedValue) > getDotsCount(newValue)\n ) {\n moveCaretTo(caretPos);\n }\n }\n\n setValue(formattedValue);\n\n if (onChange) onChange(event, { date, value: formattedValue });\n\n if (isCompleteDateInput(formattedValue)) {\n const valid = formattedValue.length > 0 && isValid(formattedValue);\n\n if (!valid) return;\n\n if (onComplete) onComplete(event, { date, value: formattedValue });\n }\n };\n\n const handleNativeInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const newDate = parseDateString(event.target.value, NATIVE_DATE_FORMAT);\n const newValue = event.target.value === '' ? '' : formatDate(newDate);\n\n setValue(newValue);\n\n if (onComplete) onComplete(event, { date: newDate, value: newValue });\n if (onChange) onChange(event, { date: newDate, value: newValue });\n };\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n if (onBlur) onBlur(event);\n };\n\n useEffect(() => {\n if (mobileMode === 'native' && isInputDateSupported()) {\n setShouldRenderNative(true);\n }\n }, [mobileMode]);\n\n useEffect(() => {\n if (typeof propValue !== 'undefined') {\n setValue(propValue);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [propValue]);\n\n return (\n <Input\n {...restProps}\n ref={mergeRefs([ref, inputRef])}\n value={value}\n inputMode='decimal'\n pattern='[0-9\\.]*'\n onChange={handleChange}\n onBlur={handleBlur}\n placeholder='ДД.ММ.ГГГГ'\n error={error}\n rightAddons={\n <React.Fragment>\n {rightAddons}\n\n {shouldRenderNative && (\n <input\n type='date'\n ref={ref}\n defaultValue={defaultValue}\n onChange={handleNativeInputChange}\n className={styles.nativeInput}\n />\n )}\n </React.Fragment>\n }\n />\n );\n },\n);\n\nfunction getDotsCount(value: string) {\n return (value.match(/\\./g) || []).length;\n}\n"],"names":[],"mappings":";;;;;;;AA+CA;;;AAGG;AACU,MAAA,SAAS,GAAG,UAAU,CAC/B,CACI,EACI,UAAU,GAAG,OAAO,EACpB,YAAY,GAAG,EAAE,EACjB,WAAW,EACX,KAAK,EACL,KAAK,EAAE,SAAS,EAChB,MAAM,EACN,QAAQ,EACR,UAAU,EACV,GAAG,SAAS,EACf,EACD,GAAG,KACH;AACA,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAmB,IAAI,CAAC;IAE/C,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;AAEnE,IAAA,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,SAAS,IAAI,YAAY,CAAC;AAE7D,IAAA,MAAM,WAAW,GAAG,CAAC,GAAW,KAAI;QAChC,qBAAqB,CAAC,MAAK;YACvB,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC;AACjD,SAAC,CAAC;AACN,KAAC;AAED,IAAA,MAAM,YAAY,GAAG,CAAC,KAAoC,KAAI;QAC1D,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,MAAM;QACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC;;AAGjD,QAAA,IAAI,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AACzB,YAAA,WAAW,CAAC,QAAQ,GAAG,CAAC,CAAC;YAEzB
|
|
1
|
+
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n type FocusEvent,\n forwardRef,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\n\nimport { Input, type InputProps } from '@alfalab/core-components-input';\n\nimport {\n format,\n formatDate,\n isCompleteDateInput,\n isInputDateSupported,\n isValid,\n NATIVE_DATE_FORMAT,\n parseDateString,\n} from './utils';\n\nimport styles from './index.module.css';\n\nexport type DateInputProps = Omit<InputProps, 'onChange'> & {\n /**\n * Управление нативным режимом на мобильных устройствах\n */\n mobileMode?: 'input' | 'native';\n\n /**\n * Обработчик изменения значения\n */\n onChange?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n\n /**\n * Обработчик окончания ввода\n */\n onComplete?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n};\n\n/**\n * @deprecated\n * use UniversalDateInput instead\n */\nexport const DateInput = forwardRef<HTMLInputElement, DateInputProps>(\n (\n {\n mobileMode = 'input',\n defaultValue = '',\n rightAddons,\n error,\n value: propValue,\n onBlur,\n onChange,\n onComplete,\n ...restProps\n },\n ref,\n ) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [shouldRenderNative, setShouldRenderNative] = useState(false);\n\n const [value, setValue] = useState(propValue || defaultValue);\n\n const moveCaretTo = (pos: number) => {\n requestAnimationFrame(() => {\n inputRef.current?.setSelectionRange(pos, pos);\n });\n };\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const { value: newValue } = event.target;\n const caretPos = event.target.selectionStart || 0;\n\n // Позволяем вводить только цифры и точки\n if (/[^\\d.]/.test(newValue)) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Не даем вводить больше, чем 2 точки\n if (getDotsCount(newValue) > 2) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Форматируем введенное значение (добавляем точки)\n const formattedValue = format(newValue);\n const date = parseDateString(formattedValue);\n\n // Управляем кареткой, если она находится не в конце инпута\n if (caretPos !== newValue.length) {\n if (formattedValue === value) {\n moveCaretTo(caretPos);\n } else if (newValue.length - formattedValue.length === 1) {\n moveCaretTo(caretPos);\n } else if (\n formattedValue.length - newValue.length === 1 &&\n getDotsCount(formattedValue) > getDotsCount(newValue)\n ) {\n moveCaretTo(caretPos);\n }\n }\n\n setValue(formattedValue);\n\n if (onChange) onChange(event, { date, value: formattedValue });\n\n if (isCompleteDateInput(formattedValue)) {\n const valid = formattedValue.length > 0 && isValid(formattedValue);\n\n if (!valid) return;\n\n if (onComplete) onComplete(event, { date, value: formattedValue });\n }\n };\n\n const handleNativeInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const newDate = parseDateString(event.target.value, NATIVE_DATE_FORMAT);\n const newValue = event.target.value === '' ? '' : formatDate(newDate);\n\n setValue(newValue);\n\n if (onComplete) onComplete(event, { date: newDate, value: newValue });\n if (onChange) onChange(event, { date: newDate, value: newValue });\n };\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n if (onBlur) onBlur(event);\n };\n\n useEffect(() => {\n if (mobileMode === 'native' && isInputDateSupported()) {\n setShouldRenderNative(true);\n }\n }, [mobileMode]);\n\n useEffect(() => {\n if (typeof propValue !== 'undefined') {\n setValue(propValue);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [propValue]);\n\n return (\n <Input\n {...restProps}\n ref={mergeRefs([ref, inputRef])}\n value={value}\n inputMode='decimal'\n pattern='[0-9\\.]*'\n onChange={handleChange}\n onBlur={handleBlur}\n placeholder='ДД.ММ.ГГГГ'\n error={error}\n rightAddons={\n <React.Fragment>\n {rightAddons}\n\n {shouldRenderNative && (\n <input\n type='date'\n ref={ref}\n defaultValue={defaultValue}\n onChange={handleNativeInputChange}\n className={styles.nativeInput}\n />\n )}\n </React.Fragment>\n }\n />\n );\n },\n);\n\nfunction getDotsCount(value: string) {\n return (value.match(/\\./g) || []).length;\n}\n"],"names":[],"mappings":"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"}
|
package/modern/index.css
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
:root {
|
|
2
2
|
--gap-0: 0px;
|
|
3
3
|
}
|
|
4
|
-
.date-
|
|
4
|
+
.date-input__nativeInput_1pf6x {
|
|
5
5
|
opacity: 0;
|
|
6
6
|
position: absolute;
|
|
7
7
|
top: var(--gap-0);
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
appearance: none;
|
|
14
14
|
z-index: 1;
|
|
15
15
|
}
|
|
16
|
-
.date-
|
|
16
|
+
.date-input__nativeInput_1pf6x::-webkit-calendar-picker-indicator {
|
|
17
17
|
display: none;
|
|
18
18
|
}
|
|
19
|
-
.date-
|
|
19
|
+
.date-input__nativeInput_1pf6x::-webkit-inner-spin-button {
|
|
20
20
|
display: none;
|
|
21
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/
|
|
1
|
+
{"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n.nativeInput {\n opacity: 0;\n position: absolute;\n top: var(--gap-0);\n left: var(--gap-0);\n width: 100%;\n height: 100%;\n appearance: none;\n z-index: 1;\n\n &::-webkit-calendar-picker-indicator {\n display: none;\n }\n &::-webkit-inner-spin-button {\n display: none;\n }\n}\n"],"names":[],"mappings":";;AAEgB,eAAe,CAAC,aAAa,CAAC,+BAA+B,CAAC;;;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { type ChangeEvent } from 'react';
|
|
2
2
|
import { type InputProps } from '@alfalab/core-components-input/moderncssm';
|
|
3
|
-
export
|
|
3
|
+
export type DateInputProps = Omit<InputProps, 'onChange'> & {
|
|
4
4
|
/**
|
|
5
5
|
* Управление нативным режимом на мобильных устройствах
|
|
6
6
|
*/
|
|
@@ -28,19 +28,19 @@ export declare const DateInput: React.ForwardRefExoticComponent<Omit<InputProps,
|
|
|
28
28
|
/**
|
|
29
29
|
* Управление нативным режимом на мобильных устройствах
|
|
30
30
|
*/
|
|
31
|
-
mobileMode?: "input" | "native"
|
|
31
|
+
mobileMode?: "input" | "native";
|
|
32
32
|
/**
|
|
33
33
|
* Обработчик изменения значения
|
|
34
34
|
*/
|
|
35
|
-
onChange?: (
|
|
35
|
+
onChange?: (event: ChangeEvent<HTMLInputElement>, payload: {
|
|
36
36
|
date: Date;
|
|
37
37
|
value: string;
|
|
38
|
-
}) => void
|
|
38
|
+
}) => void;
|
|
39
39
|
/**
|
|
40
40
|
* Обработчик окончания ввода
|
|
41
41
|
*/
|
|
42
|
-
onComplete?: (
|
|
42
|
+
onComplete?: (event: ChangeEvent<HTMLInputElement>, payload: {
|
|
43
43
|
date: Date;
|
|
44
44
|
value: string;
|
|
45
|
-
}) => void
|
|
45
|
+
}) => void;
|
|
46
46
|
} & React.RefAttributes<HTMLInputElement>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n type FocusEvent,\n forwardRef,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\n\nimport { Input, type InputProps } from '@alfalab/core-components-input';\n\nimport {\n format,\n formatDate,\n isCompleteDateInput,\n isInputDateSupported,\n isValid,\n NATIVE_DATE_FORMAT,\n parseDateString,\n} from './utils';\n\nimport styles from './index.module.css';\n\nexport type DateInputProps = Omit<InputProps, 'onChange'> & {\n /**\n * Управление нативным режимом на мобильных устройствах\n */\n mobileMode?: 'input' | 'native';\n\n /**\n * Обработчик изменения значения\n */\n onChange?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n\n /**\n * Обработчик окончания ввода\n */\n onComplete?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n};\n\n/**\n * @deprecated\n * use UniversalDateInput instead\n */\nexport const DateInput = forwardRef<HTMLInputElement, DateInputProps>(\n (\n {\n mobileMode = 'input',\n defaultValue = '',\n rightAddons,\n error,\n value: propValue,\n onBlur,\n onChange,\n onComplete,\n ...restProps\n },\n ref,\n ) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [shouldRenderNative, setShouldRenderNative] = useState(false);\n\n const [value, setValue] = useState(propValue || defaultValue);\n\n const moveCaretTo = (pos: number) => {\n requestAnimationFrame(() => {\n inputRef.current?.setSelectionRange(pos, pos);\n });\n };\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const { value: newValue } = event.target;\n const caretPos = event.target.selectionStart || 0;\n\n // Позволяем вводить только цифры и точки\n if (/[^\\d.]/.test(newValue)) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Не даем вводить больше, чем 2 точки\n if (getDotsCount(newValue) > 2) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Форматируем введенное значение (добавляем точки)\n const formattedValue = format(newValue);\n const date = parseDateString(formattedValue);\n\n // Управляем кареткой, если она находится не в конце инпута\n if (caretPos !== newValue.length) {\n if (formattedValue === value) {\n moveCaretTo(caretPos);\n } else if (newValue.length - formattedValue.length === 1) {\n moveCaretTo(caretPos);\n } else if (\n formattedValue.length - newValue.length === 1 &&\n getDotsCount(formattedValue) > getDotsCount(newValue)\n ) {\n moveCaretTo(caretPos);\n }\n }\n\n setValue(formattedValue);\n\n if (onChange) onChange(event, { date, value: formattedValue });\n\n if (isCompleteDateInput(formattedValue)) {\n const valid = formattedValue.length > 0 && isValid(formattedValue);\n\n if (!valid) return;\n\n if (onComplete) onComplete(event, { date, value: formattedValue });\n }\n };\n\n const handleNativeInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const newDate = parseDateString(event.target.value, NATIVE_DATE_FORMAT);\n const newValue = event.target.value === '' ? '' : formatDate(newDate);\n\n setValue(newValue);\n\n if (onComplete) onComplete(event, { date: newDate, value: newValue });\n if (onChange) onChange(event, { date: newDate, value: newValue });\n };\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n if (onBlur) onBlur(event);\n };\n\n useEffect(() => {\n if (mobileMode === 'native' && isInputDateSupported()) {\n setShouldRenderNative(true);\n }\n }, [mobileMode]);\n\n useEffect(() => {\n if (typeof propValue !== 'undefined') {\n setValue(propValue);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [propValue]);\n\n return (\n <Input\n {...restProps}\n ref={mergeRefs([ref, inputRef])}\n value={value}\n inputMode='decimal'\n pattern='[0-9\\.]*'\n onChange={handleChange}\n onBlur={handleBlur}\n placeholder='ДД.ММ.ГГГГ'\n error={error}\n rightAddons={\n <React.Fragment>\n {rightAddons}\n\n {shouldRenderNative && (\n <input\n type='date'\n ref={ref}\n defaultValue={defaultValue}\n onChange={handleNativeInputChange}\n className={styles.nativeInput}\n />\n )}\n </React.Fragment>\n }\n />\n );\n },\n);\n\nfunction getDotsCount(value: string) {\n return (value.match(/\\./g) || []).length;\n}\n"],"names":[],"mappings":";;;;;;;AA+CA;;;AAGG;AACU,MAAA,SAAS,GAAG,UAAU,CAC/B,CACI,EACI,UAAU,GAAG,OAAO,EACpB,YAAY,GAAG,EAAE,EACjB,WAAW,EACX,KAAK,EACL,KAAK,EAAE,SAAS,EAChB,MAAM,EACN,QAAQ,EACR,UAAU,EACV,GAAG,SAAS,EACf,EACD,GAAG,KACH;AACA,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAmB,IAAI,CAAC;IAE/C,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;AAEnE,IAAA,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,SAAS,IAAI,YAAY,CAAC;AAE7D,IAAA,MAAM,WAAW,GAAG,CAAC,GAAW,KAAI;QAChC,qBAAqB,CAAC,MAAK;YACvB,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC;AACjD,SAAC,CAAC;AACN,KAAC;AAED,IAAA,MAAM,YAAY,GAAG,CAAC,KAAoC,KAAI;QAC1D,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,MAAM;QACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC;;AAGjD,QAAA,IAAI,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AACzB,YAAA,WAAW,CAAC,QAAQ,GAAG,CAAC,CAAC;YAEzB
|
|
1
|
+
{"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n type FocusEvent,\n forwardRef,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport mergeRefs from 'react-merge-refs';\n\nimport { Input, type InputProps } from '@alfalab/core-components-input';\n\nimport {\n format,\n formatDate,\n isCompleteDateInput,\n isInputDateSupported,\n isValid,\n NATIVE_DATE_FORMAT,\n parseDateString,\n} from './utils';\n\nimport styles from './index.module.css';\n\nexport type DateInputProps = Omit<InputProps, 'onChange'> & {\n /**\n * Управление нативным режимом на мобильных устройствах\n */\n mobileMode?: 'input' | 'native';\n\n /**\n * Обработчик изменения значения\n */\n onChange?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n\n /**\n * Обработчик окончания ввода\n */\n onComplete?: (\n event: ChangeEvent<HTMLInputElement>,\n payload: { date: Date; value: string },\n ) => void;\n};\n\n/**\n * @deprecated\n * use UniversalDateInput instead\n */\nexport const DateInput = forwardRef<HTMLInputElement, DateInputProps>(\n (\n {\n mobileMode = 'input',\n defaultValue = '',\n rightAddons,\n error,\n value: propValue,\n onBlur,\n onChange,\n onComplete,\n ...restProps\n },\n ref,\n ) => {\n const inputRef = useRef<HTMLInputElement>(null);\n\n const [shouldRenderNative, setShouldRenderNative] = useState(false);\n\n const [value, setValue] = useState(propValue || defaultValue);\n\n const moveCaretTo = (pos: number) => {\n requestAnimationFrame(() => {\n inputRef.current?.setSelectionRange(pos, pos);\n });\n };\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n const { value: newValue } = event.target;\n const caretPos = event.target.selectionStart || 0;\n\n // Позволяем вводить только цифры и точки\n if (/[^\\d.]/.test(newValue)) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Не даем вводить больше, чем 2 точки\n if (getDotsCount(newValue) > 2) {\n moveCaretTo(caretPos - 1);\n\n return;\n }\n\n // Форматируем введенное значение (добавляем точки)\n const formattedValue = format(newValue);\n const date = parseDateString(formattedValue);\n\n // Управляем кареткой, если она находится не в конце инпута\n if (caretPos !== newValue.length) {\n if (formattedValue === value) {\n moveCaretTo(caretPos);\n } else if (newValue.length - formattedValue.length === 1) {\n moveCaretTo(caretPos);\n } else if (\n formattedValue.length - newValue.length === 1 &&\n getDotsCount(formattedValue) > getDotsCount(newValue)\n ) {\n moveCaretTo(caretPos);\n }\n }\n\n setValue(formattedValue);\n\n if (onChange) onChange(event, { date, value: formattedValue });\n\n if (isCompleteDateInput(formattedValue)) {\n const valid = formattedValue.length > 0 && isValid(formattedValue);\n\n if (!valid) return;\n\n if (onComplete) onComplete(event, { date, value: formattedValue });\n }\n };\n\n const handleNativeInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const newDate = parseDateString(event.target.value, NATIVE_DATE_FORMAT);\n const newValue = event.target.value === '' ? '' : formatDate(newDate);\n\n setValue(newValue);\n\n if (onComplete) onComplete(event, { date: newDate, value: newValue });\n if (onChange) onChange(event, { date: newDate, value: newValue });\n };\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n if (onBlur) onBlur(event);\n };\n\n useEffect(() => {\n if (mobileMode === 'native' && isInputDateSupported()) {\n setShouldRenderNative(true);\n }\n }, [mobileMode]);\n\n useEffect(() => {\n if (typeof propValue !== 'undefined') {\n setValue(propValue);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [propValue]);\n\n return (\n <Input\n {...restProps}\n ref={mergeRefs([ref, inputRef])}\n value={value}\n inputMode='decimal'\n pattern='[0-9\\.]*'\n onChange={handleChange}\n onBlur={handleBlur}\n placeholder='ДД.ММ.ГГГГ'\n error={error}\n rightAddons={\n <React.Fragment>\n {rightAddons}\n\n {shouldRenderNative && (\n <input\n type='date'\n ref={ref}\n defaultValue={defaultValue}\n onChange={handleNativeInputChange}\n className={styles.nativeInput}\n />\n )}\n </React.Fragment>\n }\n />\n );\n },\n);\n\nfunction getDotsCount(value: string) {\n return (value.match(/\\./g) || []).length;\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfalab/core-components-date-input",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.5",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"license": "MIT",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"main": "index.js",
|
|
11
11
|
"module": "./esm/index.js",
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@alfalab/core-components-input": "^17.1.
|
|
13
|
+
"@alfalab/core-components-input": "^17.1.3",
|
|
14
14
|
"date-fns": "^4.1.0",
|
|
15
15
|
"react-merge-refs": "^1.1.0",
|
|
16
16
|
"tslib": "^2.4.0"
|
|
@@ -24,5 +24,5 @@
|
|
|
24
24
|
"directory": "dist"
|
|
25
25
|
},
|
|
26
26
|
"themesVersion": "15.0.2",
|
|
27
|
-
"varsVersion": "11.0.
|
|
27
|
+
"varsVersion": "11.0.2"
|
|
28
28
|
}
|
package/src/index.module.css
CHANGED