InputMask
WARNING
InputMask is deprecated and will be removed in the next major release.
Mask
This is an example of a basic input with a mask feature. The mask is defined using the mask property, which specifies the input format and validates the entered value.
TIP
Remember to set a placeholder for the input field. The placeholder should match the mask.
import { Flex } from '@semcore/ui/base-components';
import InputMask from '@semcore/ui/input-mask';
import { Text } from '@semcore/ui/typography';
import React from 'react';
const Demo = () => {
return (
<Flex direction='column' gap={2} w={224}>
<Text tag='label' htmlFor='basic-example' size={200}>
Card number
</Text>
<InputMask w={224}>
<InputMask.Value
mask='9999 9999 9999 9999'
placeholder='____ ____ ____ ____'
id='basic-example'
aria-describedby='basic-example-hint'
autoComplete='cc-number'
/>
</InputMask>
<Text size={100} color='gray-500' id='basic-example-hint'>
Please enter the 16-digit number of your debit card.
</Text>
</Flex>
);
};
export default Demo;
Aliases
aliases is the object that defines how characters in the mask are validated. By default, they are configured as follows:
9- numbersa- Latin and Cyrillic letters in any case*- numbers and Latin and Cyrillic letters in any case
import { Flex } from '@semcore/ui/base-components';
import InputMask from '@semcore/ui/input-mask';
import { Text } from '@semcore/ui/typography';
import React from 'react';
const Demo = () => {
const [value, setValue] = React.useState('99');
return (
<Flex direction='column' gap={2} w={224}>
<Text tag='label' htmlFor='aliases-example' size={200}>
Item index
</Text>
<InputMask w={224}>
<InputMask.Value
id='aliases-example'
aliases={{ x: /[0-9]/ }}
mask='99xxxx'
value={value}
onChange={setValue}
aria-describedby='aliases-example-hint'
/>
</InputMask>
<Text size={100} color='gray-500' id='aliases-example-hint'>
Enter any 4 digits
</Text>
</Flex>
);
};
export default Demo;
Pipe
pipe is a function that processes and changes the InputMask value after user input.
In the example below, it is used for formatting and validating the card's expire date input. The focus is switched to the next input by the onSucces event. It is called when the entered value fully matches the input mask.
import { Box, Flex } from '@semcore/ui/base-components';
import InputMask from '@semcore/ui/input-mask';
import { Text } from '@semcore/ui/typography';
import React from 'react';
const Demo = () => {
const expireDateInput = React.useRef<HTMLInputElement>(null);
const handleSuccess = React.useCallback(() => expireDateInput.current?.focus(), []);
return (
<Flex
direction='column'
wMax={300}
gap={2}
p={8}
mx='auto'
style={{
borderRadius: 'var(--intergalactic-surface-rounded)',
background: 'var(--intergalactic-bg-secondary-neutral)',
}}
>
<Text tag='label' size={300} htmlFor='card_number'>
Card number
</Text>
<InputMask size='l' mb={2}>
<InputMask.Value
mask='9999 9999 9999 9999'
placeholder='____ ____ ____ ____'
onSuccess={handleSuccess}
title='16 digits'
id='card_number'
autoComplete='cc-number'
/>
</InputMask>
<Flex alignItems='center' justifyContent='flex-end' gap={2}>
<Text tag='label' size={300} htmlFor='expire_date'>
Expiry date
</Text>
<InputMask size='l' wMax={85}>
<InputMask.Value
ref={expireDateInput}
mask='99/99'
placeholder='MM/YY'
pipe={pipeExpireDate}
title='Month and year, 4 digits in total'
id='expire_date'
autoComplete='cc-exp'
/>
</InputMask>
</Flex>
</Flex>
);
};
const pipeExpireDate = (maskedValue: string, conf: { rawValue: string }) => {
let value = maskedValue;
if (conf.rawValue.length === 7) {
value = conf.rawValue
.split('/')
.map((valueItem, index) => {
if (valueItem.length === 2) {
return valueItem;
}
if (valueItem.length === 4 && index === 1) {
return valueItem.toString().substring(2);
}
})
.join('/');
}
const indexesOfPipedChars = [];
const firstMonthDigit = Number.parseInt(value[0], 10);
if (firstMonthDigit > 1) {
value = `0${value[0]}/${value.split('/')[1]}`;
indexesOfPipedChars.push(0);
}
const [month, year] = value
.split('/')
.map((chunk) => (chunk.includes('_') ? undefined : Number.parseInt(chunk, 10)));
const currentYear = new Date().getFullYear() % 100;
const currentMonth = new Date().getMonth() + 1;
if (month === undefined || year === undefined) return false;
if (month > 12) return false;
if (year === currentYear && month < currentMonth) return false;
if (year < currentYear) return false;
return { value, indexesOfPipedChars };
};
export default Demo;