Skip to content

Commit

Permalink
feat(phone-input): add 'clearableCountyCode' prop (#749)
Browse files Browse the repository at this point in the history
* feat(phone-input): add 'clearableCountyCode' prop

* fix(phone-input): typo

* fix(phone-input): number insertions to unclearable country input

* fix(phone-input): insertion to selected input
  • Loading branch information
koretskyhub committed Jul 19, 2021
1 parent 6d219d6 commit d110ae7
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 15 deletions.
47 changes: 32 additions & 15 deletions packages/phone-input/src/Component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useImperativeHandle, useCallback, useRef } from 'react';
import { conformToMask, TextMaskConfig } from 'text-mask-core';
import { MaskedInput, MaskedInputProps } from '@alfalab/core-components-masked-input';

import { deleteFormatting } from './utils';
import { deleteFormatting, setCaretPosition, getInsertedNumber } from './utils';

const mask = [
'+',
Expand All @@ -23,10 +23,14 @@ const mask = [
/\d/,
];

export type PhoneInputProps = Omit<MaskedInputProps, 'onBeforeDisplay' | 'type' | 'mask'>;
const countryPrefix = '+7 ';

export type PhoneInputProps = Omit<MaskedInputProps, 'onBeforeDisplay' | 'type' | 'mask'> & {
clearableCountryCode?: boolean;
};

export const PhoneInput = React.forwardRef<HTMLInputElement, PhoneInputProps>(
({ ...restProps }, ref) => {
({ clearableCountryCode = true, ...restProps }, ref) => {
const inputRef = useRef<HTMLInputElement>(null);

// Оставляет возможность прокинуть ref извне
Expand Down Expand Up @@ -59,17 +63,11 @@ export const PhoneInput = React.forwardRef<HTMLInputElement, PhoneInputProps>(
([7, 10, 13].includes(currentCaretPosition) &&
previousConformedValue.length > currentCaretPosition))
) {
const caret = currentCaretPosition;
window.requestAnimationFrame(() => {
if (inputRef !== null && inputRef.current) {
inputRef.current.selectionStart = caret;
inputRef.current.selectionEnd = caret;
}
});
setCaretPosition({ position: currentCaretPosition, inputRef });
}

// Удаление цифры перед кодом страны удаляет только саму цифру, код остается ("+7 1" -> "+7 ")
if (rawValue === '+7 ') {
if (rawValue === countryPrefix) {
return rawValue;
}

Expand All @@ -79,28 +77,47 @@ export const PhoneInput = React.forwardRef<HTMLInputElement, PhoneInputProps>(
return masked.conformedValue;
}

const insertedNumber = getInsertedNumber({
rawValue,
clearableCountryCode,
countryPrefix,
previousConformedValue,
});

// Вставка номера, начинающегося с 8 или 7: 89990313131, 71112223344
if (
conformedValue.length === mask.length &&
(rawValue.startsWith('8') || rawValue.startsWith('7'))
(insertedNumber.startsWith('8') || insertedNumber.startsWith('7'))
) {
const masked = conformToMask(`+7${rawValue.slice(1)}`, mask, config);
const masked = conformToMask(`+7${insertedNumber.slice(1)}`, mask, config);
return masked.conformedValue;
}

// Если ввод начат с 7 или 8 - выводит "+7 " и дает продолжить ввод со след. цифры
if (rawValue.length === 1 && ['7', '8'].includes(rawValue[0])) {
return '+7 ';
return countryPrefix;
}

const abortCountryCodeClearing =
!clearableCountryCode && !rawValue.startsWith(countryPrefix);

if (abortCountryCodeClearing) {
setCaretPosition({ position: countryPrefix.length, inputRef });

if (!rawValue.length) return countryPrefix;

return false;
}

return conformedValue;
},
[],
[clearableCountryCode],
);

return (
<MaskedInput
{...restProps}
value={clearableCountryCode ? undefined : countryPrefix}
mask={mask}
onBeforeDisplay={handleBeforeDisplay}
type='tel'
Expand Down
1 change: 1 addition & 0 deletions packages/phone-input/src/docs/Component.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import Changelog from '../../CHANGELOG.md';
error={text('error', '')}
hint={text('hint', '')}
label={text('label', '')}
clearableCountryCode={boolean('clearableCountryCode', true)}
leftAddons={boolean('leftAddons', false) && <Icon />}
rightAddons={boolean('rightAddons', false) && <Icon />}
bottomAddons={boolean('bottomAddons', false) && <span>bottom text</span>}
Expand Down
36 changes: 36 additions & 0 deletions packages/phone-input/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,39 @@ export const deleteFormatting = (phone: string) =>
.replace(/^7/, '')
.replace(/\s/g, '')
.replace(/-/g, '');

export function setCaretPosition({
position,
inputRef,
}: {
position: number;
inputRef: React.RefObject<HTMLInputElement>;
}) {
window.requestAnimationFrame(() => {
if (inputRef === null || !inputRef.current) return;

inputRef.current.setSelectionRange(position, position);
});
}

export function getInsertedNumber({
rawValue,
clearableCountryCode,
countryPrefix,
previousConformedValue,
}: {
rawValue: string;
clearableCountryCode: boolean;
countryPrefix: string;
previousConformedValue: string;
}) {
if (!clearableCountryCode && previousConformedValue === countryPrefix) {
if (rawValue.startsWith('7') || rawValue.startsWith('8')) {
return rawValue;
}

return rawValue.slice(countryPrefix.length);
}

return rawValue;
}

0 comments on commit d110ae7

Please sign in to comment.