@lets-events/react 12.4.1 → 12.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/.eslintrc.json +2 -2
  2. package/CHANGELOG.md +6 -0
  3. package/package.json +1 -1
  4. package/src/components/Alert.tsx +303 -303
  5. package/src/components/Avatar.tsx +55 -55
  6. package/src/components/Badge.tsx +125 -125
  7. package/src/components/Box.tsx +3 -3
  8. package/src/components/Button/index.tsx +45 -45
  9. package/src/components/Button/styledComponents.ts +313 -313
  10. package/src/components/ButtonGroup.tsx +484 -484
  11. package/src/components/Calendar/index.tsx +148 -148
  12. package/src/components/Calendar/styledComponents.ts +259 -259
  13. package/src/components/Card.tsx +67 -67
  14. package/src/components/CheckboxGroup.tsx +176 -176
  15. package/src/components/Container.tsx +39 -39
  16. package/src/components/Divider.tsx +7 -7
  17. package/src/components/DoubleCalendar/index.tsx +170 -166
  18. package/src/components/Drawer/index.tsx +100 -98
  19. package/src/components/Drawer/styledComponents.ts +103 -103
  20. package/src/components/Dropdown.tsx +302 -302
  21. package/src/components/Filter.tsx +164 -164
  22. package/src/components/Flex.tsx +118 -118
  23. package/src/components/FormFields/AddressFormFields/CityFormField.tsx +111 -111
  24. package/src/components/FormFields/AddressFormFields/CountryFormField.tsx +33 -33
  25. package/src/components/FormFields/AddressFormFields/PostalCodeFormField.tsx +39 -39
  26. package/src/components/FormFields/AddressFormFields/StateFormField.tsx +32 -32
  27. package/src/components/FormFields/AddressFormFields/index.tsx +141 -141
  28. package/src/components/FormFields/BirthDateFormField.tsx +84 -84
  29. package/src/components/FormFields/CNPJFormField.tsx +87 -87
  30. package/src/components/FormFields/CPFFormField.tsx +78 -78
  31. package/src/components/FormFields/CalendarFormField.tsx +95 -95
  32. package/src/components/FormFields/CheckboxGroupFormField.tsx +91 -91
  33. package/src/components/FormFields/DoubleCalendarFormField.tsx +93 -90
  34. package/src/components/FormFields/EmailFormField.tsx +27 -27
  35. package/src/components/FormFields/Form.tsx +39 -39
  36. package/src/components/FormFields/IdentityDocumentNumberFormField.tsx +32 -32
  37. package/src/components/FormFields/MultiSelectFormField.tsx +64 -64
  38. package/src/components/FormFields/PhoneFormField.tsx +40 -40
  39. package/src/components/FormFields/RadioGroupFormField.tsx +84 -84
  40. package/src/components/FormFields/RichEditorFormField.tsx +103 -103
  41. package/src/components/FormFields/SelectFormField.tsx +93 -93
  42. package/src/components/FormFields/SwitchFormField.tsx +46 -46
  43. package/src/components/FormFields/TextAreaFormField.tsx +59 -59
  44. package/src/components/FormFields/TextFormField.tsx +112 -112
  45. package/src/components/FormFields/TimePickerFormField.tsx +88 -88
  46. package/src/components/FormFields/subComponents/ErrorFormMessage.tsx +36 -36
  47. package/src/components/FormFields/subComponents/FormLabel.tsx +29 -29
  48. package/src/components/FormFields/utils/validation.ts +23 -23
  49. package/src/components/Grid.tsx +137 -137
  50. package/src/components/Icon.tsx +47 -47
  51. package/src/components/MenuDropdown/index.tsx +38 -38
  52. package/src/components/MenuDropdown/styledComponents.ts +31 -31
  53. package/src/components/Modal.tsx +110 -110
  54. package/src/components/MultiSelect/index.tsx +243 -243
  55. package/src/components/MultiSelect/styledComponents.ts +160 -160
  56. package/src/components/RadioGroup.tsx +210 -210
  57. package/src/components/RichEditor/QuillComponent.tsx +457 -457
  58. package/src/components/RichEditor/RichEditor.tsx +49 -49
  59. package/src/components/RichEditor/index.ts +2 -2
  60. package/src/components/RichEditor/styledComponents.ts +1151 -1151
  61. package/src/components/Section.tsx +33 -33
  62. package/src/components/Step.tsx +164 -164
  63. package/src/components/Switch.tsx +108 -108
  64. package/src/components/Text.tsx +38 -38
  65. package/src/components/TextField.tsx +372 -372
  66. package/src/components/TextareaField.tsx +138 -138
  67. package/src/components/TimePicker.tsx +328 -328
  68. package/src/components/Toast/components/ToastItem.tsx +41 -41
  69. package/src/components/Toast/components/ToastProvider.tsx +63 -63
  70. package/src/components/Toast/hooks/useToast.ts +12 -12
  71. package/src/components/Toast/index.tsx +5 -5
  72. package/src/components/Toast/styles/index.ts +135 -135
  73. package/src/components/Toast/types/index.ts +46 -46
  74. package/src/components/Tooltip/index.tsx +66 -66
  75. package/src/components/Tooltip/styles.ts +77 -77
  76. package/src/hooks/useCountries.ts +41 -41
  77. package/src/hooks/useImageUpload.ts +139 -139
  78. package/src/hooks/useOnClickOutside.tsx +42 -42
  79. package/src/index.tsx +71 -71
  80. package/src/styles/index.ts +41 -41
  81. package/src/types/typographyValues.ts +178 -178
  82. package/src/utils/getNestedValue.ts +3 -3
  83. package/src/utils/states.ts +29 -29
  84. package/src/utils/uploadService.ts +180 -180
  85. package/tsconfig.json +3 -3
  86. package/tsup.config.ts +38 -38
  87. package/.turbo/turbo-build.log +0 -19
  88. package/dist/index.d.mts +0 -15398
  89. package/dist/index.d.ts +0 -15398
  90. package/dist/index.js +0 -13390
  91. package/dist/index.mjs +0 -13284
@@ -1,141 +1,141 @@
1
- import { useEffect } from "react";
2
- import { useFormContext, useWatch, useFormState } from "react-hook-form";
3
- import { CountryFormField } from "./CountryFormField";
4
- import { PostalCodeFormField } from "./PostalCodeFormField";
5
- import { StateFormField } from "./StateFormField";
6
- import { CityFormField } from "./CityFormField";
7
- import { FormLabel } from "../subComponents/FormLabel";
8
- import { TextFormField } from "../TextFormField";
9
- import { styled } from "../../../styles";
10
-
11
- type AddressFormFieldsProps = {
12
- name: string;
13
- label: string;
14
- required?: boolean;
15
- layout?: "column" | "grid";
16
- };
17
-
18
- function getNestedValue(obj: any, path: string): any {
19
- return path.split(".").reduce((acc, key) => acc?.[key], obj);
20
- }
21
-
22
- const AddressContainerStyled = styled("div", {
23
- variants: {
24
- layout: {
25
- column: {
26
- display: "flex",
27
- flexDirection: "column",
28
- gap: "$4",
29
- },
30
- grid: {
31
- display: "grid",
32
- gap: "$8 $16",
33
- gridTemplateColumns: "repeat(2, 1fr)",
34
-
35
- "& > *:nth-child(1)": {
36
- gridColumn: "span 2",
37
- },
38
- },
39
- },
40
- },
41
- });
42
- export function AddressFormFields({
43
- name,
44
- label,
45
- required,
46
- layout = "column",
47
- }: AddressFormFieldsProps) {
48
- const { control, setValue } = useFormContext();
49
- const { errors } = useFormState({ control });
50
-
51
- const selectedCountry = useWatch({ control, name: `${name}.country` });
52
- const isBrazil = selectedCountry === "Brasil";
53
-
54
- const addressErrors = getNestedValue(errors, name);
55
- const haveError = !!addressErrors;
56
-
57
- const handleCEPChange = (cep: string) => {
58
- if (!isBrazil) return;
59
-
60
- const cleanedCep = cep?.replace(/\D/g, "");
61
-
62
- if (cleanedCep?.length !== 8) return;
63
-
64
- fetch(`https://viacep.com.br/ws/${cleanedCep}/json`)
65
- .then((res) => res.json())
66
- .then((data) => {
67
- if (!data.erro) {
68
- setValue(`${name}.street`, data.logradouro || "");
69
- setValue(`${name}.neighborhood`, data.bairro || "");
70
- setValue(`${name}.city`, data.localidade || "");
71
- setValue(`${name}.state`, data.uf || "");
72
- }
73
- })
74
- .catch(() => {
75
- console.error("Erro ao buscar CEP");
76
- });
77
- };
78
-
79
- return (
80
- <AddressContainerStyled layout={layout}>
81
- <FormLabel
82
- name={name}
83
- label={label}
84
- required={required}
85
- haveError={haveError}
86
- />
87
-
88
- <CountryFormField
89
- name={`${name}.country`}
90
- label="País"
91
- required={required}
92
- language="pt-BR"
93
- />
94
-
95
- {isBrazil ? (
96
- <PostalCodeFormField
97
- name={`${name}.zip_code`}
98
- label="CEP"
99
- required={required}
100
- placeholder="00000-000"
101
- validationErrorMessage="CEP inválido"
102
- onChange={handleCEPChange}
103
- />
104
- ) : (
105
- <TextFormField
106
- name={`${name}.zip_code`}
107
- label="Código Postal"
108
- required={required}
109
- />
110
- )}
111
-
112
- <StateFormField
113
- name={`${name}.state`}
114
- label="Estado"
115
- required={required}
116
- isBrazil={isBrazil}
117
- />
118
-
119
- <CityFormField
120
- name={`${name}.city`}
121
- stateName={`${name}.state`}
122
- label="Cidade"
123
- required={required}
124
- isBrazil={isBrazil}
125
- />
126
-
127
- <TextFormField name={`${name}.street`} label="Rua" required={required} />
128
- <TextFormField
129
- name={`${name}.number`}
130
- label="Número"
131
- required={required}
132
- />
133
- <TextFormField
134
- name={`${name}.neighborhood`}
135
- label="Bairro"
136
- required={required}
137
- />
138
- <TextFormField name={`${name}.complement`} label="Complemento" />
139
- </AddressContainerStyled>
140
- );
141
- }
1
+ import { useEffect } from "react";
2
+ import { useFormContext, useWatch, useFormState } from "react-hook-form";
3
+ import { CountryFormField } from "./CountryFormField";
4
+ import { PostalCodeFormField } from "./PostalCodeFormField";
5
+ import { StateFormField } from "./StateFormField";
6
+ import { CityFormField } from "./CityFormField";
7
+ import { FormLabel } from "../subComponents/FormLabel";
8
+ import { TextFormField } from "../TextFormField";
9
+ import { styled } from "../../../styles";
10
+
11
+ type AddressFormFieldsProps = {
12
+ name: string;
13
+ label: string;
14
+ required?: boolean;
15
+ layout?: "column" | "grid";
16
+ };
17
+
18
+ function getNestedValue(obj: any, path: string): any {
19
+ return path.split(".").reduce((acc, key) => acc?.[key], obj);
20
+ }
21
+
22
+ const AddressContainerStyled = styled("div", {
23
+ variants: {
24
+ layout: {
25
+ column: {
26
+ display: "flex",
27
+ flexDirection: "column",
28
+ gap: "$4",
29
+ },
30
+ grid: {
31
+ display: "grid",
32
+ gap: "$8 $16",
33
+ gridTemplateColumns: "repeat(2, 1fr)",
34
+
35
+ "& > *:nth-child(1)": {
36
+ gridColumn: "span 2",
37
+ },
38
+ },
39
+ },
40
+ },
41
+ });
42
+ export function AddressFormFields({
43
+ name,
44
+ label,
45
+ required,
46
+ layout = "column",
47
+ }: AddressFormFieldsProps) {
48
+ const { control, setValue } = useFormContext();
49
+ const { errors } = useFormState({ control });
50
+
51
+ const selectedCountry = useWatch({ control, name: `${name}.country` });
52
+ const isBrazil = selectedCountry === "Brasil";
53
+
54
+ const addressErrors = getNestedValue(errors, name);
55
+ const haveError = !!addressErrors;
56
+
57
+ const handleCEPChange = (cep: string) => {
58
+ if (!isBrazil) return;
59
+
60
+ const cleanedCep = cep?.replace(/\D/g, "");
61
+
62
+ if (cleanedCep?.length !== 8) return;
63
+
64
+ fetch(`https://viacep.com.br/ws/${cleanedCep}/json`)
65
+ .then((res) => res.json())
66
+ .then((data) => {
67
+ if (!data.erro) {
68
+ setValue(`${name}.street`, data.logradouro || "");
69
+ setValue(`${name}.neighborhood`, data.bairro || "");
70
+ setValue(`${name}.city`, data.localidade || "");
71
+ setValue(`${name}.state`, data.uf || "");
72
+ }
73
+ })
74
+ .catch(() => {
75
+ console.error("Erro ao buscar CEP");
76
+ });
77
+ };
78
+
79
+ return (
80
+ <AddressContainerStyled layout={layout}>
81
+ <FormLabel
82
+ name={name}
83
+ label={label}
84
+ required={required}
85
+ haveError={haveError}
86
+ />
87
+
88
+ <CountryFormField
89
+ name={`${name}.country`}
90
+ label="País"
91
+ required={required}
92
+ language="pt-BR"
93
+ />
94
+
95
+ {isBrazil ? (
96
+ <PostalCodeFormField
97
+ name={`${name}.zip_code`}
98
+ label="CEP"
99
+ required={required}
100
+ placeholder="00000-000"
101
+ validationErrorMessage="CEP inválido"
102
+ onChange={handleCEPChange}
103
+ />
104
+ ) : (
105
+ <TextFormField
106
+ name={`${name}.zip_code`}
107
+ label="Código Postal"
108
+ required={required}
109
+ />
110
+ )}
111
+
112
+ <StateFormField
113
+ name={`${name}.state`}
114
+ label="Estado"
115
+ required={required}
116
+ isBrazil={isBrazil}
117
+ />
118
+
119
+ <CityFormField
120
+ name={`${name}.city`}
121
+ stateName={`${name}.state`}
122
+ label="Cidade"
123
+ required={required}
124
+ isBrazil={isBrazil}
125
+ />
126
+
127
+ <TextFormField name={`${name}.street`} label="Rua" required={required} />
128
+ <TextFormField
129
+ name={`${name}.number`}
130
+ label="Número"
131
+ required={required}
132
+ />
133
+ <TextFormField
134
+ name={`${name}.neighborhood`}
135
+ label="Bairro"
136
+ required={required}
137
+ />
138
+ <TextFormField name={`${name}.complement`} label="Complemento" />
139
+ </AddressContainerStyled>
140
+ );
141
+ }
@@ -1,84 +1,84 @@
1
- import { TextFormField } from "./TextFormField";
2
-
3
- type Language = "pt-BR" | "en" | "es";
4
-
5
- type BirthDateFormFieldProps = {
6
- name: string;
7
- label: string;
8
- required?: boolean;
9
- placeholder?: string;
10
- validationErrorMessage: string;
11
- language: Language;
12
- };
13
-
14
- const isValidDate = (day: number, month: number, year: number): boolean => {
15
- const date = new Date(year, month - 1, day);
16
- return (
17
- date.getFullYear() === year &&
18
- date.getMonth() === month - 1 &&
19
- date.getDate() === day
20
- );
21
- };
22
- const isValidBirthDate = (value: string, language: Language): boolean => {
23
- if (!/^\d{8}$/.test(value)) return false;
24
-
25
- let day = 0;
26
- let month = 0;
27
- let year = 0;
28
- if (language === "en") {
29
- month = Number(value.slice(0, 2));
30
- day = Number(value.slice(2, 4));
31
- year = Number(value.slice(4));
32
- } else {
33
- day = Number(value.slice(0, 2));
34
- month = Number(value.slice(2, 4));
35
- year = Number(value.slice(4));
36
- }
37
-
38
- if (!isValidDate(day, month, year)) return false;
39
-
40
- const today = new Date();
41
- const birthDate = new Date(year, month - 1, day);
42
-
43
- if (birthDate > today) return false;
44
-
45
- const age = today.getFullYear() - birthDate.getFullYear();
46
- const beforeBirthday =
47
- today.getMonth() < birthDate.getMonth() ||
48
- (today.getMonth() === birthDate.getMonth() &&
49
- today.getDate() < birthDate.getDate());
50
-
51
- const realAge = beforeBirthday ? age - 1 : age;
52
-
53
- return realAge <= 100;
54
- };
55
-
56
- export const BirthDateFormField = ({
57
- name,
58
- label,
59
- required,
60
- placeholder,
61
- validationErrorMessage,
62
- language,
63
- }: BirthDateFormFieldProps) => {
64
- const inputPlaceholder =
65
- placeholder || (language === "pt-BR" ? "DD/MM/AAAA" : "MM/DD/YYYY");
66
-
67
- return (
68
- <TextFormField
69
- name={name}
70
- label={label}
71
- required={required}
72
- placeholder={inputPlaceholder}
73
- mask={{
74
- mask: "__/__/____",
75
- replacement: { _: /[0-9]/ },
76
- }}
77
- validate={(value: string) => {
78
- const isEmpty = value.replace(/[^\d]+/g, "").length === 0;
79
- if (!required && isEmpty) return true;
80
- return isValidBirthDate(value, language) || validationErrorMessage;
81
- }}
82
- />
83
- );
84
- };
1
+ import { TextFormField } from "./TextFormField";
2
+
3
+ type Language = "pt-BR" | "en" | "es";
4
+
5
+ type BirthDateFormFieldProps = {
6
+ name: string;
7
+ label: string;
8
+ required?: boolean;
9
+ placeholder?: string;
10
+ validationErrorMessage: string;
11
+ language: Language;
12
+ };
13
+
14
+ const isValidDate = (day: number, month: number, year: number): boolean => {
15
+ const date = new Date(year, month - 1, day);
16
+ return (
17
+ date.getFullYear() === year &&
18
+ date.getMonth() === month - 1 &&
19
+ date.getDate() === day
20
+ );
21
+ };
22
+ const isValidBirthDate = (value: string, language: Language): boolean => {
23
+ if (!/^\d{8}$/.test(value)) return false;
24
+
25
+ let day = 0;
26
+ let month = 0;
27
+ let year = 0;
28
+ if (language === "en") {
29
+ month = Number(value.slice(0, 2));
30
+ day = Number(value.slice(2, 4));
31
+ year = Number(value.slice(4));
32
+ } else {
33
+ day = Number(value.slice(0, 2));
34
+ month = Number(value.slice(2, 4));
35
+ year = Number(value.slice(4));
36
+ }
37
+
38
+ if (!isValidDate(day, month, year)) return false;
39
+
40
+ const today = new Date();
41
+ const birthDate = new Date(year, month - 1, day);
42
+
43
+ if (birthDate > today) return false;
44
+
45
+ const age = today.getFullYear() - birthDate.getFullYear();
46
+ const beforeBirthday =
47
+ today.getMonth() < birthDate.getMonth() ||
48
+ (today.getMonth() === birthDate.getMonth() &&
49
+ today.getDate() < birthDate.getDate());
50
+
51
+ const realAge = beforeBirthday ? age - 1 : age;
52
+
53
+ return realAge <= 100;
54
+ };
55
+
56
+ export const BirthDateFormField = ({
57
+ name,
58
+ label,
59
+ required,
60
+ placeholder,
61
+ validationErrorMessage,
62
+ language,
63
+ }: BirthDateFormFieldProps) => {
64
+ const inputPlaceholder =
65
+ placeholder || (language === "pt-BR" ? "DD/MM/AAAA" : "MM/DD/YYYY");
66
+
67
+ return (
68
+ <TextFormField
69
+ name={name}
70
+ label={label}
71
+ required={required}
72
+ placeholder={inputPlaceholder}
73
+ mask={{
74
+ mask: "__/__/____",
75
+ replacement: { _: /[0-9]/ },
76
+ }}
77
+ validate={(value: string) => {
78
+ const isEmpty = value.replace(/[^\d]+/g, "").length === 0;
79
+ if (!required && isEmpty) return true;
80
+ return isValidBirthDate(value, language) || validationErrorMessage;
81
+ }}
82
+ />
83
+ );
84
+ };
@@ -1,87 +1,87 @@
1
- import { TextFormField } from "./TextFormField";
2
-
3
- type CNPJFormFieldProps = {
4
- name: string;
5
- label: string;
6
- required?: boolean;
7
- placeholder?: string;
8
- validationErrorMessage: string;
9
- };
10
-
11
- const matchesNonDigit = new RegExp(/\D+/g);
12
-
13
- const getWeights = (size: number, start: number, end: number) => {
14
- const weights = [];
15
- for (let i = size - 1; i >= 0; i--) {
16
- weights.push((end ? i % (end - start + 1) : i) + start);
17
- }
18
- return weights;
19
- };
20
- const calcValidatorDigit = (basicDigits: number[], weights: number[]) => {
21
- const sum = basicDigits.reduce(
22
- (sum, digit, index) => sum + digit * weights[index],
23
- 0
24
- );
25
- const mod = sum % 11;
26
- return mod < 2 ? 0 : 11 - mod;
27
- };
28
- const cnpjWeights1 = getWeights(12, 2, 9);
29
- const cnpjWeights2 = getWeights(13, 2, 9);
30
- export const isValidCNPJ = (cnpj: string) => {
31
- const digitsOnlyCnpj = cnpj.replace(matchesNonDigit, "");
32
-
33
- if (digitsOnlyCnpj.length !== 14) {
34
- return false;
35
- }
36
- // Elimina CNPJs com todos os dígitos iguais (ex: 11.111.111/1111-11)
37
- if (/^(\d)\1+$/.test(digitsOnlyCnpj)) return false;
38
-
39
- const cnpjArray = digitsOnlyCnpj
40
- .split("")
41
- .map((digit) => Number.parseInt(digit));
42
-
43
- const validatorDigit1 = cnpjArray[12];
44
- const validatorDigit2 = cnpjArray[13];
45
- const basicDigits = cnpjArray.slice(0, 12);
46
-
47
- const expectedValidator1 = calcValidatorDigit(basicDigits, cnpjWeights1);
48
- if (expectedValidator1 !== validatorDigit1) {
49
- return false;
50
- }
51
-
52
- const expectedValidator2 = calcValidatorDigit(
53
- [...basicDigits, validatorDigit1],
54
- cnpjWeights2
55
- );
56
- if (expectedValidator2 !== validatorDigit2) {
57
- return false;
58
- }
59
-
60
- return true;
61
- };
62
-
63
- export const CNPJFormField = ({
64
- name,
65
- label,
66
- required,
67
- placeholder,
68
- validationErrorMessage,
69
- }: CNPJFormFieldProps) => {
70
- return (
71
- <TextFormField
72
- name={name}
73
- label={label}
74
- required={required}
75
- placeholder={placeholder || "00.000.000/0000-00"}
76
- mask={{
77
- mask: "__.___.___/____-__",
78
- replacement: { _: /[0-9]/ },
79
- }}
80
- validate={(value: string) => {
81
- const isEmpty = value.replace(matchesNonDigit, "").length === 0;
82
- if (!required && isEmpty) return true;
83
- return isValidCNPJ(value) || validationErrorMessage;
84
- }}
85
- />
86
- );
87
- };
1
+ import { TextFormField } from "./TextFormField";
2
+
3
+ type CNPJFormFieldProps = {
4
+ name: string;
5
+ label: string;
6
+ required?: boolean;
7
+ placeholder?: string;
8
+ validationErrorMessage: string;
9
+ };
10
+
11
+ const matchesNonDigit = new RegExp(/\D+/g);
12
+
13
+ const getWeights = (size: number, start: number, end: number) => {
14
+ const weights = [];
15
+ for (let i = size - 1; i >= 0; i--) {
16
+ weights.push((end ? i % (end - start + 1) : i) + start);
17
+ }
18
+ return weights;
19
+ };
20
+ const calcValidatorDigit = (basicDigits: number[], weights: number[]) => {
21
+ const sum = basicDigits.reduce(
22
+ (sum, digit, index) => sum + digit * weights[index],
23
+ 0
24
+ );
25
+ const mod = sum % 11;
26
+ return mod < 2 ? 0 : 11 - mod;
27
+ };
28
+ const cnpjWeights1 = getWeights(12, 2, 9);
29
+ const cnpjWeights2 = getWeights(13, 2, 9);
30
+ export const isValidCNPJ = (cnpj: string) => {
31
+ const digitsOnlyCnpj = cnpj.replace(matchesNonDigit, "");
32
+
33
+ if (digitsOnlyCnpj.length !== 14) {
34
+ return false;
35
+ }
36
+ // Elimina CNPJs com todos os dígitos iguais (ex: 11.111.111/1111-11)
37
+ if (/^(\d)\1+$/.test(digitsOnlyCnpj)) return false;
38
+
39
+ const cnpjArray = digitsOnlyCnpj
40
+ .split("")
41
+ .map((digit) => Number.parseInt(digit));
42
+
43
+ const validatorDigit1 = cnpjArray[12];
44
+ const validatorDigit2 = cnpjArray[13];
45
+ const basicDigits = cnpjArray.slice(0, 12);
46
+
47
+ const expectedValidator1 = calcValidatorDigit(basicDigits, cnpjWeights1);
48
+ if (expectedValidator1 !== validatorDigit1) {
49
+ return false;
50
+ }
51
+
52
+ const expectedValidator2 = calcValidatorDigit(
53
+ [...basicDigits, validatorDigit1],
54
+ cnpjWeights2
55
+ );
56
+ if (expectedValidator2 !== validatorDigit2) {
57
+ return false;
58
+ }
59
+
60
+ return true;
61
+ };
62
+
63
+ export const CNPJFormField = ({
64
+ name,
65
+ label,
66
+ required,
67
+ placeholder,
68
+ validationErrorMessage,
69
+ }: CNPJFormFieldProps) => {
70
+ return (
71
+ <TextFormField
72
+ name={name}
73
+ label={label}
74
+ required={required}
75
+ placeholder={placeholder || "00.000.000/0000-00"}
76
+ mask={{
77
+ mask: "__.___.___/____-__",
78
+ replacement: { _: /[0-9]/ },
79
+ }}
80
+ validate={(value: string) => {
81
+ const isEmpty = value.replace(matchesNonDigit, "").length === 0;
82
+ if (!required && isEmpty) return true;
83
+ return isValidCNPJ(value) || validationErrorMessage;
84
+ }}
85
+ />
86
+ );
87
+ };