Skip to content

Commit

Permalink
feat(phone-input): add extra handler for phone-input to format value (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
kdmatrosov committed Apr 29, 2020
1 parent a026c49 commit 802c8d6
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 1 deletion.
7 changes: 7 additions & 0 deletions src/phone-input/phone-input.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,11 @@ describe('phone-input', () => {
phoneInput.instance().blur();
expect(input.blur).toHaveBeenCalled();
});

it('should call shift-value', () => {
expect(PhoneInput.shiftValue('9163590999')).toBe(' 916 359 09 99');
expect(PhoneInput.shiftValue('9163590')).toBe(' 916 359 0');
expect(PhoneInput.shiftValue('9163')).toBe(' 916 3');
expect(PhoneInput.shiftValue('91')).toBe(' 91');
});
});
60 changes: 59 additions & 1 deletion src/phone-input/phone-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,31 @@ export type PhoneInputProps = DeepReadonly<InputProps & {
placeholder?: string;
}>;

type PhoneInputState = {
updatedValue?: string;
}

/**
* Компонент ввода телефона по маске.
*/
export class PhoneInput extends React.PureComponent<PhoneInputProps> {
export class PhoneInput extends React.PureComponent<PhoneInputProps, PhoneInputState> {
protected cn = createCn('phone-input');

static defaultProps: Partial<PhoneInputProps> = {
mask: '+1 111 111 11 11',
placeholder: '+7 000 000 00 00',
};

state = {
updatedValue: undefined
};

root;

render() {
const { value } = this.props;
const { updatedValue } = this.state;

return (
<Input
{ ...this.props }
Expand All @@ -48,10 +59,57 @@ export class PhoneInput extends React.PureComponent<PhoneInputProps> {
} }
formNoValidate={ true }
className={ this.cn() }
onChange={ this.handleChange }
value={ updatedValue === undefined ? value : updatedValue }
/>
);
}

/**
* Промежуточный обработчик value после изменения значения.
* В value проверяется, что первый числовой символ 7,
* если 7, то ничего не делаем
* если 8, то происходит замена на 7
* иначе вставляем 7, а остальное сдвигаем
*/
private handleChange = (value?: string, event?: React.ChangeEvent<any>) => {
const { onChange } = this.props;
let valueForOnChange = value;

if (value?.length > 1 && !/^\+7.*$/.test(value)) {
const [plus, code]: [string, string] = value;

if (code === '8') {
valueForOnChange = value.replace(/^\+(8)(.*)$/, '+7$2');
} else {
valueForOnChange = `${plus}7${PhoneInput.shiftValue(value.slice(1).replace(/\s/g, ''))}`;
}
} else if (value?.length === 1) {
valueForOnChange = '';
}
if (onChange) {
onChange(valueForOnChange, event);
} else {
this.setState({ updatedValue: valueForOnChange });
}
};

static shiftValue(originalValue: string, mask: string = ' 111 111 11 11'): string {
let shiftedValue: string = '';
let specCounter = 0;

mask.split('').forEach((sym, index) => {
if (sym !== '1' && originalValue[index - specCounter]) {
shiftedValue += sym;
specCounter += 1;
} else {
shiftedValue += originalValue[index - specCounter] || '';
}
});

return shiftedValue;
}

/**
* Устанавливает фокус на поле ввода.
*/
Expand Down

0 comments on commit 802c8d6

Please sign in to comment.