@lets-events/react 11.5.3 → 11.6.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 (74) hide show
  1. package/.eslintrc.json +2 -2
  2. package/.turbo/turbo-build.log +20 -18
  3. package/CHANGELOG.md +12 -0
  4. package/dist/index.d.mts +105 -14
  5. package/dist/index.d.ts +105 -14
  6. package/dist/index.js +1005 -143
  7. package/dist/index.mjs +966 -112
  8. package/package.json +2 -1
  9. package/src/components/Alert.tsx +303 -303
  10. package/src/components/Avatar.tsx +55 -55
  11. package/src/components/Badge.tsx +125 -125
  12. package/src/components/Box.tsx +3 -3
  13. package/src/components/Button/index.tsx +16 -16
  14. package/src/components/Button/styledComponents.ts +287 -287
  15. package/src/components/ButtonGroup.tsx +484 -484
  16. package/src/components/Calendar/index.tsx +136 -136
  17. package/src/components/Calendar/styledComponents.ts +209 -209
  18. package/src/components/Card.tsx +48 -48
  19. package/src/components/CheckboxGroup.tsx +176 -196
  20. package/src/components/Container.tsx +39 -39
  21. package/src/components/Drawer/index.tsx +48 -48
  22. package/src/components/Drawer/styledComponents.ts +46 -46
  23. package/src/components/Dropdown.tsx +192 -167
  24. package/src/components/Filter.tsx +164 -164
  25. package/src/components/Flex.tsx +118 -118
  26. package/src/components/FormFields/AddressFormFields/CityFormField.tsx +111 -0
  27. package/src/components/FormFields/AddressFormFields/CountryFormField.tsx +33 -0
  28. package/src/components/FormFields/AddressFormFields/PostalCodeFormField.tsx +45 -0
  29. package/src/components/FormFields/AddressFormFields/StateFormField.tsx +32 -0
  30. package/src/components/FormFields/AddressFormFields/index.tsx +139 -0
  31. package/src/components/FormFields/BirthDateFormField.tsx +87 -0
  32. package/src/components/FormFields/CNPJFormField.tsx +89 -0
  33. package/src/components/FormFields/CPFFormField.tsx +79 -0
  34. package/src/components/FormFields/CheckboxGroupFormField.tsx +90 -0
  35. package/src/components/FormFields/ErrorFormMessage.tsx +36 -36
  36. package/src/components/FormFields/Form.tsx +29 -25
  37. package/src/components/FormFields/FormLabel.tsx +29 -29
  38. package/src/components/FormFields/IdentityDocumentNumberFormField.tsx +42 -0
  39. package/src/components/FormFields/MultiSelectFormField.tsx +59 -59
  40. package/src/components/FormFields/PhoneFormField.tsx +130 -130
  41. package/src/components/FormFields/RadioGroupFormField.tsx +84 -0
  42. package/src/components/FormFields/SelectFormField.tsx +93 -0
  43. package/src/components/FormFields/TextAreaFormField.tsx +48 -49
  44. package/src/components/FormFields/TextFormField.tsx +76 -46
  45. package/src/components/Grid.tsx +137 -137
  46. package/src/components/Icon.tsx +47 -47
  47. package/src/components/MenuDropdown/index.tsx +30 -30
  48. package/src/components/MenuDropdown/styledComponents.ts +31 -31
  49. package/src/components/Modal.tsx +90 -90
  50. package/src/components/MultiSelect.tsx +218 -218
  51. package/src/components/RadioGroup.tsx +210 -210
  52. package/src/components/Section.tsx +33 -33
  53. package/src/components/Step.tsx +164 -164
  54. package/src/components/Switch.tsx +108 -108
  55. package/src/components/Text.tsx +38 -38
  56. package/src/components/TextField.tsx +312 -315
  57. package/src/components/TextareaField.tsx +128 -128
  58. package/src/components/TimePicker.tsx +298 -298
  59. package/src/components/Toast/components/ToastItem.tsx +41 -41
  60. package/src/components/Toast/components/ToastProvider.tsx +63 -63
  61. package/src/components/Toast/hooks/useToast.ts +12 -12
  62. package/src/components/Toast/index.tsx +5 -5
  63. package/src/components/Toast/styles/index.ts +135 -135
  64. package/src/components/Toast/types/index.ts +46 -46
  65. package/src/components/Tooltip/index.tsx +66 -66
  66. package/src/components/Tooltip/styles.ts +77 -77
  67. package/src/hooks/useCountries.ts +41 -0
  68. package/src/hooks/useOnClickOutside.tsx +20 -20
  69. package/src/index.tsx +52 -45
  70. package/src/styles/index.ts +38 -38
  71. package/src/types/typographyValues.ts +178 -178
  72. package/src/utils/getNestedValue.ts +3 -0
  73. package/src/utils/states.ts +29 -0
  74. package/tsconfig.json +3 -3
@@ -0,0 +1,33 @@
1
+ import { Flex } from "../../Flex";
2
+ import { SelectFormField } from "../SelectFormField";
3
+ import { useCountries } from "../../../hooks/useCountries";
4
+
5
+ type CountryFormFieldProps = {
6
+ name: string;
7
+ label: string;
8
+ required?: boolean;
9
+ placeholder?: string;
10
+ language?: "es" | "pt-BR" | "en";
11
+ haveError?: boolean;
12
+ };
13
+
14
+ export function CountryFormField({
15
+ name,
16
+ label,
17
+ required,
18
+ language = "pt-BR",
19
+ }: CountryFormFieldProps) {
20
+ const countries = useCountries(language);
21
+
22
+ return (
23
+ <Flex direction="column">
24
+ <SelectFormField
25
+ label={label}
26
+ name={name}
27
+ options={countries}
28
+ required={required}
29
+ defaultValue="Brasil"
30
+ />
31
+ </Flex>
32
+ );
33
+ }
@@ -0,0 +1,45 @@
1
+ import { useController, useFormContext } from "react-hook-form";
2
+ import { TextFormField } from "../TextFormField";
3
+
4
+ export const PostalCodeFormField = ({
5
+ name,
6
+ label,
7
+ required,
8
+ placeholder,
9
+ validationErrorMessage,
10
+ }: {
11
+ name: string;
12
+ label: string;
13
+ required?: boolean;
14
+ placeholder?: string;
15
+ validationErrorMessage: string;
16
+ }) => {
17
+ const { control } = useFormContext();
18
+ const {
19
+ field: { onChange, value },
20
+ } = useController({ name, control });
21
+
22
+ return (
23
+ <TextFormField
24
+ name={name}
25
+ label={label}
26
+ required={required}
27
+ placeholder={placeholder || "00000-000"}
28
+ mask={{
29
+ mask: "_____-___",
30
+ replacement: { _: /[0-9]/ },
31
+ }}
32
+ value={value}
33
+ onChange={onChange}
34
+ validation={{
35
+ validate: (value: string) => {
36
+ const isEmpty = value.replace(/[^\d]/g, "").length === 0;
37
+ if (!required && isEmpty) return true;
38
+ return (
39
+ /^\d{8}$/.test(value.replace(/\D/g, "")) || validationErrorMessage
40
+ );
41
+ },
42
+ }}
43
+ />
44
+ );
45
+ };
@@ -0,0 +1,32 @@
1
+ import { SelectFormField } from "../SelectFormField";
2
+ import { TextFormField } from "../TextFormField";
3
+ import { brazilianStates } from "../../../utils/states";
4
+
5
+ type StateFormFieldProps = {
6
+ name: string;
7
+ label: string;
8
+ required?: boolean;
9
+ isBrazil: boolean;
10
+ };
11
+
12
+ export function StateFormField({
13
+ name,
14
+ label,
15
+ required,
16
+ isBrazil,
17
+ }: StateFormFieldProps) {
18
+ return (
19
+ <>
20
+ {isBrazil ? (
21
+ <SelectFormField
22
+ name={name}
23
+ options={brazilianStates}
24
+ required={required}
25
+ label={label}
26
+ />
27
+ ) : (
28
+ <TextFormField name={name} required={required} label={label} />
29
+ )}
30
+ </>
31
+ );
32
+ }
@@ -0,0 +1,139 @@
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 "../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 cep = useWatch({ control, name: `${name}.zip_code` });
53
+ const isBrazil = selectedCountry === "Brasil";
54
+
55
+ const addressErrors = getNestedValue(errors, name);
56
+ const haveError = !!addressErrors;
57
+
58
+ useEffect(() => {
59
+ const cleanedCep = cep?.replace(/\D/g, "");
60
+
61
+ if (isBrazil && cleanedCep?.length === 8) {
62
+ fetch(`https://viacep.com.br/ws/${cleanedCep}/json`)
63
+ .then((res) => res.json())
64
+ .then((data) => {
65
+ if (!data.erro) {
66
+ setValue(`${name}.street`, data.logradouro || "");
67
+ setValue(`${name}.neighborhood`, data.bairro || "");
68
+ setValue(`${name}.city`, data.localidade || "");
69
+ setValue(`${name}.state`, data.uf || "");
70
+ }
71
+ })
72
+ .catch(() => {
73
+ console.error("Erro ao buscar CEP");
74
+ });
75
+ }
76
+ }, [cep, isBrazil]);
77
+
78
+ return (
79
+ <AddressContainerStyled layout={layout}>
80
+ <FormLabel
81
+ name={name}
82
+ label={label}
83
+ required={required}
84
+ haveError={haveError}
85
+ />
86
+
87
+ <CountryFormField
88
+ name={`${name}.country`}
89
+ label="País"
90
+ required={required}
91
+ language="pt-BR"
92
+ />
93
+
94
+ {isBrazil ? (
95
+ <PostalCodeFormField
96
+ name={`${name}.zip_code`}
97
+ label="CEP"
98
+ required={required}
99
+ placeholder="00000-000"
100
+ validationErrorMessage="CEP inválido"
101
+ />
102
+ ) : (
103
+ <TextFormField
104
+ name={`${name}.zip_code`}
105
+ label="Código Postal"
106
+ required={required}
107
+ />
108
+ )}
109
+
110
+ <StateFormField
111
+ name={`${name}.state`}
112
+ label="Estado"
113
+ required={required}
114
+ isBrazil={isBrazil}
115
+ />
116
+
117
+ <CityFormField
118
+ name={`${name}.city`}
119
+ stateName={`${name}.state`}
120
+ label="Cidade"
121
+ required={required}
122
+ isBrazil={isBrazil}
123
+ />
124
+
125
+ <TextFormField name={`${name}.street`} label="Rua" required={required} />
126
+ <TextFormField
127
+ name={`${name}.number`}
128
+ label="Número"
129
+ required={required}
130
+ />
131
+ <TextFormField
132
+ name={`${name}.neighborhood`}
133
+ label="Bairro"
134
+ required={required}
135
+ />
136
+ <TextFormField name={`${name}.complement`} label="Complemento" />
137
+ </AddressContainerStyled>
138
+ );
139
+ }
@@ -0,0 +1,87 @@
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
+
23
+ const isValidBirthDate = (value: string, language: Language): boolean => {
24
+ const [part1, part2, part3] = value.split("/").map(Number);
25
+ let day = 0,
26
+ month = 0,
27
+ year = 0;
28
+
29
+ if (language === "en") {
30
+ month = part1;
31
+ day = part2;
32
+ year = part3;
33
+ } else {
34
+ day = part1;
35
+ month = part2;
36
+ year = part3;
37
+ }
38
+
39
+ if (!isValidDate(day, month, year)) return false;
40
+
41
+ const today = new Date();
42
+ const birthDate = new Date(year, month - 1, day);
43
+
44
+ if (birthDate > today) return false;
45
+
46
+ const age = today.getFullYear() - birthDate.getFullYear();
47
+ const beforeBirthday =
48
+ today.getMonth() < birthDate.getMonth() ||
49
+ (today.getMonth() === birthDate.getMonth() &&
50
+ today.getDate() < birthDate.getDate());
51
+
52
+ const realAge = beforeBirthday ? age - 1 : age;
53
+
54
+ return realAge <= 100;
55
+ };
56
+
57
+ export const BirthDateFormField = ({
58
+ name,
59
+ label,
60
+ required,
61
+ placeholder,
62
+ validationErrorMessage,
63
+ language,
64
+ }: BirthDateFormFieldProps) => {
65
+ const inputPlaceholder =
66
+ placeholder || (language === "en" ? "MM/DD/YYYY" : "DD/MM/AAAA");
67
+
68
+ return (
69
+ <TextFormField
70
+ name={name}
71
+ label={label}
72
+ required={required}
73
+ placeholder={inputPlaceholder}
74
+ mask={{
75
+ mask: "__/__/____",
76
+ replacement: { _: /[0-9]/ },
77
+ }}
78
+ validation={{
79
+ validate: (value: string) => {
80
+ const isEmpty = value.replace(/[^\d]+/g, "").length === 0;
81
+ if (!required && isEmpty) return true;
82
+ return isValidBirthDate(value, language) || validationErrorMessage;
83
+ },
84
+ }}
85
+ />
86
+ );
87
+ };
@@ -0,0 +1,89 @@
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
+ validation={{
81
+ validate: (value: string) => {
82
+ const isEmpty = value.replace(matchesNonDigit, "").length === 0;
83
+ if (!required && isEmpty) return true;
84
+ return isValidCNPJ(value) || validationErrorMessage;
85
+ },
86
+ }}
87
+ />
88
+ );
89
+ };
@@ -0,0 +1,79 @@
1
+ import { useFormContext, useWatch } from "react-hook-form";
2
+ import { CheckboxGroup, CheckboxItem } from "../CheckboxGroup";
3
+ import { Flex } from "../Flex";
4
+ import { TextFormField } from "./TextFormField";
5
+
6
+ type CPFFormFieldProps = {
7
+ name: string;
8
+ label: string;
9
+ required?: boolean;
10
+ placeholder?: string;
11
+ validationErrorMessage: string;
12
+ foreignerLabel: string;
13
+ };
14
+
15
+ const isValidCPF = (cpf: string) => {
16
+ cpf = cpf.replace(/[^\d]+/g, "");
17
+ if (cpf.length !== 11 || /^(\d)\1{10}$/.test(cpf)) return false;
18
+
19
+ let sum = 0;
20
+ for (let i = 0; i < 9; i++) sum += parseInt(cpf.charAt(i)) * (10 - i);
21
+ let rest = (sum * 10) % 11;
22
+ if (rest === 10 || rest === 11) rest = 0;
23
+ if (rest !== parseInt(cpf.charAt(9))) return false;
24
+
25
+ sum = 0;
26
+ for (let i = 0; i < 10; i++) sum += parseInt(cpf.charAt(i)) * (11 - i);
27
+ rest = (sum * 10) % 11;
28
+ if (rest === 10 || rest === 11) rest = 0;
29
+ if (rest !== parseInt(cpf.charAt(10))) return false;
30
+
31
+ return true;
32
+ };
33
+
34
+ export const CPFFormField = ({
35
+ name,
36
+ label,
37
+ required,
38
+ placeholder,
39
+ validationErrorMessage,
40
+ foreignerLabel,
41
+ }: CPFFormFieldProps) => {
42
+ const { control, setValue } = useFormContext();
43
+ const foreigner = useWatch({ name: "foreigner", control });
44
+
45
+ return (
46
+ <Flex direction="column">
47
+ <TextFormField
48
+ name={name}
49
+ label={label}
50
+ required={required && !foreigner}
51
+ placeholder={placeholder || "000.000.000-00"}
52
+ mask={{
53
+ mask: "___.___.___-__",
54
+ replacement: { _: /[0-9]/ },
55
+ }}
56
+ validation={{
57
+ validate: (value: string) => {
58
+ if (!required || foreigner) return true;
59
+ return isValidCPF(value) || validationErrorMessage;
60
+ },
61
+ }}
62
+ disabled={foreigner}
63
+ />
64
+
65
+ <CheckboxGroup
66
+ name="foreigner"
67
+ onValueChange={(value) => {
68
+ const isForeigner = value.includes("true");
69
+ setValue("foreigner", isForeigner);
70
+ if (isForeigner) {
71
+ setValue(name, "");
72
+ }
73
+ }}
74
+ >
75
+ <CheckboxItem value="true">{foreignerLabel}</CheckboxItem>
76
+ </CheckboxGroup>
77
+ </Flex>
78
+ );
79
+ };
@@ -0,0 +1,90 @@
1
+ import { Controller, useFormContext } from "react-hook-form";
2
+ import { Flex } from "../Flex";
3
+ import { FormLabel } from "./FormLabel";
4
+ import { ErrorFormMessage } from "./ErrorFormMessage";
5
+ import { CheckboxGroup, CheckboxItem } from "../CheckboxGroup";
6
+ import { getNestedValue } from "../../utils/getNestedValue";
7
+
8
+ type Option = {
9
+ label: string;
10
+ value: string;
11
+ };
12
+
13
+ export type CheckboxGroupFormFieldProps = {
14
+ name: string;
15
+ label: string;
16
+ options: Option[];
17
+ required?: boolean;
18
+ validationErrorMessage?: string;
19
+ defaultValue?: string[];
20
+ color?: "blue" | "success" | "error";
21
+ fontWeight?: "regular" | "medium" | "semibold" | "bold";
22
+ disabled?: boolean;
23
+ };
24
+
25
+ export const CheckboxGroupFormField = ({
26
+ name,
27
+ label,
28
+ options,
29
+ required,
30
+ validationErrorMessage = "Selecione pelo menos uma opção.",
31
+ defaultValue = [],
32
+ color = "blue",
33
+ fontWeight = "regular",
34
+ disabled = false,
35
+ }: CheckboxGroupFormFieldProps) => {
36
+ const {
37
+ control,
38
+ formState: { errors },
39
+ } = useFormContext();
40
+
41
+ const fieldError = getNestedValue(errors, name);
42
+ const haveError = !!fieldError;
43
+ const errorMsg = fieldError?.message;
44
+
45
+ const validationRules = {
46
+ required: required ? validationErrorMessage : false,
47
+ validate: required
48
+ ? (value: string[]) => value?.length > 0 || validationErrorMessage
49
+ : undefined,
50
+ };
51
+
52
+ return (
53
+ <Flex direction="column">
54
+ <FormLabel
55
+ name={name}
56
+ label={label}
57
+ required={required}
58
+ haveError={haveError}
59
+ />
60
+
61
+ <Controller
62
+ name={name}
63
+ control={control}
64
+ rules={validationRules}
65
+ defaultValue={defaultValue}
66
+ render={({ field }) => (
67
+ <CheckboxGroup
68
+ name={name}
69
+ onValueChange={field.onChange}
70
+ color={haveError ? "error" : color}
71
+ fontWeight={fontWeight}
72
+ disabled={disabled}
73
+ >
74
+ {options.map((option) => (
75
+ <CheckboxItem
76
+ key={option.value}
77
+ value={option.value}
78
+ disabled={disabled}
79
+ >
80
+ {option.label}
81
+ </CheckboxItem>
82
+ ))}
83
+ </CheckboxGroup>
84
+ )}
85
+ />
86
+
87
+ <ErrorFormMessage message={errorMsg} />
88
+ </Flex>
89
+ );
90
+ };
@@ -1,36 +1,36 @@
1
- import { faXmarkCircle } from "@fortawesome/free-solid-svg-icons";
2
- import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
3
- import { colors } from "@lets-events/tokens";
4
- import { Flex } from "../Flex";
5
- import { Text } from "../Text";
6
- import {
7
- FieldError,
8
- FieldErrorsImpl,
9
- FieldValues,
10
- Merge,
11
- } from "react-hook-form";
12
-
13
- export type ErrorFormMessageProps = {
14
- message?:
15
- | string
16
- | FieldError
17
- | Merge<FieldError, FieldErrorsImpl<any>>
18
- | undefined;
19
- };
20
-
21
- export const ErrorFormMessage = ({ message }: ErrorFormMessageProps) => {
22
- if (!message) return null;
23
-
24
- if (typeof message !== "string") {
25
- return null;
26
- }
27
-
28
- return (
29
- <Flex justify={"start"} align={"center"} gap={6}>
30
- <FontAwesomeIcon icon={faXmarkCircle} color={colors.error600} size="1x" />
31
- <Text typography={"bodyXS"} fontWeight={"medium"} color="error600">
32
- {message}
33
- </Text>
34
- </Flex>
35
- );
36
- };
1
+ import { faXmarkCircle } from "@fortawesome/free-solid-svg-icons";
2
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
3
+ import { colors } from "@lets-events/tokens";
4
+ import { Flex } from "../Flex";
5
+ import { Text } from "../Text";
6
+ import {
7
+ FieldError,
8
+ FieldErrorsImpl,
9
+ FieldValues,
10
+ Merge,
11
+ } from "react-hook-form";
12
+
13
+ export type ErrorFormMessageProps = {
14
+ message?:
15
+ | string
16
+ | FieldError
17
+ | Merge<FieldError, FieldErrorsImpl<any>>
18
+ | undefined;
19
+ };
20
+
21
+ export const ErrorFormMessage = ({ message }: ErrorFormMessageProps) => {
22
+ if (!message) return null;
23
+
24
+ if (typeof message !== "string") {
25
+ return null;
26
+ }
27
+
28
+ return (
29
+ <Flex justify={"start"} align={"center"} gap={6}>
30
+ <FontAwesomeIcon icon={faXmarkCircle} color={colors.error600} size="1x" />
31
+ <Text typography={"bodyXS"} fontWeight={"medium"} color="error600">
32
+ {message}
33
+ </Text>
34
+ </Flex>
35
+ );
36
+ };