@skbkontur/react-ui 6.1.4-6d143.0 → 6.1.4-6ff90.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/MaskedInput/MaskedInput.d.ts +1 -1
- package/components/MaskedInput/MaskedInput.js +5 -5
- package/components/MaskedInput/MaskedInput.js.map +1 -1
- package/components/MaskedInputV2/MaskedInputV2.d.ts +1 -1
- package/components/MaskedInputV2/MaskedInputV2.js +2 -2
- package/components/MaskedInputV2/MaskedInputV2.js.map +1 -1
- package/components/MaskedInputV2/internal/showOverlay.js +3 -1
- package/components/MaskedInputV2/internal/showOverlay.js.map +1 -1
- package/components/MaskedInputV2/internal/useInputOverflow.js +5 -1
- package/components/MaskedInputV2/internal/useInputOverflow.js.map +1 -1
- package/internal/Popup/PopupPin.js +8 -6
- package/internal/Popup/PopupPin.js.map +1 -1
- package/internal/themes/BasicTheme.d.ts +162 -0
- package/internal/themes/BasicTheme.js +162 -0
- package/internal/themes/BasicTheme.js.map +1 -1
- package/lib/featureFlagsContext/ReactUIFeatureFlagsContext.d.ts +1 -2
- package/lib/featureFlagsContext/ReactUIFeatureFlagsContext.js +1 -1
- package/lib/featureFlagsContext/ReactUIFeatureFlagsContext.js.map +1 -1
- package/package.json +1 -1
|
@@ -51,6 +51,6 @@ export interface MaskedInputProps extends MaskedProps, Omit<InputProps, 'showCle
|
|
|
51
51
|
}
|
|
52
52
|
/** Поле ввода, которое ограничивает формат вводимого значения по заданной маске. Такое поле облегчает пользователю ввод и снижает количество ошибок.
|
|
53
53
|
*
|
|
54
|
-
* Для
|
|
54
|
+
* По умолчанию используется исправленная реализация MaskedInputV2. Для legacy-поведения включите фичафлаг `maskedInputUseLegacyBehavior` в {@link ReactUIFeatureFlagsContext}.
|
|
55
55
|
*/
|
|
56
56
|
export declare const MaskedInput: import("../../lib/forwardRefAndName.js").ReactUIComponentWithRef<Input, MaskedInputProps> & Record<never, never>;
|
|
@@ -30,13 +30,13 @@ export var getSafeMaskInputType = function (type) {
|
|
|
30
30
|
};
|
|
31
31
|
/** Поле ввода, которое ограничивает формат вводимого значения по заданной маске. Такое поле облегчает пользователю ввод и снижает количество ошибок.
|
|
32
32
|
*
|
|
33
|
-
* Для
|
|
33
|
+
* По умолчанию используется исправленная реализация MaskedInputV2. Для legacy-поведения включите фичафлаг `maskedInputUseLegacyBehavior` в {@link ReactUIFeatureFlagsContext}.
|
|
34
34
|
*/
|
|
35
35
|
export var MaskedInput = forwardRefAndName('MaskedInput', function MaskedInput(props, ref) {
|
|
36
|
-
var
|
|
37
|
-
if (
|
|
38
|
-
return React.createElement(
|
|
36
|
+
var maskedInputUseLegacyBehavior = useContext(ReactUIFeatureFlagsContext).maskedInputUseLegacyBehavior;
|
|
37
|
+
if (maskedInputUseLegacyBehavior) {
|
|
38
|
+
return React.createElement(MaskedInputLegacy, __assign({ ref: ref }, props));
|
|
39
39
|
}
|
|
40
|
-
return React.createElement(
|
|
40
|
+
return React.createElement(MaskedInputV2, __assign({ ref: ref, __fromMaskedInputFacade: true }, props));
|
|
41
41
|
});
|
|
42
42
|
//# sourceMappingURL=MaskedInput.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MaskedInput.js","sourceRoot":"","sources":["MaskedInput.tsx"],"names":[],"mappings":";;;;;;;;;;;AACA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAG1C,OAAO,EAAE,0BAA0B,EAAE,MAAM,wCAAwC,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,OAAO,EAAE,aAAa,EAA2B,MAAM,2BAA2B,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AA0D3D,MAAM,CAAC,IAAM,oBAAoB,GAAG,UAAC,IAAgB;IACnD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IAED,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ,CAAC;QACd,KAAK,MAAM,CAAC;QACZ,KAAK,MAAM,CAAC;QACZ,KAAK,UAAU;YACb,OAAO,MAAM,CAAC;QAChB;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC,CAAC;AAYF;;;GAGG;AACH,MAAM,CAAC,IAAM,WAAW,GAAG,iBAAiB,CAC1C,aAAa,EACb,SAAS,WAAW,CAAC,KAAuB,EAAE,GAAsB;IAC1D,IAAA,
|
|
1
|
+
{"version":3,"file":"MaskedInput.js","sourceRoot":"","sources":["MaskedInput.tsx"],"names":[],"mappings":";;;;;;;;;;;AACA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAG1C,OAAO,EAAE,0BAA0B,EAAE,MAAM,wCAAwC,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,OAAO,EAAE,aAAa,EAA2B,MAAM,2BAA2B,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AA0D3D,MAAM,CAAC,IAAM,oBAAoB,GAAG,UAAC,IAAgB;IACnD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IAED,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ,CAAC;QACd,KAAK,MAAM,CAAC;QACZ,KAAK,MAAM,CAAC;QACZ,KAAK,UAAU;YACb,OAAO,MAAM,CAAC;QAChB;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC,CAAC;AAYF;;;GAGG;AACH,MAAM,CAAC,IAAM,WAAW,GAAG,iBAAiB,CAC1C,aAAa,EACb,SAAS,WAAW,CAAC,KAAuB,EAAE,GAAsB;IAC1D,IAAA,4BAA4B,GAAK,UAAU,CAAC,0BAA0B,CAAC,6BAA3C,CAA4C;IAEhF,IAAI,4BAA4B,EAAE,CAAC;QACjC,OAAO,oBAAC,iBAAiB,aAAC,GAAG,EAAE,GAAG,IAAM,KAAK,EAAI,CAAC;IACpD,CAAC;IAED,OAAO,oBAAC,aAAa,aAAC,GAAG,EAAE,GAAG,EAAE,uBAAuB,UAAM,KAA4B,EAAI,CAAC;AAChG,CAAC,CACF,CAAC","sourcesContent":["import type { IMaskInputProps } from '@skbkontur/react-imask';\nimport React, { useContext } from 'react';\nimport type { Ref } from 'react';\n\nimport { ReactUIFeatureFlagsContext } from '../../lib/featureFlagsContext/index.js';\nimport { forwardRefAndName } from '../../lib/forwardRefAndName.js';\nimport type { Input, InputProps, InputType } from '../Input/index.js';\nimport { MaskedInputV2, type MaskedInputV2Props } from '../MaskedInputV2/index.js';\nimport { MaskedInputLegacy } from './MaskedInputLegacy.js';\n\nexport type MaskedInputOnBeforePasteValue = (value: string) => string;\n\nexport interface MaskedProps {\n /** Шаблон ввода, определяющий допустимые символы. */\n mask: string;\n\n /** Плейсхолдер, который отображается на месте ещё не введённых пользователем символов.\n * @default _ */\n maskChar?: string;\n\n /** Словарь правил для настройки маски, где:\n * ключ — символ для использования в маске;\n * значение — регулярка-правило.\n * @default { '9': '[0-9]', 'a': '[A-Za-z]', '*': '[A-Za-z0-9]' } */\n formatChars?: Record<string, string>;\n\n /** Всегда показывать символы маски, независимо от фокуса в поле.\n * @default false */\n alwaysShowMask?: boolean;\n\n /** Событие некорректного ввода.\n * Вторым аргументом передаётся метод вспыхивания рамки поля.\n *\n * Если обработчик не задан, то при событии рамка всегда вспыхивает.\n *\n * @param value значение поля\n * @param blink метод вспыхивания рамки поля\n */\n onUnexpectedInput?: (value: string, blink: () => void) => void;\n\n /**\n * Событие перед вставкой текста в поле.\n * Вызывается с аргументом value — текст из буфера.\n *\n * Обработчик должен вернуть текст — он попадёт в поле.\n *\n * @param value значение вставки.\n */\n onBeforePasteValue?: MaskedInputOnBeforePasteValue;\n\n /** Убирает из value символы маски, которые пользователь не вводил.\n * @default false */\n unmask?: boolean;\n\n /** Раскрашивает символы маски.\n * @default true\n * @ignore */\n colored?: boolean;\n\n /** Задает пропсы для компонента `IMaskInput`. Необходимы для юнит-тестов\n * @ignore */\n imaskProps?: IMaskInputProps<HTMLInputElement>;\n}\n\nexport type MaskInputType = Exclude<InputType, 'number' | 'date' | 'time' | 'password'>;\n\nexport const getSafeMaskInputType = (type?: InputType): MaskInputType | undefined => {\n if (!type) {\n return type;\n }\n\n switch (type) {\n case 'number':\n case 'date':\n case 'time':\n case 'password':\n return 'text';\n default:\n return type;\n }\n};\n\nexport interface MaskedInputProps\n extends\n MaskedProps,\n Omit<\n InputProps,\n 'showClearIcon' | 'mask' | 'maxLength' | 'type' | 'alwaysShowMask' | 'onUnexpectedInput' | 'maskChar'\n > {\n type?: MaskInputType;\n}\n\n/** Поле ввода, которое ограничивает формат вводимого значения по заданной маске. Такое поле облегчает пользователю ввод и снижает количество ошибок.\n *\n * По умолчанию используется исправленная реализация MaskedInputV2. Для legacy-поведения включите фичафлаг `maskedInputUseLegacyBehavior` в {@link ReactUIFeatureFlagsContext}.\n */\nexport const MaskedInput = forwardRefAndName(\n 'MaskedInput',\n function MaskedInput(props: MaskedInputProps, ref: Ref<Input | null>) {\n const { maskedInputUseLegacyBehavior } = useContext(ReactUIFeatureFlagsContext);\n\n if (maskedInputUseLegacyBehavior) {\n return <MaskedInputLegacy ref={ref} {...props} />;\n }\n\n return <MaskedInputV2 ref={ref} __fromMaskedInputFacade {...(props as MaskedInputV2Props)} />;\n },\n);\n"]}
|
|
@@ -53,6 +53,6 @@ export interface MaskedInputV2Props extends MaskedInputV2MaskedProps, Omit<Input
|
|
|
53
53
|
/** @ignore */
|
|
54
54
|
__fromMaskedInputFacade?: boolean;
|
|
55
55
|
}
|
|
56
|
-
/** @deprecated Используйте {@link MaskedInput}
|
|
56
|
+
/** @deprecated Используйте {@link MaskedInput}. Для legacy-поведения включите фичафлаг `maskedInputUseLegacyBehavior` в {@link ReactUIFeatureFlagsContext}. */
|
|
57
57
|
export declare const MaskedInputV2: import("../../lib/forwardRefAndName.js").ReactUIComponentWithRef<Input, MaskedInputV2Props> & Record<never, never>;
|
|
58
58
|
export { getDefinitions, getMaskChar };
|
|
@@ -52,7 +52,7 @@ function getMaskInputMode(type, inputMode) {
|
|
|
52
52
|
}
|
|
53
53
|
return undefined;
|
|
54
54
|
}
|
|
55
|
-
/** @deprecated Используйте {@link MaskedInput}
|
|
55
|
+
/** @deprecated Используйте {@link MaskedInput}. Для legacy-поведения включите фичафлаг `maskedInputUseLegacyBehavior` в {@link ReactUIFeatureFlagsContext}. */
|
|
56
56
|
export var MaskedInputV2 = forwardRefAndName('MaskedInputV2', function MaskedInputV2(props, ref) {
|
|
57
57
|
var mask = props.mask, maskChar = props.maskChar, formatChars = props.formatChars, _a = props.alwaysShowMask, alwaysShowMask = _a === void 0 ? false : _a, _b = props.colored, colored = _b === void 0 ? true : _b, _c = props.imaskProps, customIMaskProps = _c === void 0 ? EMPTY_IMASK_PROPS : _c, _d = props.unmask, unmask = _d === void 0 ? false : _d, onValueChange = props.onValueChange, onUnexpectedInput = props.onUnexpectedInput, onBeforePasteValue = props.onBeforePasteValue, _element = props.element, className = props.className,
|
|
58
58
|
// @ts-expect-error: могут передавать игнорируя ошибку
|
|
@@ -61,7 +61,7 @@ export var MaskedInputV2 = forwardRefAndName('MaskedInputV2', function MaskedInp
|
|
|
61
61
|
_showClearIcon = props.showClearIcon, selectAllOnFocus = props.selectAllOnFocus, type = props.type, __fromMaskedInputFacade = props.__fromMaskedInputFacade, inputProps = __rest(props, ["mask", "maskChar", "formatChars", "alwaysShowMask", "colored", "imaskProps", "unmask", "onValueChange", "onUnexpectedInput", "onBeforePasteValue", "element", "className", "maxLength", "showClearIcon", "selectAllOnFocus", "type", "__fromMaskedInputFacade"]);
|
|
62
62
|
useEffect(function () {
|
|
63
63
|
if (!__fromMaskedInputFacade) {
|
|
64
|
-
warning(false, '[MaskedInputV2]:
|
|
64
|
+
warning(false, '[MaskedInputV2]: This component is for internal use only. Please use MaskedInput instead.');
|
|
65
65
|
}
|
|
66
66
|
}, [__fromMaskedInputFacade]);
|
|
67
67
|
var theme = useContext(ThemeContext);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MaskedInputV2.js","sourceRoot":"","sources":["MaskedInputV2.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useContext, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport type { Ref } from 'react';\nimport warning from 'warning';\n\nimport { forwardRefAndName } from '../../lib/forwardRefAndName.js';\nimport { useEmotion, useStyles } from '../../lib/renderEnvironment/index.js';\nimport { ThemeContext } from '../../lib/theming/ThemeContext.js';\nimport type { InputProps, InputType } from '../Input/index.js';\nimport { Input, selectionAllowedTypes } from '../Input/index.js';\nimport { extractRaw, findNearestRawLeft, computePasteMaskedCursor } from './internal/helpers.js';\nimport { MaskedCore } from './internal/MaskedCore.js';\nimport { setMaskInputSelectionRange } from './internal/setMaskInputSelectionRange.js';\nimport { useMaskEngine } from './internal/useMaskEngine.js';\nimport { getDefinitions, getMaskChar } from './MaskedInputV2.helpers.js';\nimport { getStyles, globalClasses } from './MaskedInputV2.styles.js';\nimport type { IMaskInputProps } from './react-imask/mixin.js';\n\nexport type MaskedInputV2OnBeforePasteValue = (value: string) => string;\n\nexport interface MaskedInputV2MaskedProps {\n /** Шаблон ввода, определяющий допустимые символы. */\n mask: string;\n\n /** Плейсхолдер, который отображается на месте ещё не введённых пользователем символов.\n * @default _ */\n maskChar?: string;\n\n /** Словарь правил для настройки маски, где:\n * ключ — символ для использования в маске;\n * значение — регулярка-правило.\n * @default { '9': '[0-9]', 'a': '[A-Za-z]', '*': '[A-Za-z0-9]' } */\n formatChars?: Record<string, string>;\n\n /** Всегда показывать символы маски, независимо от фокуса в поле.\n * @default false */\n alwaysShowMask?: boolean;\n\n /** Событие некорректного ввода.\n * Вторым аргументом передаётся метод вспыхивания рамки поля.\n *\n * Если обработчик не задан, то при событии рамка всегда вспыхивает.\n *\n * @param value значение поля\n * @param blink метод вспыхивания рамки поля\n */\n onUnexpectedInput?: (value: string, blink: () => void) => void;\n\n /**\n * Событие перед вставкой текста в поле.\n * Вызывается с аргументом value — текст из буфера.\n *\n * Обработчик должен вернуть текст — он попадёт в поле.\n *\n * @param value значение вставки.\n */\n onBeforePasteValue?: MaskedInputV2OnBeforePasteValue;\n\n /** Убирает из value символы маски, которые пользователь не вводил.\n * @default false */\n unmask?: boolean;\n\n /** Раскрашивает символы маски.\n * @default true\n * @ignore */\n colored?: boolean;\n\n /** Задает пропсы для компонента `IMaskInput`. Необходимы для юнит-тестов\n * @ignore */\n imaskProps?: IMaskInputProps<HTMLInputElement>;\n}\n\nexport type MaskInputType = Exclude<InputType, 'number' | 'date' | 'time' | 'password'>;\n\nconst EMPTY_IMASK_PROPS = {};\n\nexport const getSafeMaskInputType = (type?: InputType | string): MaskInputType | undefined => {\n if (!type) {\n return undefined;\n }\n\n const normalizedType = type.trim() as InputType;\n\n if (normalizedType === 'password' || !selectionAllowedTypes.includes(normalizedType)) {\n return 'text';\n }\n\n return normalizedType as MaskInputType;\n};\n\nfunction getMaskInputMode(\n type: InputType | string | undefined,\n inputMode: React.InputHTMLAttributes<HTMLInputElement>['inputMode'],\n): React.InputHTMLAttributes<HTMLInputElement>['inputMode'] {\n if (inputMode) {\n return inputMode;\n }\n\n if (type?.trim() === 'email') {\n return 'email';\n }\n\n return undefined;\n}\n\nexport interface MaskedInputV2Props\n extends\n MaskedInputV2MaskedProps,\n Omit<\n InputProps,\n 'showClearIcon' | 'mask' | 'maxLength' | 'type' | 'alwaysShowMask' | 'onUnexpectedInput' | 'maskChar'\n > {\n type?: MaskInputType;\n\n /** @ignore */\n __fromMaskedInputFacade?: boolean;\n}\n\n/** @deprecated Используйте {@link MaskedInput} с фичафлагом `useFixedMaskedInput` в {@link ReactUIFeatureFlagsContext}. */\nexport const MaskedInputV2 = forwardRefAndName(\n 'MaskedInputV2',\n function MaskedInputV2(props: MaskedInputV2Props, ref: Ref<Input | null>) {\n const {\n mask,\n maskChar,\n formatChars,\n alwaysShowMask = false,\n colored = true,\n imaskProps: customIMaskProps = EMPTY_IMASK_PROPS,\n unmask = false,\n onValueChange,\n onUnexpectedInput,\n onBeforePasteValue,\n element: _element,\n className,\n // @ts-expect-error: могут передавать игнорируя ошибку\n maxLength,\n // @ts-expect-error: могут передавать игнорируя ошибку\n showClearIcon: _showClearIcon,\n selectAllOnFocus,\n type,\n __fromMaskedInputFacade,\n ...inputProps\n } = props;\n\n useEffect(() => {\n if (!__fromMaskedInputFacade) {\n warning(\n false,\n '[MaskedInputV2]: компонент не предназначен для прямого использования. Используйте MaskedInput с фичафлагом useFixedMaskedInput.',\n );\n }\n }, [__fromMaskedInputFacade]);\n\n const theme = useContext(ThemeContext);\n const { cx } = useEmotion();\n const styles = useStyles(getStyles);\n\n const inputRef = useRef<Input>(null);\n const coreInputRef = useRef<HTMLInputElement>(null);\n\n const [focused, setFocused] = useState(false);\n\n const prevMaskRef = useRef(props.mask);\n const pendingCursorRestoreRef = useRef<number | null>(null);\n const pendingSelectionRestoreRef = useRef<{ start: number; end: number } | null>(null);\n const lastCaretRef = useRef(0);\n\n const historyRef = useRef<Array<{ raw: string; cursorPos: number }>>([]);\n const historyIndexRef = useRef(-1);\n\n // Сохраняем позицию курсора перед сменой маски (render-phase read of stable ref).\n // При коммите DOM браузер сбросит курсор в конец из-за изменения value,\n // поэтому восстанавливаем его синхронно в useLayoutEffect ниже.\n if (prevMaskRef.current !== props.mask) {\n pendingCursorRestoreRef.current = lastCaretRef.current;\n prevMaskRef.current = props.mask;\n historyRef.current = [];\n historyIndexRef.current = -1;\n }\n\n // Движок: IMask как чистый калькулятор, не привязанный к DOM\n const engine = useMaskEngine({\n mask,\n maskChar,\n formatChars,\n unmask,\n alwaysShowMask,\n imaskProps: customIMaskProps,\n });\n\n // Единственный источник истины — raw (только то, что ввёл пользователь, без маски)\n const [raw, setRaw] = useState<string>(() =>\n extractRaw((props.value ?? props.defaultValue) as string | number | undefined, engine),\n );\n\n // MaskState вычисляется синхронно из raw — оба визуальных слоя читают из него\n const maskState = useMemo(() => engine.compute(raw, focused), [raw, focused, engine]);\n\n const syncedImaskRef = useRef(engine.imask);\n const prevSyncedValueRef = useRef(props.value);\n\n // Синхронизировать raw при изменении props.value или правил маски\n useEffect(() => {\n const engineChanged = syncedImaskRef.current !== engine.imask;\n const valueChanged = prevSyncedValueRef.current !== props.value;\n syncedImaskRef.current = engine.imask;\n prevSyncedValueRef.current = props.value;\n\n if (props.value !== undefined) {\n if (valueChanged || engineChanged) {\n setRaw(extractRaw(props.value, engine));\n }\n return;\n }\n\n if (engineChanged) {\n setRaw((prev) => {\n engine.imask.unmaskedValue = prev;\n return engine.imask.rawInputValue;\n });\n }\n }, [props.value, engine]);\n\n // Вызывать onValueChange только при реальном изменении outputValue,\n // и НЕ при первом рендере (воспроизводит нативное поведение onChange)\n const isFirstRender = useRef(true);\n const prevOutputValue = useRef<string>(maskState.outputValue);\n useEffect(() => {\n if (isFirstRender.current) {\n isFirstRender.current = false;\n prevOutputValue.current = maskState.outputValue;\n return;\n }\n if (maskState.outputValue !== prevOutputValue.current) {\n prevOutputValue.current = maskState.outputValue;\n onValueChange?.(maskState.outputValue);\n }\n }, [maskState.outputValue]);\n\n useImperativeHandle<Input | null, (Input & { selectAll: () => void }) | null>(ref, () => {\n if (!inputRef.current) {\n return null;\n }\n return Object.assign(inputRef.current, {\n selectAll: () => {\n inputRef.current?.focus();\n pendingSelectionRestoreRef.current = { start: 0, end: maskState.typedLength };\n },\n });\n }, [maskState.typedLength]);\n\n useLayoutEffect(() => {\n if (pendingSelectionRestoreRef.current !== null && coreInputRef.current) {\n const { start, end } = pendingSelectionRestoreRef.current;\n pendingSelectionRestoreRef.current = null;\n setMaskInputSelectionRange(coreInputRef.current, start, end);\n lastCaretRef.current = end;\n return;\n }\n\n if (pendingCursorRestoreRef.current !== null && coreInputRef.current) {\n setMaskInputSelectionRange(coreInputRef.current, pendingCursorRestoreRef.current);\n lastCaretRef.current = pendingCursorRestoreRef.current;\n pendingCursorRestoreRef.current = null;\n }\n });\n\n useEffect(() => {\n if (!focused) {\n return;\n }\n\n const el = coreInputRef.current;\n if (!el) {\n return;\n }\n\n const syncCaret = () => {\n if (document.activeElement === el) {\n lastCaretRef.current = el.selectionStart ?? 0;\n }\n };\n\n document.addEventListener('selectionchange', syncCaret);\n return () => document.removeEventListener('selectionchange', syncCaret);\n }, [focused]);\n\n return (\n <Input\n ref={inputRef}\n {...inputProps}\n type={getSafeMaskInputType(type)}\n inputMode={getMaskInputMode(type, inputProps.inputMode)}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onSelect={handleSelect}\n className={cx(globalClasses.root, className, styles.root(theme))}\n element={\n <MaskedCore\n maskState={maskState}\n slotMap={engine.slotMap}\n engine={engine}\n focused={focused}\n currentRaw={raw}\n onRawChange={handleRawChange}\n onUnexpectedInput={triggerUnexpectedInput}\n onUndo={handleUndo}\n onRedo={handleRedo}\n coreInputRef={coreInputRef}\n colored={colored}\n selectAllOnFocus={selectAllOnFocus}\n />\n }\n />\n );\n\n function handleRawChange(input: string, source: 'input' | 'paste', cursorPos?: number) {\n if (source === 'paste') {\n handlePasteChange(input, cursorPos);\n } else {\n if (input !== raw && cursorPos !== undefined) {\n pushHistory(input, cursorPos);\n }\n setRaw(input);\n }\n }\n\n function handlePasteChange(pasted: string, _cursorPos?: number) {\n const el = coreInputRef.current;\n const selectionStart = el?.selectionStart ?? 0;\n\n // Находим rawPos по maskedPos курсора\n const rawCursorPos =\n engine.slotMap.maskedToRaw[selectionStart] !== null && engine.slotMap.maskedToRaw[selectionStart] !== undefined\n ? (engine.slotMap.maskedToRaw[selectionStart] as number)\n : findNearestRawLeft(selectionStart, engine.slotMap);\n\n const rawBefore = raw.slice(0, rawCursorPos);\n const rawAfter = raw.slice(rawCursorPos);\n const transformed = onBeforePasteValue ? onBeforePasteValue(pasted) : pasted;\n const result = engine.applyPaste(raw, rawCursorPos, transformed);\n\n if (result.overflow) {\n // IF-1157: paste с overflow → onUnexpectedInput\n triggerUnexpectedInput();\n }\n\n const postPasteMaskState = engine.compute(result.raw, true);\n const maskedCursorPos = computePasteMaskedCursor(\n rawBefore,\n rawAfter,\n result.raw,\n rawCursorPos,\n engine.slotMap,\n postPasteMaskState.typedLength,\n );\n\n if (result.raw !== raw) {\n pushHistory(result.raw, maskedCursorPos);\n }\n\n setRaw(result.raw);\n pendingCursorRestoreRef.current = maskedCursorPos;\n\n if (onBeforePasteValue && onValueChange) {\n // Legacy-контракт: при кастомной вставке наружу уходит результат onBeforePasteValue,\n // а не masked/unmasked outputValue (нужно для ComboBox и совместимости с IMaskInput).\n prevOutputValue.current = engine.compute(result.raw, focused).outputValue;\n onValueChange(transformed);\n }\n }\n\n function pushHistory(newRaw: string, cursorPos: number) {\n const MAX_HISTORY_LENGTH = 100;\n\n if (historyRef.current.length === 0) {\n historyRef.current.push({ raw, cursorPos: 0 });\n historyIndexRef.current = 0;\n }\n\n if (historyIndexRef.current < historyRef.current.length - 1) {\n historyRef.current = historyRef.current.slice(0, historyIndexRef.current + 1);\n }\n\n historyRef.current.push({ raw: newRaw, cursorPos });\n if (historyRef.current.length > MAX_HISTORY_LENGTH) {\n historyRef.current.shift();\n }\n historyIndexRef.current = historyRef.current.length - 1;\n }\n\n function handleUndo() {\n if (historyRef.current.length === 0) {\n return;\n }\n const nextIndex = Math.max(0, historyIndexRef.current - 1);\n if (nextIndex !== historyIndexRef.current) {\n historyIndexRef.current = nextIndex;\n const state = historyRef.current[nextIndex];\n setRaw(state.raw);\n pendingCursorRestoreRef.current = state.cursorPos;\n }\n }\n\n function handleRedo() {\n if (historyRef.current.length === 0) {\n return;\n }\n const nextIndex = Math.min(historyRef.current.length - 1, historyIndexRef.current + 1);\n if (nextIndex !== historyIndexRef.current) {\n historyIndexRef.current = nextIndex;\n const state = historyRef.current[nextIndex];\n setRaw(state.raw);\n pendingCursorRestoreRef.current = state.cursorPos;\n }\n }\n\n function triggerUnexpectedInput() {\n const blink = inputRef.current?.blink.bind(inputRef.current) ?? (() => undefined);\n onUnexpectedInput ? onUnexpectedInput(maskState.outputValue, blink) : blink();\n }\n\n function handleFocus(e: React.FocusEvent<HTMLInputElement>) {\n setFocused(true);\n props.onFocus?.(e);\n }\n\n function handleBlur(e: React.FocusEvent<HTMLInputElement>) {\n setFocused(false);\n props.onBlur?.(e);\n }\n\n function handleSelect(e: React.SyntheticEvent<HTMLInputElement>) {\n if (coreInputRef.current) {\n lastCaretRef.current = coreInputRef.current.selectionStart ?? 0;\n }\n inputProps.onSelect?.(e);\n }\n },\n);\n\n// Вспомогательные функции для совместимости (используются в стори и тестах)\nexport { getDefinitions, getMaskChar };\n"]}
|
|
1
|
+
{"version":3,"file":"MaskedInputV2.js","sourceRoot":"","sources":["MaskedInputV2.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useContext, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport type { Ref } from 'react';\nimport warning from 'warning';\n\nimport { forwardRefAndName } from '../../lib/forwardRefAndName.js';\nimport { useEmotion, useStyles } from '../../lib/renderEnvironment/index.js';\nimport { ThemeContext } from '../../lib/theming/ThemeContext.js';\nimport type { InputProps, InputType } from '../Input/index.js';\nimport { Input, selectionAllowedTypes } from '../Input/index.js';\nimport { extractRaw, findNearestRawLeft, computePasteMaskedCursor } from './internal/helpers.js';\nimport { MaskedCore } from './internal/MaskedCore.js';\nimport { setMaskInputSelectionRange } from './internal/setMaskInputSelectionRange.js';\nimport { useMaskEngine } from './internal/useMaskEngine.js';\nimport { getDefinitions, getMaskChar } from './MaskedInputV2.helpers.js';\nimport { getStyles, globalClasses } from './MaskedInputV2.styles.js';\nimport type { IMaskInputProps } from './react-imask/mixin.js';\n\nexport type MaskedInputV2OnBeforePasteValue = (value: string) => string;\n\nexport interface MaskedInputV2MaskedProps {\n /** Шаблон ввода, определяющий допустимые символы. */\n mask: string;\n\n /** Плейсхолдер, который отображается на месте ещё не введённых пользователем символов.\n * @default _ */\n maskChar?: string;\n\n /** Словарь правил для настройки маски, где:\n * ключ — символ для использования в маске;\n * значение — регулярка-правило.\n * @default { '9': '[0-9]', 'a': '[A-Za-z]', '*': '[A-Za-z0-9]' } */\n formatChars?: Record<string, string>;\n\n /** Всегда показывать символы маски, независимо от фокуса в поле.\n * @default false */\n alwaysShowMask?: boolean;\n\n /** Событие некорректного ввода.\n * Вторым аргументом передаётся метод вспыхивания рамки поля.\n *\n * Если обработчик не задан, то при событии рамка всегда вспыхивает.\n *\n * @param value значение поля\n * @param blink метод вспыхивания рамки поля\n */\n onUnexpectedInput?: (value: string, blink: () => void) => void;\n\n /**\n * Событие перед вставкой текста в поле.\n * Вызывается с аргументом value — текст из буфера.\n *\n * Обработчик должен вернуть текст — он попадёт в поле.\n *\n * @param value значение вставки.\n */\n onBeforePasteValue?: MaskedInputV2OnBeforePasteValue;\n\n /** Убирает из value символы маски, которые пользователь не вводил.\n * @default false */\n unmask?: boolean;\n\n /** Раскрашивает символы маски.\n * @default true\n * @ignore */\n colored?: boolean;\n\n /** Задает пропсы для компонента `IMaskInput`. Необходимы для юнит-тестов\n * @ignore */\n imaskProps?: IMaskInputProps<HTMLInputElement>;\n}\n\nexport type MaskInputType = Exclude<InputType, 'number' | 'date' | 'time' | 'password'>;\n\nconst EMPTY_IMASK_PROPS = {};\n\nexport const getSafeMaskInputType = (type?: InputType | string): MaskInputType | undefined => {\n if (!type) {\n return undefined;\n }\n\n const normalizedType = type.trim() as InputType;\n\n if (normalizedType === 'password' || !selectionAllowedTypes.includes(normalizedType)) {\n return 'text';\n }\n\n return normalizedType as MaskInputType;\n};\n\nfunction getMaskInputMode(\n type: InputType | string | undefined,\n inputMode: React.InputHTMLAttributes<HTMLInputElement>['inputMode'],\n): React.InputHTMLAttributes<HTMLInputElement>['inputMode'] {\n if (inputMode) {\n return inputMode;\n }\n\n if (type?.trim() === 'email') {\n return 'email';\n }\n\n return undefined;\n}\n\nexport interface MaskedInputV2Props\n extends\n MaskedInputV2MaskedProps,\n Omit<\n InputProps,\n 'showClearIcon' | 'mask' | 'maxLength' | 'type' | 'alwaysShowMask' | 'onUnexpectedInput' | 'maskChar'\n > {\n type?: MaskInputType;\n\n /** @ignore */\n __fromMaskedInputFacade?: boolean;\n}\n\n/** @deprecated Используйте {@link MaskedInput}. Для legacy-поведения включите фичафлаг `maskedInputUseLegacyBehavior` в {@link ReactUIFeatureFlagsContext}. */\nexport const MaskedInputV2 = forwardRefAndName(\n 'MaskedInputV2',\n function MaskedInputV2(props: MaskedInputV2Props, ref: Ref<Input | null>) {\n const {\n mask,\n maskChar,\n formatChars,\n alwaysShowMask = false,\n colored = true,\n imaskProps: customIMaskProps = EMPTY_IMASK_PROPS,\n unmask = false,\n onValueChange,\n onUnexpectedInput,\n onBeforePasteValue,\n element: _element,\n className,\n // @ts-expect-error: могут передавать игнорируя ошибку\n maxLength,\n // @ts-expect-error: могут передавать игнорируя ошибку\n showClearIcon: _showClearIcon,\n selectAllOnFocus,\n type,\n __fromMaskedInputFacade,\n ...inputProps\n } = props;\n\n useEffect(() => {\n if (!__fromMaskedInputFacade) {\n warning(false, '[MaskedInputV2]: This component is for internal use only. Please use MaskedInput instead.');\n }\n }, [__fromMaskedInputFacade]);\n\n const theme = useContext(ThemeContext);\n const { cx } = useEmotion();\n const styles = useStyles(getStyles);\n\n const inputRef = useRef<Input>(null);\n const coreInputRef = useRef<HTMLInputElement>(null);\n\n const [focused, setFocused] = useState(false);\n\n const prevMaskRef = useRef(props.mask);\n const pendingCursorRestoreRef = useRef<number | null>(null);\n const pendingSelectionRestoreRef = useRef<{ start: number; end: number } | null>(null);\n const lastCaretRef = useRef(0);\n\n const historyRef = useRef<Array<{ raw: string; cursorPos: number }>>([]);\n const historyIndexRef = useRef(-1);\n\n // Сохраняем позицию курсора перед сменой маски (render-phase read of stable ref).\n // При коммите DOM браузер сбросит курсор в конец из-за изменения value,\n // поэтому восстанавливаем его синхронно в useLayoutEffect ниже.\n if (prevMaskRef.current !== props.mask) {\n pendingCursorRestoreRef.current = lastCaretRef.current;\n prevMaskRef.current = props.mask;\n historyRef.current = [];\n historyIndexRef.current = -1;\n }\n\n // Движок: IMask как чистый калькулятор, не привязанный к DOM\n const engine = useMaskEngine({\n mask,\n maskChar,\n formatChars,\n unmask,\n alwaysShowMask,\n imaskProps: customIMaskProps,\n });\n\n // Единственный источник истины — raw (только то, что ввёл пользователь, без маски)\n const [raw, setRaw] = useState<string>(() =>\n extractRaw((props.value ?? props.defaultValue) as string | number | undefined, engine),\n );\n\n // MaskState вычисляется синхронно из raw — оба визуальных слоя читают из него\n const maskState = useMemo(() => engine.compute(raw, focused), [raw, focused, engine]);\n\n const syncedImaskRef = useRef(engine.imask);\n const prevSyncedValueRef = useRef(props.value);\n\n // Синхронизировать raw при изменении props.value или правил маски\n useEffect(() => {\n const engineChanged = syncedImaskRef.current !== engine.imask;\n const valueChanged = prevSyncedValueRef.current !== props.value;\n syncedImaskRef.current = engine.imask;\n prevSyncedValueRef.current = props.value;\n\n if (props.value !== undefined) {\n if (valueChanged || engineChanged) {\n setRaw(extractRaw(props.value, engine));\n }\n return;\n }\n\n if (engineChanged) {\n setRaw((prev) => {\n engine.imask.unmaskedValue = prev;\n return engine.imask.rawInputValue;\n });\n }\n }, [props.value, engine]);\n\n // Вызывать onValueChange только при реальном изменении outputValue,\n // и НЕ при первом рендере (воспроизводит нативное поведение onChange)\n const isFirstRender = useRef(true);\n const prevOutputValue = useRef<string>(maskState.outputValue);\n useEffect(() => {\n if (isFirstRender.current) {\n isFirstRender.current = false;\n prevOutputValue.current = maskState.outputValue;\n return;\n }\n if (maskState.outputValue !== prevOutputValue.current) {\n prevOutputValue.current = maskState.outputValue;\n onValueChange?.(maskState.outputValue);\n }\n }, [maskState.outputValue]);\n\n useImperativeHandle<Input | null, (Input & { selectAll: () => void }) | null>(ref, () => {\n if (!inputRef.current) {\n return null;\n }\n return Object.assign(inputRef.current, {\n selectAll: () => {\n inputRef.current?.focus();\n pendingSelectionRestoreRef.current = { start: 0, end: maskState.typedLength };\n },\n });\n }, [maskState.typedLength]);\n\n useLayoutEffect(() => {\n if (pendingSelectionRestoreRef.current !== null && coreInputRef.current) {\n const { start, end } = pendingSelectionRestoreRef.current;\n pendingSelectionRestoreRef.current = null;\n setMaskInputSelectionRange(coreInputRef.current, start, end);\n lastCaretRef.current = end;\n return;\n }\n\n if (pendingCursorRestoreRef.current !== null && coreInputRef.current) {\n setMaskInputSelectionRange(coreInputRef.current, pendingCursorRestoreRef.current);\n lastCaretRef.current = pendingCursorRestoreRef.current;\n pendingCursorRestoreRef.current = null;\n }\n });\n\n useEffect(() => {\n if (!focused) {\n return;\n }\n\n const el = coreInputRef.current;\n if (!el) {\n return;\n }\n\n const syncCaret = () => {\n if (document.activeElement === el) {\n lastCaretRef.current = el.selectionStart ?? 0;\n }\n };\n\n document.addEventListener('selectionchange', syncCaret);\n return () => document.removeEventListener('selectionchange', syncCaret);\n }, [focused]);\n\n return (\n <Input\n ref={inputRef}\n {...inputProps}\n type={getSafeMaskInputType(type)}\n inputMode={getMaskInputMode(type, inputProps.inputMode)}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onSelect={handleSelect}\n className={cx(globalClasses.root, className, styles.root(theme))}\n element={\n <MaskedCore\n maskState={maskState}\n slotMap={engine.slotMap}\n engine={engine}\n focused={focused}\n currentRaw={raw}\n onRawChange={handleRawChange}\n onUnexpectedInput={triggerUnexpectedInput}\n onUndo={handleUndo}\n onRedo={handleRedo}\n coreInputRef={coreInputRef}\n colored={colored}\n selectAllOnFocus={selectAllOnFocus}\n />\n }\n />\n );\n\n function handleRawChange(input: string, source: 'input' | 'paste', cursorPos?: number) {\n if (source === 'paste') {\n handlePasteChange(input, cursorPos);\n } else {\n if (input !== raw && cursorPos !== undefined) {\n pushHistory(input, cursorPos);\n }\n setRaw(input);\n }\n }\n\n function handlePasteChange(pasted: string, _cursorPos?: number) {\n const el = coreInputRef.current;\n const selectionStart = el?.selectionStart ?? 0;\n\n // Находим rawPos по maskedPos курсора\n const rawCursorPos =\n engine.slotMap.maskedToRaw[selectionStart] !== null && engine.slotMap.maskedToRaw[selectionStart] !== undefined\n ? (engine.slotMap.maskedToRaw[selectionStart] as number)\n : findNearestRawLeft(selectionStart, engine.slotMap);\n\n const rawBefore = raw.slice(0, rawCursorPos);\n const rawAfter = raw.slice(rawCursorPos);\n const transformed = onBeforePasteValue ? onBeforePasteValue(pasted) : pasted;\n const result = engine.applyPaste(raw, rawCursorPos, transformed);\n\n if (result.overflow) {\n // IF-1157: paste с overflow → onUnexpectedInput\n triggerUnexpectedInput();\n }\n\n const postPasteMaskState = engine.compute(result.raw, true);\n const maskedCursorPos = computePasteMaskedCursor(\n rawBefore,\n rawAfter,\n result.raw,\n rawCursorPos,\n engine.slotMap,\n postPasteMaskState.typedLength,\n );\n\n if (result.raw !== raw) {\n pushHistory(result.raw, maskedCursorPos);\n }\n\n setRaw(result.raw);\n pendingCursorRestoreRef.current = maskedCursorPos;\n\n if (onBeforePasteValue && onValueChange) {\n // Legacy-контракт: при кастомной вставке наружу уходит результат onBeforePasteValue,\n // а не masked/unmasked outputValue (нужно для ComboBox и совместимости с IMaskInput).\n prevOutputValue.current = engine.compute(result.raw, focused).outputValue;\n onValueChange(transformed);\n }\n }\n\n function pushHistory(newRaw: string, cursorPos: number) {\n const MAX_HISTORY_LENGTH = 100;\n\n if (historyRef.current.length === 0) {\n historyRef.current.push({ raw, cursorPos: 0 });\n historyIndexRef.current = 0;\n }\n\n if (historyIndexRef.current < historyRef.current.length - 1) {\n historyRef.current = historyRef.current.slice(0, historyIndexRef.current + 1);\n }\n\n historyRef.current.push({ raw: newRaw, cursorPos });\n if (historyRef.current.length > MAX_HISTORY_LENGTH) {\n historyRef.current.shift();\n }\n historyIndexRef.current = historyRef.current.length - 1;\n }\n\n function handleUndo() {\n if (historyRef.current.length === 0) {\n return;\n }\n const nextIndex = Math.max(0, historyIndexRef.current - 1);\n if (nextIndex !== historyIndexRef.current) {\n historyIndexRef.current = nextIndex;\n const state = historyRef.current[nextIndex];\n setRaw(state.raw);\n pendingCursorRestoreRef.current = state.cursorPos;\n }\n }\n\n function handleRedo() {\n if (historyRef.current.length === 0) {\n return;\n }\n const nextIndex = Math.min(historyRef.current.length - 1, historyIndexRef.current + 1);\n if (nextIndex !== historyIndexRef.current) {\n historyIndexRef.current = nextIndex;\n const state = historyRef.current[nextIndex];\n setRaw(state.raw);\n pendingCursorRestoreRef.current = state.cursorPos;\n }\n }\n\n function triggerUnexpectedInput() {\n const blink = inputRef.current?.blink.bind(inputRef.current) ?? (() => undefined);\n onUnexpectedInput ? onUnexpectedInput(maskState.outputValue, blink) : blink();\n }\n\n function handleFocus(e: React.FocusEvent<HTMLInputElement>) {\n setFocused(true);\n props.onFocus?.(e);\n }\n\n function handleBlur(e: React.FocusEvent<HTMLInputElement>) {\n setFocused(false);\n props.onBlur?.(e);\n }\n\n function handleSelect(e: React.SyntheticEvent<HTMLInputElement>) {\n if (coreInputRef.current) {\n lastCaretRef.current = coreInputRef.current.selectionStart ?? 0;\n }\n inputProps.onSelect?.(e);\n }\n },\n);\n\n// Вспомогательные функции для совместимости (используются в стори и тестах)\nexport { getDefinitions, getMaskChar };\n"]}
|
|
@@ -9,6 +9,8 @@ export function getShowOverlay(maskState, focused, overflows) {
|
|
|
9
9
|
// (плейсхолдеры) всегда рисуется через overlay, а не через value input.
|
|
10
10
|
return hasMaskPart(maskState);
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
// Полностью введённое значение (без декоративной части маски) рисуем нативным
|
|
13
|
+
// текстом input — иначе overlay с overflow:hidden обрезает конец при горизонтальном скролле.
|
|
14
|
+
return hasMaskPart(maskState);
|
|
13
15
|
}
|
|
14
16
|
//# sourceMappingURL=showOverlay.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"showOverlay.js","sourceRoot":"","sources":["showOverlay.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,WAAW,CAAC,SAAoB;IAC9C,OAAO,SAAS,CAAC,YAAY,CAAC,MAAM,GAAG,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAAoB,EAAE,OAAgB,EAAE,SAAiB;IAAjB,0BAAA,EAAA,iBAAiB;IACtF,IAAI,SAAS,EAAE,CAAC;QACd,8EAA8E;QAC9E,0EAA0E;QAC1E,wEAAwE;QACxE,OAAO,WAAW,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,WAAW,CAAC,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"showOverlay.js","sourceRoot":"","sources":["showOverlay.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,WAAW,CAAC,SAAoB;IAC9C,OAAO,SAAS,CAAC,YAAY,CAAC,MAAM,GAAG,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAAoB,EAAE,OAAgB,EAAE,SAAiB;IAAjB,0BAAA,EAAA,iBAAiB;IACtF,IAAI,SAAS,EAAE,CAAC;QACd,8EAA8E;QAC9E,0EAA0E;QAC1E,wEAAwE;QACxE,OAAO,WAAW,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAED,8EAA8E;IAC9E,6FAA6F;IAC7F,OAAO,WAAW,CAAC,SAAS,CAAC,CAAC;AAChC,CAAC","sourcesContent":["import type { MaskState } from './types.js';\n\nexport function hasMaskPart(maskState: MaskState): boolean {\n return maskState.displayValue.length > maskState.typedValue.length;\n}\n\nexport function getShowOverlay(maskState: MaskState, focused: boolean, overflows = false): boolean {\n if (overflows) {\n // При переполнении скрываем overlay только для полностью введённого значения:\n // иначе overlay не совпадает с прокруткой input. Декоративная часть маски\n // (плейсхолдеры) всегда рисуется через overlay, а не через value input.\n return hasMaskPart(maskState);\n }\n\n // Полностью введённое значение (без декоративной части маски) рисуем нативным\n // текстом input — иначе overlay с overflow:hidden обрезает конец при горизонтальном скролле.\n return hasMaskPart(maskState);\n}\n"]}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { useLayoutEffect, useState } from 'react';
|
|
2
2
|
import { measureInputTextWidth } from './measureInputTextWidth.js';
|
|
3
3
|
export function isInputTextOverflowing(input, displayValue) {
|
|
4
|
-
|
|
4
|
+
if (input.scrollWidth > input.clientWidth) {
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
var text = input.value || displayValue;
|
|
8
|
+
return measureInputTextWidth(input, text) > input.clientWidth;
|
|
5
9
|
}
|
|
6
10
|
/** Горизонтальное переполнение текста внутри input. */
|
|
7
11
|
export function useInputOverflow(inputRef, displayValue, remeasureKey) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useInputOverflow.js","sourceRoot":"","sources":["useInputOverflow.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAElD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,MAAM,UAAU,sBAAsB,CAAC,KAAuB,EAAE,YAAoB;IAClF,OAAO,qBAAqB,CAAC,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"useInputOverflow.js","sourceRoot":"","sources":["useInputOverflow.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAElD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,MAAM,UAAU,sBAAsB,CAAC,KAAuB,EAAE,YAAoB;IAClF,IAAI,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAM,IAAI,GAAG,KAAK,CAAC,KAAK,IAAI,YAAY,CAAC;IACzC,OAAO,qBAAqB,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC;AAChE,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,gBAAgB,CAC9B,QAAkD,EAClD,YAAoB,EACpB,YAAqB;IAEf,IAAA,KAA0B,QAAQ,CAAC,KAAK,CAAC,EAAxC,QAAQ,QAAA,EAAE,WAAW,QAAmB,CAAC;IAEhD,eAAe,CAAC;QACd,IAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QAED,IAAM,OAAO,GAAG;YACd,WAAW,CAAC,UAAC,IAAI;gBACf,IAAM,IAAI,GAAG,sBAAsB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;gBACzD,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;YACrC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,OAAO,EAAE,CAAC;QAEV,IAAI,OAAO,cAAc,KAAK,WAAW,EAAE,CAAC;YAC1C,OAAO;QACT,CAAC;QAED,IAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;QAC7C,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAExB,OAAO,cAAM,OAAA,QAAQ,CAAC,UAAU,EAAE,EAArB,CAAqB,CAAC;IACrC,CAAC,EAAE,CAAC,YAAY,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;IAE3C,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import type React from 'react';\nimport { useLayoutEffect, useState } from 'react';\n\nimport { measureInputTextWidth } from './measureInputTextWidth.js';\n\nexport function isInputTextOverflowing(input: HTMLInputElement, displayValue: string): boolean {\n if (input.scrollWidth > input.clientWidth) {\n return true;\n }\n\n const text = input.value || displayValue;\n return measureInputTextWidth(input, text) > input.clientWidth;\n}\n\n/** Горизонтальное переполнение текста внутри input. */\nexport function useInputOverflow(\n inputRef: React.RefObject<HTMLInputElement | null>,\n displayValue: string,\n remeasureKey: unknown,\n): boolean {\n const [overflow, setOverflow] = useState(false);\n\n useLayoutEffect(() => {\n const input = inputRef.current;\n if (!input) {\n return;\n }\n\n const measure = () => {\n setOverflow((prev) => {\n const next = isInputTextOverflowing(input, displayValue);\n return prev === next ? prev : next;\n });\n };\n\n measure();\n\n if (typeof ResizeObserver === 'undefined') {\n return;\n }\n\n const observer = new ResizeObserver(measure);\n observer.observe(input);\n\n return () => observer.disconnect();\n }, [displayValue, inputRef, remeasureKey]);\n\n return overflow;\n}\n"]}
|
|
@@ -77,13 +77,12 @@ var PopupPin = /** @class */ (function (_super) {
|
|
|
77
77
|
_this.getPinCoordinates = function (popupElement) {
|
|
78
78
|
var popupRect = _this.getPopupElementRect(popupElement);
|
|
79
79
|
var _a = _this.positionObject, direction = _a.direction, align = _a.align;
|
|
80
|
-
var defaultPinCoordinates = {
|
|
81
|
-
top: popupRect.height,
|
|
82
|
-
left: _this.getPinLeftCoordinate(popupRect, align),
|
|
83
|
-
};
|
|
84
80
|
switch (direction) {
|
|
85
81
|
case 'top':
|
|
86
|
-
return
|
|
82
|
+
return {
|
|
83
|
+
top: popupRect.height,
|
|
84
|
+
left: _this.getPinLeftCoordinate(popupRect, align),
|
|
85
|
+
};
|
|
87
86
|
case 'bottom':
|
|
88
87
|
return {
|
|
89
88
|
top: -2 * _this.props.size,
|
|
@@ -101,7 +100,10 @@ var PopupPin = /** @class */ (function (_super) {
|
|
|
101
100
|
};
|
|
102
101
|
default:
|
|
103
102
|
warning(false, "Can't get coordinates: invalid direction '".concat(direction, "'. Must be one of - 'top', 'right', 'bottom', 'left'."));
|
|
104
|
-
return
|
|
103
|
+
return {
|
|
104
|
+
top: popupRect.height,
|
|
105
|
+
left: _this.getPinLeftCoordinate(popupRect, align),
|
|
106
|
+
};
|
|
105
107
|
}
|
|
106
108
|
};
|
|
107
109
|
_this.getPinTopCoordinate = function (popupRect, align) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PopupPin.js","sourceRoot":"","sources":["PopupPin.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { Emotion } from '@emotion/css/create-instance';\nimport React from 'react';\nimport warning from 'warning';\n\nimport { responsiveLayout } from '../../components/ResponsiveLayout/decorator.js';\nimport { getDOMRect } from '../../lib/dom/getDOMRect.js';\nimport type { GlobalObject } from '../../lib/globalObject.js';\nimport * as LayoutEvents from '../../lib/LayoutEvents.js';\nimport { withRenderEnvironment } from '../../lib/renderEnvironment/index.js';\nimport type { Theme } from '../../lib/theming/Theme.js';\nimport { ThemeContext } from '../../lib/theming/ThemeContext.js';\nimport type { Nullable } from '../../typings/utility-types.js';\nimport { PopupDataTids } from './Popup.js';\nimport type { PositionObject, Rect } from './PopupHelper.js';\nimport { PopupHelper } from './PopupHelper.js';\nimport { getStyles } from './PopupPin.styles.js';\n\ninterface PopupPinProps {\n /** Цвет фона пина */\n backgroundColor: string;\n\n /** Смещение пина от края попапа. Край задаётся в пропе position вторым словом */\n offset: number;\n\n /** Ссылка на попап */\n popupElement?: Nullable<Element>;\n\n /** Позиция попапа, по которой будет вычислено положение пина */\n popupPosition: string;\n\n /**\n * Высота пина в px. Ширина основания = 2 × size для top/bottom, для left/right наоборот.\n */\n size: number;\n}\n\ninterface ClampedPinPosition {\n left: number;\n top: number;\n hidden: boolean;\n}\n\n@withRenderEnvironment\n@responsiveLayout\nexport class PopupPin extends React.Component<PopupPinProps> {\n public static __KONTUR_REACT_UI__ = 'PopupPin';\n public static displayName = 'PopupPin';\n\n private positionObject!: PositionObject;\n private theme!: Theme;\n private isMobileLayout!: boolean;\n\n private styles!: ReturnType<typeof getStyles>;\n private emotion!: Emotion;\n private cx!: Emotion['cx'];\n private globalObject!: GlobalObject;\n private layoutEventsToken: Nullable<ReturnType<typeof LayoutEvents.addListener>> = null;\n private layoutUpdateId: Nullable<number> = null;\n private cachedPopupElement: Nullable<Element> = null;\n\n public componentDidMount() {\n this.layoutEventsToken = LayoutEvents.addListener(this.handleLayoutEvent, this.globalObject);\n this.scheduleRemeasure();\n }\n\n public componentDidUpdate(prevProps: PopupPinProps) {\n if (\n prevProps.popupPosition !== this.props.popupPosition ||\n prevProps.offset !== this.props.offset ||\n prevProps.popupElement !== this.props.popupElement\n ) {\n this.scheduleRemeasure();\n }\n }\n\n public componentWillUnmount() {\n this.cancelScheduledRemeasure();\n this.layoutEventsToken?.remove();\n this.layoutEventsToken = null;\n }\n\n public render() {\n return (\n <ThemeContext.Consumer>\n {(theme) => {\n this.theme = theme;\n return this.renderPinContent();\n }}\n </ThemeContext.Consumer>\n );\n }\n\n private renderPinContent() {\n this.styles = getStyles(this.emotion);\n\n if (this.props.popupElement) {\n this.cachedPopupElement = this.props.popupElement;\n }\n\n const popupElement = this.props.popupElement || this.cachedPopupElement;\n\n if (!popupElement) {\n return null;\n }\n\n this.positionObject = PopupHelper.getPositionObject(this.props.popupPosition);\n\n const coords = this.getPinCoordinates(popupElement);\n if (!coords || typeof coords.left !== 'number' || typeof coords.top !== 'number') {\n return null;\n }\n\n const popupRect = this.getPopupElementRect(popupElement);\n const clampedPosition = this.applyEdgeClamp(coords, popupRect);\n const inlineStyle = this.getPinInlineStyle(clampedPosition.left, clampedPosition.top);\n const directionalStyle = this.getPinDirectionalStyle();\n if (!inlineStyle || !directionalStyle) {\n return null;\n }\n\n const pinEdgePadding = this.getPinEdgePadding();\n\n return (\n <div\n data-tid={PopupDataTids.popupPin}\n className={this.cx(\n this.styles.pin(),\n pinEdgePadding > 0 && this.styles.pinAnimated(),\n clampedPosition.hidden && this.styles.pinHidden(),\n directionalStyle,\n )}\n style={inlineStyle}\n ></div>\n );\n }\n\n private getPinEdgePadding(): number {\n return PopupHelper.getPopupViewportSidePadding(this.theme, this.isMobileLayout);\n }\n\n private handleLayoutEvent = () => {\n this.scheduleRemeasure();\n };\n\n private scheduleRemeasure() {\n this.cancelScheduledRemeasure();\n this.layoutUpdateId = this.globalObject.requestAnimationFrame?.(() => {\n this.layoutUpdateId = null;\n this.forceUpdate();\n });\n }\n\n private cancelScheduledRemeasure() {\n if (this.layoutUpdateId && this.layoutUpdateId !== null) {\n this.globalObject.cancelAnimationFrame?.(this.layoutUpdateId);\n this.layoutUpdateId = null;\n }\n }\n\n private getPopupOppositeDirection() {\n const popupDirection = PopupHelper.getPositionObject(this.props.popupPosition).direction;\n switch (popupDirection) {\n case 'top':\n return 'bottom';\n case 'bottom':\n return 'top';\n case 'left':\n return 'right';\n case 'right':\n return 'left';\n default:\n warning(\n false,\n `Can't get opposite direction: invalid direction ${popupDirection}. Must be one of - 'top', 'bottom', 'left', 'right'.`,\n );\n return 'bottom';\n }\n }\n\n private getPinInlineStyle = (left: number, top: number) => {\n const direction = this.getPopupOppositeDirection();\n if (!direction) {\n return;\n }\n\n // Добавляем запас в 1px, чтобы пофиксить случайные отделения пинов\n const correctedLeft = left - 1;\n const correctedTop = top - 1;\n const correctedSize = this.props.size + 1;\n\n const defaultPinInlineStyle = {\n [direction]: -this.props.size + 'px',\n left: correctedLeft + 'px',\n width: correctedSize * 2 + 'px',\n height: correctedSize + 'px',\n backgroundColor: this.props.backgroundColor,\n };\n\n switch (direction) {\n case 'top':\n case 'bottom':\n return defaultPinInlineStyle;\n case 'left':\n case 'right':\n return {\n [direction]: -this.props.size + 'px',\n top: correctedTop + 'px',\n height: correctedSize * 2 + 'px',\n width: correctedSize + 'px',\n backgroundColor: this.props.backgroundColor,\n };\n default:\n warning(\n false,\n `Can't get inline style: invalid direction '${direction}'. Must be one of - 'top', 'right', 'bottom', 'left'.`,\n );\n return defaultPinInlineStyle;\n }\n };\n\n private clampValue(value: number, min: number, max: number) {\n return Math.min(Math.max(value, min), max);\n }\n\n private applyEdgeClamp(coords: { left: number; top: number }, popupRect: Rect): ClampedPinPosition {\n const pinEdgePadding = this.getPinEdgePadding();\n\n if (pinEdgePadding <= 0) {\n return { left: coords.left, top: coords.top, hidden: false };\n }\n\n const { direction } = this.positionObject;\n const pinSpan = 2 * this.props.size;\n\n if (direction === 'top' || direction === 'bottom') {\n const minLeft = pinEdgePadding;\n const maxLeft = popupRect.width - pinSpan - pinEdgePadding;\n const clampedLeft = this.clampValue(coords.left, minLeft, maxLeft);\n const centerOffset = coords.left - clampedLeft;\n\n return {\n left: clampedLeft,\n top: coords.top,\n hidden: centerOffset !== 0,\n };\n }\n\n const minTop = pinEdgePadding;\n const maxTop = popupRect.height - pinSpan - pinEdgePadding;\n const clampedTop = this.clampValue(coords.top, minTop, maxTop);\n const centerOffset = coords.top - clampedTop;\n\n return {\n left: coords.left,\n top: clampedTop,\n hidden: centerOffset !== 0,\n };\n }\n\n private getPopupElementRect(popupElement: Element): Rect {\n const rect = getDOMRect(popupElement);\n\n return {\n top: 0,\n left: 0,\n width: rect.width,\n height: rect.height,\n };\n }\n\n private getPinCoordinates = (popupElement: Element) => {\n const popupRect = this.getPopupElementRect(popupElement);\n const { direction, align } = this.positionObject;\n\n const defaultPinCoordinates = {\n top: popupRect.height,\n left: this.getPinLeftCoordinate(popupRect, align),\n };\n\n switch (direction) {\n case 'top':\n return defaultPinCoordinates;\n case 'bottom':\n return {\n top: -2 * this.props.size,\n left: this.getPinLeftCoordinate(popupRect, align),\n };\n case 'left':\n return {\n top: this.getPinTopCoordinate(popupRect, align),\n left: popupRect.width,\n };\n case 'right':\n return {\n top: this.getPinTopCoordinate(popupRect, align),\n left: -2 * this.props.size,\n };\n default:\n warning(\n false,\n `Can't get coordinates: invalid direction '${direction}'. Must be one of - 'top', 'right', 'bottom', 'left'.`,\n );\n return defaultPinCoordinates;\n }\n };\n\n private getPinTopCoordinate = (popupRect: Rect, align: string) => {\n const defaultTopCoordinate = this.props.offset;\n switch (align) {\n case 'top':\n return defaultTopCoordinate;\n case 'middle':\n return popupRect.height / 2 - this.props.size;\n case 'bottom':\n return popupRect.height - this.props.offset - 2 * this.props.size;\n default:\n warning(\n false,\n `Can't get top coordinate: invalid align '${align}'. Must be one of - 'top', 'middle', 'bottom'.`,\n );\n return defaultTopCoordinate;\n }\n };\n\n private getPinLeftCoordinate = (popupRect: Rect, align: string) => {\n const defaultLetfCoordinate = popupRect.width / 2 - this.props.size;\n switch (align) {\n case 'left':\n return this.props.offset;\n case 'center':\n return defaultLetfCoordinate + this.props.offset;\n case 'right':\n return popupRect.width - this.props.offset - 2 * this.props.size;\n default:\n warning(\n false,\n `Can't get left coordinate: invalid align '${align}'. Must be one of - 'left', 'center', 'right'.`,\n );\n return defaultLetfCoordinate;\n }\n };\n\n private getPinDirectionalStyle = () => {\n switch (this.positionObject.direction) {\n case 'top':\n return this.styles.pinTop();\n case 'bottom':\n return this.styles.pinBottom();\n case 'left':\n return this.styles.pinLeft();\n case 'right':\n return this.styles.pinRight();\n default:\n warning(\n false,\n `Can't get directional style: invalid direction '${this.positionObject.direction}'. Must be one of - 'top', 'right', 'bottom', 'left'.`,\n );\n return this.styles.pinTop();\n }\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"PopupPin.js","sourceRoot":"","sources":["PopupPin.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { Emotion } from '@emotion/css/create-instance';\nimport React from 'react';\nimport warning from 'warning';\n\nimport { responsiveLayout } from '../../components/ResponsiveLayout/decorator.js';\nimport { getDOMRect } from '../../lib/dom/getDOMRect.js';\nimport type { GlobalObject } from '../../lib/globalObject.js';\nimport * as LayoutEvents from '../../lib/LayoutEvents.js';\nimport { withRenderEnvironment } from '../../lib/renderEnvironment/index.js';\nimport type { Theme } from '../../lib/theming/Theme.js';\nimport { ThemeContext } from '../../lib/theming/ThemeContext.js';\nimport type { Nullable } from '../../typings/utility-types.js';\nimport { PopupDataTids } from './Popup.js';\nimport type { PositionObject, Rect } from './PopupHelper.js';\nimport { PopupHelper } from './PopupHelper.js';\nimport { getStyles } from './PopupPin.styles.js';\n\ninterface PopupPinProps {\n /** Цвет фона пина */\n backgroundColor: string;\n\n /** Смещение пина от края попапа. Край задаётся в пропе position вторым словом */\n offset: number;\n\n /** Ссылка на попап */\n popupElement?: Nullable<Element>;\n\n /** Позиция попапа, по которой будет вычислено положение пина */\n popupPosition: string;\n\n /**\n * Высота пина в px. Ширина основания = 2 × size для top/bottom, для left/right наоборот.\n */\n size: number;\n}\n\ninterface ClampedPinPosition {\n left: number;\n top: number;\n hidden: boolean;\n}\n\n@withRenderEnvironment\n@responsiveLayout\nexport class PopupPin extends React.Component<PopupPinProps> {\n public static __KONTUR_REACT_UI__ = 'PopupPin';\n public static displayName = 'PopupPin';\n\n private positionObject!: PositionObject;\n private theme!: Theme;\n private isMobileLayout!: boolean;\n\n private styles!: ReturnType<typeof getStyles>;\n private emotion!: Emotion;\n private cx!: Emotion['cx'];\n private globalObject!: GlobalObject;\n private layoutEventsToken: Nullable<ReturnType<typeof LayoutEvents.addListener>> = null;\n private layoutUpdateId: Nullable<number> = null;\n private cachedPopupElement: Nullable<Element> = null;\n\n public componentDidMount() {\n this.layoutEventsToken = LayoutEvents.addListener(this.handleLayoutEvent, this.globalObject);\n this.scheduleRemeasure();\n }\n\n public componentDidUpdate(prevProps: PopupPinProps) {\n if (\n prevProps.popupPosition !== this.props.popupPosition ||\n prevProps.offset !== this.props.offset ||\n prevProps.popupElement !== this.props.popupElement\n ) {\n this.scheduleRemeasure();\n }\n }\n\n public componentWillUnmount() {\n this.cancelScheduledRemeasure();\n this.layoutEventsToken?.remove();\n this.layoutEventsToken = null;\n }\n\n public render() {\n return (\n <ThemeContext.Consumer>\n {(theme) => {\n this.theme = theme;\n return this.renderPinContent();\n }}\n </ThemeContext.Consumer>\n );\n }\n\n private renderPinContent() {\n this.styles = getStyles(this.emotion);\n\n if (this.props.popupElement) {\n this.cachedPopupElement = this.props.popupElement;\n }\n\n const popupElement = this.props.popupElement || this.cachedPopupElement;\n\n if (!popupElement) {\n return null;\n }\n\n this.positionObject = PopupHelper.getPositionObject(this.props.popupPosition);\n\n const coords = this.getPinCoordinates(popupElement);\n if (!coords || typeof coords.left !== 'number' || typeof coords.top !== 'number') {\n return null;\n }\n\n const popupRect = this.getPopupElementRect(popupElement);\n const clampedPosition = this.applyEdgeClamp(coords, popupRect);\n const inlineStyle = this.getPinInlineStyle(clampedPosition.left, clampedPosition.top);\n const directionalStyle = this.getPinDirectionalStyle();\n if (!inlineStyle || !directionalStyle) {\n return null;\n }\n\n const pinEdgePadding = this.getPinEdgePadding();\n\n return (\n <div\n data-tid={PopupDataTids.popupPin}\n className={this.cx(\n this.styles.pin(),\n pinEdgePadding > 0 && this.styles.pinAnimated(),\n clampedPosition.hidden && this.styles.pinHidden(),\n directionalStyle,\n )}\n style={inlineStyle}\n ></div>\n );\n }\n\n private getPinEdgePadding(): number {\n return PopupHelper.getPopupViewportSidePadding(this.theme, this.isMobileLayout);\n }\n\n private handleLayoutEvent = () => {\n this.scheduleRemeasure();\n };\n\n private scheduleRemeasure() {\n this.cancelScheduledRemeasure();\n this.layoutUpdateId = this.globalObject.requestAnimationFrame?.(() => {\n this.layoutUpdateId = null;\n this.forceUpdate();\n });\n }\n\n private cancelScheduledRemeasure() {\n if (this.layoutUpdateId && this.layoutUpdateId !== null) {\n this.globalObject.cancelAnimationFrame?.(this.layoutUpdateId);\n this.layoutUpdateId = null;\n }\n }\n\n private getPopupOppositeDirection() {\n const popupDirection = PopupHelper.getPositionObject(this.props.popupPosition).direction;\n switch (popupDirection) {\n case 'top':\n return 'bottom';\n case 'bottom':\n return 'top';\n case 'left':\n return 'right';\n case 'right':\n return 'left';\n default:\n warning(\n false,\n `Can't get opposite direction: invalid direction ${popupDirection}. Must be one of - 'top', 'bottom', 'left', 'right'.`,\n );\n return 'bottom';\n }\n }\n\n private getPinInlineStyle = (left: number, top: number) => {\n const direction = this.getPopupOppositeDirection();\n if (!direction) {\n return;\n }\n\n // Добавляем запас в 1px, чтобы пофиксить случайные отделения пинов\n const correctedLeft = left - 1;\n const correctedTop = top - 1;\n const correctedSize = this.props.size + 1;\n\n const defaultPinInlineStyle = {\n [direction]: -this.props.size + 'px',\n left: correctedLeft + 'px',\n width: correctedSize * 2 + 'px',\n height: correctedSize + 'px',\n backgroundColor: this.props.backgroundColor,\n };\n\n switch (direction) {\n case 'top':\n case 'bottom':\n return defaultPinInlineStyle;\n case 'left':\n case 'right':\n return {\n [direction]: -this.props.size + 'px',\n top: correctedTop + 'px',\n height: correctedSize * 2 + 'px',\n width: correctedSize + 'px',\n backgroundColor: this.props.backgroundColor,\n };\n default:\n warning(\n false,\n `Can't get inline style: invalid direction '${direction}'. Must be one of - 'top', 'right', 'bottom', 'left'.`,\n );\n return defaultPinInlineStyle;\n }\n };\n\n private clampValue(value: number, min: number, max: number) {\n return Math.min(Math.max(value, min), max);\n }\n\n private applyEdgeClamp(coords: { left: number; top: number }, popupRect: Rect): ClampedPinPosition {\n const pinEdgePadding = this.getPinEdgePadding();\n\n if (pinEdgePadding <= 0) {\n return { left: coords.left, top: coords.top, hidden: false };\n }\n\n const { direction } = this.positionObject;\n const pinSpan = 2 * this.props.size;\n\n if (direction === 'top' || direction === 'bottom') {\n const minLeft = pinEdgePadding;\n const maxLeft = popupRect.width - pinSpan - pinEdgePadding;\n const clampedLeft = this.clampValue(coords.left, minLeft, maxLeft);\n const centerOffset = coords.left - clampedLeft;\n\n return {\n left: clampedLeft,\n top: coords.top,\n hidden: centerOffset !== 0,\n };\n }\n\n const minTop = pinEdgePadding;\n const maxTop = popupRect.height - pinSpan - pinEdgePadding;\n const clampedTop = this.clampValue(coords.top, minTop, maxTop);\n const centerOffset = coords.top - clampedTop;\n\n return {\n left: coords.left,\n top: clampedTop,\n hidden: centerOffset !== 0,\n };\n }\n\n private getPopupElementRect(popupElement: Element): Rect {\n const rect = getDOMRect(popupElement);\n\n return {\n top: 0,\n left: 0,\n width: rect.width,\n height: rect.height,\n };\n }\n\n private getPinCoordinates = (popupElement: Element) => {\n const popupRect = this.getPopupElementRect(popupElement);\n const { direction, align } = this.positionObject;\n\n switch (direction) {\n case 'top':\n return {\n top: popupRect.height,\n left: this.getPinLeftCoordinate(popupRect, align),\n };\n case 'bottom':\n return {\n top: -2 * this.props.size,\n left: this.getPinLeftCoordinate(popupRect, align),\n };\n case 'left':\n return {\n top: this.getPinTopCoordinate(popupRect, align),\n left: popupRect.width,\n };\n case 'right':\n return {\n top: this.getPinTopCoordinate(popupRect, align),\n left: -2 * this.props.size,\n };\n default:\n warning(\n false,\n `Can't get coordinates: invalid direction '${direction}'. Must be one of - 'top', 'right', 'bottom', 'left'.`,\n );\n return {\n top: popupRect.height,\n left: this.getPinLeftCoordinate(popupRect, align),\n };\n }\n };\n\n private getPinTopCoordinate = (popupRect: Rect, align: string) => {\n const defaultTopCoordinate = this.props.offset;\n switch (align) {\n case 'top':\n return defaultTopCoordinate;\n case 'middle':\n return popupRect.height / 2 - this.props.size;\n case 'bottom':\n return popupRect.height - this.props.offset - 2 * this.props.size;\n default:\n warning(\n false,\n `Can't get top coordinate: invalid align '${align}'. Must be one of - 'top', 'middle', 'bottom'.`,\n );\n return defaultTopCoordinate;\n }\n };\n\n private getPinLeftCoordinate = (popupRect: Rect, align: string) => {\n const defaultLetfCoordinate = popupRect.width / 2 - this.props.size;\n switch (align) {\n case 'left':\n return this.props.offset;\n case 'center':\n return defaultLetfCoordinate + this.props.offset;\n case 'right':\n return popupRect.width - this.props.offset - 2 * this.props.size;\n default:\n warning(\n false,\n `Can't get left coordinate: invalid align '${align}'. Must be one of - 'left', 'center', 'right'.`,\n );\n return defaultLetfCoordinate;\n }\n };\n\n private getPinDirectionalStyle = () => {\n switch (this.positionObject.direction) {\n case 'top':\n return this.styles.pinTop();\n case 'bottom':\n return this.styles.pinBottom();\n case 'left':\n return this.styles.pinLeft();\n case 'right':\n return this.styles.pinRight();\n default:\n warning(\n false,\n `Can't get directional style: invalid direction '${this.positionObject.direction}'. Must be one of - 'top', 'right', 'bottom', 'left'.`,\n );\n return this.styles.pinTop();\n }\n };\n}\n"]}
|