Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"private": true,
"dependencies": {
"@apollo/client": "^3.3.7",
"@hookform/resolvers": "^1.3.4",
"@hookform/resolvers": "^2.8.8",
"@naveteam/dispatcher": "^1.1.0",
"@naveteam/pandora-frontend": "^1.0.4",
"@sentry/browser": "5.14",
Expand All @@ -25,12 +25,12 @@
"react-datepicker": "^3.6.0",
"react-dom": "^17.0.1",
"react-helmet": "^5.2.1",
"react-hook-form": "^6.15.1",
"react-hook-form": "^7.26.1",
"react-is": "^16.13.1",
"react-query": "^3.9.8",
"react-router-dom": "^5.0.1",
"react-scripts": "^3.3.0",
"react-text-mask": "^5.4.3",
"rifm": "^0.12.1",
"sanitize.css": "^11.0.0",
"styled-components": "^5.0.1",
"styled-system": "^5.1.5",
Expand Down
80 changes: 52 additions & 28 deletions src/components/Input/Input.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,57 @@
import React, { forwardRef } from 'react'
import React, { useMemo } from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import MaskedInput from 'react-text-mask'

import Column from 'components/Column'
import { useRifm } from 'rifm'
import Text from 'components/Text'

import { mergeRefs } from 'helpers'

const InputComponent = forwardRef(({ label, name, placeholder, error, disabled, type, mask, ...props }, ref) => (
<Column {...props}>
{label && <Text mb={5}>{label}</Text>}
<Column height={60} position='relative'>
{!mask ? (
<Input name={name} ref={ref} placeholder={placeholder} error={error} type={type} />
) : (
<MaskedInput
mask={mask}
name={name}
placeholder={placeholder}
error={error}
type={type}
render={(maskedRef, inputProps) => <Input ref={mergeRefs(maskedRef, ref)} {...inputProps} />}
/>
)}
<Text position='absolute' bottom={0} color='red' variant='small'>
{error}
</Text>
import { useController } from 'react-hook-form'

const InputComponent = ({
label,
name,
placeholder,
disabled,
mask,
defaultValue = '',
type = 'text',
rules,
...props
}) => {
const {
field: { ref, value, onChange, ...field },
fieldState: { error }
} = useController({ name, rules, defaultValue })

const defaultMask = useMemo(
() => ({
format: str => str,
append: str => str,
accept: /./g,
...mask
}),
[mask]
)

const rifm = useRifm({
value,
onChange,
...defaultMask
})

return (
<Column {...props}>
{label && <Text mb={5}>{label}</Text>}
<Column height={60} position='relative'>
<Input {...field} {...rifm} type={type} error={error} placeholder={placeholder} />
<Text position='absolute' bottom={0} color='red' variant='small'>
{error?.message}
</Text>
</Column>
</Column>
</Column>
))
)
}

const Input = styled.input`
height: 40px;
Expand All @@ -46,11 +68,13 @@ InputComponent.defaultProps = {
InputComponent.propTypes = {
label: PropTypes.string,
name: PropTypes.string,
register: PropTypes.func,
placeholder: PropTypes.string,
error: PropTypes.string,
disabled: PropTypes.bool,
mask: PropTypes.array
mask: PropTypes.shape({
format: PropTypes.func,
append: PropTypes.func,
accept: PropTypes.instanceOf(RegExp)
})
}

export default InputComponent
61 changes: 60 additions & 1 deletion src/helpers/masks.js
Original file line number Diff line number Diff line change
@@ -1 +1,60 @@
export const dateMask = [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/]
export const dateMask = {
format: string => {
const numbers = string.replace(/\D/g, '').substr(0, 8).split('')

return numbers.reduce((acc, digit, index) => `${acc}${[2, 4].includes(index) ? '/' : ''}${digit}`, '')
},
accept: /\d+/g
}

export const phoneMask = {
format: string => {
const numbers = string.replace(/\D/g, '').substr(0, 11)
const match = numbers.match(/^(\d{1,2})(\d{0,5})(\d{0,4})$/)

if (!match) return numbers

return `(${match[1]})${match[2] ? ' ' : ''}${match[2]}${match[3] ? ' ' : ''}${match[3]}`
},
accept: /\d+/g
}

export const cpfMask = {
format: string => {
const numbers = string.replace(/\D/g, '').substr(0, 11)
const match = numbers.match(/^(\d{1,3})(\d{0,3})(\d{0,3})(\d{0,2})$/)

if (!match) return numbers

return `${match[1]}${match[2] ? '.' : ''}${match[2]}${match[3] ? '.' : ''}${match[3]}${match[4] ? '-' : ''}${
match[4]
}`
},
accept: /\d+/g
}

export const cepMask = {
format: string => {
const numbers = string.replace(/\D/g, '').substr(0, 8)
const match = numbers.match(/^(\d{1,5})(\d{0,3})$/)

if (!match) return numbers

return `${match[1]}${match[2] ? '-' : ''}${match[2]}`
},
accept: /\d+/g
}

export const moneyMask = {
format: string => {
const numbers = Number(string.replace(/\D/g, '')) / 100

if (!numbers) return ''

return numbers.toLocaleString('pt-BR', {
style: 'currency',
currency: 'BRL'
})
},
accept: /\d+/g
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

achei muito pica já ter algumas das máscaras mais comuns, só algumas sugestões.

  • a de currency eu tentaria deixar mais genérico, de uma forma q a gente pudesse escolher moedas diferentes de BRL.

  • adicionar uma máscara de cnpj

  • criar um helper de criação de mascaras númericas, tipo oq o createNumberMask do text-mask-addons faz (https://www.npmjs.com/package/text-mask-addons), será que isso caberia mais à nossa lib de hooks (prometheus)?

34 changes: 12 additions & 22 deletions src/routes/Login/Login.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import { useForm } from 'react-hook-form'
import { useForm, FormProvider } from 'react-hook-form'

import Column from 'components/Column'
import Input from 'components/Input'
Expand All @@ -12,29 +12,19 @@ import { loginResolver } from 'helpers/yup-schemas'
const Login = () => {
const { login } = useUser()

const { register, handleSubmit, errors, formState } = useForm({ resolver: loginResolver })
const methods = useForm({ resolver: loginResolver })
const { handleSubmit, formState } = methods

return (
<Column as='form' onSubmit={handleSubmit(login)} p={40} alignItems='center'>
<Input
name='email'
ref={register}
label='E-mail'
placeholder='[email protected]'
error={errors.email?.message}
/>
<Input
name='password'
ref={register}
label='Senha'
placeholder='******'
error={errors.password?.message}
type='password'
/>
<Button bg='purple' isLoading={formState.isSubmitting}>
Entrar
</Button>
</Column>
<FormProvider {...methods}>
<Column as='form' onSubmit={handleSubmit(login)} p={40} alignItems='center'>
<Input name='email' label='E-mail' placeholder='[email protected]' />
<Input name='password' label='Senha' placeholder='******' type='password' />
<Button bg='purple' isLoading={formState.isSubmitting}>
Entrar
</Button>
</Column>
</FormProvider>
)
}

Expand Down
Loading