@lets-events/react 7.0.1 → 7.2.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.
@@ -1,29 +1,39 @@
1
- import React, { useCallback, useState } from "react";
2
- import { Dialog as TimePickerRadix } from "@radix-ui/themes";
1
+ import React, { useCallback, useRef, useState } from "react";
3
2
  import { Box } from "./Box";
4
3
  import { Button } from "./Button";
5
4
  import { TextField, TextFieldSlot } from "./TextField";
6
5
  import { Text } from "./Text";
7
6
  import Icon from "./Icon";
8
7
  import { styled } from "../styles";
8
+ import { useOnClickOutside } from "../hooks/useOnClickOutside";
9
9
 
10
10
  export const TimePickerStyled = styled("div", {
11
+ position: "relative",
11
12
  fontFamily: "$default",
12
13
  lineHeight: "$base",
13
14
  fontSize: "$14",
14
15
  maxWidth: "200px",
15
16
  borderRadius: "$sm",
17
+ "> div > div": {
18
+ paddingLeft: "1rem",
19
+ input: {
20
+ textAlign: "right",
21
+ },
22
+ },
16
23
  });
17
- export const TimePickerTitleStyled = styled(TimePickerRadix.Title, {
18
- display: "none",
19
- });
20
- export const TimePickerDialogStyled = styled(TimePickerRadix.Content, {
24
+
25
+ export const TimePickerDropdownStyled = styled("div", {
26
+ position: "absolute",
27
+ left: 0,
28
+ zIndex: 10,
21
29
  width: "100%",
22
30
  maxWidth: "8.875rem",
31
+ backgroundColor: "$neutral50",
23
32
  border: "1px solid $neutral300",
24
33
  borderRadius: "$sm",
25
34
  boxShadow: "0px 2px 8px 0px $shadow50",
26
35
  });
36
+
27
37
  export const TimePickerFooterStyled = styled("div", {
28
38
  borderTop: "2px solid $neutral100",
29
39
  padding: "$4 $16",
@@ -32,6 +42,7 @@ export const TimePickerFooterStyled = styled("div", {
32
42
  alignItems: "center",
33
43
  height: "3rem",
34
44
  });
45
+
35
46
  export const TimerPickerContentStyled = styled("div", {
36
47
  display: "flex",
37
48
  gap: "$16",
@@ -40,21 +51,36 @@ export const TimerPickerContentStyled = styled("div", {
40
51
  "& > div:nth-child(2)": {
41
52
  order: 2,
42
53
  },
54
+ input: {
55
+ padding: "0",
56
+ textAlign: "center!important",
57
+ },
43
58
  });
59
+
44
60
  export type TimePickerProps = {
45
61
  selected: string | undefined;
46
62
  setSelected: React.Dispatch<React.SetStateAction<string | undefined>>;
63
+ position?: "bottom" | "top";
47
64
  };
48
65
 
49
- export function TimePicker({ selected, setSelected }: TimePickerProps) {
66
+ export function TimePicker({
67
+ selected,
68
+ setSelected,
69
+ position = "bottom",
70
+ }: TimePickerProps) {
50
71
  const [hours, setHours] = useState("00");
51
72
  const [minutes, setMinutes] = useState("00");
73
+ const [isOpen, setIsOpen] = useState(false);
74
+ const dropdownRef = useRef(null);
75
+
76
+ useOnClickOutside(dropdownRef, () => setIsOpen(false));
52
77
 
53
78
  const pad = (num: number) => String(num).padStart(2, "0");
54
79
 
55
80
  const handleInputValue = useCallback(
56
81
  (time: string) => {
57
82
  setSelected(time);
83
+ setIsOpen(false);
58
84
  },
59
85
  [setSelected]
60
86
  );
@@ -71,7 +97,6 @@ export function TimePicker({ selected, setSelected }: TimePickerProps) {
71
97
  },
72
98
  [hours, minutes]
73
99
  );
74
-
75
100
  const handleDecrement = useCallback(
76
101
  (type: "hours" | "minutes") => {
77
102
  if (type === "hours") {
@@ -86,24 +111,25 @@ export function TimePicker({ selected, setSelected }: TimePickerProps) {
86
111
  );
87
112
 
88
113
  return (
89
- <TimePickerRadix.Root>
90
- <TimePickerStyled>
91
- <TimePickerRadix.Trigger>
92
- <TextField
93
- value={selected}
94
- readOnly
95
- type="text"
96
- placeholder="00:00"
97
- typography="labelSmall"
98
- fontWeight="regular"
99
- >
100
- <TextFieldSlot>
101
- <Icon name="clock" size="xl" />
102
- </TextFieldSlot>
103
- </TextField>
104
- </TimePickerRadix.Trigger>
105
- <TimePickerDialogStyled>
106
- <TimePickerTitleStyled>Horário</TimePickerTitleStyled>
114
+ <TimePickerStyled ref={dropdownRef}>
115
+ <TextField
116
+ value={selected}
117
+ readOnly
118
+ type="text"
119
+ placeholder="00:00"
120
+ typography="labelSmall"
121
+ fontWeight="regular"
122
+ onClick={() => setIsOpen((prev) => !prev)}
123
+ >
124
+ <TextFieldSlot>
125
+ <Icon name="clock" size="xl" />
126
+ </TextFieldSlot>
127
+ </TextField>
128
+
129
+ {isOpen && (
130
+ <TimePickerDropdownStyled
131
+ style={position === "top" ? { bottom: "110%" } : { top: "110%" }}
132
+ >
107
133
  <TimerPickerContentStyled>
108
134
  {["hours", "minutes"].map((unit) => (
109
135
  <Box
@@ -143,9 +169,7 @@ export function TimePicker({ selected, setSelected }: TimePickerProps) {
143
169
  typography="labelSmall"
144
170
  fontWeight="regular"
145
171
  textAlign="center"
146
- style={{ padding: "4px" }}
147
172
  />
148
-
149
173
  <Button
150
174
  variant="text"
151
175
  onClick={() => handleDecrement(unit as "hours" | "minutes")}
@@ -172,20 +196,18 @@ export function TimePicker({ selected, setSelected }: TimePickerProps) {
172
196
  <Text>:</Text>
173
197
  </TimerPickerContentStyled>
174
198
  <TimePickerFooterStyled>
175
- <TimePickerRadix.Close>
176
- <Button
177
- variant="text"
178
- color="brand"
179
- onClick={() => handleInputValue(`${hours}:${minutes}`)}
180
- typography="buttonMedium"
181
- fontWeight="medium"
182
- >
183
- Aplicar
184
- </Button>
185
- </TimePickerRadix.Close>
199
+ <Button
200
+ variant="text"
201
+ color="brand"
202
+ onClick={() => handleInputValue(`${hours}:${minutes}`)}
203
+ typography="buttonMedium"
204
+ fontWeight="medium"
205
+ >
206
+ Aplicar
207
+ </Button>
186
208
  </TimePickerFooterStyled>
187
- </TimePickerDialogStyled>
188
- </TimePickerStyled>
189
- </TimePickerRadix.Root>
209
+ </TimePickerDropdownStyled>
210
+ )}
211
+ </TimePickerStyled>
190
212
  );
191
213
  }
@@ -0,0 +1,20 @@
1
+ import { useEffect } from "react";
2
+
3
+ export function useOnClickOutside(ref: any, handler: () => void) {
4
+ useEffect(() => {
5
+ const listener = (event: MouseEvent | TouchEvent) => {
6
+ if (!ref.current || ref.current.contains(event.target)) {
7
+ return;
8
+ }
9
+ handler();
10
+ };
11
+
12
+ document.addEventListener("mousedown", listener);
13
+ document.addEventListener("touchstart", listener);
14
+
15
+ return () => {
16
+ document.removeEventListener("mousedown", listener);
17
+ document.removeEventListener("touchstart", listener);
18
+ };
19
+ }, [ref, handler]);
20
+ }
package/src/index.tsx CHANGED
@@ -20,6 +20,7 @@ export * from './components/TimePicker'
20
20
  export * from './components/Alert'
21
21
  export * from './components/Switch'
22
22
  export * from './components/Step'
23
+ export * from './components/TextareaField'
23
24
 
24
25
  // Layouts
25
26
  export * from './components/Flex'