@iclips/ui 2.0.0 → 2.0.2
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.
- package/MIGRATION-v2.md +93 -58
- package/dist/components/ui/charts/kpi-card.cjs +1 -1
- package/dist/components/ui/charts/kpi-card.cjs.map +1 -1
- package/dist/components/ui/charts/kpi-card.js +69 -65
- package/dist/components/ui/charts/kpi-card.js.map +1 -1
- package/dist/components/ui/forms/date-picker.cjs +1 -1
- package/dist/components/ui/forms/date-picker.cjs.map +1 -1
- package/dist/components/ui/forms/date-picker.js +104 -102
- package/dist/components/ui/forms/date-picker.js.map +1 -1
- package/dist/components/ui/forms/date-range-picker.cjs +1 -1
- package/dist/components/ui/forms/date-range-picker.cjs.map +1 -1
- package/dist/components/ui/forms/date-range-picker.js +167 -165
- package/dist/components/ui/forms/date-range-picker.js.map +1 -1
- package/dist/components/ui/forms/month-range-picker.cjs +1 -1
- package/dist/components/ui/forms/month-range-picker.cjs.map +1 -1
- package/dist/components/ui/forms/month-range-picker.js +141 -139
- package/dist/components/ui/forms/month-range-picker.js.map +1 -1
- package/dist/components/ui/use-controllable-value.cjs +2 -0
- package/dist/components/ui/use-controllable-value.cjs.map +1 -0
- package/dist/components/ui/use-controllable-value.js +14 -0
- package/dist/components/ui/use-controllable-value.js.map +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.cts +31 -10
- package/dist/index.d.ts +31 -10
- package/package.json +1 -2
|
@@ -1,63 +1,65 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsxs as
|
|
3
|
-
import * as
|
|
4
|
-
import { format as
|
|
2
|
+
import { jsxs as i, jsx as s } from "react/jsx-runtime";
|
|
3
|
+
import * as f from "react";
|
|
4
|
+
import { format as H, subDays as B, startOfMonth as O, endOfMonth as at, subMonths as A, parse as it, isValid as lt } from "date-fns";
|
|
5
5
|
import { ptBR as mt } from "date-fns/locale";
|
|
6
|
-
import { X as ft, CalendarIcon as
|
|
7
|
-
import { cn as
|
|
8
|
-
import {
|
|
6
|
+
import { X as ft, CalendarIcon as ct } from "lucide-react";
|
|
7
|
+
import { cn as ut } from "../utils.js";
|
|
8
|
+
import { useControllableValue as dt } from "../use-controllable-value.js";
|
|
9
|
+
import { Input as pt } from "./input.js";
|
|
9
10
|
import { Button as y } from "../primitives/button.js";
|
|
10
|
-
import { Calendar as
|
|
11
|
-
import { TimePicker as
|
|
12
|
-
import { Popover as
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
return
|
|
11
|
+
import { Calendar as ht } from "./calendar.js";
|
|
12
|
+
import { TimePicker as F } from "./time-picker.js";
|
|
13
|
+
import { Popover as yt, PopoverTrigger as gt, PopoverContent as bt } from "../overlays/popover.js";
|
|
14
|
+
const vt = () => {
|
|
15
|
+
const a = /* @__PURE__ */ new Date();
|
|
16
|
+
return a.setHours(0, 0, 0, 0), [
|
|
16
17
|
{
|
|
17
18
|
label: "Hoje",
|
|
18
|
-
value: { from:
|
|
19
|
+
value: { from: a, to: a }
|
|
19
20
|
},
|
|
20
21
|
{
|
|
21
22
|
label: "Últimos 7 dias",
|
|
22
|
-
value: { from:
|
|
23
|
+
value: { from: B(a, 6), to: a }
|
|
23
24
|
},
|
|
24
25
|
{
|
|
25
26
|
label: "Últimos 30 dias",
|
|
26
|
-
value: { from:
|
|
27
|
+
value: { from: B(a, 29), to: a }
|
|
27
28
|
},
|
|
28
29
|
{
|
|
29
30
|
label: "Este mês",
|
|
30
|
-
value: { from:
|
|
31
|
+
value: { from: O(a), to: a }
|
|
31
32
|
},
|
|
32
33
|
{
|
|
33
34
|
label: "Mês passado",
|
|
34
35
|
value: {
|
|
35
|
-
from:
|
|
36
|
-
to:
|
|
36
|
+
from: O(A(a, 1)),
|
|
37
|
+
to: at(A(a, 1))
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
];
|
|
40
|
-
},
|
|
41
|
-
value:
|
|
42
|
-
|
|
41
|
+
}, Nt = f.forwardRef(({
|
|
42
|
+
value: a,
|
|
43
|
+
defaultValue: K,
|
|
44
|
+
onChange: L,
|
|
43
45
|
placeholder: T = "Selecione um período",
|
|
44
|
-
disabled:
|
|
45
|
-
minDate:
|
|
46
|
-
maxDate:
|
|
47
|
-
dateFormat:
|
|
48
|
-
locale:
|
|
46
|
+
disabled: M = !1,
|
|
47
|
+
minDate: g,
|
|
48
|
+
maxDate: b,
|
|
49
|
+
dateFormat: D = "dd/MM/yyyy",
|
|
50
|
+
locale: u = mt,
|
|
49
51
|
className: X,
|
|
50
|
-
error:
|
|
52
|
+
error: P = !1,
|
|
51
53
|
numberOfMonths: q = 2,
|
|
52
|
-
showTime:
|
|
53
|
-
timeFormat:
|
|
54
|
-
minuteStep:
|
|
55
|
-
presets:
|
|
56
|
-
showDefaultPresets:
|
|
54
|
+
showTime: d = !1,
|
|
55
|
+
timeFormat: $ = "24h",
|
|
56
|
+
minuteStep: R = 15,
|
|
57
|
+
presets: V,
|
|
58
|
+
showDefaultPresets: j = !0,
|
|
57
59
|
id: G,
|
|
58
60
|
name: J
|
|
59
61
|
}, Q) => {
|
|
60
|
-
const [U,
|
|
62
|
+
const [e, m] = dt(a, K, L), [U, x] = f.useState(!1), [v, p] = f.useState(""), [S, c] = f.useState(!1), h = d ? `${D} HH:mm` : D, W = f.useMemo(() => d ? [
|
|
61
63
|
"dd/MM/yyyy HH:mm",
|
|
62
64
|
"dd/MM/yy HH:mm",
|
|
63
65
|
"d/M/yyyy HH:mm",
|
|
@@ -67,237 +69,237 @@ const yt = () => {
|
|
|
67
69
|
"dd/MM/yy",
|
|
68
70
|
"d/M/yyyy",
|
|
69
71
|
"d/M/yy"
|
|
70
|
-
], [
|
|
71
|
-
|
|
72
|
-
if (
|
|
73
|
-
const
|
|
74
|
-
p(
|
|
72
|
+
], [d]);
|
|
73
|
+
f.useEffect(() => {
|
|
74
|
+
if (e != null && e.from) {
|
|
75
|
+
const t = H(e.from, h, { locale: u }), r = e.to ? H(e.to, h, { locale: u }) : "";
|
|
76
|
+
p(r ? `${t} → ${r}` : t), c(!1);
|
|
75
77
|
} else
|
|
76
|
-
p(""),
|
|
77
|
-
}, [
|
|
78
|
-
const
|
|
79
|
-
if (!(
|
|
80
|
-
const
|
|
81
|
-
return `${
|
|
82
|
-
}, [
|
|
83
|
-
if (!(
|
|
84
|
-
const
|
|
85
|
-
return `${
|
|
86
|
-
}, [
|
|
87
|
-
if (!
|
|
88
|
-
|
|
78
|
+
p(""), c(!1);
|
|
79
|
+
}, [e, h, u]);
|
|
80
|
+
const z = f.useMemo(() => [...j ? vt() : [], ...V || []], [V, j]), w = f.useMemo(() => {
|
|
81
|
+
if (!(e != null && e.from)) return "00:00";
|
|
82
|
+
const t = e.from.getHours().toString().padStart(2, "0"), r = e.from.getMinutes().toString().padStart(2, "0");
|
|
83
|
+
return `${t}:${r}`;
|
|
84
|
+
}, [e == null ? void 0 : e.from]), C = f.useMemo(() => {
|
|
85
|
+
if (!(e != null && e.to)) return "23:59";
|
|
86
|
+
const t = e.to.getHours().toString().padStart(2, "0"), r = e.to.getMinutes().toString().padStart(2, "0");
|
|
87
|
+
return `${t}:${r}`;
|
|
88
|
+
}, [e == null ? void 0 : e.to]), Y = (t) => {
|
|
89
|
+
if (!t) {
|
|
90
|
+
m(void 0);
|
|
89
91
|
return;
|
|
90
92
|
}
|
|
91
|
-
if (
|
|
92
|
-
if (
|
|
93
|
-
const [
|
|
94
|
-
|
|
93
|
+
if (d) {
|
|
94
|
+
if (t.from) {
|
|
95
|
+
const [r, n] = w.split(":").map(Number);
|
|
96
|
+
t.from.setHours(r, n, 0, 0);
|
|
95
97
|
}
|
|
96
|
-
if (
|
|
97
|
-
const [
|
|
98
|
-
|
|
98
|
+
if (t.to) {
|
|
99
|
+
const [r, n] = C.split(":").map(Number);
|
|
100
|
+
t.to.setHours(r, n, 0, 0);
|
|
99
101
|
}
|
|
100
102
|
} else
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}, Z = (
|
|
104
|
-
if (!(
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
}, _ = (
|
|
108
|
-
if (!(
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
},
|
|
112
|
-
const
|
|
113
|
-
from: new Date(
|
|
114
|
-
to: new Date(
|
|
103
|
+
t.from && t.from.setHours(0, 0, 0, 0), t.to && t.to.setHours(23, 59, 59, 999);
|
|
104
|
+
m(t);
|
|
105
|
+
}, Z = (t) => {
|
|
106
|
+
if (!(e != null && e.from)) return;
|
|
107
|
+
const r = new Date(e.from), [n, o] = t.split(":").map(Number);
|
|
108
|
+
r.setHours(n, o, 0, 0), m({ ...e, from: r });
|
|
109
|
+
}, _ = (t) => {
|
|
110
|
+
if (!(e != null && e.to)) return;
|
|
111
|
+
const r = new Date(e.to), [n, o] = t.split(":").map(Number);
|
|
112
|
+
r.setHours(n, o, 0, 0), m({ ...e, to: r });
|
|
113
|
+
}, tt = (t) => {
|
|
114
|
+
const r = {
|
|
115
|
+
from: new Date(t.value.from),
|
|
116
|
+
to: new Date(t.value.to)
|
|
115
117
|
};
|
|
116
|
-
if (
|
|
117
|
-
const [
|
|
118
|
-
|
|
118
|
+
if (d) {
|
|
119
|
+
const [n, o] = w.split(":").map(Number), [l, N] = C.split(":").map(Number);
|
|
120
|
+
r.from.setHours(n, o, 0, 0), r.to.setHours(l, N, 0, 0);
|
|
119
121
|
}
|
|
120
|
-
|
|
121
|
-
},
|
|
122
|
-
const
|
|
123
|
-
if (!
|
|
124
|
-
for (const
|
|
122
|
+
m(r);
|
|
123
|
+
}, I = (t) => {
|
|
124
|
+
const r = t.trim();
|
|
125
|
+
if (!r) return null;
|
|
126
|
+
for (const n of W)
|
|
125
127
|
try {
|
|
126
|
-
const o =
|
|
127
|
-
if (
|
|
128
|
-
if (
|
|
128
|
+
const o = it(r, n, /* @__PURE__ */ new Date());
|
|
129
|
+
if (lt(o)) {
|
|
130
|
+
if (g && o < g || b && o > b) continue;
|
|
129
131
|
return o;
|
|
130
132
|
}
|
|
131
133
|
} catch {
|
|
132
134
|
continue;
|
|
133
135
|
}
|
|
134
136
|
return null;
|
|
135
|
-
},
|
|
136
|
-
const
|
|
137
|
-
if (!
|
|
138
|
-
const
|
|
139
|
-
let o = null,
|
|
140
|
-
for (const
|
|
141
|
-
if (
|
|
142
|
-
const
|
|
143
|
-
if (
|
|
137
|
+
}, et = (t) => {
|
|
138
|
+
const r = t.trim();
|
|
139
|
+
if (!r) return null;
|
|
140
|
+
const n = ["→", "-", "até", "a"];
|
|
141
|
+
let o = null, l = null;
|
|
142
|
+
for (const N of n)
|
|
143
|
+
if (r.includes(N)) {
|
|
144
|
+
const k = r.split(N).map((nt) => nt.trim());
|
|
145
|
+
if (k.length === 2 && (o = I(k[0]), l = I(k[1]), o && l))
|
|
144
146
|
break;
|
|
145
147
|
}
|
|
146
|
-
return o || (o =
|
|
147
|
-
},
|
|
148
|
-
const
|
|
149
|
-
p(
|
|
150
|
-
},
|
|
151
|
-
if (!
|
|
152
|
-
|
|
148
|
+
return o || (o = I(r), o && (l = new Date(o))), !o || !l ? null : (o > l && ([o, l] = [l, o]), { from: o, to: l });
|
|
149
|
+
}, rt = (t) => {
|
|
150
|
+
const r = t.target.value.replace(/[^\d/:\s→-]/g, "");
|
|
151
|
+
p(r), c(!1);
|
|
152
|
+
}, E = () => {
|
|
153
|
+
if (!v.trim()) {
|
|
154
|
+
m(void 0), c(!1);
|
|
153
155
|
return;
|
|
154
156
|
}
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
},
|
|
158
|
-
if (
|
|
159
|
-
|
|
160
|
-
else if (
|
|
161
|
-
if (
|
|
162
|
-
const
|
|
163
|
-
p(
|
|
157
|
+
const t = et(v);
|
|
158
|
+
t ? (m(t), c(!1)) : c(!0);
|
|
159
|
+
}, ot = (t) => {
|
|
160
|
+
if (t.key === "Enter")
|
|
161
|
+
t.preventDefault(), E(), S || x(!0);
|
|
162
|
+
else if (t.key === "Escape") {
|
|
163
|
+
if (t.preventDefault(), e != null && e.from) {
|
|
164
|
+
const r = H(e.from, h, { locale: u }), n = e.to ? H(e.to, h, { locale: u }) : "";
|
|
165
|
+
p(n ? `${r} → ${n}` : r);
|
|
164
166
|
} else
|
|
165
167
|
p("");
|
|
166
|
-
|
|
168
|
+
c(!1);
|
|
167
169
|
}
|
|
168
|
-
},
|
|
169
|
-
|
|
170
|
+
}, st = (t) => {
|
|
171
|
+
t.stopPropagation(), m(void 0), p(""), c(!1);
|
|
170
172
|
};
|
|
171
|
-
return /* @__PURE__ */
|
|
172
|
-
/* @__PURE__ */
|
|
173
|
-
/* @__PURE__ */
|
|
174
|
-
|
|
173
|
+
return /* @__PURE__ */ i(yt, { open: U, onOpenChange: x, children: [
|
|
174
|
+
/* @__PURE__ */ i("div", { className: "relative w-full", children: [
|
|
175
|
+
/* @__PURE__ */ s(
|
|
176
|
+
pt,
|
|
175
177
|
{
|
|
176
178
|
ref: Q,
|
|
177
179
|
id: G,
|
|
178
180
|
name: J,
|
|
179
|
-
value:
|
|
180
|
-
onChange:
|
|
181
|
-
onBlur:
|
|
182
|
-
onKeyDown:
|
|
181
|
+
value: v,
|
|
182
|
+
onChange: rt,
|
|
183
|
+
onBlur: E,
|
|
184
|
+
onKeyDown: ot,
|
|
183
185
|
placeholder: T,
|
|
184
|
-
disabled:
|
|
185
|
-
"aria-invalid":
|
|
186
|
-
className:
|
|
186
|
+
disabled: M,
|
|
187
|
+
"aria-invalid": P || S,
|
|
188
|
+
className: ut(
|
|
187
189
|
"pr-20",
|
|
188
|
-
(
|
|
190
|
+
(P || S) && "border-destructive focus-visible:ring-destructive/20",
|
|
189
191
|
X
|
|
190
192
|
)
|
|
191
193
|
}
|
|
192
194
|
),
|
|
193
|
-
/* @__PURE__ */
|
|
194
|
-
|
|
195
|
+
/* @__PURE__ */ i("div", { className: "absolute inset-y-0 right-0 flex items-center gap-1 pr-1", children: [
|
|
196
|
+
v && !M && /* @__PURE__ */ i(
|
|
195
197
|
y,
|
|
196
198
|
{
|
|
197
199
|
type: "button",
|
|
198
200
|
variant: "ghost",
|
|
199
201
|
size: "sm",
|
|
200
202
|
className: "h-7 w-7 p-0 hover:bg-transparent",
|
|
201
|
-
onClick:
|
|
203
|
+
onClick: st,
|
|
202
204
|
tabIndex: -1,
|
|
203
205
|
children: [
|
|
204
|
-
/* @__PURE__ */
|
|
205
|
-
/* @__PURE__ */
|
|
206
|
+
/* @__PURE__ */ s(ft, { className: "h-4 w-4 text-muted-foreground hover:text-foreground" }),
|
|
207
|
+
/* @__PURE__ */ s("span", { className: "sr-only", children: "Limpar" })
|
|
206
208
|
]
|
|
207
209
|
}
|
|
208
210
|
),
|
|
209
|
-
/* @__PURE__ */
|
|
211
|
+
/* @__PURE__ */ s(gt, { asChild: !0, children: /* @__PURE__ */ s(
|
|
210
212
|
y,
|
|
211
213
|
{
|
|
212
214
|
type: "button",
|
|
213
215
|
variant: "ghost",
|
|
214
216
|
size: "sm",
|
|
215
217
|
className: "h-7 w-7 p-0 hover:bg-transparent",
|
|
216
|
-
disabled:
|
|
218
|
+
disabled: M,
|
|
217
219
|
"aria-label": "Abrir calendário",
|
|
218
|
-
children: /* @__PURE__ */
|
|
220
|
+
children: /* @__PURE__ */ s(ct, { className: "h-4 w-4 text-muted-foreground" })
|
|
219
221
|
}
|
|
220
222
|
) })
|
|
221
223
|
] })
|
|
222
224
|
] }),
|
|
223
|
-
/* @__PURE__ */
|
|
224
|
-
|
|
225
|
-
/* @__PURE__ */
|
|
226
|
-
|
|
225
|
+
/* @__PURE__ */ s(bt, { className: "w-auto p-0", align: "start", children: /* @__PURE__ */ i("div", { className: "flex", children: [
|
|
226
|
+
z.length > 0 && /* @__PURE__ */ i("div", { className: "border-r p-3 space-y-1 w-32.5", children: [
|
|
227
|
+
/* @__PURE__ */ s("p", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Atalhos" }),
|
|
228
|
+
z.map((t) => /* @__PURE__ */ s(
|
|
227
229
|
y,
|
|
228
230
|
{
|
|
229
231
|
variant: "ghost",
|
|
230
232
|
size: "sm",
|
|
231
233
|
className: "w-full justify-start text-sm h-8 truncate",
|
|
232
|
-
onClick: () =>
|
|
233
|
-
children: /* @__PURE__ */
|
|
234
|
+
onClick: () => tt(t),
|
|
235
|
+
children: /* @__PURE__ */ s("span", { className: "truncate", children: t.label })
|
|
234
236
|
},
|
|
235
|
-
|
|
237
|
+
t.label
|
|
236
238
|
))
|
|
237
239
|
] }),
|
|
238
|
-
/* @__PURE__ */
|
|
239
|
-
/* @__PURE__ */
|
|
240
|
-
|
|
240
|
+
/* @__PURE__ */ i("div", { children: [
|
|
241
|
+
/* @__PURE__ */ s(
|
|
242
|
+
ht,
|
|
241
243
|
{
|
|
242
244
|
mode: "range",
|
|
243
|
-
selected:
|
|
245
|
+
selected: e,
|
|
244
246
|
onSelect: Y,
|
|
245
247
|
numberOfMonths: q,
|
|
246
|
-
disabled: (
|
|
247
|
-
locale:
|
|
248
|
+
disabled: (t) => !!(g && t < g || b && t > b),
|
|
249
|
+
locale: u,
|
|
248
250
|
autoFocus: !0
|
|
249
251
|
}
|
|
250
252
|
),
|
|
251
|
-
|
|
252
|
-
/* @__PURE__ */
|
|
253
|
-
/* @__PURE__ */
|
|
254
|
-
/* @__PURE__ */
|
|
255
|
-
|
|
253
|
+
d && (e == null ? void 0 : e.from) && (e == null ? void 0 : e.to) && /* @__PURE__ */ i("div", { className: "border-t p-3 flex gap-6", children: [
|
|
254
|
+
/* @__PURE__ */ i("div", { className: "flex-1", children: [
|
|
255
|
+
/* @__PURE__ */ s("p", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Hora início" }),
|
|
256
|
+
/* @__PURE__ */ s(
|
|
257
|
+
F,
|
|
256
258
|
{
|
|
257
|
-
value:
|
|
259
|
+
value: w,
|
|
258
260
|
onChange: Z,
|
|
259
|
-
format:
|
|
260
|
-
minuteStep:
|
|
261
|
+
format: $,
|
|
262
|
+
minuteStep: R,
|
|
261
263
|
variant: "select",
|
|
262
264
|
showIcon: !1
|
|
263
265
|
}
|
|
264
266
|
)
|
|
265
267
|
] }),
|
|
266
|
-
/* @__PURE__ */
|
|
267
|
-
/* @__PURE__ */
|
|
268
|
-
/* @__PURE__ */
|
|
269
|
-
|
|
268
|
+
/* @__PURE__ */ i("div", { className: "flex-1", children: [
|
|
269
|
+
/* @__PURE__ */ s("p", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Hora fim" }),
|
|
270
|
+
/* @__PURE__ */ s(
|
|
271
|
+
F,
|
|
270
272
|
{
|
|
271
|
-
value:
|
|
273
|
+
value: C,
|
|
272
274
|
onChange: _,
|
|
273
|
-
format:
|
|
274
|
-
minuteStep:
|
|
275
|
+
format: $,
|
|
276
|
+
minuteStep: R,
|
|
275
277
|
variant: "select",
|
|
276
278
|
showIcon: !1
|
|
277
279
|
}
|
|
278
280
|
)
|
|
279
281
|
] })
|
|
280
282
|
] }),
|
|
281
|
-
/* @__PURE__ */
|
|
282
|
-
/* @__PURE__ */
|
|
283
|
+
/* @__PURE__ */ i("div", { className: "border-t p-3 flex justify-end gap-2", children: [
|
|
284
|
+
/* @__PURE__ */ s(
|
|
283
285
|
y,
|
|
284
286
|
{
|
|
285
287
|
variant: "outline",
|
|
286
288
|
size: "sm",
|
|
287
289
|
onClick: () => {
|
|
288
|
-
|
|
290
|
+
m(void 0);
|
|
289
291
|
},
|
|
290
292
|
children: "Limpar"
|
|
291
293
|
}
|
|
292
294
|
),
|
|
293
|
-
/* @__PURE__ */
|
|
295
|
+
/* @__PURE__ */ s(y, { size: "sm", onClick: () => x(!1), children: "Confirmar" })
|
|
294
296
|
] })
|
|
295
297
|
] })
|
|
296
298
|
] }) })
|
|
297
299
|
] });
|
|
298
300
|
});
|
|
299
|
-
|
|
301
|
+
Nt.displayName = "DateRangePicker";
|
|
300
302
|
export {
|
|
301
|
-
|
|
303
|
+
Nt as DateRangePicker
|
|
302
304
|
};
|
|
303
305
|
//# sourceMappingURL=date-range-picker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-range-picker.js","sources":["../../../../src/components/ui/forms/date-range-picker.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { format, parse, isValid, subDays, startOfMonth, endOfMonth, subMonths, type Locale } from \"date-fns\";\nimport { ptBR } from \"date-fns/locale\";\nimport { CalendarIcon, X } from \"lucide-react\";\nimport { DateRange } from \"react-day-picker\";\n\nimport { cn } from \"../utils\";\nimport { Input } from \"./input\";\nimport { Button } from \"../primitives/button\";\nimport { Calendar } from \"./calendar\";\nimport { TimePicker } from \"./time-picker\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../overlays/popover\";\n\nexport interface DateRangePreset {\n label: string;\n value: DateRange;\n}\n\nexport interface DateRangePickerProps {\n /**\n * Intervalo de datas selecionado\n */\n value?: DateRange;\n /**\n * Callback quando o intervalo muda\n */\n onChange?: (range: DateRange | undefined) => void;\n /**\n * Placeholder do campo\n * @default \"Selecione um período\"\n */\n placeholder?: string;\n /**\n * Desabilita o componente\n */\n disabled?: boolean;\n /**\n * Data mínima permitida\n */\n minDate?: Date;\n /**\n * Data máxima permitida\n */\n maxDate?: Date;\n /**\n * Formato de exibição da data\n * @default \"dd/MM/yyyy\"\n */\n dateFormat?: string;\n /**\n * Locale para formatação\n * @default ptBR\n */\n locale?: Locale;\n /**\n * Classes CSS adicionais para o trigger\n */\n className?: string;\n /**\n * Estado de erro\n */\n error?: boolean;\n /**\n * Número de meses a exibir\n * @default 2\n */\n numberOfMonths?: 1 | 2;\n /**\n * Mostra seletor de hora\n * @default false\n */\n showTime?: boolean;\n /**\n * Formato de hora (12h ou 24h)\n * @default \"24h\"\n */\n timeFormat?: \"12h\" | \"24h\";\n /**\n * Incremento de minutos\n * @default 15\n */\n minuteStep?: 1 | 5 | 10 | 15 | 30;\n /**\n * Presets de intervalos rápidos\n */\n presets?: DateRangePreset[];\n /**\n * Mostra presets padrão (Hoje, Últimos 7 dias, etc.)\n * @default true\n */\n showDefaultPresets?: boolean;\n /**\n * ID do campo para acessibilidade\n */\n id?: string;\n /**\n * Nome do campo para formulários\n */\n name?: string;\n}\n\n// Presets padrão\nconst getDefaultPresets = (): DateRangePreset[] => {\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n\n return [\n {\n label: \"Hoje\",\n value: { from: today, to: today },\n },\n {\n label: \"Últimos 7 dias\",\n value: { from: subDays(today, 6), to: today },\n },\n {\n label: \"Últimos 30 dias\",\n value: { from: subDays(today, 29), to: today },\n },\n {\n label: \"Este mês\",\n value: { from: startOfMonth(today), to: today },\n },\n {\n label: \"Mês passado\",\n value: {\n from: startOfMonth(subMonths(today, 1)),\n to: endOfMonth(subMonths(today, 1)),\n },\n },\n ];\n};\n\n/**\n * DateRangePicker - Campo de seleção de intervalo de datas com hora opcional\n *\n * @example\n * // Básico\n * <DateRangePicker\n * value={dateRange}\n * onChange={setDateRange}\n * placeholder=\"Período do relatório\"\n * />\n *\n * @example\n * // Com hora\n * <DateRangePicker\n * value={booking}\n * onChange={setBooking}\n * placeholder=\"Reserva da sala\"\n * showTime\n * minuteStep={30}\n * />\n *\n * @example\n * // Com presets customizados\n * <DateRangePicker\n * value={period}\n * onChange={setPeriod}\n * presets={[\n * { label: \"Q1\", value: { from: q1Start, to: q1End } },\n * { label: \"Q2\", value: { from: q2Start, to: q2End } },\n * ]}\n * />\n */\nconst DateRangePicker = React.forwardRef<\n React.ElementRef<typeof Input>,\n DateRangePickerProps\n>(({\n value,\n onChange,\n placeholder = \"Selecione um período\",\n disabled = false,\n minDate,\n maxDate,\n dateFormat = \"dd/MM/yyyy\",\n locale = ptBR,\n className,\n error = false,\n numberOfMonths = 2,\n showTime = false,\n timeFormat = \"24h\",\n minuteStep = 15,\n presets,\n showDefaultPresets = true,\n id,\n name,\n}, ref) => {\n const [open, setOpen] = React.useState(false);\n const [inputValue, setInputValue] = React.useState(\"\");\n const [isInvalid, setIsInvalid] = React.useState(false);\n\n // Formato com hora se necessário\n const displayFormat = showTime ? `${dateFormat} HH:mm` : dateFormat;\n \n // Formatos aceitos para parsing\n const parseFormats = React.useMemo(() => {\n if (showTime) {\n return [\n \"dd/MM/yyyy HH:mm\",\n \"dd/MM/yy HH:mm\",\n \"d/M/yyyy HH:mm\",\n \"d/M/yy HH:mm\",\n ];\n }\n return [\n \"dd/MM/yyyy\",\n \"dd/MM/yy\",\n \"d/M/yyyy\",\n \"d/M/yy\",\n ];\n }, [showTime]);\n\n // Sincroniza inputValue com value\n React.useEffect(() => {\n if (value?.from) {\n const fromStr = format(value.from, displayFormat, { locale });\n const toStr = value.to ? format(value.to, displayFormat, { locale }) : \"\";\n setInputValue(toStr ? `${fromStr} → ${toStr}` : fromStr);\n setIsInvalid(false);\n } else {\n setInputValue(\"\");\n setIsInvalid(false);\n }\n }, [value, displayFormat, locale]);\n\n // Combina presets padrão com customizados\n const allPresets = React.useMemo(() => {\n const defaults = showDefaultPresets ? getDefaultPresets() : [];\n return [...defaults, ...(presets || [])];\n }, [presets, showDefaultPresets]);\n\n // Extrai hora do valor atual\n const startTime = React.useMemo(() => {\n if (!value?.from) return \"00:00\";\n const h = value.from.getHours().toString().padStart(2, \"0\");\n const m = value.from.getMinutes().toString().padStart(2, \"0\");\n return `${h}:${m}`;\n }, [value?.from]);\n\n const endTime = React.useMemo(() => {\n if (!value?.to) return \"23:59\";\n const h = value.to.getHours().toString().padStart(2, \"0\");\n const m = value.to.getMinutes().toString().padStart(2, \"0\");\n return `${h}:${m}`;\n }, [value?.to]);\n\n // Handler para seleção de data\n const handleDateSelect = (range: DateRange | undefined) => {\n if (!range) {\n onChange?.(undefined);\n return;\n }\n\n // Se showTime, preserva os horários existentes\n if (showTime) {\n if (range.from) {\n const [h, m] = startTime.split(\":\").map(Number);\n range.from.setHours(h, m, 0, 0);\n }\n if (range.to) {\n const [h, m] = endTime.split(\":\").map(Number);\n range.to.setHours(h, m, 0, 0);\n }\n } else {\n // Sem hora, usa início e fim do dia\n if (range.from) range.from.setHours(0, 0, 0, 0);\n if (range.to) range.to.setHours(23, 59, 59, 999);\n }\n\n onChange?.(range);\n };\n\n // Handler para mudança de hora início\n const handleStartTimeChange = (time: string) => {\n if (!value?.from) return;\n\n const newFrom = new Date(value.from);\n const [h, m] = time.split(\":\").map(Number);\n newFrom.setHours(h, m, 0, 0);\n\n onChange?.({ ...value, from: newFrom });\n };\n\n // Handler para mudança de hora fim\n const handleEndTimeChange = (time: string) => {\n if (!value?.to) return;\n\n const newTo = new Date(value.to);\n const [h, m] = time.split(\":\").map(Number);\n newTo.setHours(h, m, 0, 0);\n\n onChange?.({ ...value, to: newTo });\n };\n\n // Handler para presets\n const handlePresetSelect = (preset: DateRangePreset) => {\n const newRange = {\n from: new Date(preset.value.from!),\n to: new Date(preset.value.to!),\n };\n\n if (showTime) {\n const [sh, sm] = startTime.split(\":\").map(Number);\n const [eh, em] = endTime.split(\":\").map(Number);\n newRange.from.setHours(sh, sm, 0, 0);\n newRange.to.setHours(eh, em, 0, 0);\n }\n\n onChange?.(newRange);\n };\n\n // Parse de data individual\n const parseSingleDate = (input: string): Date | null => {\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n for (const fmt of parseFormats) {\n try {\n const parsed = parse(trimmed, fmt, new Date());\n if (isValid(parsed)) {\n if (minDate && parsed < minDate) continue;\n if (maxDate && parsed > maxDate) continue;\n return parsed;\n }\n } catch {\n continue;\n }\n }\n return null;\n };\n\n // Parse do intervalo digitado\n const parseInputRange = (input: string): DateRange | null => {\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n // Separa por → ou -\n const separators = [\"→\", \"-\", \"até\", \"a\"];\n let from: Date | null = null;\n let to: Date | null = null;\n\n for (const sep of separators) {\n if (trimmed.includes(sep)) {\n const parts = trimmed.split(sep).map(p => p.trim());\n if (parts.length === 2) {\n from = parseSingleDate(parts[0]);\n to = parseSingleDate(parts[1]);\n if (from && to) break;\n }\n }\n }\n\n // Se não encontrou separador, tenta parsear como data única\n if (!from) {\n from = parseSingleDate(trimmed);\n if (from) {\n to = new Date(from); // Mesmo dia\n }\n }\n\n if (!from || !to) return null;\n\n // Garante que from <= to\n if (from > to) {\n [from, to] = [to, from];\n }\n\n return { from, to };\n };\n\n // Handler para input digitado\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n setInputValue(newValue);\n setIsInvalid(false);\n };\n\n // Handler para blur do input\n const handleInputBlur = () => {\n if (!inputValue.trim()) {\n onChange?.(undefined);\n setIsInvalid(false);\n return;\n }\n\n const parsed = parseInputRange(inputValue);\n if (parsed) {\n onChange?.(parsed);\n setIsInvalid(false);\n } else {\n setIsInvalid(true);\n }\n };\n\n // Handler para Enter\n const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleInputBlur();\n if (!isInvalid) {\n setOpen(true);\n }\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n if (value?.from) {\n const fromStr = format(value.from, displayFormat, { locale });\n const toStr = value.to ? format(value.to, displayFormat, { locale }) : \"\";\n setInputValue(toStr ? `${fromStr} → ${toStr}` : fromStr);\n } else {\n setInputValue(\"\");\n }\n setIsInvalid(false);\n }\n };\n\n // Handler para limpar\n const handleClear = (e: React.MouseEvent) => {\n e.stopPropagation();\n onChange?.(undefined);\n setInputValue(\"\");\n setIsInvalid(false);\n };\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <div className=\"relative w-full\">\n <Input\n ref={ref}\n id={id}\n name={name}\n value={inputValue}\n onChange={handleInputChange}\n onBlur={handleInputBlur}\n onKeyDown={handleInputKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n aria-invalid={error || isInvalid}\n className={cn(\n \"pr-20\",\n (error || isInvalid) && \"border-destructive focus-visible:ring-destructive/20\",\n className\n )}\n />\n <div className=\"absolute inset-y-0 right-0 flex items-center gap-1 pr-1\">\n {inputValue && !disabled && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 w-7 p-0 hover:bg-transparent\"\n onClick={handleClear}\n tabIndex={-1}\n >\n <X className=\"h-4 w-4 text-muted-foreground hover:text-foreground\" />\n <span className=\"sr-only\">Limpar</span>\n </Button>\n )}\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 w-7 p-0 hover:bg-transparent\"\n disabled={disabled}\n aria-label=\"Abrir calendário\"\n >\n <CalendarIcon className=\"h-4 w-4 text-muted-foreground\" />\n </Button>\n </PopoverTrigger>\n </div>\n </div>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <div className=\"flex\">\n {/* Presets sidebar */}\n {allPresets.length > 0 && (\n <div className=\"border-r p-3 space-y-1 w-32.5\">\n <p className=\"text-xs font-medium text-muted-foreground mb-2\">\n Atalhos\n </p>\n {allPresets.map((preset) => (\n <Button\n key={preset.label}\n variant=\"ghost\"\n size=\"sm\"\n className=\"w-full justify-start text-sm h-8 truncate\"\n onClick={() => handlePresetSelect(preset)}\n >\n <span className=\"truncate\">{preset.label}</span>\n </Button>\n ))}\n </div>\n )}\n\n {/* Calendário */}\n <div>\n <Calendar\n mode=\"range\"\n selected={value}\n onSelect={handleDateSelect}\n numberOfMonths={numberOfMonths}\n disabled={(date) => {\n if (minDate && date < minDate) return true;\n if (maxDate && date > maxDate) return true;\n return false;\n }}\n locale={locale}\n autoFocus\n />\n\n {/* Time pickers */}\n {showTime && value?.from && value?.to && (\n <div className=\"border-t p-3 flex gap-6\">\n <div className=\"flex-1\">\n <p className=\"text-xs font-medium text-muted-foreground mb-2\">\n Hora início\n </p>\n <TimePicker\n value={startTime}\n onChange={handleStartTimeChange}\n format={timeFormat}\n minuteStep={minuteStep}\n variant=\"select\"\n showIcon={false}\n />\n </div>\n <div className=\"flex-1\">\n <p className=\"text-xs font-medium text-muted-foreground mb-2\">\n Hora fim\n </p>\n <TimePicker\n value={endTime}\n onChange={handleEndTimeChange}\n format={timeFormat}\n minuteStep={minuteStep}\n variant=\"select\"\n showIcon={false}\n />\n </div>\n </div>\n )}\n\n {/* Footer */}\n <div className=\"border-t p-3 flex justify-end gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => {\n onChange?.(undefined);\n }}\n >\n Limpar\n </Button>\n <Button size=\"sm\" onClick={() => setOpen(false)}>\n Confirmar\n </Button>\n </div>\n </div>\n </div>\n </PopoverContent>\n </Popover>\n );\n});\n\nDateRangePicker.displayName = \"DateRangePicker\";\n\nexport { DateRangePicker };\n"],"names":["getDefaultPresets","today","subDays","startOfMonth","subMonths","endOfMonth","DateRangePicker","React","value","onChange","placeholder","disabled","minDate","maxDate","dateFormat","locale","ptBR","className","error","numberOfMonths","showTime","timeFormat","minuteStep","presets","showDefaultPresets","id","name","ref","open","setOpen","inputValue","setInputValue","isInvalid","setIsInvalid","displayFormat","parseFormats","fromStr","format","toStr","allPresets","startTime","h","m","endTime","handleDateSelect","range","handleStartTimeChange","time","newFrom","handleEndTimeChange","newTo","handlePresetSelect","preset","newRange","sh","sm","eh","em","parseSingleDate","input","trimmed","fmt","parsed","parse","isValid","parseInputRange","separators","from","to","sep","parts","p","handleInputChange","e","newValue","handleInputBlur","handleInputKeyDown","handleClear","jsxs","Popover","jsx","Input","cn","Button","X","PopoverTrigger","CalendarIcon","PopoverContent","Calendar","date","TimePicker"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"date-range-picker.js","sources":["../../../../src/components/ui/forms/date-range-picker.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { format, parse, isValid, subDays, startOfMonth, endOfMonth, subMonths, type Locale } from \"date-fns\";\nimport { ptBR } from \"date-fns/locale\";\nimport { CalendarIcon, X } from \"lucide-react\";\nimport { DateRange } from \"react-day-picker\";\n\nimport { cn } from \"../utils\";\nimport { useControllableValue } from \"../use-controllable-value\";\nimport { Input } from \"./input\";\nimport { Button } from \"../primitives/button\";\nimport { Calendar } from \"./calendar\";\nimport { TimePicker } from \"./time-picker\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../overlays/popover\";\n\nexport interface DateRangePreset {\n label: string;\n value: DateRange;\n}\n\nexport interface DateRangePickerProps {\n /**\n * Intervalo de datas selecionado (modo controlado). Omita para o modo não-controlado.\n */\n value?: DateRange;\n /**\n * Valor inicial no modo não-controlado (quando `value` não é passado).\n */\n defaultValue?: DateRange;\n /**\n * Callback quando o intervalo muda. Chamado nos dois modos.\n */\n onChange?: (range: DateRange | undefined) => void;\n /**\n * Placeholder do campo\n * @default \"Selecione um período\"\n */\n placeholder?: string;\n /**\n * Desabilita o componente\n */\n disabled?: boolean;\n /**\n * Data mínima permitida\n */\n minDate?: Date;\n /**\n * Data máxima permitida\n */\n maxDate?: Date;\n /**\n * Formato de exibição da data\n * @default \"dd/MM/yyyy\"\n */\n dateFormat?: string;\n /**\n * Locale para formatação\n * @default ptBR\n */\n locale?: Locale;\n /**\n * Classes CSS adicionais para o trigger\n */\n className?: string;\n /**\n * Estado de erro\n */\n error?: boolean;\n /**\n * Número de meses a exibir\n * @default 2\n */\n numberOfMonths?: 1 | 2;\n /**\n * Mostra seletor de hora\n * @default false\n */\n showTime?: boolean;\n /**\n * Formato de hora (12h ou 24h)\n * @default \"24h\"\n */\n timeFormat?: \"12h\" | \"24h\";\n /**\n * Incremento de minutos\n * @default 15\n */\n minuteStep?: 1 | 5 | 10 | 15 | 30;\n /**\n * Presets de intervalos rápidos\n */\n presets?: DateRangePreset[];\n /**\n * Mostra presets padrão (Hoje, Últimos 7 dias, etc.)\n * @default true\n */\n showDefaultPresets?: boolean;\n /**\n * ID do campo para acessibilidade\n */\n id?: string;\n /**\n * Nome do campo para formulários\n */\n name?: string;\n}\n\n// Presets padrão\nconst getDefaultPresets = (): DateRangePreset[] => {\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n\n return [\n {\n label: \"Hoje\",\n value: { from: today, to: today },\n },\n {\n label: \"Últimos 7 dias\",\n value: { from: subDays(today, 6), to: today },\n },\n {\n label: \"Últimos 30 dias\",\n value: { from: subDays(today, 29), to: today },\n },\n {\n label: \"Este mês\",\n value: { from: startOfMonth(today), to: today },\n },\n {\n label: \"Mês passado\",\n value: {\n from: startOfMonth(subMonths(today, 1)),\n to: endOfMonth(subMonths(today, 1)),\n },\n },\n ];\n};\n\n/**\n * DateRangePicker - Campo de seleção de intervalo de datas com hora opcional\n *\n * @example\n * // Básico\n * <DateRangePicker\n * value={dateRange}\n * onChange={setDateRange}\n * placeholder=\"Período do relatório\"\n * />\n *\n * @example\n * // Com hora\n * <DateRangePicker\n * value={booking}\n * onChange={setBooking}\n * placeholder=\"Reserva da sala\"\n * showTime\n * minuteStep={30}\n * />\n *\n * @example\n * // Com presets customizados\n * <DateRangePicker\n * value={period}\n * onChange={setPeriod}\n * presets={[\n * { label: \"Q1\", value: { from: q1Start, to: q1End } },\n * { label: \"Q2\", value: { from: q2Start, to: q2End } },\n * ]}\n * />\n */\nconst DateRangePicker = React.forwardRef<\n React.ElementRef<typeof Input>,\n DateRangePickerProps\n>(({\n value: valueProp,\n defaultValue,\n onChange,\n placeholder = \"Selecione um período\",\n disabled = false,\n minDate,\n maxDate,\n dateFormat = \"dd/MM/yyyy\",\n locale = ptBR,\n className,\n error = false,\n numberOfMonths = 2,\n showTime = false,\n timeFormat = \"24h\",\n minuteStep = 15,\n presets,\n showDefaultPresets = true,\n id,\n name,\n}, ref) => {\n const [value, setValue] = useControllableValue<DateRange>(valueProp, defaultValue, onChange);\n const [open, setOpen] = React.useState(false);\n const [inputValue, setInputValue] = React.useState(\"\");\n const [isInvalid, setIsInvalid] = React.useState(false);\n\n // Formato com hora se necessário\n const displayFormat = showTime ? `${dateFormat} HH:mm` : dateFormat;\n \n // Formatos aceitos para parsing\n const parseFormats = React.useMemo(() => {\n if (showTime) {\n return [\n \"dd/MM/yyyy HH:mm\",\n \"dd/MM/yy HH:mm\",\n \"d/M/yyyy HH:mm\",\n \"d/M/yy HH:mm\",\n ];\n }\n return [\n \"dd/MM/yyyy\",\n \"dd/MM/yy\",\n \"d/M/yyyy\",\n \"d/M/yy\",\n ];\n }, [showTime]);\n\n // Sincroniza inputValue com value\n React.useEffect(() => {\n if (value?.from) {\n const fromStr = format(value.from, displayFormat, { locale });\n const toStr = value.to ? format(value.to, displayFormat, { locale }) : \"\";\n setInputValue(toStr ? `${fromStr} → ${toStr}` : fromStr);\n setIsInvalid(false);\n } else {\n setInputValue(\"\");\n setIsInvalid(false);\n }\n }, [value, displayFormat, locale]);\n\n // Combina presets padrão com customizados\n const allPresets = React.useMemo(() => {\n const defaults = showDefaultPresets ? getDefaultPresets() : [];\n return [...defaults, ...(presets || [])];\n }, [presets, showDefaultPresets]);\n\n // Extrai hora do valor atual\n const startTime = React.useMemo(() => {\n if (!value?.from) return \"00:00\";\n const h = value.from.getHours().toString().padStart(2, \"0\");\n const m = value.from.getMinutes().toString().padStart(2, \"0\");\n return `${h}:${m}`;\n }, [value?.from]);\n\n const endTime = React.useMemo(() => {\n if (!value?.to) return \"23:59\";\n const h = value.to.getHours().toString().padStart(2, \"0\");\n const m = value.to.getMinutes().toString().padStart(2, \"0\");\n return `${h}:${m}`;\n }, [value?.to]);\n\n // Handler para seleção de data\n const handleDateSelect = (range: DateRange | undefined) => {\n if (!range) {\n setValue(undefined);\n return;\n }\n\n // Se showTime, preserva os horários existentes\n if (showTime) {\n if (range.from) {\n const [h, m] = startTime.split(\":\").map(Number);\n range.from.setHours(h, m, 0, 0);\n }\n if (range.to) {\n const [h, m] = endTime.split(\":\").map(Number);\n range.to.setHours(h, m, 0, 0);\n }\n } else {\n // Sem hora, usa início e fim do dia\n if (range.from) range.from.setHours(0, 0, 0, 0);\n if (range.to) range.to.setHours(23, 59, 59, 999);\n }\n\n setValue(range);\n };\n\n // Handler para mudança de hora início\n const handleStartTimeChange = (time: string) => {\n if (!value?.from) return;\n\n const newFrom = new Date(value.from);\n const [h, m] = time.split(\":\").map(Number);\n newFrom.setHours(h, m, 0, 0);\n\n setValue({ ...value, from: newFrom });\n };\n\n // Handler para mudança de hora fim\n const handleEndTimeChange = (time: string) => {\n if (!value?.to) return;\n\n const newTo = new Date(value.to);\n const [h, m] = time.split(\":\").map(Number);\n newTo.setHours(h, m, 0, 0);\n\n setValue({ ...value, to: newTo });\n };\n\n // Handler para presets\n const handlePresetSelect = (preset: DateRangePreset) => {\n const newRange = {\n from: new Date(preset.value.from!),\n to: new Date(preset.value.to!),\n };\n\n if (showTime) {\n const [sh, sm] = startTime.split(\":\").map(Number);\n const [eh, em] = endTime.split(\":\").map(Number);\n newRange.from.setHours(sh, sm, 0, 0);\n newRange.to.setHours(eh, em, 0, 0);\n }\n\n setValue(newRange);\n };\n\n // Parse de data individual\n const parseSingleDate = (input: string): Date | null => {\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n for (const fmt of parseFormats) {\n try {\n const parsed = parse(trimmed, fmt, new Date());\n if (isValid(parsed)) {\n if (minDate && parsed < minDate) continue;\n if (maxDate && parsed > maxDate) continue;\n return parsed;\n }\n } catch {\n continue;\n }\n }\n return null;\n };\n\n // Parse do intervalo digitado\n const parseInputRange = (input: string): DateRange | null => {\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n // Separa por → ou -\n const separators = [\"→\", \"-\", \"até\", \"a\"];\n let from: Date | null = null;\n let to: Date | null = null;\n\n for (const sep of separators) {\n if (trimmed.includes(sep)) {\n const parts = trimmed.split(sep).map(p => p.trim());\n if (parts.length === 2) {\n from = parseSingleDate(parts[0]);\n to = parseSingleDate(parts[1]);\n if (from && to) break;\n }\n }\n }\n\n // Se não encontrou separador, tenta parsear como data única\n if (!from) {\n from = parseSingleDate(trimmed);\n if (from) {\n to = new Date(from); // Mesmo dia\n }\n }\n\n if (!from || !to) return null;\n\n // Garante que from <= to\n if (from > to) {\n [from, to] = [to, from];\n }\n\n return { from, to };\n };\n\n // Handler para input digitado\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n // Campo de data: só aceita dígitos, separadores de data/hora e o \"→\" do intervalo.\n const newValue = e.target.value.replace(/[^\\d/:\\s→-]/g, \"\");\n setInputValue(newValue);\n setIsInvalid(false);\n };\n\n // Handler para blur do input\n const handleInputBlur = () => {\n if (!inputValue.trim()) {\n setValue(undefined);\n setIsInvalid(false);\n return;\n }\n\n const parsed = parseInputRange(inputValue);\n if (parsed) {\n setValue(parsed);\n setIsInvalid(false);\n } else {\n setIsInvalid(true);\n }\n };\n\n // Handler para Enter\n const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleInputBlur();\n if (!isInvalid) {\n setOpen(true);\n }\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n if (value?.from) {\n const fromStr = format(value.from, displayFormat, { locale });\n const toStr = value.to ? format(value.to, displayFormat, { locale }) : \"\";\n setInputValue(toStr ? `${fromStr} → ${toStr}` : fromStr);\n } else {\n setInputValue(\"\");\n }\n setIsInvalid(false);\n }\n };\n\n // Handler para limpar\n const handleClear = (e: React.MouseEvent) => {\n e.stopPropagation();\n setValue(undefined);\n setInputValue(\"\");\n setIsInvalid(false);\n };\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <div className=\"relative w-full\">\n <Input\n ref={ref}\n id={id}\n name={name}\n value={inputValue}\n onChange={handleInputChange}\n onBlur={handleInputBlur}\n onKeyDown={handleInputKeyDown}\n placeholder={placeholder}\n disabled={disabled}\n aria-invalid={error || isInvalid}\n className={cn(\n \"pr-20\",\n (error || isInvalid) && \"border-destructive focus-visible:ring-destructive/20\",\n className\n )}\n />\n <div className=\"absolute inset-y-0 right-0 flex items-center gap-1 pr-1\">\n {inputValue && !disabled && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 w-7 p-0 hover:bg-transparent\"\n onClick={handleClear}\n tabIndex={-1}\n >\n <X className=\"h-4 w-4 text-muted-foreground hover:text-foreground\" />\n <span className=\"sr-only\">Limpar</span>\n </Button>\n )}\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 w-7 p-0 hover:bg-transparent\"\n disabled={disabled}\n aria-label=\"Abrir calendário\"\n >\n <CalendarIcon className=\"h-4 w-4 text-muted-foreground\" />\n </Button>\n </PopoverTrigger>\n </div>\n </div>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <div className=\"flex\">\n {/* Presets sidebar */}\n {allPresets.length > 0 && (\n <div className=\"border-r p-3 space-y-1 w-32.5\">\n <p className=\"text-xs font-medium text-muted-foreground mb-2\">\n Atalhos\n </p>\n {allPresets.map((preset) => (\n <Button\n key={preset.label}\n variant=\"ghost\"\n size=\"sm\"\n className=\"w-full justify-start text-sm h-8 truncate\"\n onClick={() => handlePresetSelect(preset)}\n >\n <span className=\"truncate\">{preset.label}</span>\n </Button>\n ))}\n </div>\n )}\n\n {/* Calendário */}\n <div>\n <Calendar\n mode=\"range\"\n selected={value}\n onSelect={handleDateSelect}\n numberOfMonths={numberOfMonths}\n disabled={(date) => {\n if (minDate && date < minDate) return true;\n if (maxDate && date > maxDate) return true;\n return false;\n }}\n locale={locale}\n autoFocus\n />\n\n {/* Time pickers */}\n {showTime && value?.from && value?.to && (\n <div className=\"border-t p-3 flex gap-6\">\n <div className=\"flex-1\">\n <p className=\"text-xs font-medium text-muted-foreground mb-2\">\n Hora início\n </p>\n <TimePicker\n value={startTime}\n onChange={handleStartTimeChange}\n format={timeFormat}\n minuteStep={minuteStep}\n variant=\"select\"\n showIcon={false}\n />\n </div>\n <div className=\"flex-1\">\n <p className=\"text-xs font-medium text-muted-foreground mb-2\">\n Hora fim\n </p>\n <TimePicker\n value={endTime}\n onChange={handleEndTimeChange}\n format={timeFormat}\n minuteStep={minuteStep}\n variant=\"select\"\n showIcon={false}\n />\n </div>\n </div>\n )}\n\n {/* Footer */}\n <div className=\"border-t p-3 flex justify-end gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => {\n setValue(undefined);\n }}\n >\n Limpar\n </Button>\n <Button size=\"sm\" onClick={() => setOpen(false)}>\n Confirmar\n </Button>\n </div>\n </div>\n </div>\n </PopoverContent>\n </Popover>\n );\n});\n\nDateRangePicker.displayName = \"DateRangePicker\";\n\nexport { DateRangePicker };\n"],"names":["getDefaultPresets","today","subDays","startOfMonth","subMonths","endOfMonth","DateRangePicker","React","valueProp","defaultValue","onChange","placeholder","disabled","minDate","maxDate","dateFormat","locale","ptBR","className","error","numberOfMonths","showTime","timeFormat","minuteStep","presets","showDefaultPresets","id","name","ref","value","setValue","useControllableValue","open","setOpen","inputValue","setInputValue","isInvalid","setIsInvalid","displayFormat","parseFormats","fromStr","format","toStr","allPresets","startTime","h","m","endTime","handleDateSelect","range","handleStartTimeChange","time","newFrom","handleEndTimeChange","newTo","handlePresetSelect","preset","newRange","sh","sm","eh","em","parseSingleDate","input","trimmed","fmt","parsed","parse","isValid","parseInputRange","separators","from","to","sep","parts","p","handleInputChange","e","newValue","handleInputBlur","handleInputKeyDown","handleClear","jsxs","Popover","jsx","Input","cn","Button","X","PopoverTrigger","CalendarIcon","PopoverContent","Calendar","date","TimePicker"],"mappings":"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"}
|