Skip to content

Instantly share code, notes, and snippets.

@jonasmarco
Last active May 23, 2022 02:20
Show Gist options
  • Save jonasmarco/f7b571aa5b435df906ac982f71d31b8c to your computer and use it in GitHub Desktop.
Save jonasmarco/f7b571aa5b435df906ac982f71d31b8c to your computer and use it in GitHub Desktop.
Máscara simples para input de número de telefone brasileiro com 8 ou 9 dígitos e DDD - Versão TypeScript
import React from 'react'
import PropTypes from 'prop-types'
const TYPES = {
OITO: '9999-9999',
NOVE: '99999-9999',
SNOVE: '9 9999-9999',
DDDOITO: '(99)9999-9999',
DDDNOVE: '(99)99999-9999',
DDDSNOVE: '(99)9 9999-9999',
SDDDOITO: '(99) 9999-9999',
SDDDNOVE: '(99) 99999-9999',
SDDDSNOVE: '(99) 9 9999-9999',
}
type Props = {
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void
temDDD: boolean
separaDDD: boolean
separaNono: boolean
placeholder: string
value: string
required: boolean
}
const defaultProps = {
temDDD: false,
separaNono: false,
separaDDD: false,
placeholder: '',
value: '',
required: false,
}
const TelefoneBrasileiroInput = (props: Props) => {
const MAX_LENGTH = props.temDDD
? props.separaDDD
? props.separaNono
? clear(TYPES.SDDDSNOVE).length
: clear(TYPES.SDDDNOVE).length
: props.separaNono
? clear(TYPES.DDDSNOVE).length
: clear(TYPES.DDDNOVE).length
: props.separaNono
? clear(TYPES.SNOVE).length
: clear(TYPES.NOVE).length
const { onChange } = props
let value = clear(props.value)
if (value) {
value = applyMask(value, TYPES[getMask(value)])
}
function onLocalChange(ev: React.ChangeEvent<HTMLInputElement>) {
let value = clear(ev.target.value)
const mask = getMask(value)
const nextLength = value.length
if (nextLength > MAX_LENGTH) return
value = applyMask(value, TYPES[mask])
ev.target.value = value
onChange(ev)
}
function getMask(value: string): string {
if (props.temDDD) {
if (props.separaDDD) {
if (props.separaNono) {
return value.length > 10 ? 'SDDDSNOVE' : 'SDDDOITO'
} else {
return value.length > 10 ? 'SDDDNOVE' : 'SDDDOITO'
}
} else {
if (props.separaNono) {
return value.length > 10 ? 'DDDSNOVE' : 'DDDOITO'
} else {
return value.length > 10 ? 'DDDNOVE' : 'DDDOITO'
}
}
} else {
if (props.separaNono) {
return value.length > 8 ? 'SNOVE' : 'OITO'
} else {
return value.length > 8 ? 'NOVE' : 'OITO'
}
}
}
function applyMask(value: string, mask: string): string {
let result = ''
let inc = 0
Array.from(value).forEach((letter, index) => {
while (!mask[index + inc].match(/[0-9]/)) {
result += mask[index + inc]
inc++
}
result += letter
})
return result
}
function clear(value: string): string {
return value && value.replace(/[^0-9]/g, '')
}
return <input {...props} value={value} onChange={onLocalChange} />
}
TelefoneBrasileiroInput.propTypes = {
value: PropTypes.string,
onChange: PropTypes.func,
}
TelefoneBrasileiroInput.defaultProps = defaultProps
export default TelefoneBrasileiroInput
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment