diff --git a/package.json b/package.json index d9cdd07..2f65f17 100644 --- a/package.json +++ b/package.json @@ -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", @@ -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", diff --git a/src/components/Input/Input.js b/src/components/Input/Input.js index ef1d6fe..aa05975 100644 --- a/src/components/Input/Input.js +++ b/src/components/Input/Input.js @@ -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) => ( - - {label && {label}} - - {!mask ? ( - - ) : ( - } - /> - )} - - {error} - +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 ( + + {label && {label}} + + + + {error?.message} + + - -)) + ) +} const Input = styled.input` height: 40px; @@ -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 diff --git a/src/helpers/masks.js b/src/helpers/masks.js index cf4a21c..e7c37c4 100644 --- a/src/helpers/masks.js +++ b/src/helpers/masks.js @@ -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 +} diff --git a/src/routes/Login/Login.js b/src/routes/Login/Login.js index b924f34..b698d8c 100644 --- a/src/routes/Login/Login.js +++ b/src/routes/Login/Login.js @@ -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' @@ -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 ( - - - - - + + + + + + + ) } diff --git a/src/routes/UserForm/UserForm.js b/src/routes/UserForm/UserForm.js index e260bba..889b7e9 100644 --- a/src/routes/UserForm/UserForm.js +++ b/src/routes/UserForm/UserForm.js @@ -1,5 +1,5 @@ import React, { useMemo, useEffect } from 'react' -import { useForm, Controller } from 'react-hook-form' +import { useForm, Controller, FormProvider } from 'react-hook-form' import { useParams, useHistory } from 'react-router-dom' import { useQuery } from 'react-query' @@ -21,16 +21,17 @@ const UserForm = () => { const { handleOpenModal, handleCloseModal } = useModal() const { userRoles, isLoadingRoles } = useUser() + const methods = useForm({ + resolver: userFormResolver + }) + const { handleSubmit, - register, errors, reset, control, formState: { isSubmitting } - } = useForm({ - resolver: userFormResolver - }) + } = methods const { id } = useParams() const history = useHistory() @@ -99,98 +100,64 @@ const UserForm = () => { )} - - - {id ? 'Editar usuário' : 'Criar usuário'} - - - - - - ( - - - - - - - + + + + {id ? 'Editar usuário' : 'Criar usuário'} + + + + + + + + + + ( + + + + + + + + ) } diff --git a/src/routes/UsersList/UsersFilters.js b/src/routes/UsersList/UsersFilters.js index f20a91a..f408deb 100644 --- a/src/routes/UsersList/UsersFilters.js +++ b/src/routes/UsersList/UsersFilters.js @@ -1,5 +1,5 @@ import React from 'react' -import { useForm, Controller } from 'react-hook-form' +import { useForm, Controller, FormProvider } from 'react-hook-form' import Row from 'components/Row' import Input from 'components/Input' @@ -14,15 +14,15 @@ import { useUser } from 'context/user-context' const UsersFilters = ({ filters = {}, setFilters }) => { const { userRoles } = useUser([]) + const methods = useForm({ + defaultValues: filters + }) const { - register, handleSubmit, formState: { isSubmitting }, reset, control - } = useForm({ - defaultValues: filters - }) + } = methods const handleClearForm = () => { reset({ role: null, created_at: null }) @@ -30,59 +30,61 @@ const UsersFilters = ({ filters = {}, setFilters }) => { } return ( - - - - - ( - + + ( +