From ffcbebcdb7c07425f6cf7ecb507d3c0ff9dc4cc6 Mon Sep 17 00:00:00 2001 From: lossir Date: Fri, 21 Feb 2025 10:10:26 +0500 Subject: [PATCH 1/2] fix(MaskedInput): wip 1 --- .../MaskedInput/FixedIMaskInput.tsx | 5 +- .../components/MaskedInput/IMaskInput.tsx | 331 ++++++++++++++++++ .../MaskedInput/MaskedInput.helpers.ts | 2 +- .../components/MaskedInput/MaskedInput.tsx | 2 +- .../lib/date/InternalDateValidator.ts | 2 +- packages/react-ui/package.json | 4 +- yarn.lock | 61 ++-- 7 files changed, 378 insertions(+), 29 deletions(-) create mode 100644 packages/react-ui/components/MaskedInput/IMaskInput.tsx diff --git a/packages/react-ui/components/MaskedInput/FixedIMaskInput.tsx b/packages/react-ui/components/MaskedInput/FixedIMaskInput.tsx index c1830c229a6..087d2dec0de 100644 --- a/packages/react-ui/components/MaskedInput/FixedIMaskInput.tsx +++ b/packages/react-ui/components/MaskedInput/FixedIMaskInput.tsx @@ -1,6 +1,5 @@ import React, { useEffect, useImperativeHandle, useRef } from 'react'; -import { InputMask, MaskedPatternOptions } from 'imask'; -import { IMaskInput, IMaskInputProps } from 'react-imask'; +import type { InputMask, MaskedPatternOptions } from '@lossir/imask'; import { forwardRefAndName } from '../../lib/forwardRefAndName'; import { @@ -17,6 +16,8 @@ import { } from '../../lib/events/keyboard/identifiers'; import { MouseDrag } from '../../lib/events/MouseDrag'; +import { IMaskInput, type IMaskInputProps } from './IMaskInput'; + export type FixedIMaskInputProps = IMaskInputProps; type HeadDirection = 'left' | 'right'; diff --git a/packages/react-ui/components/MaskedInput/IMaskInput.tsx b/packages/react-ui/components/MaskedInput/IMaskInput.tsx new file mode 100644 index 00000000000..3a7033e7101 --- /dev/null +++ b/packages/react-ui/components/MaskedInput/IMaskInput.tsx @@ -0,0 +1,331 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import type { InputMask, InputMaskElement, FactoryOpts, AllFactoryStaticOpts } from '@lossir/imask'; +import iMask from '@lossir/imask'; + +type AnyProps = Record; + +export type Falsy = false | 0 | '' | null | undefined; + +export type ReactMaskOpts = FactoryOpts & { unmask?: 'typed' | boolean }; + +export type UnmaskValue = Opts['unmask'] extends 'typed' + ? InputMask['typedValue'] + : Opts['unmask'] extends Falsy + ? InputMask['value'] + : InputMask['unmaskedValue']; + +export type ExtractReactMaskOpts< + MaskElement extends InputMaskElement, + Props extends IMaskInputProps, +> = Extract; + +export interface ReactMaskProps< + MaskElement extends InputMaskElement, + Props extends IMaskInputProps = AnyProps, +> { + onAccept?: ( + value: UnmaskValue>, + maskRef: InputMask>, + e?: InputEvent, + ) => void; + onComplete?: ( + value: UnmaskValue>, + maskRef: InputMask>, + e?: InputEvent, + ) => void; + unmask?: ExtractReactMaskOpts['unmask']; + value?: UnmaskValue>; + inputRef?: React.Ref; + ref?: React.Ref>; +} + +const MASK_PROPS: { + [key in keyof (AllFactoryStaticOpts & ReactMaskProps)]: any; +} = { + // common + mask: PropTypes.oneOfType([ + PropTypes.array, + PropTypes.func, + PropTypes.string, + PropTypes.instanceOf(RegExp), + PropTypes.oneOf([Date, Number, iMask.Masked]), + PropTypes.instanceOf(iMask.Masked as any), + ]), + value: PropTypes.any, + unmask: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['typed'])]), + prepare: PropTypes.func, + prepareChar: PropTypes.func, + validate: PropTypes.func, + commit: PropTypes.func, + overwrite: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['shift'])]), + eager: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['append', 'remove'])]), + skipInvalid: PropTypes.bool, + + // events + onAccept: PropTypes.func, + onComplete: PropTypes.func, + + // pattern + placeholderChar: PropTypes.string, + displayChar: PropTypes.string, + lazy: PropTypes.bool, + definitions: PropTypes.object, + blocks: PropTypes.object, + + // enum + enum: PropTypes.arrayOf(PropTypes.string), + + // range + maxLength: PropTypes.number, + from: PropTypes.number, + to: PropTypes.number, + + // date + pattern: PropTypes.string, + format: PropTypes.func, + parse: PropTypes.func, + autofix: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['pad'])]), + + // number + radix: PropTypes.string, + thousandsSeparator: PropTypes.string, + mapToRadix: PropTypes.arrayOf(PropTypes.string), + scale: PropTypes.number, + normalizeZeros: PropTypes.bool, + padFractionalZeros: PropTypes.bool, + min: PropTypes.oneOfType([PropTypes.number, PropTypes.instanceOf(Date)]), + max: PropTypes.oneOfType([PropTypes.number, PropTypes.instanceOf(Date)]), + + // dynamic + dispatch: PropTypes.func, + + // ref + inputRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({ current: PropTypes.object })]), +} as const; + +const MASK_PROPS_NAMES = (Object.keys(MASK_PROPS) as Array).filter((p) => p !== 'value'); +const NON_MASK_OPTIONS_NAMES = ['value', 'unmask', 'onAccept', 'onComplete', 'inputRef'] as const; + +export type ReactElementProps = Omit< + Omit, keyof typeof MASK_PROPS>, + (typeof NON_MASK_OPTIONS_NAMES)[number] | 'maxLength' +>; + +type NonMaskProps = AnyProps> = Omit< + Props, + keyof FactoryOpts +>; + +export type ReactMixinComponent< + MaskElement extends InputMaskElement, + Props extends IMaskMixinProps = AnyProps, +> = React.ComponentType< + ReactElementProps & { inputRef: React.Ref } & NonMaskProps +>; + +export type MaskPropsKeys = Exclude; +const MASK_OPTIONS_NAMES = MASK_PROPS_NAMES.filter( + (pName) => NON_MASK_OPTIONS_NAMES.indexOf(pName as (typeof NON_MASK_OPTIONS_NAMES)[number]) < 0, +) as MaskPropsKeys[]; + +export type ExtractMaskOpts> = Extract< + Props, + FactoryOpts +>; + +export type IMaskMixinProps = Omit, 'ref'> & + FactoryOpts; + +export type IMaskInputProps = ReactElementProps & + IMaskMixinProps; + +function iMaskMixin = AnyProps>( + ComposedComponent: ReactMixinComponent, +) { + const MaskedComponent = class extends React.Component { + static displayName: string; + static propTypes: typeof MASK_PROPS; + + element!: MaskElement; + maskRef?: InputMask>; + + constructor(props: Props) { + super(props); + this._inputRef = this._inputRef.bind(this); + } + + componentDidMount() { + if (!this.props.mask) { + return; + } + + this.initMask(); + } + + componentDidUpdate() { + const props = this.props; + const maskOptions = this._extractMaskOptionsFromProps(props); + if (maskOptions.mask) { + if (this.maskRef) { + this.maskRef.updateOptions(maskOptions as any); + if ('value' in props && props.value !== undefined) { + this.maskValue = props.value; + } + } else { + this.initMask(maskOptions); + } + } else { + this.destroyMask(); + if ('value' in props && props.value !== undefined) { + if ( + (this.element as HTMLElement)?.isContentEditable && + (this.element as HTMLElement).tagName !== 'INPUT' && + (this.element as HTMLElement).tagName !== 'TEXTAREA' + ) { + (this.element as HTMLElement).textContent = props.value; + } else { + (this.element as HTMLInputElement).value = props.value; + } + } + } + } + + componentWillUnmount() { + this.destroyMask(); + } + + _inputRef(el: MaskElement) { + this.element = el; + if (this.props.inputRef) { + if (Object.prototype.hasOwnProperty.call(this.props.inputRef, 'current')) { + (this.props.inputRef as React.MutableRefObject).current = el; + } else { + (this.props.inputRef as React.RefCallback)(el); + } + } + } + + initMask(maskOptions: ExtractMaskOpts = this._extractMaskOptionsFromProps(this.props)) { + this.maskRef = iMask(this.element, maskOptions) + .on('accept', this._onAccept.bind(this)) + .on('complete', this._onComplete.bind(this)); + + if ('value' in this.props && this.props.value !== undefined) { + this.maskValue = this.props.value; + } + } + + destroyMask() { + if (this.maskRef) { + this.maskRef.destroy(); + delete this.maskRef; + } + } + + _extractMaskOptionsFromProps(props: Readonly): ExtractMaskOpts { + const { ...cloneProps }: Readonly = props; + + // keep only mask options + (Object.keys(cloneProps) as Array) + .filter((prop) => MASK_OPTIONS_NAMES.indexOf(prop as MaskPropsKeys) < 0) + .forEach((nonMaskProp) => { + delete cloneProps[nonMaskProp]; + }); + + return cloneProps as ExtractMaskOpts; + } + + _extractNonMaskProps(props: Readonly): NonMaskProps { + const { ...cloneProps } = props as Props; + + (MASK_PROPS_NAMES as Array).forEach((maskProp) => { + if (maskProp !== 'maxLength') { + delete cloneProps[maskProp]; + } + }); + if (!('defaultValue' in cloneProps)) { + cloneProps.defaultValue = props.mask ? '' : cloneProps.value; + } + delete cloneProps.value; + + return cloneProps as NonMaskProps; + } + + get maskValue(): UnmaskValue> { + if (!this.maskRef) { + return '' as UnmaskValue>; + } + + if (this.props.unmask === 'typed') { + return this.maskRef.typedValue; + } + if (this.props.unmask) { + return this.maskRef.unmaskedValue; + } + return this.maskRef.value; + } + + set maskValue(value: UnmaskValue>) { + if (!this.maskRef) { + return; + } + + const _value = (value === null && this.props.unmask !== 'typed' ? '' : value) as UnmaskValue< + ExtractReactMaskOpts + >; + if (this.props.unmask === 'typed') { + this.maskRef.typedValue = _value; + } else if (this.props.unmask) { + this.maskRef.unmaskedValue = _value; + } else { + this.maskRef.value = _value; + } + } + + _onAccept(e?: InputEvent) { + if (this.props.onAccept && this.maskRef) { + this.props.onAccept(this.maskValue, this.maskRef, e); + } + } + + _onComplete(e?: InputEvent) { + if (this.props.onComplete && this.maskRef) { + this.props.onComplete(this.maskValue, this.maskRef, e); + } + } + + render() { + return React.createElement(ComposedComponent, { + ...this._extractNonMaskProps(this.props), + inputRef: this._inputRef, + }); + } + }; + + const nestedComponentName = ComposedComponent.displayName || ComposedComponent.name || 'Component'; + MaskedComponent.displayName = `IMask(${nestedComponentName})`; + MaskedComponent.propTypes = MASK_PROPS; + + return React.forwardRef, Props>((props, ref) => + React.createElement(MaskedComponent, { ...props, ref }), + ); +} + +const IMaskInputClass = iMaskMixin(({ inputRef, ...props }) => + React.createElement('input', { + ...props, + ref: inputRef, + }), +); + +const IMaskInputFn = >( + props: Props, + ref: React.Ref>, +) => React.createElement(IMaskInputClass as any, { ...props, ref }); // TODO fix no idea + +export const IMaskInput = React.forwardRef( + IMaskInputFn as >( + props: Props & { ref?: React.Ref> }, + ) => React.ReactElement, +); diff --git a/packages/react-ui/components/MaskedInput/MaskedInput.helpers.ts b/packages/react-ui/components/MaskedInput/MaskedInput.helpers.ts index eb3c8275aeb..dc7895b8a32 100644 --- a/packages/react-ui/components/MaskedInput/MaskedInput.helpers.ts +++ b/packages/react-ui/components/MaskedInput/MaskedInput.helpers.ts @@ -1,4 +1,4 @@ -import { Definitions } from 'imask'; +import { Definitions } from '@lossir/imask'; import { isNonNullable } from '../../lib/utils'; diff --git a/packages/react-ui/components/MaskedInput/MaskedInput.tsx b/packages/react-ui/components/MaskedInput/MaskedInput.tsx index ae1f4081076..a8b4e6f2293 100644 --- a/packages/react-ui/components/MaskedInput/MaskedInput.tsx +++ b/packages/react-ui/components/MaskedInput/MaskedInput.tsx @@ -1,5 +1,4 @@ import React, { Ref, useImperativeHandle, useRef, useState, useEffect } from 'react'; -import { IMaskInputProps } from 'react-imask'; import { forwardRefAndName } from '../../lib/forwardRefAndName'; import { cx } from '../../lib/theming/Emotion'; @@ -11,6 +10,7 @@ import { globalClasses } from './MaskedInput.styles'; import { getDefinitions, getMaskChar } from './MaskedInput.helpers'; import { ColorableInputElement } from './ColorableInputElement'; import { FixedIMaskInput } from './FixedIMaskInput'; +import { IMaskInputProps } from './IMaskInput'; export interface MaskedProps { /** Паттерн маски */ diff --git a/packages/react-ui/lib/date/InternalDateValidator.ts b/packages/react-ui/lib/date/InternalDateValidator.ts index dcecd071423..298b62fce37 100644 --- a/packages/react-ui/lib/date/InternalDateValidator.ts +++ b/packages/react-ui/lib/date/InternalDateValidator.ts @@ -123,7 +123,7 @@ export class InternalDateValidator { return true; } - public static testParseToNumber(value: InternalDateComponentRaw): value is NonNullable { + public static testParseToNumber(value: InternalDateComponentRaw): value is number { if (value !== null) { return typeof value === 'number' || !Number.isNaN(parseInt(value, 10)); } diff --git a/packages/react-ui/package.json b/packages/react-ui/package.json index d997c5005c4..e1bc71d1634 100644 --- a/packages/react-ui/package.json +++ b/packages/react-ui/package.json @@ -51,6 +51,7 @@ "dependencies": { "@babel/runtime": "^7.24.6", "@emotion/css": "^11.11.2", + "@lossir/imask": "^7.6.2", "@skbkontur/global-object": "^0.4.4", "eventemitter3": "^5.0.1", "invariant": "^2.2.4", @@ -60,7 +61,6 @@ "normalize-wheel": "^1.0.1", "prop-types": "^15.8.1", "react-focus-lock": "2.11.2", - "react-imask": "7.6.1", "react-input-mask": "2.0.4", "react-is": "^18.3.1", "react-transition-group": "^4.4.5", @@ -151,8 +151,8 @@ "selenium-webdriver": "^4.27.0", "semver": "^7.6.2", "serve": "^13.0.2", - "string-replace-loader": "3.1.0", "storybook": "7.6.18", + "string-replace-loader": "3.1.0", "style-loader": "^4.0.0", "stylelint": "^16.6.0", "stylelint-config-standard": "^36.0.0", diff --git a/yarn.lock b/yarn.lock index a53aea53f62..5a124b14252 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2573,10 +2573,10 @@ resolved "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime-corejs3@^7.24.4": - version "7.25.6" - resolved "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.25.6.tgz#5e3facf42775cc95bcde95746e940061931286e4" - integrity sha512-Gz0Nrobx8szge6kQQ5Z5MX9L3ObqNwCQY1PSwSNzreFL7aHGxv8Fp2j3ETV6/wWdbiV+mW6OSm8oQhg3Tcsniw== +"@babel/runtime-corejs3@^7.24.5": + version "7.26.9" + resolved "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.26.9.tgz#8b73bae47453aa3dd2839ac52598581a7dd8332f" + integrity sha512-5EVjbTegqN7RSJle6hMWYxO4voo4rI+9krITk+DWR+diJgGrjZjrIBnJhjrHYYQsFgI7j1w1QnrvV7YSKBfYGg== dependencies: core-js-pure "^3.30.2" regenerator-runtime "^0.14.0" @@ -4342,6 +4342,13 @@ npmlog "^4.1.2" write-file-atomic "^3.0.3" +"@lossir/imask@^7.6.2": + version "7.6.2" + resolved "https://registry.npmjs.org/@lossir/imask/-/imask-7.6.2.tgz#51da1786831b18ad94c7d574e6f3e60df6036ee9" + integrity sha512-rmc5fOK30ZacfZzGCtB9O5jt5yNe8CHYjBvUenH3pKRrNvwfCd9PCWIqUvBR3b0dZ3T3iomamcxew6nvFBox6w== + dependencies: + "@babel/runtime-corejs3" "^7.24.5" + "@mdx-js/react@^2.1.5": version "2.3.0" resolved "https://registry.npmjs.org/@mdx-js/react/-/react-2.3.0.tgz#4208bd6d70f0d0831def28ef28c26149b03180b3" @@ -13265,13 +13272,6 @@ image-size@~0.5.0: resolved "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" integrity sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w= -imask@^7.6.1: - version "7.6.1" - resolved "https://registry.npmjs.org/imask/-/imask-7.6.1.tgz#04fa4693bf47a4a71bbf7325408e0d058a74dcad" - integrity sha512-sJlIFM7eathUEMChTh9Mrfw/IgiWgJqBKq2VNbyXvBZ7ev/IlO6/KQTKlV/Fm+viQMLrFLG/zCuudrLIwgK2dg== - dependencies: - "@babel/runtime-corejs3" "^7.24.4" - immediate@~3.0.5: version "3.0.6" resolved "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" @@ -18110,14 +18110,6 @@ react-icons@^3.8.0: dependencies: camelcase "^5.0.0" -react-imask@7.6.1: - version "7.6.1" - resolved "https://registry.npmjs.org/react-imask/-/react-imask-7.6.1.tgz#40dbb03f0c9b2652a16450ff29a53581b5ae773d" - integrity sha512-vLNfzcCz62Yzx/GRGh5tiCph9Gbh2cZu+Tz8OiO5it2eNuuhpA0DWhhSlOtVtSJ80+Bx+vFK5De8eQ9AmbkXzA== - dependencies: - imask "^7.6.1" - prop-types "^15.8.1" - react-input-mask@2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/react-input-mask/-/react-input-mask-2.0.4.tgz#9ade5cf8196f4a856dbf010820fe75a795f3eb14" @@ -19983,7 +19975,7 @@ string-replace-loader@3.1.0, string-replace-loader@^3.1.0: loader-utils "^2.0.0" schema-utils "^3.0.0" -"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -20001,6 +19993,15 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" @@ -20127,7 +20128,7 @@ stringify-object@^3.2.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -20148,6 +20149,13 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -22015,7 +22023,7 @@ wordwrap@^1.0.0: resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -22033,6 +22041,15 @@ wrap-ansi@^5.1.0: string-width "^3.0.0" strip-ansi "^5.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From 9e6046f6e146ea0d1d42f5a16d534797dacce8fa Mon Sep 17 00:00:00 2001 From: lossir Date: Fri, 21 Feb 2025 11:27:04 +0500 Subject: [PATCH 2/2] fix(MaskedInput): wip 2 --- packages/react-ui/components/MaskedInput/IMaskInput.tsx | 4 ++-- .../react-ui/components/ResponsiveLayout/ResponsiveLayout.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-ui/components/MaskedInput/IMaskInput.tsx b/packages/react-ui/components/MaskedInput/IMaskInput.tsx index 3a7033e7101..fa80566e7d8 100644 --- a/packages/react-ui/components/MaskedInput/IMaskInput.tsx +++ b/packages/react-ui/components/MaskedInput/IMaskInput.tsx @@ -12,8 +12,8 @@ export type ReactMaskOpts = FactoryOpts & { unmask?: 'typed' | boolean }; export type UnmaskValue = Opts['unmask'] extends 'typed' ? InputMask['typedValue'] : Opts['unmask'] extends Falsy - ? InputMask['value'] - : InputMask['unmaskedValue']; + ? InputMask['value'] + : InputMask['unmaskedValue']; export type ExtractReactMaskOpts< MaskElement extends InputMaskElement, diff --git a/packages/react-ui/components/ResponsiveLayout/ResponsiveLayout.tsx b/packages/react-ui/components/ResponsiveLayout/ResponsiveLayout.tsx index 7d1a5c5d6e6..ab65c520bc9 100644 --- a/packages/react-ui/components/ResponsiveLayout/ResponsiveLayout.tsx +++ b/packages/react-ui/components/ResponsiveLayout/ResponsiveLayout.tsx @@ -31,7 +31,7 @@ export function ResponsiveLayout(props return ( - {isFunction(props.children) ? props.children(layoutFlags) ?? null : props.children ?? null} + {isFunction(props.children) ? (props.children(layoutFlags) ?? null) : (props.children ?? null)} ); }