@lets-events/react 12.11.2 → 12.11.3

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 +24 -21
  3. package/CHANGELOG.md +6 -0
  4. package/dist/index.js +171 -139
  5. package/dist/index.mjs +171 -139
  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 -168
  15. package/src/components/Calendar/styledComponents.ts +508 -480
  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 -204
  21. package/src/components/Drawer/index.tsx +113 -113
  22. package/src/components/Drawer/styledComponents.ts +97 -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,204 +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
- CalendarStyled,
14
- DayPickerWrapperStyledToDoubleCalendar,
15
- CalendarButtonStyled,
16
- } from "../Calendar/styledComponents";
17
-
18
- export type DateRange = { from?: Date; to?: Date } | undefined;
19
-
20
- export type DoubleCalendarProps = ComponentProps<typeof CalendarStyled> & {
21
- calendarLayout?: "label" | "dropdown" | "dropdown-months" | "dropdown-years";
22
- selected: DateRange;
23
- setSelected: React.Dispatch<React.SetStateAction<DateRange>>;
24
- position?: "top" | "bottom" | "top-right" | "bottom-right";
25
- action?: boolean;
26
- simpleAction?: boolean;
27
- actionText?: string;
28
- hasError?: boolean;
29
- expand?: boolean;
30
- allowPastDates?: boolean;
31
- maxYearsFromNow?: number;
32
- maxDate?: Date;
33
- disabled?: boolean;
34
- };
35
-
36
- export function DoubleCalendar({
37
- action,
38
- actionText,
39
- simpleAction,
40
- calendarLayout,
41
- selected,
42
- setSelected,
43
- position = "bottom",
44
- hasError,
45
- expand,
46
- allowPastDates = false,
47
- maxYearsFromNow = 20,
48
- maxDate,
49
- disabled = false,
50
- ...props
51
- }: DoubleCalendarProps) {
52
- const [startValue, setStartValue] = useState("");
53
- const [endValue, setEndValue] = useState("");
54
- const [showContainer, setShowCalendar] = useState(false);
55
- const initialSelectedRef = useRef<DateRange | undefined>(undefined);
56
-
57
- const dropdownRef = useRef<HTMLDivElement>(null);
58
-
59
- useOnClickOutside(dropdownRef, () => {
60
- setShowCalendar(false);
61
- });
62
- const today = new Date();
63
- const resolvedMaxDate =
64
- maxDate ??
65
- (typeof maxYearsFromNow === "number" ? addYears(today, maxYearsFromNow) : undefined);
66
- const disabledDays: Matcher[] = [];
67
-
68
- if (!allowPastDates) {
69
- disabledDays.push({ before: today });
70
- }
71
- if (resolvedMaxDate) {
72
- disabledDays.push({ after: resolvedMaxDate });
73
- }
74
-
75
- useEffect(() => {
76
- if (selected && selected.from) {
77
- setStartValue(format(selected.from, "dd/MM/yyyy"));
78
- } else {
79
- setStartValue("");
80
- }
81
-
82
- if (selected && selected.to) {
83
- setEndValue(format(selected.to, "dd/MM/yyyy"));
84
- } else {
85
- setEndValue("");
86
- }
87
- }, [selected]);
88
-
89
- return (
90
- <div>
91
- <CalendarStyled {...props} expand={expand} ref={dropdownRef}>
92
- <CalendarButtonStyled
93
- expand={expand}
94
- type="button"
95
- onClick={() =>
96
- setShowCalendar((prev) => {
97
- const next = !prev;
98
- if (!prev) initialSelectedRef.current = selected;
99
- return next;
100
- })
101
- }
102
- disabled={disabled}
103
- >
104
- <div style={{ display: "flex", gap: "8px", width: "100%" }}>
105
- <TextField
106
- placeholder="00/00/0000 - 00/00/0000"
107
- type="text"
108
- value={`${startValue || "00/00/0000"} - ${endValue || "00/00/0000"}`}
109
- readOnly
110
- inputMode="numeric"
111
- textAlign={"right"}
112
- color={hasError ? "error" : "default"}
113
- disabled={disabled}
114
- >
115
- <TextFieldSlot>
116
- <Icon name="calendar" size={"xl"} color="#4C4F54"/>
117
- </TextFieldSlot>
118
- </TextField>
119
- </div>
120
- </CalendarButtonStyled>
121
-
122
- {showContainer && (
123
- <CalendarContentStyled position={position}>
124
- <Box>
125
- <DayPickerWrapperStyledToDoubleCalendar>
126
- <DayPicker
127
- mode="range"
128
- numberOfMonths={2}
129
- captionLayout={calendarLayout}
130
- selected={selected as any}
131
- onSelect={setSelected}
132
- required
133
- locale={ptBR}
134
- disabled={disabledDays.length > 0 ? disabledDays : undefined}
135
- fromMonth={allowPastDates ? undefined : today}
136
- toMonth={resolvedMaxDate}
137
- />
138
- </DayPickerWrapperStyledToDoubleCalendar>
139
- </Box>
140
-
141
- {action && (
142
- <CalendarFooterStyled>
143
- <div style={{ textAlign: "center", padding: "1rem" }}>
144
- <span>
145
- {`${selected?.from ? format(selected.from, "dd/MM/yyyy") : "00/00/0000"} — ${selected?.to ? format(selected.to, "dd/MM/yyyy") : "00/00/0000"}`}
146
- </span>
147
- </div>
148
- <Button
149
- style={{ margin: "0 0.5rem" }}
150
- variant="text"
151
- color="neutral"
152
- type="button"
153
- onClick={() => {
154
- setSelected(initialSelectedRef.current);
155
- setShowCalendar(false);
156
- }}
157
- size={"medium"}
158
- fontWeight="regular"
159
- >
160
- Cancelar
161
- </Button>
162
- <Button
163
- style={{ margin: "0 0.5rem" }}
164
- variant="text"
165
- color="brand"
166
- type="button"
167
- onClick={() => {
168
- setShowCalendar(false);
169
- }}
170
- size={"medium"}
171
- fontWeight="medium"
172
- >
173
- {actionText ?? "Aplicar"}
174
- </Button>
175
- </CalendarFooterStyled>
176
- )}
177
- {simpleAction && (
178
- <CalendarFooterStyled>
179
- <div
180
- style={{ display: "flex", justifyContent: "center", padding: "1rem", width: "100%" }}>
181
- <Button
182
- style={{ margin: "0 0.5rem" }}
183
- variant="text"
184
- color="brand"
185
- type="button"
186
- onClick={() => {
187
- setShowCalendar(false);
188
- }}
189
- size={"medium"}
190
- fontWeight="medium"
191
- >
192
- {actionText ?? "Aplicar"}
193
- </Button>
194
- </div>
195
- </CalendarFooterStyled>
196
- )}
197
- </CalendarContentStyled>
198
- )}
199
- </CalendarStyled>
200
- </div>
201
- );
202
- }
203
-
204
- 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, 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
+ }