@lets-events/react 12.11.3 → 12.11.5

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 (96) hide show
  1. package/.eslintrc.json +2 -2
  2. package/.turbo/turbo-build.log +21 -24
  3. package/CHANGELOG.md +12 -0
  4. package/dist/index.js +37 -31
  5. package/dist/index.mjs +46 -40
  6. package/package.json +1 -1
  7. package/src/components/Alert.tsx +303 -303
  8. package/src/components/Avatar.tsx +55 -55
  9. package/src/components/Badge.tsx +132 -132
  10. package/src/components/Box.tsx +3 -3
  11. package/src/components/Button/index.tsx +85 -85
  12. package/src/components/Button/styledComponents.ts +361 -361
  13. package/src/components/ButtonGroup.tsx +484 -484
  14. package/src/components/Calendar/index.tsx +172 -172
  15. package/src/components/Calendar/styledComponents.ts +508 -508
  16. package/src/components/Card.tsx +74 -74
  17. package/src/components/CheckboxGroup.tsx +176 -176
  18. package/src/components/Container.tsx +39 -39
  19. package/src/components/Divider.tsx +7 -7
  20. package/src/components/DoubleCalendar/index.tsx +208 -208
  21. package/src/components/Drawer/index.tsx +113 -113
  22. package/src/components/Drawer/styledComponents.ts +105 -97
  23. package/src/components/Dropdown.tsx +302 -302
  24. package/src/components/Filter.tsx +164 -164
  25. package/src/components/Flex.tsx +130 -130
  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 +98 -98
  35. package/src/components/FormFields/CheckboxGroupFormField.tsx +91 -91
  36. package/src/components/FormFields/DateAndTimeFormField.tsx +217 -217
  37. package/src/components/FormFields/DoubleCalendarFormField.tsx +96 -96
  38. package/src/components/FormFields/EmailFormField.tsx +27 -27
  39. package/src/components/FormFields/Form.tsx +39 -39
  40. package/src/components/FormFields/IdentityDocumentNumberFormField.tsx +32 -32
  41. package/src/components/FormFields/MultiSelectFormField.tsx +64 -64
  42. package/src/components/FormFields/PhoneFormField.tsx +40 -40
  43. package/src/components/FormFields/RadioGroupFormField.tsx +88 -88
  44. package/src/components/FormFields/RichEditorFormField.tsx +128 -128
  45. package/src/components/FormFields/SelectFormField.tsx +113 -113
  46. package/src/components/FormFields/SwitchFormField.tsx +46 -46
  47. package/src/components/FormFields/TextAreaFormField.tsx +61 -61
  48. package/src/components/FormFields/TextFormField.tsx +112 -112
  49. package/src/components/FormFields/TimePickerFormField.tsx +88 -88
  50. package/src/components/FormFields/subComponents/ErrorFormMessage.tsx +36 -36
  51. package/src/components/FormFields/subComponents/FormLabel.tsx +36 -36
  52. package/src/components/FormFields/utils/validation.ts +23 -23
  53. package/src/components/Grid.tsx +137 -137
  54. package/src/components/Icon.tsx +47 -47
  55. package/src/components/MenuDropdown/index.tsx +38 -38
  56. package/src/components/MenuDropdown/styledComponents.ts +31 -31
  57. package/src/components/Modal.tsx +135 -135
  58. package/src/components/MultiSelect/index.tsx +418 -418
  59. package/src/components/MultiSelect/styledComponents.ts +176 -176
  60. package/src/components/RadioGroup.tsx +210 -210
  61. package/src/components/RichEditor/QuillComponent.tsx +419 -419
  62. package/src/components/RichEditor/RichEditor.tsx +53 -53
  63. package/src/components/RichEditor/RichTextPresenter.tsx +18 -18
  64. package/src/components/RichEditor/editorConfig.ts +149 -149
  65. package/src/components/RichEditor/index.ts +3 -3
  66. package/src/components/RichEditor/styledComponents.ts +1175 -1175
  67. package/src/components/RichEditor/types.ts +12 -12
  68. package/src/components/Section.tsx +33 -33
  69. package/src/components/Step.tsx +164 -164
  70. package/src/components/Switch.tsx +108 -108
  71. package/src/components/Text.tsx +54 -54
  72. package/src/components/TextField.tsx +423 -423
  73. package/src/components/TextareaField.tsx +116 -116
  74. package/src/components/TimePicker.tsx +357 -357
  75. package/src/components/Toast/components/ToastItem.tsx +41 -41
  76. package/src/components/Toast/components/ToastProvider.tsx +63 -63
  77. package/src/components/Toast/hooks/useToast.ts +12 -12
  78. package/src/components/Toast/index.tsx +5 -5
  79. package/src/components/Toast/styles/index.ts +135 -135
  80. package/src/components/Toast/types/index.ts +46 -46
  81. package/src/components/ToggleElement/index.tsx +58 -58
  82. package/src/components/Tooltip/index.tsx +126 -126
  83. package/src/components/Tooltip/styles.ts +77 -77
  84. package/src/hooks/useCountries.ts +41 -41
  85. package/src/hooks/useHasHover.ts +21 -21
  86. package/src/hooks/useImageUpload.ts +139 -139
  87. package/src/hooks/useMediaQuery.ts +19 -19
  88. package/src/hooks/useOnClickOutside.tsx +42 -42
  89. package/src/index.tsx +72 -72
  90. package/src/styles/index.ts +41 -41
  91. package/src/types/typographyValues.ts +178 -178
  92. package/src/utils/getNestedValue.ts +3 -3
  93. package/src/utils/states.ts +29 -29
  94. package/src/utils/uploadService.ts +180 -180
  95. package/tsconfig.json +3 -3
  96. package/tsup.config.ts +38 -38
@@ -1,208 +1,208 @@
1
- import React, { ComponentProps, useRef, useEffect, useState } from "react";
2
- import { useOnClickOutside } from "../../hooks/useOnClickOutside";
3
- import { DayPicker, Matcher } from "react-day-picker";
4
- import { ptBR } from "date-fns/locale";
5
- import { format, addYears } from "date-fns";
6
- import { Button } from "../Button";
7
- import { Box } from "../Box";
8
- import { TextField, TextFieldSlot } from "../TextField";
9
- import Icon from "../Icon";
10
- import {
11
- CalendarContentStyled,
12
- CalendarFooterStyled,
13
- CalendarOverlayStyled,
14
- CalendarStyled,
15
- DayPickerWrapperStyledToDoubleCalendar,
16
- CalendarButtonStyled,
17
- } from "../Calendar/styledComponents";
18
-
19
- export type DateRange = { from?: Date; to?: Date } | undefined;
20
-
21
- export type DoubleCalendarProps = ComponentProps<typeof CalendarStyled> & {
22
- calendarLayout?: "label" | "dropdown" | "dropdown-months" | "dropdown-years";
23
- selected: DateRange;
24
- setSelected: React.Dispatch<React.SetStateAction<DateRange>>;
25
- position?: "top" | "bottom" | "top-right" | "bottom-right";
26
- action?: boolean;
27
- simpleAction?: boolean;
28
- actionText?: string;
29
- hasError?: boolean;
30
- expand?: boolean;
31
- allowPastDates?: boolean;
32
- maxYearsFromNow?: number;
33
- maxDate?: Date;
34
- disabled?: boolean;
35
- };
36
-
37
- export function DoubleCalendar({
38
- action,
39
- actionText,
40
- simpleAction,
41
- calendarLayout,
42
- selected,
43
- setSelected,
44
- position = "bottom",
45
- hasError,
46
- expand,
47
- allowPastDates = false,
48
- maxYearsFromNow = 20,
49
- maxDate,
50
- disabled = false,
51
- ...props
52
- }: DoubleCalendarProps) {
53
- const [startValue, setStartValue] = useState("");
54
- const [endValue, setEndValue] = useState("");
55
- const [showContainer, setShowCalendar] = useState(false);
56
- const initialSelectedRef = useRef<DateRange | undefined>(undefined);
57
-
58
- const dropdownRef = useRef<HTMLDivElement>(null);
59
-
60
- useOnClickOutside(dropdownRef, () => {
61
- setShowCalendar(false);
62
- });
63
- const today = new Date();
64
- const resolvedMaxDate =
65
- maxDate ??
66
- (typeof maxYearsFromNow === "number" ? addYears(today, maxYearsFromNow) : undefined);
67
- const disabledDays: Matcher[] = [];
68
-
69
- if (!allowPastDates) {
70
- disabledDays.push({ before: today });
71
- }
72
- if (resolvedMaxDate) {
73
- disabledDays.push({ after: resolvedMaxDate });
74
- }
75
-
76
- useEffect(() => {
77
- if (selected && selected.from) {
78
- setStartValue(format(selected.from, "dd/MM/yyyy"));
79
- } else {
80
- setStartValue("");
81
- }
82
-
83
- if (selected && selected.to) {
84
- setEndValue(format(selected.to, "dd/MM/yyyy"));
85
- } else {
86
- setEndValue("");
87
- }
88
- }, [selected]);
89
-
90
- return (
91
- <div>
92
- {showContainer && (
93
- <CalendarOverlayStyled onClick={() => setShowCalendar(false)} />
94
- )}
95
- <CalendarStyled {...props} expand={expand} ref={dropdownRef}>
96
- <CalendarButtonStyled
97
- expand={expand}
98
- type="button"
99
- onClick={() =>
100
- setShowCalendar((prev) => {
101
- const next = !prev;
102
- if (!prev) initialSelectedRef.current = selected;
103
- return next;
104
- })
105
- }
106
- disabled={disabled}
107
- >
108
- <div style={{ display: "flex", gap: "8px", width: "100%" }}>
109
- <TextField
110
- placeholder="00/00/0000 - 00/00/0000"
111
- type="text"
112
- value={`${startValue || "00/00/0000"} - ${endValue || "00/00/0000"}`}
113
- readOnly
114
- inputMode="numeric"
115
- textAlign={"right"}
116
- color={hasError ? "error" : "default"}
117
- disabled={disabled}
118
- >
119
- <TextFieldSlot>
120
- <Icon name="calendar" size={"xl"} color="#4C4F54"/>
121
- </TextFieldSlot>
122
- </TextField>
123
- </div>
124
- </CalendarButtonStyled>
125
-
126
- {showContainer && (
127
- <CalendarContentStyled position={position}>
128
- <Box>
129
- <DayPickerWrapperStyledToDoubleCalendar>
130
- <DayPicker
131
- mode="range"
132
- numberOfMonths={2}
133
- captionLayout={calendarLayout}
134
- selected={selected as any}
135
- onSelect={setSelected}
136
- required
137
- locale={ptBR}
138
- disabled={disabledDays.length > 0 ? disabledDays : undefined}
139
- fromMonth={allowPastDates ? undefined : today}
140
- toMonth={resolvedMaxDate}
141
- />
142
- </DayPickerWrapperStyledToDoubleCalendar>
143
- </Box>
144
-
145
- {action && (
146
- <CalendarFooterStyled>
147
- <div style={{ textAlign: "center", padding: "1rem" }}>
148
- <span>
149
- {`${selected?.from ? format(selected.from, "dd/MM/yyyy") : "00/00/0000"} — ${selected?.to ? format(selected.to, "dd/MM/yyyy") : "00/00/0000"}`}
150
- </span>
151
- </div>
152
- <Button
153
- style={{ margin: "0 0.5rem" }}
154
- variant="text"
155
- color="neutral"
156
- type="button"
157
- onClick={() => {
158
- setSelected(initialSelectedRef.current);
159
- setShowCalendar(false);
160
- }}
161
- size={"medium"}
162
- fontWeight="regular"
163
- >
164
- Cancelar
165
- </Button>
166
- <Button
167
- style={{ margin: "0 0.5rem" }}
168
- variant="text"
169
- color="brand"
170
- type="button"
171
- onClick={() => {
172
- setShowCalendar(false);
173
- }}
174
- size={"medium"}
175
- fontWeight="medium"
176
- >
177
- {actionText ?? "Aplicar"}
178
- </Button>
179
- </CalendarFooterStyled>
180
- )}
181
- {simpleAction && (
182
- <CalendarFooterStyled>
183
- <div
184
- style={{ display: "flex", justifyContent: "center", padding: "1rem", width: "100%" }}>
185
- <Button
186
- style={{ margin: "0 0.5rem" }}
187
- variant="text"
188
- color="brand"
189
- type="button"
190
- onClick={() => {
191
- setShowCalendar(false);
192
- }}
193
- size={"medium"}
194
- fontWeight="medium"
195
- >
196
- {actionText ?? "Aplicar"}
197
- </Button>
198
- </div>
199
- </CalendarFooterStyled>
200
- )}
201
- </CalendarContentStyled>
202
- )}
203
- </CalendarStyled>
204
- </div>
205
- );
206
- }
207
-
208
- export default DoubleCalendar;
1
+ import React, { ComponentProps, useRef, useEffect, useState } from "react";
2
+ import { useOnClickOutside } from "../../hooks/useOnClickOutside";
3
+ import { DayPicker, Matcher } from "react-day-picker";
4
+ import { ptBR } from "date-fns/locale";
5
+ import { format, addYears } from "date-fns";
6
+ import { Button } from "../Button";
7
+ import { Box } from "../Box";
8
+ import { TextField, TextFieldSlot } from "../TextField";
9
+ import Icon from "../Icon";
10
+ import {
11
+ CalendarContentStyled,
12
+ CalendarFooterStyled,
13
+ CalendarOverlayStyled,
14
+ CalendarStyled,
15
+ DayPickerWrapperStyledToDoubleCalendar,
16
+ CalendarButtonStyled,
17
+ } from "../Calendar/styledComponents";
18
+
19
+ export type DateRange = { from?: Date; to?: Date } | undefined;
20
+
21
+ export type DoubleCalendarProps = ComponentProps<typeof CalendarStyled> & {
22
+ calendarLayout?: "label" | "dropdown" | "dropdown-months" | "dropdown-years";
23
+ selected: DateRange;
24
+ setSelected: React.Dispatch<React.SetStateAction<DateRange>>;
25
+ position?: "top" | "bottom" | "top-right" | "bottom-right";
26
+ action?: boolean;
27
+ simpleAction?: boolean;
28
+ actionText?: string;
29
+ hasError?: boolean;
30
+ expand?: boolean;
31
+ allowPastDates?: boolean;
32
+ maxYearsFromNow?: number;
33
+ maxDate?: Date;
34
+ disabled?: boolean;
35
+ };
36
+
37
+ export function DoubleCalendar({
38
+ action,
39
+ actionText,
40
+ simpleAction,
41
+ calendarLayout,
42
+ selected,
43
+ setSelected,
44
+ position = "bottom",
45
+ hasError,
46
+ expand,
47
+ allowPastDates = false,
48
+ maxYearsFromNow = 20,
49
+ maxDate,
50
+ disabled = false,
51
+ ...props
52
+ }: DoubleCalendarProps) {
53
+ const [startValue, setStartValue] = useState("");
54
+ const [endValue, setEndValue] = useState("");
55
+ const [showContainer, setShowCalendar] = useState(false);
56
+ const initialSelectedRef = useRef<DateRange | undefined>(undefined);
57
+
58
+ const dropdownRef = useRef<HTMLDivElement>(null);
59
+
60
+ useOnClickOutside(dropdownRef, () => {
61
+ setShowCalendar(false);
62
+ });
63
+ const today = new Date();
64
+ const resolvedMaxDate =
65
+ maxDate ??
66
+ (typeof maxYearsFromNow === "number" ? addYears(today, maxYearsFromNow) : undefined);
67
+ const disabledDays: Matcher[] = [];
68
+
69
+ if (!allowPastDates) {
70
+ disabledDays.push({ before: today });
71
+ }
72
+ if (resolvedMaxDate) {
73
+ disabledDays.push({ after: resolvedMaxDate });
74
+ }
75
+
76
+ useEffect(() => {
77
+ if (selected && selected.from) {
78
+ setStartValue(format(selected.from, "dd/MM/yyyy"));
79
+ } else {
80
+ setStartValue("");
81
+ }
82
+
83
+ if (selected && selected.to) {
84
+ setEndValue(format(selected.to, "dd/MM/yyyy"));
85
+ } else {
86
+ setEndValue("");
87
+ }
88
+ }, [selected]);
89
+
90
+ return (
91
+ <div>
92
+ {showContainer && (
93
+ <CalendarOverlayStyled onClick={() => setShowCalendar(false)} />
94
+ )}
95
+ <CalendarStyled {...props} expand={expand} ref={dropdownRef}>
96
+ <CalendarButtonStyled
97
+ expand={expand}
98
+ type="button"
99
+ onClick={() =>
100
+ setShowCalendar((prev) => {
101
+ const next = !prev;
102
+ if (!prev) initialSelectedRef.current = selected;
103
+ return next;
104
+ })
105
+ }
106
+ disabled={disabled}
107
+ >
108
+ <div style={{ display: "flex", gap: "8px", width: "100%" }}>
109
+ <TextField
110
+ placeholder="00/00/0000 - 00/00/0000"
111
+ type="text"
112
+ value={`${startValue || "00/00/0000"} - ${endValue || "00/00/0000"}`}
113
+ readOnly
114
+ inputMode="numeric"
115
+ textAlign={"right"}
116
+ color={hasError ? "error" : "default"}
117
+ disabled={disabled}
118
+ >
119
+ <TextFieldSlot>
120
+ <Icon name="calendar" size={"xl"} color="#4C4F54"/>
121
+ </TextFieldSlot>
122
+ </TextField>
123
+ </div>
124
+ </CalendarButtonStyled>
125
+
126
+ {showContainer && (
127
+ <CalendarContentStyled position={position}>
128
+ <Box>
129
+ <DayPickerWrapperStyledToDoubleCalendar>
130
+ <DayPicker
131
+ mode="range"
132
+ numberOfMonths={2}
133
+ captionLayout={calendarLayout}
134
+ selected={selected as any}
135
+ onSelect={setSelected}
136
+ required
137
+ locale={ptBR}
138
+ disabled={disabledDays.length > 0 ? disabledDays : undefined}
139
+ fromMonth={allowPastDates ? undefined : today}
140
+ toMonth={resolvedMaxDate}
141
+ />
142
+ </DayPickerWrapperStyledToDoubleCalendar>
143
+ </Box>
144
+
145
+ {action && (
146
+ <CalendarFooterStyled>
147
+ <div style={{ textAlign: "center", padding: "1rem" }}>
148
+ <span>
149
+ {`${selected?.from ? format(selected.from, "dd/MM/yyyy") : "00/00/0000"} — ${selected?.to ? format(selected.to, "dd/MM/yyyy") : "00/00/0000"}`}
150
+ </span>
151
+ </div>
152
+ <Button
153
+ style={{ margin: "0 0.5rem" }}
154
+ variant="text"
155
+ color="neutral"
156
+ type="button"
157
+ onClick={() => {
158
+ setSelected(initialSelectedRef.current);
159
+ setShowCalendar(false);
160
+ }}
161
+ size={"medium"}
162
+ fontWeight="regular"
163
+ >
164
+ Cancelar
165
+ </Button>
166
+ <Button
167
+ style={{ margin: "0 0.5rem" }}
168
+ variant="text"
169
+ color="brand"
170
+ type="button"
171
+ onClick={() => {
172
+ setShowCalendar(false);
173
+ }}
174
+ size={"medium"}
175
+ fontWeight="medium"
176
+ >
177
+ {actionText ?? "Aplicar"}
178
+ </Button>
179
+ </CalendarFooterStyled>
180
+ )}
181
+ {simpleAction && (
182
+ <CalendarFooterStyled>
183
+ <div
184
+ style={{ display: "flex", justifyContent: "center", padding: "1rem", width: "100%" }}>
185
+ <Button
186
+ style={{ margin: "0 0.5rem" }}
187
+ variant="text"
188
+ color="brand"
189
+ type="button"
190
+ onClick={() => {
191
+ setShowCalendar(false);
192
+ }}
193
+ size={"medium"}
194
+ fontWeight="medium"
195
+ >
196
+ {actionText ?? "Aplicar"}
197
+ </Button>
198
+ </div>
199
+ </CalendarFooterStyled>
200
+ )}
201
+ </CalendarContentStyled>
202
+ )}
203
+ </CalendarStyled>
204
+ </div>
205
+ );
206
+ }
207
+
208
+ export default DoubleCalendar;
@@ -1,113 +1,113 @@
1
- import { ComponentProps, ReactNode, useEffect, useRef } from "react";
2
- import { colors, Colors } from "@lets-events/tokens";
3
- import Icon from "../Icon";
4
- import {
5
- DrawerOverlayStyled,
6
- DrawerContainerStyled,
7
- DrawerHeaderDiv,
8
- DrawerHeaderTitle,
9
- DrawerHeaderCloseButton,
10
- GoBackButtonStyled,
11
- DrawerWrapper,
12
- } from "./styledComponents";
13
- import { Flex } from "../Flex";
14
-
15
- export type DrawerProps = ComponentProps<typeof DrawerOverlayStyled> & {
16
- isOpen: boolean;
17
- onClose: () => void;
18
- closeAriaLabel?: string;
19
- width?: string;
20
- backgroundColor?: keyof Colors;
21
- title: string;
22
- children?: ReactNode;
23
- goBackIcon?: ReactNode;
24
- goBackAction?: () => void;
25
- zIndex?: number;
26
- clickOutsideAvailable?: boolean;
27
- actionButton?: ReactNode;
28
- goBackAriaLabel?: string;
29
- };
30
-
31
- export function Drawer({
32
- isOpen,
33
- onClose,
34
- closeAriaLabel = "Fechar",
35
- width,
36
- backgroundColor,
37
- title,
38
- children,
39
- goBackIcon,
40
- goBackAction,
41
- zIndex = 1000,
42
- clickOutsideAvailable = true,
43
- actionButton = null,
44
- goBackAriaLabel = "Voltar",
45
- }: DrawerProps) {
46
- useEffect(() => {
47
- if (isOpen) {
48
- const scrollbarWidth =
49
- window.innerWidth - document.documentElement.clientWidth;
50
-
51
- document.body.style.overflow = "hidden";
52
- document.body.style.paddingRight = `${scrollbarWidth}px`;
53
- } else {
54
- document.body.style.overflow = "";
55
- document.body.style.paddingRight = "";
56
- }
57
-
58
- return () => {
59
- document.body.style.overflow = "";
60
- document.body.style.paddingRight = "";
61
- };
62
- }, [isOpen]);
63
-
64
- return (
65
- <>
66
- <DrawerOverlayStyled
67
- css={{
68
- zIndex,
69
- }}
70
- onClick={clickOutsideAvailable ? onClose : undefined}
71
- open={isOpen}
72
- />
73
- <DrawerWrapper
74
- css={{
75
- zIndex: zIndex + 1,
76
- width: width ?? "34.25rem",
77
- maxWidth: "100%",
78
- "@md": {
79
- width: "100%",
80
- }
81
- }}
82
- open={isOpen}
83
- >
84
- <DrawerContainerStyled
85
- open={isOpen}
86
- css={{
87
- backgroundColor: colors[backgroundColor ?? "neutral50"],
88
- }}
89
- >
90
- <DrawerHeaderDiv>
91
- <Flex gap={8} align="center">
92
- {goBackIcon && (
93
- <GoBackButtonStyled type="button" onClick={goBackAction} aria-label={goBackAriaLabel}>
94
- {goBackIcon}
95
- <span style={{ display: "none" }}>{goBackAriaLabel}</span>
96
- </GoBackButtonStyled>
97
- )}
98
- <DrawerHeaderTitle>{title}</DrawerHeaderTitle>
99
- </Flex>
100
- <Flex gap={8}>
101
- {actionButton && actionButton}
102
- <DrawerHeaderCloseButton onClick={onClose} aria-label={closeAriaLabel}>
103
- <Icon size={"xl"} color="$dark600" name="xmark" />
104
- <span style={{ display: "none" }}>{closeAriaLabel}</span>
105
- </DrawerHeaderCloseButton>
106
- </Flex>
107
- </DrawerHeaderDiv>
108
- {isOpen ? children : null}
109
- </DrawerContainerStyled>
110
- </DrawerWrapper>
111
- </>
112
- );
113
- }
1
+ import { ComponentProps, ReactNode, useEffect } from "react";
2
+ import { colors, Colors } from "@lets-events/tokens";
3
+ import Icon from "../Icon";
4
+ import {
5
+ DrawerOverlayStyled,
6
+ DrawerContainerStyled,
7
+ DrawerBodyStyled,
8
+ DrawerHeaderDiv,
9
+ DrawerHeaderTitle,
10
+ DrawerHeaderCloseButton,
11
+ GoBackButtonStyled,
12
+ DrawerWrapper,
13
+ } from "./styledComponents";
14
+ import { Flex } from "../Flex";
15
+
16
+ export type DrawerProps = ComponentProps<typeof DrawerOverlayStyled> & {
17
+ isOpen: boolean;
18
+ onClose: () => void;
19
+ closeAriaLabel?: string;
20
+ width?: string;
21
+ backgroundColor?: keyof Colors;
22
+ title: string;
23
+ children?: ReactNode;
24
+ goBackIcon?: ReactNode;
25
+ goBackAction?: () => void;
26
+ zIndex?: number;
27
+ clickOutsideAvailable?: boolean;
28
+ actionButton?: ReactNode;
29
+ goBackAriaLabel?: string;
30
+ };
31
+
32
+ export function Drawer({
33
+ isOpen,
34
+ onClose,
35
+ closeAriaLabel = "Fechar",
36
+ width,
37
+ backgroundColor,
38
+ title,
39
+ children,
40
+ goBackIcon,
41
+ goBackAction,
42
+ zIndex = 1000,
43
+ clickOutsideAvailable = true,
44
+ actionButton = null,
45
+ goBackAriaLabel = "Voltar",
46
+ }: DrawerProps) {
47
+ useEffect(() => {
48
+ if (isOpen) {
49
+ const scrollbarWidth =
50
+ window.innerWidth - document.documentElement.clientWidth;
51
+
52
+ document.body.style.overflow = "hidden";
53
+ document.body.style.paddingRight = `${scrollbarWidth}px`;
54
+ } else {
55
+ document.body.style.overflow = "";
56
+ document.body.style.paddingRight = "";
57
+ }
58
+
59
+ return () => {
60
+ document.body.style.overflow = "";
61
+ document.body.style.paddingRight = "";
62
+ };
63
+ }, [isOpen]);
64
+
65
+ return (
66
+ <>
67
+ <DrawerOverlayStyled
68
+ css={{
69
+ zIndex,
70
+ }}
71
+ onClick={clickOutsideAvailable ? onClose : undefined}
72
+ open={isOpen}
73
+ />
74
+ <DrawerWrapper
75
+ css={{
76
+ zIndex: zIndex + 1,
77
+ width: width ?? "34.25rem",
78
+ maxWidth: "100%",
79
+ "@md": {
80
+ width: "100%",
81
+ }
82
+ }}
83
+ open={isOpen}
84
+ >
85
+ <DrawerContainerStyled
86
+ css={{
87
+ backgroundColor: colors[backgroundColor ?? "neutral50"],
88
+ }}
89
+ >
90
+ <DrawerHeaderDiv>
91
+ <Flex gap={8} align="center">
92
+ {goBackIcon && (
93
+ <GoBackButtonStyled type="button" onClick={goBackAction} aria-label={goBackAriaLabel}>
94
+ {goBackIcon}
95
+ <span style={{ display: "none" }}>{goBackAriaLabel}</span>
96
+ </GoBackButtonStyled>
97
+ )}
98
+ <DrawerHeaderTitle>{title}</DrawerHeaderTitle>
99
+ </Flex>
100
+ <Flex gap={8}>
101
+ {actionButton && actionButton}
102
+ <DrawerHeaderCloseButton onClick={onClose} aria-label={closeAriaLabel}>
103
+ <Icon size={"xl"} color="$dark600" name="xmark" />
104
+ <span style={{ display: "none" }}>{closeAriaLabel}</span>
105
+ </DrawerHeaderCloseButton>
106
+ </Flex>
107
+ </DrawerHeaderDiv>
108
+ {isOpen ? <DrawerBodyStyled>{children}</DrawerBodyStyled> : null}
109
+ </DrawerContainerStyled>
110
+ </DrawerWrapper>
111
+ </>
112
+ );
113
+ }