@lets-events/react 11.8.1 → 12.1.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 (87) hide show
  1. package/.eslintrc.json +2 -2
  2. package/.turbo/turbo-build.log +21 -18
  3. package/CHANGELOG.md +12 -0
  4. package/dist/index.d.mts +139 -11
  5. package/dist/index.d.ts +139 -11
  6. package/dist/index.js +1260 -361
  7. package/dist/index.mjs +1251 -358
  8. package/package.json +7 -2
  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 +288 -287
  15. package/src/components/ButtonGroup.tsx +484 -484
  16. package/src/components/Calendar/index.tsx +146 -136
  17. package/src/components/Calendar/styledComponents.ts +250 -209
  18. package/src/components/Card.tsx +48 -48
  19. package/src/components/CheckboxGroup.tsx +176 -176
  20. package/src/components/Container.tsx +39 -39
  21. package/src/components/Drawer/index.tsx +129 -55
  22. package/src/components/Drawer/styledComponents.ts +46 -46
  23. package/src/components/Dropdown.tsx +302 -302
  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 -111
  27. package/src/components/FormFields/AddressFormFields/CountryFormField.tsx +33 -33
  28. package/src/components/FormFields/AddressFormFields/PostalCodeFormField.tsx +39 -39
  29. package/src/components/FormFields/AddressFormFields/StateFormField.tsx +32 -32
  30. package/src/components/FormFields/AddressFormFields/index.tsx +141 -141
  31. package/src/components/FormFields/BirthDateFormField.tsx +84 -84
  32. package/src/components/FormFields/CNPJFormField.tsx +87 -87
  33. package/src/components/FormFields/CPFFormField.tsx +78 -78
  34. package/src/components/FormFields/CalendarFormField.tsx +92 -0
  35. package/src/components/FormFields/CheckboxGroupFormField.tsx +91 -91
  36. package/src/components/FormFields/EmailFormField.tsx +27 -27
  37. package/src/components/FormFields/Form.tsx +39 -39
  38. package/src/components/FormFields/IdentityDocumentNumberFormField.tsx +37 -40
  39. package/src/components/FormFields/MultiSelectFormField.tsx +64 -55
  40. package/src/components/FormFields/PhoneFormField.tsx +40 -40
  41. package/src/components/FormFields/RadioGroupFormField.tsx +84 -84
  42. package/src/components/FormFields/RichEditorFormField.tsx +69 -0
  43. package/src/components/FormFields/SelectFormField.tsx +93 -93
  44. package/src/components/FormFields/TextAreaFormField.tsx +57 -48
  45. package/src/components/FormFields/TextFormField.tsx +112 -112
  46. package/src/components/FormFields/TimePickerFormField.tsx +88 -0
  47. package/src/components/FormFields/subComponents/ErrorFormMessage.tsx +36 -36
  48. package/src/components/FormFields/subComponents/FormLabel.tsx +29 -29
  49. package/src/components/FormFields/utils/validation.ts +23 -23
  50. package/src/components/Grid.tsx +137 -137
  51. package/src/components/Icon.tsx +47 -47
  52. package/src/components/MenuDropdown/index.tsx +38 -38
  53. package/src/components/MenuDropdown/styledComponents.ts +31 -31
  54. package/src/components/Modal.tsx +90 -90
  55. package/src/components/MultiSelect.tsx +311 -267
  56. package/src/components/RadioGroup.tsx +210 -210
  57. package/src/components/RichEditor/QuillComponent.tsx +413 -0
  58. package/src/components/RichEditor/RichEditor.tsx +38 -0
  59. package/src/components/RichEditor/index.ts +2 -0
  60. package/src/components/RichEditor/styledComponents.ts +62 -0
  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 -365
  66. package/src/components/TextareaField.tsx +128 -128
  67. package/src/components/TimePicker.tsx +325 -298
  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 -0
  78. package/src/hooks/useOnClickOutside.tsx +42 -20
  79. package/src/index.tsx +67 -55
  80. package/src/styles/index.ts +38 -38
  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 -0
  85. package/tsconfig.json +3 -3
  86. package/tsup.config.ts +38 -0
  87. package/dist/index.css +0 -171
@@ -0,0 +1,180 @@
1
+ export interface UploadConfig {
2
+ apiUrl: string;
3
+ s3Bucket: string;
4
+ s3Region: string;
5
+ s3Url: string;
6
+ timeout?: number;
7
+ maxFileSize?: number;
8
+ endpoints?: {
9
+ presignedUrl: string;
10
+ upload: string;
11
+ };
12
+ }
13
+
14
+ interface UploadResponse {
15
+ url: string;
16
+ filename: string;
17
+ size: number;
18
+ type: string;
19
+ }
20
+
21
+ interface UploadProgress {
22
+ amount: number;
23
+ message: string;
24
+ }
25
+ const generateUniqueFilename = (originalName: string): string => {
26
+ const timestamp = Date.now().toString(36);
27
+ const random = Math.random().toString(36).substring(2, 8);
28
+ const extension = originalName.split(".").pop();
29
+
30
+ return `${timestamp}_${random}.${extension}`;
31
+ };
32
+
33
+ export class UploadService {
34
+ static async getPresignedUrl(
35
+ filename: string,
36
+ contentType: string,
37
+ config: UploadConfig
38
+ ): Promise<string> {
39
+ const apiUrl = config.apiUrl;
40
+ const presignedUrlEndpoint = config.endpoints?.presignedUrl;
41
+ const bucket = config.s3Bucket;
42
+
43
+ try {
44
+ const response = await fetch(`${apiUrl}${presignedUrlEndpoint}`, {
45
+ method: "POST",
46
+ headers: {
47
+ "Content-Type": "application/json",
48
+ },
49
+ body: JSON.stringify({
50
+ filename,
51
+ contentType,
52
+ bucket,
53
+ }),
54
+ });
55
+
56
+ if (!response.ok) {
57
+ throw new Error("Falha ao gerar URL de upload");
58
+ }
59
+
60
+ const data = await response.json();
61
+ return data.presignedUrl;
62
+ } catch (error) {
63
+ console.error("Erro ao gerar URL pré-assinada:", error);
64
+ throw new Error("Falha ao gerar URL de upload");
65
+ }
66
+ }
67
+
68
+ static async uploadToS3(
69
+ file: File,
70
+ config: UploadConfig,
71
+ onProgress?: (progress: UploadProgress) => void
72
+ ): Promise<UploadResponse> {
73
+ try {
74
+ const uniqueFilename = generateUniqueFilename(file.name);
75
+ const blob = new Blob([file], { type: file.type });
76
+
77
+ const s3Url = `${config.s3Url}/${uniqueFilename}`;
78
+
79
+ return new Promise((resolve, reject) => {
80
+ const xhr = new XMLHttpRequest();
81
+
82
+ xhr.upload.addEventListener("progress", (event) => {
83
+ if (event.lengthComputable) {
84
+ const percentComplete = Math.round(
85
+ (event.loaded / event.total) * 100
86
+ );
87
+ onProgress?.({
88
+ amount: percentComplete,
89
+ message: `Fazendo upload... ${percentComplete}%`,
90
+ });
91
+ }
92
+ });
93
+
94
+ xhr.addEventListener("load", () => {
95
+ if (xhr.status === 200) {
96
+ resolve({
97
+ url: s3Url,
98
+ filename: uniqueFilename,
99
+ size: file.size,
100
+ type: file.type,
101
+ });
102
+ } else {
103
+ reject(new Error(`Upload falhou com status: ${xhr.status}`));
104
+ }
105
+ });
106
+
107
+ xhr.addEventListener("error", () => {
108
+ reject(new Error("Erro de rede durante upload"));
109
+ });
110
+
111
+ xhr.open("PUT", s3Url);
112
+ xhr.setRequestHeader("Content-Type", file.type);
113
+ xhr.send(blob);
114
+ });
115
+ } catch (error) {
116
+ console.error("Erro no upload:", error);
117
+ throw error;
118
+ }
119
+ }
120
+
121
+ static async uploadViaAPI(
122
+ file: File,
123
+ config: UploadConfig,
124
+ onProgress?: (progress: UploadProgress) => void
125
+ ): Promise<UploadResponse> {
126
+ try {
127
+ const formData = new FormData();
128
+ formData.append("file", file);
129
+ const bucket = config.s3Bucket;
130
+ formData.append("bucket", bucket);
131
+
132
+ const xhr = new XMLHttpRequest();
133
+
134
+ return new Promise((resolve, reject) => {
135
+ xhr.upload.addEventListener("progress", (event) => {
136
+ if (event.lengthComputable) {
137
+ const percentComplete = Math.round(
138
+ (event.loaded / event.total) * 100
139
+ );
140
+ onProgress?.({
141
+ amount: percentComplete,
142
+ message: `Fazendo upload... ${percentComplete}%`,
143
+ });
144
+ }
145
+ });
146
+
147
+ xhr.addEventListener("load", () => {
148
+ if (xhr.status === 200) {
149
+ try {
150
+ const response = JSON.parse(xhr.responseText);
151
+ resolve({
152
+ url: response.url,
153
+ filename: response.filename,
154
+ size: file.size,
155
+ type: file.type,
156
+ });
157
+ } catch (error) {
158
+ reject(new Error("Resposta inválida do servidor"));
159
+ }
160
+ } else {
161
+ reject(new Error(`Upload falhou com status: ${xhr.status}`));
162
+ }
163
+ });
164
+
165
+ xhr.addEventListener("error", () => {
166
+ reject(new Error("Erro de rede durante upload"));
167
+ });
168
+
169
+ const apiUrl = config.apiUrl;
170
+ const uploadEndpoint = config.endpoints?.upload;
171
+
172
+ xhr.open("POST", `${apiUrl}${uploadEndpoint}`);
173
+ xhr.send(formData);
174
+ });
175
+ } catch (error) {
176
+ console.error("Erro no upload via API:", error);
177
+ throw error;
178
+ }
179
+ }
180
+ }
package/tsconfig.json CHANGED
@@ -1,4 +1,4 @@
1
- {
2
- "extends": "@lets-events/ts-config/react.json",
3
- "include": ["src"]
1
+ {
2
+ "extends": "@lets-events/ts-config/react.json",
3
+ "include": ["src"]
4
4
  }
package/tsup.config.ts ADDED
@@ -0,0 +1,38 @@
1
+ import { defineConfig } from "tsup";
2
+
3
+ export default defineConfig({
4
+ entry: ["src/index.tsx"],
5
+ format: ["esm", "cjs"],
6
+ dts: true,
7
+ external: ["react"],
8
+ define: {
9
+ "process.env.REACT_APP_API_URL": JSON.stringify(
10
+ process.env.REACT_APP_API_URL || "https://api.lets.events"
11
+ ),
12
+ "process.env.REACT_APP_S3_BUCKET": JSON.stringify(
13
+ process.env.REACT_APP_S3_BUCKET || "lets.events-development"
14
+ ),
15
+ "process.env.REACT_APP_S3_REGION": JSON.stringify(
16
+ process.env.REACT_APP_S3_REGION || "sa-east-1"
17
+ ),
18
+ "process.env.REACT_APP_AWS_URL": JSON.stringify(
19
+ process.env.REACT_APP_AWS_URL ||
20
+ "https://s3-sa-east-1.amazonaws.com/lets.events-development"
21
+ ),
22
+ "process.env.REACT_APP_UPLOAD_TIMEOUT": JSON.stringify(
23
+ process.env.REACT_APP_UPLOAD_TIMEOUT || "30000"
24
+ ),
25
+ "process.env.REACT_APP_MAX_FILE_SIZE": JSON.stringify(
26
+ process.env.REACT_APP_MAX_FILE_SIZE || "5242880"
27
+ ),
28
+ "process.env.NODE_ENV": JSON.stringify(
29
+ process.env.NODE_ENV || "development"
30
+ ),
31
+ "process.env.REACT_APP_AWS_ACCESS_KEY_ID": JSON.stringify(
32
+ process.env.REACT_APP_AWS_ACCESS_KEY_ID || ""
33
+ ),
34
+ "process.env.REACT_APP_AWS_SECRET_ACCESS_KEY": JSON.stringify(
35
+ process.env.REACT_APP_AWS_SECRET_ACCESS_KEY || ""
36
+ ),
37
+ },
38
+ });
package/dist/index.css DELETED
@@ -1,171 +0,0 @@
1
- /* ../../node_modules/react-international-phone/dist/index.css */
2
- .react-international-phone-country-selector {
3
- position: relative;
4
- }
5
- .react-international-phone-country-selector-button {
6
- display: flex;
7
- height: var(--react-international-phone-height, 36px);
8
- box-sizing: border-box;
9
- align-items: center;
10
- justify-content: center;
11
- padding: 0;
12
- border: 1px solid var(--react-international-phone-country-selector-border-color, var(--react-international-phone-border-color, gainsboro));
13
- margin: 0;
14
- appearance: button;
15
- -webkit-appearance: button;
16
- background-color: var(--react-international-phone-country-selector-background-color, var(--react-international-phone-background-color, white));
17
- cursor: pointer;
18
- text-transform: none;
19
- user-select: none;
20
- }
21
- .react-international-phone-country-selector-button:hover {
22
- background-color: var(--react-international-phone-country-selector-background-color-hover, whitesmoke);
23
- }
24
- .react-international-phone-country-selector-button--hide-dropdown {
25
- cursor: auto;
26
- }
27
- .react-international-phone-country-selector-button--hide-dropdown:hover {
28
- background-color: transparent;
29
- }
30
- .react-international-phone-country-selector-button__button-content {
31
- display: flex;
32
- align-items: center;
33
- justify-content: center;
34
- }
35
- .react-international-phone-country-selector-button__flag-emoji {
36
- margin: 0 4px;
37
- }
38
- .react-international-phone-country-selector-button__flag-emoji--disabled {
39
- opacity: .75;
40
- }
41
- .react-international-phone-country-selector-button__dropdown-arrow {
42
- border-top: var(--react-international-phone-country-selector-arrow-size, 4px) solid var(--react-international-phone-country-selector-arrow-color, #777);
43
- border-right: var(--react-international-phone-country-selector-arrow-size, 4px) solid transparent;
44
- border-left: var(--react-international-phone-country-selector-arrow-size, 4px) solid transparent;
45
- margin-right: 4px;
46
- transition: all .1s ease-out;
47
- }
48
- .react-international-phone-country-selector-button__dropdown-arrow--active {
49
- transform: rotateX(180deg);
50
- }
51
- .react-international-phone-country-selector-button__dropdown-arrow--disabled {
52
- border-top-color: var(--react-international-phone-disabled-country-selector-arrow-color, #999);
53
- }
54
- .react-international-phone-country-selector-button--disabled {
55
- background-color: var(--react-international-phone-disabled-country-selector-background-color, var(--react-international-phone-disabled-background-color, whitesmoke));
56
- cursor: auto;
57
- }
58
- .react-international-phone-country-selector-button--disabled:hover {
59
- background-color: var(--react-international-phone-disabled-country-selector-background-color, var(--react-international-phone-disabled-background-color, whitesmoke));
60
- }
61
- .react-international-phone-flag-emoji {
62
- width: var(--react-international-phone-flag-width, 24px);
63
- height: var(--react-international-phone-flag-height, 24px);
64
- box-sizing: border-box;
65
- }
66
- .react-international-phone-country-selector-dropdown {
67
- position: absolute;
68
- z-index: 1;
69
- top: var(--react-international-phone-dropdown-top, 44px);
70
- left: var(--react-international-phone-dropdown-left, 0);
71
- display: flex;
72
- width: 300px;
73
- max-height: 200px;
74
- flex-direction: column;
75
- padding: 4px 0;
76
- margin: 0;
77
- background-color: var(--react-international-phone-dropdown-item-background-color, var(--react-international-phone-background-color, white));
78
- box-shadow: var(--react-international-phone-dropdown-shadow, 2px 2px 16px rgba(0, 0, 0, .25));
79
- color: var(--react-international-phone-dropdown-item-text-color, var(--react-international-phone-text-color, #222));
80
- list-style: none;
81
- overflow-y: scroll;
82
- }
83
- .react-international-phone-country-selector-dropdown__preferred-list-divider {
84
- height: 1px;
85
- border: none;
86
- margin: var(--react-international-phone-dropdown-preferred-list-divider-margin, 0);
87
- background: var(--react-international-phone-dropdown-preferred-list-divider-color, var(--react-international-phone-border-color, gainsboro));
88
- }
89
- .react-international-phone-country-selector-dropdown__list-item {
90
- display: flex;
91
- min-height: var(--react-international-phone-dropdown-item-height, 28px);
92
- box-sizing: border-box;
93
- align-items: center;
94
- padding: 2px 8px;
95
- }
96
- .react-international-phone-country-selector-dropdown__list-item-flag-emoji {
97
- margin-right: 8px;
98
- }
99
- .react-international-phone-country-selector-dropdown__list-item-country-name {
100
- overflow: hidden;
101
- margin-right: 8px;
102
- font-size: var(--react-international-phone-dropdown-item-font-size, 14px);
103
- text-overflow: ellipsis;
104
- white-space: nowrap;
105
- }
106
- .react-international-phone-country-selector-dropdown__list-item-dial-code {
107
- color: var(--react-international-phone-dropdown-item-dial-code-color, gray);
108
- font-size: var(--react-international-phone-dropdown-item-font-size, 14px);
109
- }
110
- .react-international-phone-country-selector-dropdown__list-item:hover {
111
- background-color: var(--react-international-phone-selected-dropdown-item-background-color, var(--react-international-phone-selected-dropdown-item-background-color, whitesmoke));
112
- cursor: pointer;
113
- }
114
- .react-international-phone-country-selector-dropdown__list-item--selected,
115
- .react-international-phone-country-selector-dropdown__list-item--focused {
116
- background-color: var(--react-international-phone-selected-dropdown-item-background-color, whitesmoke);
117
- color: var(--react-international-phone-selected-dropdown-item-text-color, var(--react-international-phone-text-color, #222));
118
- }
119
- .react-international-phone-country-selector-dropdown__list-item--selected .react-international-phone-country-selector-dropdown__list-item-dial-code,
120
- .react-international-phone-country-selector-dropdown__list-item--focused .react-international-phone-country-selector-dropdown__list-item-dial-code {
121
- color: var(--react-international-phone-selected-dropdown-item-dial-code-color, var(--react-international-phone-dropdown-item-dial-code-color, gray));
122
- }
123
- .react-international-phone-country-selector-dropdown__list-item--focused {
124
- background-color: var(--react-international-phone-selected-dropdown-item-background-color, var(--react-international-phone-selected-dropdown-item-background-color, whitesmoke));
125
- }
126
- .react-international-phone-dial-code-preview {
127
- display: flex;
128
- align-items: center;
129
- justify-content: center;
130
- padding: 0 8px;
131
- border: 1px solid var(--react-international-phone-dial-code-preview-border-color, var(--react-international-phone-border-color, gainsboro));
132
- margin-right: -1px;
133
- background-color: var(--react-international-phone-dial-code-preview-background-color, var(--react-international-phone-background-color, white));
134
- color: var(--react-international-phone-dial-code-preview-text-color, var(--react-international-phone-text-color, #222));
135
- font-size: var(--react-international-phone-dial-code-preview-font-size, var(--react-international-phone-font-size, 13px));
136
- }
137
- .react-international-phone-dial-code-preview--disabled {
138
- background-color: var(--react-international-phone-dial-code-preview-disabled-background-color, var(--react-international-phone-disabled-background-color, whitesmoke));
139
- color: var(--react-international-phone-dial-code-preview-disabled-text-color, var(--react-international-phone-disabled-text-color, #666));
140
- }
141
- .react-international-phone-input-container {
142
- display: flex;
143
- }
144
- .react-international-phone-input-container .react-international-phone-country-selector-button {
145
- border-radius: var(--react-international-phone-border-radius, 4px);
146
- margin-right: -1px;
147
- border-bottom-right-radius: 0;
148
- border-top-right-radius: 0;
149
- }
150
- .react-international-phone-input-container .react-international-phone-input {
151
- overflow: visible;
152
- height: var(--react-international-phone-height, 36px);
153
- box-sizing: border-box;
154
- padding: 0 8px;
155
- border: 1px solid var(--react-international-phone-border-color, gainsboro);
156
- border-radius: var(--react-international-phone-border-radius, 4px);
157
- margin: 0;
158
- background-color: var(--react-international-phone-background-color, white);
159
- border-bottom-left-radius: 0;
160
- border-top-left-radius: 0;
161
- color: var(--react-international-phone-text-color, #222);
162
- font-family: inherit;
163
- font-size: var(--react-international-phone-font-size, 13px);
164
- }
165
- .react-international-phone-input-container .react-international-phone-input:focus {
166
- outline: none;
167
- }
168
- .react-international-phone-input-container .react-international-phone-input--disabled {
169
- background-color: var(--react-international-phone-disabled-background-color, whitesmoke);
170
- color: var(--react-international-phone-disabled-text-color, #666);
171
- }