@iclips/ui 2.0.0 → 2.0.1
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/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 -1
|
@@ -1,34 +1,36 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsxs as m, jsx as
|
|
3
|
-
import { format as
|
|
4
|
-
import { ptBR as
|
|
5
|
-
import { X as
|
|
6
|
-
import * as
|
|
7
|
-
import { Button as
|
|
8
|
-
import { Calendar as
|
|
9
|
-
import { Input as
|
|
10
|
-
import { Popover as
|
|
11
|
-
import { TimePicker as
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
2
|
+
import { jsxs as m, jsx as n } from "react/jsx-runtime";
|
|
3
|
+
import { format as S, parse as G, isValid as J } from "date-fns";
|
|
4
|
+
import { ptBR as Q } from "date-fns/locale";
|
|
5
|
+
import { X as U, CalendarIcon as W } from "lucide-react";
|
|
6
|
+
import * as c from "react";
|
|
7
|
+
import { Button as H } from "../primitives/button.js";
|
|
8
|
+
import { Calendar as Y } from "./calendar.js";
|
|
9
|
+
import { Input as Z } from "./input.js";
|
|
10
|
+
import { Popover as _, PopoverTrigger as T, PopoverContent as ee } from "../overlays/popover.js";
|
|
11
|
+
import { TimePicker as te } from "./time-picker.js";
|
|
12
|
+
import { useControllableValue as re } from "../use-controllable-value.js";
|
|
13
|
+
import { cn as ne } from "../utils.js";
|
|
14
|
+
const se = c.forwardRef(({
|
|
15
|
+
value: w,
|
|
16
|
+
defaultValue: k,
|
|
17
|
+
onChange: P,
|
|
16
18
|
placeholder: x = "Selecione uma data",
|
|
17
|
-
disabled:
|
|
19
|
+
disabled: s = !1,
|
|
18
20
|
minDate: d,
|
|
19
21
|
maxDate: p,
|
|
20
22
|
dateFormat: D,
|
|
21
|
-
locale: y =
|
|
22
|
-
className:
|
|
23
|
-
error:
|
|
24
|
-
showTime:
|
|
25
|
-
timeFormat:
|
|
23
|
+
locale: y = Q,
|
|
24
|
+
className: V,
|
|
25
|
+
error: N = !1,
|
|
26
|
+
showTime: i = !1,
|
|
27
|
+
timeFormat: B = "24h",
|
|
26
28
|
minuteStep: j = 5,
|
|
27
|
-
defaultTime:
|
|
29
|
+
defaultTime: C = "09:00",
|
|
28
30
|
id: z,
|
|
29
31
|
name: E
|
|
30
32
|
}, F) => {
|
|
31
|
-
const [R,
|
|
33
|
+
const [r, l] = re(w, k, P), [R, h] = c.useState(!1), [v, f] = c.useState(""), [g, o] = c.useState(!1), M = D || (i ? "dd/MM/yyyy HH:mm" : "dd/MM/yyyy"), K = c.useMemo(() => i ? [
|
|
32
34
|
"dd/MM/yyyy HH:mm",
|
|
33
35
|
"dd/MM/yyyy HH:mm:ss",
|
|
34
36
|
"dd/MM/yy HH:mm",
|
|
@@ -41,157 +43,157 @@ const tt = f.forwardRef(({
|
|
|
41
43
|
"d/M/yy",
|
|
42
44
|
"ddMMyyyy",
|
|
43
45
|
"ddMMyy"
|
|
44
|
-
], [
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}, [
|
|
48
|
-
const
|
|
49
|
-
if (!
|
|
50
|
-
const
|
|
51
|
-
return `${
|
|
52
|
-
}, [
|
|
53
|
-
if (!
|
|
54
|
-
if (!
|
|
55
|
-
|
|
46
|
+
], [i]);
|
|
47
|
+
c.useEffect(() => {
|
|
48
|
+
r ? (f(S(r, M, { locale: y })), o(!1)) : (f(""), o(!1));
|
|
49
|
+
}, [r, M, y]);
|
|
50
|
+
const I = c.useMemo(() => {
|
|
51
|
+
if (!r) return C;
|
|
52
|
+
const e = r.getHours().toString().padStart(2, "0"), t = r.getMinutes().toString().padStart(2, "0");
|
|
53
|
+
return `${e}:${t}`;
|
|
54
|
+
}, [r, C]), O = (e) => {
|
|
55
|
+
if (!s) {
|
|
56
|
+
if (!e) {
|
|
57
|
+
l(void 0);
|
|
56
58
|
return;
|
|
57
59
|
}
|
|
58
|
-
if (
|
|
59
|
-
const [
|
|
60
|
-
|
|
60
|
+
if (i) {
|
|
61
|
+
const [t, u] = I.split(":").map(Number);
|
|
62
|
+
e.setHours(t, u, 0, 0);
|
|
61
63
|
} else
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
e.setHours(0, 0, 0, 0);
|
|
65
|
+
l(e), i || h(!1);
|
|
64
66
|
}
|
|
65
|
-
}, $ = (
|
|
66
|
-
if (
|
|
67
|
-
const
|
|
68
|
-
|
|
67
|
+
}, $ = (e) => {
|
|
68
|
+
if (r) {
|
|
69
|
+
const t = new Date(r), [u, a] = e.split(":").map(Number);
|
|
70
|
+
t.setHours(u, a, 0, 0), l(t);
|
|
69
71
|
} else {
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
+
const t = /* @__PURE__ */ new Date(), [u, a] = e.split(":").map(Number);
|
|
73
|
+
t.setHours(u, a, 0, 0), l(t);
|
|
72
74
|
}
|
|
73
|
-
},
|
|
74
|
-
const
|
|
75
|
-
if (!
|
|
76
|
-
for (const
|
|
75
|
+
}, A = (e) => {
|
|
76
|
+
const t = e.trim();
|
|
77
|
+
if (!t) return null;
|
|
78
|
+
for (const u of K)
|
|
77
79
|
try {
|
|
78
|
-
const
|
|
79
|
-
if (
|
|
80
|
-
if (d &&
|
|
81
|
-
return
|
|
80
|
+
const a = G(t, u, /* @__PURE__ */ new Date());
|
|
81
|
+
if (J(a)) {
|
|
82
|
+
if (d && a < d || p && a > p) continue;
|
|
83
|
+
return a;
|
|
82
84
|
}
|
|
83
85
|
} catch {
|
|
84
86
|
continue;
|
|
85
87
|
}
|
|
86
88
|
return null;
|
|
87
|
-
},
|
|
88
|
-
if (
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
},
|
|
92
|
-
if (
|
|
89
|
+
}, L = (e) => {
|
|
90
|
+
if (s) return;
|
|
91
|
+
const t = e.target.value.replace(/[^\d/:\s]/g, "");
|
|
92
|
+
f(t), o(!1);
|
|
93
|
+
}, b = () => {
|
|
94
|
+
if (s) return;
|
|
93
95
|
if (!v.trim()) {
|
|
94
|
-
|
|
96
|
+
l(void 0), o(!1);
|
|
95
97
|
return;
|
|
96
98
|
}
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
},
|
|
100
|
-
|
|
101
|
-
},
|
|
102
|
-
|
|
99
|
+
const e = A(v);
|
|
100
|
+
e ? (l(e), o(!1)) : o(!0);
|
|
101
|
+
}, X = (e) => {
|
|
102
|
+
e.key === "Enter" ? (e.preventDefault(), b(), g || h(!0)) : e.key === "Escape" && (e.preventDefault(), f(r ? S(r, M, { locale: y }) : ""), o(!1));
|
|
103
|
+
}, q = (e) => {
|
|
104
|
+
e.stopPropagation(), l(void 0), f(""), o(!1);
|
|
103
105
|
};
|
|
104
|
-
return /* @__PURE__ */ m(
|
|
105
|
-
|
|
106
|
+
return /* @__PURE__ */ m(_, { open: !s && R, onOpenChange: (e) => {
|
|
107
|
+
s || h(e);
|
|
106
108
|
}, children: [
|
|
107
109
|
/* @__PURE__ */ m("div", { className: "relative w-full", children: [
|
|
108
|
-
/* @__PURE__ */
|
|
109
|
-
|
|
110
|
+
/* @__PURE__ */ n(
|
|
111
|
+
Z,
|
|
110
112
|
{
|
|
111
113
|
ref: F,
|
|
112
114
|
id: z,
|
|
113
115
|
name: E,
|
|
114
116
|
value: v,
|
|
115
|
-
onChange:
|
|
116
|
-
onBlur:
|
|
117
|
-
onKeyDown:
|
|
117
|
+
onChange: L,
|
|
118
|
+
onBlur: b,
|
|
119
|
+
onKeyDown: X,
|
|
118
120
|
placeholder: x,
|
|
119
|
-
disabled:
|
|
120
|
-
"aria-invalid":
|
|
121
|
-
className:
|
|
121
|
+
disabled: s,
|
|
122
|
+
"aria-invalid": N || g,
|
|
123
|
+
className: ne(
|
|
122
124
|
"pr-20",
|
|
123
|
-
(
|
|
124
|
-
|
|
125
|
+
(N || g) && "border-destructive focus-visible:ring-destructive/20",
|
|
126
|
+
V
|
|
125
127
|
)
|
|
126
128
|
}
|
|
127
129
|
),
|
|
128
130
|
/* @__PURE__ */ m("div", { className: "absolute inset-y-0 right-0 flex items-center gap-1 pr-1", children: [
|
|
129
|
-
v && !
|
|
130
|
-
|
|
131
|
+
v && !s && /* @__PURE__ */ m(
|
|
132
|
+
H,
|
|
131
133
|
{
|
|
132
134
|
type: "button",
|
|
133
135
|
variant: "ghost",
|
|
134
136
|
size: "sm",
|
|
135
137
|
className: "h-7 w-7 p-0 hover:bg-transparent",
|
|
136
|
-
onClick:
|
|
138
|
+
onClick: q,
|
|
137
139
|
tabIndex: -1,
|
|
138
140
|
children: [
|
|
139
|
-
/* @__PURE__ */
|
|
140
|
-
/* @__PURE__ */
|
|
141
|
+
/* @__PURE__ */ n(U, { className: "h-4 w-4 text-muted-foreground hover:text-foreground" }),
|
|
142
|
+
/* @__PURE__ */ n("span", { className: "sr-only", children: "Limpar" })
|
|
141
143
|
]
|
|
142
144
|
}
|
|
143
145
|
),
|
|
144
|
-
/* @__PURE__ */
|
|
145
|
-
|
|
146
|
+
/* @__PURE__ */ n(T, { asChild: !0, children: /* @__PURE__ */ n(
|
|
147
|
+
H,
|
|
146
148
|
{
|
|
147
149
|
type: "button",
|
|
148
150
|
variant: "ghost",
|
|
149
151
|
size: "sm",
|
|
150
152
|
className: "h-7 w-7 p-0 hover:bg-transparent",
|
|
151
|
-
disabled:
|
|
153
|
+
disabled: s,
|
|
152
154
|
"aria-label": "Abrir calendário",
|
|
153
|
-
children: /* @__PURE__ */
|
|
155
|
+
children: /* @__PURE__ */ n(W, { className: "h-4 w-4 text-muted-foreground" })
|
|
154
156
|
}
|
|
155
157
|
) })
|
|
156
158
|
] })
|
|
157
159
|
] }),
|
|
158
|
-
/* @__PURE__ */ m(
|
|
159
|
-
/* @__PURE__ */
|
|
160
|
-
|
|
160
|
+
/* @__PURE__ */ m(ee, { className: "w-auto p-0", align: "start", children: [
|
|
161
|
+
/* @__PURE__ */ n(
|
|
162
|
+
Y,
|
|
161
163
|
{
|
|
162
164
|
mode: "single",
|
|
163
|
-
selected:
|
|
165
|
+
selected: r,
|
|
164
166
|
onSelect: O,
|
|
165
|
-
disabled: (
|
|
167
|
+
disabled: (e) => !!(d && e < d || p && e > p),
|
|
166
168
|
locale: y,
|
|
167
169
|
autoFocus: !0,
|
|
168
|
-
defaultMonth:
|
|
170
|
+
defaultMonth: r || void 0
|
|
169
171
|
}
|
|
170
172
|
),
|
|
171
|
-
|
|
172
|
-
|
|
173
|
+
i && /* @__PURE__ */ n("div", { className: "border-t p-3", children: /* @__PURE__ */ n(
|
|
174
|
+
te,
|
|
173
175
|
{
|
|
174
|
-
value:
|
|
176
|
+
value: I,
|
|
175
177
|
onChange: $,
|
|
176
|
-
format:
|
|
178
|
+
format: B,
|
|
177
179
|
minuteStep: j,
|
|
178
180
|
variant: "inline",
|
|
179
181
|
showIcon: !0
|
|
180
182
|
}
|
|
181
183
|
) }),
|
|
182
|
-
|
|
183
|
-
|
|
184
|
+
i && /* @__PURE__ */ n("div", { className: "border-t p-3 flex justify-end", children: /* @__PURE__ */ n(
|
|
185
|
+
H,
|
|
184
186
|
{
|
|
185
187
|
size: "sm",
|
|
186
|
-
onClick: () =>
|
|
188
|
+
onClick: () => h(!1),
|
|
187
189
|
children: "Confirmar"
|
|
188
190
|
}
|
|
189
191
|
) })
|
|
190
192
|
] })
|
|
191
193
|
] });
|
|
192
194
|
});
|
|
193
|
-
|
|
195
|
+
se.displayName = "DatePicker";
|
|
194
196
|
export {
|
|
195
|
-
|
|
197
|
+
se as DatePicker
|
|
196
198
|
};
|
|
197
199
|
//# sourceMappingURL=date-picker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-picker.js","sources":["../../../../src/components/ui/forms/date-picker.tsx"],"sourcesContent":["\"use client\";\n\nimport { format, isValid, parse, type Locale } from \"date-fns\";\nimport { ptBR } from \"date-fns/locale\";\nimport { CalendarIcon, X } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport { Button } from \"../primitives/button\";\nimport { Calendar } from \"./calendar\";\nimport { Input } from \"./input\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../overlays/popover\";\nimport { TimePicker } from \"./time-picker\";\nimport { cn } from \"../utils\";\n\nexport interface DatePickerProps {\n /**\n * Data selecionada\n */\n value?: Date;\n /**\n * Callback quando a data muda\n */\n onChange?: (date: Date | undefined) => void;\n /**\n * Placeholder do campo\n * @default \"Selecione uma data\"\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\" ou \"dd/MM/yyyy HH:mm\" se showTime\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 * 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 5\n */\n minuteStep?: 1 | 5 | 10 | 15 | 30;\n /**\n * Horário padrão quando showTime=true e uma data é selecionada\n * @default \"09:00\"\n */\n defaultTime?: string;\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/**\n * DatePicker - Campo de seleção de data com hora opcional\n *\n * @example\n * // Apenas data\n * <DatePicker\n * value={date}\n * onChange={setDate}\n * placeholder=\"Data de nascimento\"\n * />\n *\n * @example\n * // Data e hora\n * <DatePicker\n * value={appointmentDate}\n * onChange={setAppointmentDate}\n * placeholder=\"Data e hora da reunião\"\n * showTime\n * minuteStep={15}\n * />\n *\n * @example\n * // Com limites\n * <DatePicker\n * value={date}\n * onChange={setDate}\n * minDate={new Date()}\n * maxDate={addMonths(new Date(), 3)}\n * />\n */\nconst DatePicker = React.forwardRef<\n React.ElementRef<typeof Input>,\n DatePickerProps\n>(({\n value,\n onChange,\n placeholder = \"Selecione uma data\",\n disabled = false,\n minDate,\n maxDate,\n dateFormat,\n locale = ptBR,\n className,\n error = false,\n showTime = false,\n timeFormat = \"24h\",\n minuteStep = 5,\n defaultTime = \"09:00\",\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 padrão baseado em showTime\n const displayFormat = dateFormat || (showTime ? \"dd/MM/yyyy HH:mm\" : \"dd/MM/yyyy\");\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/yyyy HH:mm:ss\",\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 \"ddMMyyyy\",\n \"ddMMyy\",\n ];\n }, [showTime]);\n\n // Sincroniza inputValue com value\n React.useEffect(() => {\n if (value) {\n setInputValue(format(value, displayFormat, { locale }));\n setIsInvalid(false);\n } else {\n setInputValue(\"\");\n setIsInvalid(false);\n }\n }, [value, displayFormat, locale]);\n\n // Extrai hora/minuto do valor atual\n const currentTime = React.useMemo(() => {\n if (!value) return defaultTime;\n const hours = value.getHours().toString().padStart(2, \"0\");\n const minutes = value.getMinutes().toString().padStart(2, \"0\");\n return `${hours}:${minutes}`;\n }, [value, defaultTime]);\n\n // Handler para seleção de data\n const handleDateSelect = (date: Date | undefined) => {\n if (disabled) return;\n if (!date) {\n onChange?.(undefined);\n return;\n }\n\n if (showTime) {\n // Preserva o horário atual ou usa o padrão\n const [hours, minutes] = currentTime.split(\":\").map(Number);\n date.setHours(hours, minutes, 0, 0);\n } else {\n // Sem hora, zera o horário\n date.setHours(0, 0, 0, 0);\n }\n\n onChange?.(date);\n\n // Fecha o popover se não tiver seleção de hora\n if (!showTime) {\n setOpen(false);\n }\n };\n\n // Handler para mudança de hora\n const handleTimeChange = (time: string) => {\n if (!value) {\n // Se não tem data, cria uma nova com a data de hoje\n const today = new Date();\n const [hours, minutes] = time.split(\":\").map(Number);\n today.setHours(hours, minutes, 0, 0);\n onChange?.(today);\n } else {\n // Atualiza apenas o horário\n const newDate = new Date(value);\n const [hours, minutes] = time.split(\":\").map(Number);\n newDate.setHours(hours, minutes, 0, 0);\n onChange?.(newDate);\n }\n };\n\n // Parse da data digitada\n const parseInputDate = (input: string): Date | null => {\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n // Tenta cada formato\n for (const fmt of parseFormats) {\n try {\n const parsed = parse(trimmed, fmt, new Date());\n if (isValid(parsed)) {\n // Valida limites\n if (minDate && parsed < minDate) continue;\n if (maxDate && parsed > maxDate) continue;\n return parsed;\n }\n } catch {\n continue;\n }\n }\n\n return null;\n };\n\n // Handler para input digitado\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled) return;\n const newValue = e.target.value;\n setInputValue(newValue);\n setIsInvalid(false);\n };\n\n // Handler para blur do input (valida quando sai do campo)\n const handleInputBlur = () => {\n if (disabled) return;\n if (!inputValue.trim()) {\n onChange?.(undefined);\n setIsInvalid(false);\n return;\n }\n\n const parsed = parseInputDate(inputValue);\n if (parsed) {\n onChange?.(parsed);\n setIsInvalid(false);\n } else {\n setIsInvalid(true);\n // Mantém o inputValue para que o usuário possa corrigir\n }\n };\n\n // Handler para Enter no input\n const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleInputBlur();\n if (!isInvalid) {\n setOpen(true); // Abre o calendário após validar\n }\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n // Restaura o valor original\n if (value) {\n setInputValue(format(value, displayFormat, { locale }));\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={!disabled && open} onOpenChange={(o) => { if (!disabled) setOpen(o); }}>\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 <Calendar\n mode=\"single\"\n selected={value}\n onSelect={handleDateSelect}\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 defaultMonth={value || undefined}\n />\n\n {showTime && (\n <div className=\"border-t p-3\">\n <TimePicker\n value={currentTime}\n onChange={handleTimeChange}\n format={timeFormat}\n minuteStep={minuteStep}\n variant=\"inline\"\n showIcon\n />\n </div>\n )}\n\n {showTime && (\n <div className=\"border-t p-3 flex justify-end\">\n <Button\n size=\"sm\"\n onClick={() => setOpen(false)}\n >\n Confirmar\n </Button>\n </div>\n )}\n </PopoverContent>\n </Popover>\n );\n});\n\nDatePicker.displayName = \"DatePicker\";\n\nexport { DatePicker };\n\n"],"names":["DatePicker","React","value","onChange","placeholder","disabled","minDate","maxDate","dateFormat","locale","ptBR","className","error","showTime","timeFormat","minuteStep","defaultTime","id","name","ref","open","setOpen","inputValue","setInputValue","isInvalid","setIsInvalid","displayFormat","parseFormats","format","currentTime","hours","minutes","handleDateSelect","date","handleTimeChange","time","newDate","today","parseInputDate","input","trimmed","fmt","parsed","parse","isValid","handleInputChange","e","newValue","handleInputBlur","handleInputKeyDown","handleClear","jsxs","Popover","o","jsx","Input","cn","Button","X","PopoverTrigger","CalendarIcon","PopoverContent","Calendar","TimePicker"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"date-picker.js","sources":["../../../../src/components/ui/forms/date-picker.tsx"],"sourcesContent":["\"use client\";\n\nimport { format, isValid, parse, type Locale } from \"date-fns\";\nimport { ptBR } from \"date-fns/locale\";\nimport { CalendarIcon, X } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport { Button } from \"../primitives/button\";\nimport { Calendar } from \"./calendar\";\nimport { Input } from \"./input\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../overlays/popover\";\nimport { TimePicker } from \"./time-picker\";\nimport { useControllableValue } from \"../use-controllable-value\";\nimport { cn } from \"../utils\";\n\nexport interface DatePickerProps {\n /**\n * Data selecionada (modo controlado). Omita para o modo não-controlado.\n */\n value?: Date;\n /**\n * Valor inicial no modo não-controlado (quando `value` não é passado).\n */\n defaultValue?: Date;\n /**\n * Callback quando a data muda. Chamado nos dois modos.\n */\n onChange?: (date: Date | undefined) => void;\n /**\n * Placeholder do campo\n * @default \"Selecione uma data\"\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\" ou \"dd/MM/yyyy HH:mm\" se showTime\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 * 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 5\n */\n minuteStep?: 1 | 5 | 10 | 15 | 30;\n /**\n * Horário padrão quando showTime=true e uma data é selecionada\n * @default \"09:00\"\n */\n defaultTime?: string;\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/**\n * DatePicker - Campo de seleção de data com hora opcional\n *\n * @example\n * // Apenas data\n * <DatePicker\n * value={date}\n * onChange={setDate}\n * placeholder=\"Data de nascimento\"\n * />\n *\n * @example\n * // Data e hora\n * <DatePicker\n * value={appointmentDate}\n * onChange={setAppointmentDate}\n * placeholder=\"Data e hora da reunião\"\n * showTime\n * minuteStep={15}\n * />\n *\n * @example\n * // Com limites\n * <DatePicker\n * value={date}\n * onChange={setDate}\n * minDate={new Date()}\n * maxDate={addMonths(new Date(), 3)}\n * />\n */\nconst DatePicker = React.forwardRef<\n React.ElementRef<typeof Input>,\n DatePickerProps\n>(({\n value: valueProp,\n defaultValue,\n onChange,\n placeholder = \"Selecione uma data\",\n disabled = false,\n minDate,\n maxDate,\n dateFormat,\n locale = ptBR,\n className,\n error = false,\n showTime = false,\n timeFormat = \"24h\",\n minuteStep = 5,\n defaultTime = \"09:00\",\n id,\n name,\n}, ref) => {\n const [value, setValue] = useControllableValue<Date>(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 padrão baseado em showTime\n const displayFormat = dateFormat || (showTime ? \"dd/MM/yyyy HH:mm\" : \"dd/MM/yyyy\");\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/yyyy HH:mm:ss\",\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 \"ddMMyyyy\",\n \"ddMMyy\",\n ];\n }, [showTime]);\n\n // Sincroniza inputValue com value\n React.useEffect(() => {\n if (value) {\n setInputValue(format(value, displayFormat, { locale }));\n setIsInvalid(false);\n } else {\n setInputValue(\"\");\n setIsInvalid(false);\n }\n }, [value, displayFormat, locale]);\n\n // Extrai hora/minuto do valor atual\n const currentTime = React.useMemo(() => {\n if (!value) return defaultTime;\n const hours = value.getHours().toString().padStart(2, \"0\");\n const minutes = value.getMinutes().toString().padStart(2, \"0\");\n return `${hours}:${minutes}`;\n }, [value, defaultTime]);\n\n // Handler para seleção de data\n const handleDateSelect = (date: Date | undefined) => {\n if (disabled) return;\n if (!date) {\n setValue(undefined);\n return;\n }\n\n if (showTime) {\n // Preserva o horário atual ou usa o padrão\n const [hours, minutes] = currentTime.split(\":\").map(Number);\n date.setHours(hours, minutes, 0, 0);\n } else {\n // Sem hora, zera o horário\n date.setHours(0, 0, 0, 0);\n }\n\n setValue(date);\n\n // Fecha o popover se não tiver seleção de hora\n if (!showTime) {\n setOpen(false);\n }\n };\n\n // Handler para mudança de hora\n const handleTimeChange = (time: string) => {\n if (!value) {\n // Se não tem data, cria uma nova com a data de hoje\n const today = new Date();\n const [hours, minutes] = time.split(\":\").map(Number);\n today.setHours(hours, minutes, 0, 0);\n setValue(today);\n } else {\n // Atualiza apenas o horário\n const newDate = new Date(value);\n const [hours, minutes] = time.split(\":\").map(Number);\n newDate.setHours(hours, minutes, 0, 0);\n setValue(newDate);\n }\n };\n\n // Parse da data digitada\n const parseInputDate = (input: string): Date | null => {\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n // Tenta cada formato\n for (const fmt of parseFormats) {\n try {\n const parsed = parse(trimmed, fmt, new Date());\n if (isValid(parsed)) {\n // Valida limites\n if (minDate && parsed < minDate) continue;\n if (maxDate && parsed > maxDate) continue;\n return parsed;\n }\n } catch {\n continue;\n }\n }\n\n return null;\n };\n\n // Handler para input digitado\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled) return;\n // Campo de data: só aceita dígitos, separadores de data e de hora.\n const newValue = e.target.value.replace(/[^\\d/:\\s]/g, \"\");\n setInputValue(newValue);\n setIsInvalid(false);\n };\n\n // Handler para blur do input (valida quando sai do campo)\n const handleInputBlur = () => {\n if (disabled) return;\n if (!inputValue.trim()) {\n setValue(undefined);\n setIsInvalid(false);\n return;\n }\n\n const parsed = parseInputDate(inputValue);\n if (parsed) {\n setValue(parsed);\n setIsInvalid(false);\n } else {\n setIsInvalid(true);\n // Mantém o inputValue para que o usuário possa corrigir\n }\n };\n\n // Handler para Enter no input\n const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n handleInputBlur();\n if (!isInvalid) {\n setOpen(true); // Abre o calendário após validar\n }\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n // Restaura o valor original\n if (value) {\n setInputValue(format(value, displayFormat, { locale }));\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={!disabled && open} onOpenChange={(o) => { if (!disabled) setOpen(o); }}>\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 <Calendar\n mode=\"single\"\n selected={value}\n onSelect={handleDateSelect}\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 defaultMonth={value || undefined}\n />\n\n {showTime && (\n <div className=\"border-t p-3\">\n <TimePicker\n value={currentTime}\n onChange={handleTimeChange}\n format={timeFormat}\n minuteStep={minuteStep}\n variant=\"inline\"\n showIcon\n />\n </div>\n )}\n\n {showTime && (\n <div className=\"border-t p-3 flex justify-end\">\n <Button\n size=\"sm\"\n onClick={() => setOpen(false)}\n >\n Confirmar\n </Button>\n </div>\n )}\n </PopoverContent>\n </Popover>\n );\n});\n\nDatePicker.displayName = \"DatePicker\";\n\nexport { DatePicker };\n\n"],"names":["DatePicker","React","valueProp","defaultValue","onChange","placeholder","disabled","minDate","maxDate","dateFormat","locale","ptBR","className","error","showTime","timeFormat","minuteStep","defaultTime","id","name","ref","value","setValue","useControllableValue","open","setOpen","inputValue","setInputValue","isInvalid","setIsInvalid","displayFormat","parseFormats","format","currentTime","hours","minutes","handleDateSelect","date","handleTimeChange","time","newDate","today","parseInputDate","input","trimmed","fmt","parsed","parse","isValid","handleInputChange","newValue","handleInputBlur","handleInputKeyDown","handleClear","jsxs","Popover","o","jsx","Input","cn","Button","X","PopoverTrigger","CalendarIcon","PopoverContent","Calendar","TimePicker"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),ne=require("react"),l=require("date-fns"),ae=require("date-fns/locale"),$=require("lucide-react"),le=require("../utils.cjs"),ie=require("../use-controllable-value.cjs"),ce=require("./input.cjs"),g=require("../primitives/button.cjs"),ue=require("./calendar.cjs"),F=require("./time-picker.cjs"),I=require("../overlays/popover.cjs");function fe(n){const y=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const m in n)if(m!=="default"){const b=Object.getOwnPropertyDescriptor(n,m);Object.defineProperty(y,m,b.get?b:{enumerable:!0,get:()=>n[m]})}}return y.default=n,Object.freeze(y)}const u=fe(ne),me=()=>{const n=new Date;return n.setHours(0,0,0,0),[{label:"Hoje",value:{from:n,to:n}},{label:"Últimos 7 dias",value:{from:l.subDays(n,6),to:n}},{label:"Últimos 30 dias",value:{from:l.subDays(n,29),to:n}},{label:"Este mês",value:{from:l.startOfMonth(n),to:n}},{label:"Mês passado",value:{from:l.startOfMonth(l.subMonths(n,1)),to:l.endOfMonth(l.subMonths(n,1))}}]},_=u.forwardRef(({value:n,defaultValue:y,onChange:m,placeholder:b="Selecione um período",disabled:H=!1,minDate:j,maxDate:v,dateFormat:q="dd/MM/yyyy",locale:d=ae.ptBR,className:A,error:O=!1,numberOfMonths:K=2,showTime:p=!1,timeFormat:R="24h",minuteStep:B=15,presets:V,showDefaultPresets:z=!0,id:L,name:X},G)=>{const[t,c]=ie.useControllableValue(n,y,m),[J,S]=u.useState(!1),[M,h]=u.useState(""),[w,f]=u.useState(!1),x=p?`${q} HH:mm`:q,Q=u.useMemo(()=>p?["dd/MM/yyyy HH:mm","dd/MM/yy HH:mm","d/M/yyyy HH:mm","d/M/yy HH:mm"]:["dd/MM/yyyy","dd/MM/yy","d/M/yyyy","d/M/yy"],[p]);u.useEffect(()=>{if(t!=null&&t.from){const e=l.format(t.from,x,{locale:d}),s=t.to?l.format(t.to,x,{locale:d}):"";h(s?`${e} → ${s}`:e),f(!1)}else h(""),f(!1)},[t,x,d]);const E=u.useMemo(()=>[...z?me():[],...V||[]],[V,z]),C=u.useMemo(()=>{if(!(t!=null&&t.from))return"00:00";const e=t.from.getHours().toString().padStart(2,"0"),s=t.from.getMinutes().toString().padStart(2,"0");return`${e}:${s}`},[t==null?void 0:t.from]),P=u.useMemo(()=>{if(!(t!=null&&t.to))return"23:59";const e=t.to.getHours().toString().padStart(2,"0"),s=t.to.getMinutes().toString().padStart(2,"0");return`${e}:${s}`},[t==null?void 0:t.to]),U=e=>{if(!e){c(void 0);return}if(p){if(e.from){const[s,a]=C.split(":").map(Number);e.from.setHours(s,a,0,0)}if(e.to){const[s,a]=P.split(":").map(Number);e.to.setHours(s,a,0,0)}}else e.from&&e.from.setHours(0,0,0,0),e.to&&e.to.setHours(23,59,59,999);c(e)},W=e=>{if(!(t!=null&&t.from))return;const s=new Date(t.from),[a,o]=e.split(":").map(Number);s.setHours(a,o,0,0),c({...t,from:s})},Y=e=>{if(!(t!=null&&t.to))return;const s=new Date(t.to),[a,o]=e.split(":").map(Number);s.setHours(a,o,0,0),c({...t,to:s})},Z=e=>{const s={from:new Date(e.value.from),to:new Date(e.value.to)};if(p){const[a,o]=C.split(":").map(Number),[i,N]=P.split(":").map(Number);s.from.setHours(a,o,0,0),s.to.setHours(i,N,0,0)}c(s)},k=e=>{const s=e.trim();if(!s)return null;for(const a of Q)try{const o=l.parse(s,a,new Date);if(l.isValid(o)){if(j&&o<j||v&&o>v)continue;return o}}catch{continue}return null},ee=e=>{const s=e.trim();if(!s)return null;const a=["→","-","até","a"];let o=null,i=null;for(const N of a)if(s.includes(N)){const D=s.split(N).map(oe=>oe.trim());if(D.length===2&&(o=k(D[0]),i=k(D[1]),o&&i))break}return o||(o=k(s),o&&(i=new Date(o))),!o||!i?null:(o>i&&([o,i]=[i,o]),{from:o,to:i})},te=e=>{const s=e.target.value.replace(/[^\d/:\s→-]/g,"");h(s),f(!1)},T=()=>{if(!M.trim()){c(void 0),f(!1);return}const e=ee(M);e?(c(e),f(!1)):f(!0)},se=e=>{if(e.key==="Enter")e.preventDefault(),T(),w||S(!0);else if(e.key==="Escape"){if(e.preventDefault(),t!=null&&t.from){const s=l.format(t.from,x,{locale:d}),a=t.to?l.format(t.to,x,{locale:d}):"";h(a?`${s} → ${a}`:s)}else h("");f(!1)}},re=e=>{e.stopPropagation(),c(void 0),h(""),f(!1)};return r.jsxs(I.Popover,{open:J,onOpenChange:S,children:[r.jsxs("div",{className:"relative w-full",children:[r.jsx(ce.Input,{ref:G,id:L,name:X,value:M,onChange:te,onBlur:T,onKeyDown:se,placeholder:b,disabled:H,"aria-invalid":O||w,className:le.cn("pr-20",(O||w)&&"border-destructive focus-visible:ring-destructive/20",A)}),r.jsxs("div",{className:"absolute inset-y-0 right-0 flex items-center gap-1 pr-1",children:[M&&!H&&r.jsxs(g.Button,{type:"button",variant:"ghost",size:"sm",className:"h-7 w-7 p-0 hover:bg-transparent",onClick:re,tabIndex:-1,children:[r.jsx($.X,{className:"h-4 w-4 text-muted-foreground hover:text-foreground"}),r.jsx("span",{className:"sr-only",children:"Limpar"})]}),r.jsx(I.PopoverTrigger,{asChild:!0,children:r.jsx(g.Button,{type:"button",variant:"ghost",size:"sm",className:"h-7 w-7 p-0 hover:bg-transparent",disabled:H,"aria-label":"Abrir calendário",children:r.jsx($.CalendarIcon,{className:"h-4 w-4 text-muted-foreground"})})})]})]}),r.jsx(I.PopoverContent,{className:"w-auto p-0",align:"start",children:r.jsxs("div",{className:"flex",children:[E.length>0&&r.jsxs("div",{className:"border-r p-3 space-y-1 w-32.5",children:[r.jsx("p",{className:"text-xs font-medium text-muted-foreground mb-2",children:"Atalhos"}),E.map(e=>r.jsx(g.Button,{variant:"ghost",size:"sm",className:"w-full justify-start text-sm h-8 truncate",onClick:()=>Z(e),children:r.jsx("span",{className:"truncate",children:e.label})},e.label))]}),r.jsxs("div",{children:[r.jsx(ue.Calendar,{mode:"range",selected:t,onSelect:U,numberOfMonths:K,disabled:e=>!!(j&&e<j||v&&e>v),locale:d,autoFocus:!0}),p&&(t==null?void 0:t.from)&&(t==null?void 0:t.to)&&r.jsxs("div",{className:"border-t p-3 flex gap-6",children:[r.jsxs("div",{className:"flex-1",children:[r.jsx("p",{className:"text-xs font-medium text-muted-foreground mb-2",children:"Hora início"}),r.jsx(F.TimePicker,{value:C,onChange:W,format:R,minuteStep:B,variant:"select",showIcon:!1})]}),r.jsxs("div",{className:"flex-1",children:[r.jsx("p",{className:"text-xs font-medium text-muted-foreground mb-2",children:"Hora fim"}),r.jsx(F.TimePicker,{value:P,onChange:Y,format:R,minuteStep:B,variant:"select",showIcon:!1})]})]}),r.jsxs("div",{className:"border-t p-3 flex justify-end gap-2",children:[r.jsx(g.Button,{variant:"outline",size:"sm",onClick:()=>{c(void 0)},children:"Limpar"}),r.jsx(g.Button,{size:"sm",onClick:()=>S(!1),children:"Confirmar"})]})]})]})})]})});_.displayName="DateRangePicker";exports.DateRangePicker=_;
|
|
2
2
|
//# sourceMappingURL=date-range-picker.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-range-picker.cjs","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.cjs","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","newValue","handleInputBlur","handleInputKeyDown","handleClear","jsxs","Popover","jsx","Input","cn","Button","X","PopoverTrigger","CalendarIcon","PopoverContent","Calendar","date","TimePicker"],"mappings":"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"}
|