framepexls-ui-lib 0.1.8 → 0.1.10

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.
@@ -0,0 +1,268 @@
1
+ "use strict";
2
+ "use client";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+ var TimeRangeField_exports = {};
31
+ __export(TimeRangeField_exports, {
32
+ default: () => TimeRangeField
33
+ });
34
+ module.exports = __toCommonJS(TimeRangeField_exports);
35
+ var import_jsx_runtime = require("react/jsx-runtime");
36
+ var import_react = require("react");
37
+ var import_react_dom = require("react-dom");
38
+ var import_Input = __toESM(require("./Input"));
39
+ var import_TimePopover = __toESM(require("./TimePopover"));
40
+ const pad2 = (n) => n < 10 ? `0${n}` : String(n);
41
+ function parseHHmm(v) {
42
+ if (!v) return null;
43
+ const [hh, mm] = String(v).split(":").map((x) => parseInt(x, 10));
44
+ if (Number.isNaN(hh) || Number.isNaN(mm)) return null;
45
+ return { hh: Math.max(0, Math.min(23, hh)), mm: Math.max(0, Math.min(59, mm)) };
46
+ }
47
+ function fmtHHmm(hh, mm) {
48
+ return `${pad2(hh)}:${pad2(mm)}`;
49
+ }
50
+ function TimeRangeField({ value, onValueChange, portal = true, portalId, clearable = true, step = 5, placeholder = "Selecciona rango", className, disabled }) {
51
+ var _a, _b, _c, _d, _e, _f;
52
+ const anchorRef = (0, import_react.useRef)(null);
53
+ const [open, setOpen] = (0, import_react.useState)(false);
54
+ const [portalRoot, setPortalRoot] = (0, import_react.useState)(null);
55
+ const [anchorRect, setAnchorRect] = (0, import_react.useState)(null);
56
+ const [from, setFrom] = (0, import_react.useState)(() => {
57
+ var _a2;
58
+ return (_a2 = parseHHmm(value == null ? void 0 : value.from)) != null ? _a2 : null;
59
+ });
60
+ const [to, setTo] = (0, import_react.useState)(() => {
61
+ var _a2;
62
+ return (_a2 = parseHHmm(value == null ? void 0 : value.to)) != null ? _a2 : null;
63
+ });
64
+ const fromBtnRef = (0, import_react.useRef)(null);
65
+ const toBtnRef = (0, import_react.useRef)(null);
66
+ const [showFromPop, setShowFromPop] = (0, import_react.useState)(false);
67
+ const [showToPop, setShowToPop] = (0, import_react.useState)(false);
68
+ (0, import_react.useEffect)(() => {
69
+ var _a2;
70
+ setFrom((_a2 = parseHHmm(value == null ? void 0 : value.from)) != null ? _a2 : null);
71
+ }, [value == null ? void 0 : value.from]);
72
+ (0, import_react.useEffect)(() => {
73
+ var _a2;
74
+ setTo((_a2 = parseHHmm(value == null ? void 0 : value.to)) != null ? _a2 : null);
75
+ }, [value == null ? void 0 : value.to]);
76
+ (0, import_react.useEffect)(() => {
77
+ if (!portal) return;
78
+ const el = portalId ? document.getElementById(portalId) : null;
79
+ setPortalRoot(el != null ? el : document.body);
80
+ }, [portal, portalId]);
81
+ const display = (0, import_react.useMemo)(() => {
82
+ var _a2;
83
+ const a = from ? fmtHHmm(from.hh, from.mm) : null;
84
+ const b = to ? fmtHHmm(to.hh, to.mm) : null;
85
+ if (!a && !b) return "";
86
+ if (a && b) return `${a} \u2013 ${b}`;
87
+ return (_a2 = a != null ? a : b) != null ? _a2 : "";
88
+ }, [from, to]);
89
+ const openPopover = () => {
90
+ if (disabled) return;
91
+ if (!anchorRef.current) return;
92
+ setAnchorRect(anchorRef.current.getBoundingClientRect());
93
+ setOpen(true);
94
+ };
95
+ (0, import_react.useEffect)(() => {
96
+ if (!open) return;
97
+ const onDown = (e) => {
98
+ var _a2;
99
+ const t = e.target;
100
+ if (t.closest("[data-trf-pop]")) return;
101
+ if (t.closest("[data-dtf-pop]")) return;
102
+ if ((_a2 = anchorRef.current) == null ? void 0 : _a2.contains(t)) return;
103
+ setOpen(false);
104
+ };
105
+ const update = () => {
106
+ if (!anchorRef.current) return;
107
+ setAnchorRect(anchorRef.current.getBoundingClientRect());
108
+ };
109
+ const onEsc = (e) => {
110
+ if (e.key === "Escape") setOpen(false);
111
+ };
112
+ window.addEventListener("pointerdown", onDown, true);
113
+ window.addEventListener("scroll", update, true);
114
+ window.addEventListener("resize", update);
115
+ window.addEventListener("keydown", onEsc);
116
+ return () => {
117
+ window.removeEventListener("pointerdown", onDown, true);
118
+ window.removeEventListener("scroll", update, true);
119
+ window.removeEventListener("resize", update);
120
+ window.removeEventListener("keydown", onEsc);
121
+ };
122
+ }, [open]);
123
+ const stylePop = (() => {
124
+ if (!anchorRect) return { visibility: "hidden" };
125
+ const W = 360, GAP = 8, MARGIN = 8, H = 180;
126
+ let left = anchorRect.right - W;
127
+ left = Math.max(MARGIN, Math.min(left, window.innerWidth - (W + MARGIN)));
128
+ let top = anchorRect.bottom + GAP;
129
+ if (top + H > window.innerHeight) top = Math.max(MARGIN, anchorRect.top - GAP - H);
130
+ return { position: "fixed", top, left, zIndex: 1e5 };
131
+ })();
132
+ const commit = (f, t) => {
133
+ let f2 = f, t2 = t;
134
+ if (f2 && t2) {
135
+ const a = f2.hh * 60 + f2.mm;
136
+ const b = t2.hh * 60 + t2.mm;
137
+ if (b < a) t2 = { ...f2 };
138
+ }
139
+ setFrom(f2);
140
+ setTo(t2);
141
+ onValueChange == null ? void 0 : onValueChange({ from: f2 ? fmtHHmm(f2.hh, f2.mm) : null, to: t2 ? fmtHHmm(t2.hh, t2.mm) : null });
142
+ };
143
+ const popover = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { "data-trf-pop": true, style: stylePop, className: "w-1/3 overflow-hidden rounded-2xl border border-slate-200 bg-white shadow-xl dark:border-white/10 dark:bg-[#0e0d0e]", children: [
144
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between gap-2 px-3 py-2 text-sm", children: [
145
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "font-medium", children: "Selecciona horario" }),
146
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
147
+ "button",
148
+ {
149
+ type: "button",
150
+ className: "rounded-xl bg-slate-900 px-3 py-1.5 text-white hover:opacity-95 active:scale-[0.98] dark:bg-white dark:text-slate-900",
151
+ onClick: () => setOpen(false),
152
+ children: "Aplicar"
153
+ }
154
+ )
155
+ ] }),
156
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-2 gap-3 border-t border-slate-100 p-3 text-sm dark:border-white/10", children: [
157
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
158
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mb-1 text-xs text-slate-500 dark:text-slate-300", children: "Desde" }),
159
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
160
+ "button",
161
+ {
162
+ type: "button",
163
+ className: "rounded-xl ring-1 ring-slate-200 px-2.5 py-1.5 font-medium tracking-wide hover:bg-slate-50 active:scale-[0.98] dark:ring-white/10 dark:hover:bg-white/10",
164
+ onClick: () => setShowFromPop((v) => !v),
165
+ ref: fromBtnRef,
166
+ children: from ? fmtHHmm(from.hh, from.mm) : "--:--"
167
+ }
168
+ ),
169
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
170
+ "button",
171
+ {
172
+ type: "button",
173
+ className: "ml-2 rounded-xl ring-1 ring-slate-200 px-2.5 py-1.5 hover:bg-slate-50 active:scale-[0.98] dark:ring-white/10 dark:hover:bg-white/10",
174
+ onClick: () => {
175
+ const t = /* @__PURE__ */ new Date();
176
+ const rounded = Math.round(t.getMinutes() / step) * step % 60;
177
+ commit({ hh: t.getHours(), mm: rounded }, to);
178
+ },
179
+ children: "Ahora"
180
+ }
181
+ )
182
+ ] }),
183
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
184
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mb-1 text-xs text-slate-500 dark:text-slate-300", children: "Hasta" }),
185
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
186
+ "button",
187
+ {
188
+ type: "button",
189
+ className: "rounded-xl ring-1 ring-slate-200 px-2.5 py-1.5 font-medium tracking-wide hover:bg-slate-50 active:scale-[0.98] dark:ring-white/10 dark:hover:bg-white/10",
190
+ onClick: () => setShowToPop((v) => !v),
191
+ ref: toBtnRef,
192
+ children: to ? fmtHHmm(to.hh, to.mm) : "--:--"
193
+ }
194
+ ),
195
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
196
+ "button",
197
+ {
198
+ type: "button",
199
+ className: "ml-2 rounded-xl ring-1 ring-slate-200 px-2.5 py-1.5 hover:bg-slate-50 active:scale-[0.98] dark:ring-white/10 dark:hover:bg-white/10",
200
+ onClick: () => {
201
+ const t = /* @__PURE__ */ new Date();
202
+ const rounded = Math.round(t.getMinutes() / step) * step % 60;
203
+ const candidate = { hh: t.getHours(), mm: rounded };
204
+ commit(from, candidate);
205
+ },
206
+ children: "Ahora"
207
+ }
208
+ )
209
+ ] })
210
+ ] })
211
+ ] });
212
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ref: anchorRef, className, children: [
213
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
214
+ import_Input.default,
215
+ {
216
+ value: display,
217
+ placeholder,
218
+ onClick: openPopover,
219
+ clearable,
220
+ onClear: () => {
221
+ setFrom(null);
222
+ setTo(null);
223
+ onValueChange == null ? void 0 : onValueChange({ from: null, to: null });
224
+ },
225
+ disabled,
226
+ rightSlot: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
227
+ "button",
228
+ {
229
+ type: "button",
230
+ className: "pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-lg border border-slate-200 bg-white text-slate-600 hover:bg-slate-50 active:scale-95 dark:border-white/10 dark:bg-white/5",
231
+ onClick: (e) => {
232
+ e.preventDefault();
233
+ openPopover();
234
+ },
235
+ title: "Abrir selector de horas",
236
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", className: "h-4.5 w-4.5", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
237
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 7v5l3 3" }),
238
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "9" })
239
+ ] })
240
+ }
241
+ )
242
+ }
243
+ ),
244
+ open && (portal ? portalRoot && (0, import_react_dom.createPortal)(popover, portalRoot) : popover),
245
+ open && showFromPop && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
246
+ import_TimePopover.default,
247
+ {
248
+ anchorEl: fromBtnRef.current,
249
+ hh: (_a = from == null ? void 0 : from.hh) != null ? _a : 0,
250
+ mm: (_b = from == null ? void 0 : from.mm) != null ? _b : 0,
251
+ onChange: (H, M) => commit({ hh: H, mm: M }, to),
252
+ onClose: () => setShowFromPop(false),
253
+ step
254
+ }
255
+ ),
256
+ open && showToPop && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
257
+ import_TimePopover.default,
258
+ {
259
+ anchorEl: toBtnRef.current,
260
+ hh: (_d = to == null ? void 0 : to.hh) != null ? _d : (_c = from == null ? void 0 : from.hh) != null ? _c : 0,
261
+ mm: (_f = to == null ? void 0 : to.mm) != null ? _f : (_e = from == null ? void 0 : from.mm) != null ? _e : 0,
262
+ onChange: (H, M) => commit(from, { hh: H, mm: M }),
263
+ onClose: () => setShowToPop(false),
264
+ step
265
+ }
266
+ )
267
+ ] });
268
+ }
@@ -0,0 +1,238 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useMemo, useRef, useState } from "react";
4
+ import { createPortal } from "react-dom";
5
+ import Input from "./Input";
6
+ import TimePopover from "./TimePopover";
7
+ const pad2 = (n) => n < 10 ? `0${n}` : String(n);
8
+ function parseHHmm(v) {
9
+ if (!v) return null;
10
+ const [hh, mm] = String(v).split(":").map((x) => parseInt(x, 10));
11
+ if (Number.isNaN(hh) || Number.isNaN(mm)) return null;
12
+ return { hh: Math.max(0, Math.min(23, hh)), mm: Math.max(0, Math.min(59, mm)) };
13
+ }
14
+ function fmtHHmm(hh, mm) {
15
+ return `${pad2(hh)}:${pad2(mm)}`;
16
+ }
17
+ function TimeRangeField({ value, onValueChange, portal = true, portalId, clearable = true, step = 5, placeholder = "Selecciona rango", className, disabled }) {
18
+ var _a, _b, _c, _d, _e, _f;
19
+ const anchorRef = useRef(null);
20
+ const [open, setOpen] = useState(false);
21
+ const [portalRoot, setPortalRoot] = useState(null);
22
+ const [anchorRect, setAnchorRect] = useState(null);
23
+ const [from, setFrom] = useState(() => {
24
+ var _a2;
25
+ return (_a2 = parseHHmm(value == null ? void 0 : value.from)) != null ? _a2 : null;
26
+ });
27
+ const [to, setTo] = useState(() => {
28
+ var _a2;
29
+ return (_a2 = parseHHmm(value == null ? void 0 : value.to)) != null ? _a2 : null;
30
+ });
31
+ const fromBtnRef = useRef(null);
32
+ const toBtnRef = useRef(null);
33
+ const [showFromPop, setShowFromPop] = useState(false);
34
+ const [showToPop, setShowToPop] = useState(false);
35
+ useEffect(() => {
36
+ var _a2;
37
+ setFrom((_a2 = parseHHmm(value == null ? void 0 : value.from)) != null ? _a2 : null);
38
+ }, [value == null ? void 0 : value.from]);
39
+ useEffect(() => {
40
+ var _a2;
41
+ setTo((_a2 = parseHHmm(value == null ? void 0 : value.to)) != null ? _a2 : null);
42
+ }, [value == null ? void 0 : value.to]);
43
+ useEffect(() => {
44
+ if (!portal) return;
45
+ const el = portalId ? document.getElementById(portalId) : null;
46
+ setPortalRoot(el != null ? el : document.body);
47
+ }, [portal, portalId]);
48
+ const display = useMemo(() => {
49
+ var _a2;
50
+ const a = from ? fmtHHmm(from.hh, from.mm) : null;
51
+ const b = to ? fmtHHmm(to.hh, to.mm) : null;
52
+ if (!a && !b) return "";
53
+ if (a && b) return `${a} \u2013 ${b}`;
54
+ return (_a2 = a != null ? a : b) != null ? _a2 : "";
55
+ }, [from, to]);
56
+ const openPopover = () => {
57
+ if (disabled) return;
58
+ if (!anchorRef.current) return;
59
+ setAnchorRect(anchorRef.current.getBoundingClientRect());
60
+ setOpen(true);
61
+ };
62
+ useEffect(() => {
63
+ if (!open) return;
64
+ const onDown = (e) => {
65
+ var _a2;
66
+ const t = e.target;
67
+ if (t.closest("[data-trf-pop]")) return;
68
+ if (t.closest("[data-dtf-pop]")) return;
69
+ if ((_a2 = anchorRef.current) == null ? void 0 : _a2.contains(t)) return;
70
+ setOpen(false);
71
+ };
72
+ const update = () => {
73
+ if (!anchorRef.current) return;
74
+ setAnchorRect(anchorRef.current.getBoundingClientRect());
75
+ };
76
+ const onEsc = (e) => {
77
+ if (e.key === "Escape") setOpen(false);
78
+ };
79
+ window.addEventListener("pointerdown", onDown, true);
80
+ window.addEventListener("scroll", update, true);
81
+ window.addEventListener("resize", update);
82
+ window.addEventListener("keydown", onEsc);
83
+ return () => {
84
+ window.removeEventListener("pointerdown", onDown, true);
85
+ window.removeEventListener("scroll", update, true);
86
+ window.removeEventListener("resize", update);
87
+ window.removeEventListener("keydown", onEsc);
88
+ };
89
+ }, [open]);
90
+ const stylePop = (() => {
91
+ if (!anchorRect) return { visibility: "hidden" };
92
+ const W = 360, GAP = 8, MARGIN = 8, H = 180;
93
+ let left = anchorRect.right - W;
94
+ left = Math.max(MARGIN, Math.min(left, window.innerWidth - (W + MARGIN)));
95
+ let top = anchorRect.bottom + GAP;
96
+ if (top + H > window.innerHeight) top = Math.max(MARGIN, anchorRect.top - GAP - H);
97
+ return { position: "fixed", top, left, zIndex: 1e5 };
98
+ })();
99
+ const commit = (f, t) => {
100
+ let f2 = f, t2 = t;
101
+ if (f2 && t2) {
102
+ const a = f2.hh * 60 + f2.mm;
103
+ const b = t2.hh * 60 + t2.mm;
104
+ if (b < a) t2 = { ...f2 };
105
+ }
106
+ setFrom(f2);
107
+ setTo(t2);
108
+ onValueChange == null ? void 0 : onValueChange({ from: f2 ? fmtHHmm(f2.hh, f2.mm) : null, to: t2 ? fmtHHmm(t2.hh, t2.mm) : null });
109
+ };
110
+ const popover = /* @__PURE__ */ jsxs("div", { "data-trf-pop": true, style: stylePop, className: "w-1/3 overflow-hidden rounded-2xl border border-slate-200 bg-white shadow-xl dark:border-white/10 dark:bg-[#0e0d0e]", children: [
111
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 px-3 py-2 text-sm", children: [
112
+ /* @__PURE__ */ jsx("div", { className: "font-medium", children: "Selecciona horario" }),
113
+ /* @__PURE__ */ jsx(
114
+ "button",
115
+ {
116
+ type: "button",
117
+ className: "rounded-xl bg-slate-900 px-3 py-1.5 text-white hover:opacity-95 active:scale-[0.98] dark:bg-white dark:text-slate-900",
118
+ onClick: () => setOpen(false),
119
+ children: "Aplicar"
120
+ }
121
+ )
122
+ ] }),
123
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3 border-t border-slate-100 p-3 text-sm dark:border-white/10", children: [
124
+ /* @__PURE__ */ jsxs("div", { children: [
125
+ /* @__PURE__ */ jsx("div", { className: "mb-1 text-xs text-slate-500 dark:text-slate-300", children: "Desde" }),
126
+ /* @__PURE__ */ jsx(
127
+ "button",
128
+ {
129
+ type: "button",
130
+ className: "rounded-xl ring-1 ring-slate-200 px-2.5 py-1.5 font-medium tracking-wide hover:bg-slate-50 active:scale-[0.98] dark:ring-white/10 dark:hover:bg-white/10",
131
+ onClick: () => setShowFromPop((v) => !v),
132
+ ref: fromBtnRef,
133
+ children: from ? fmtHHmm(from.hh, from.mm) : "--:--"
134
+ }
135
+ ),
136
+ /* @__PURE__ */ jsx(
137
+ "button",
138
+ {
139
+ type: "button",
140
+ className: "ml-2 rounded-xl ring-1 ring-slate-200 px-2.5 py-1.5 hover:bg-slate-50 active:scale-[0.98] dark:ring-white/10 dark:hover:bg-white/10",
141
+ onClick: () => {
142
+ const t = /* @__PURE__ */ new Date();
143
+ const rounded = Math.round(t.getMinutes() / step) * step % 60;
144
+ commit({ hh: t.getHours(), mm: rounded }, to);
145
+ },
146
+ children: "Ahora"
147
+ }
148
+ )
149
+ ] }),
150
+ /* @__PURE__ */ jsxs("div", { children: [
151
+ /* @__PURE__ */ jsx("div", { className: "mb-1 text-xs text-slate-500 dark:text-slate-300", children: "Hasta" }),
152
+ /* @__PURE__ */ jsx(
153
+ "button",
154
+ {
155
+ type: "button",
156
+ className: "rounded-xl ring-1 ring-slate-200 px-2.5 py-1.5 font-medium tracking-wide hover:bg-slate-50 active:scale-[0.98] dark:ring-white/10 dark:hover:bg-white/10",
157
+ onClick: () => setShowToPop((v) => !v),
158
+ ref: toBtnRef,
159
+ children: to ? fmtHHmm(to.hh, to.mm) : "--:--"
160
+ }
161
+ ),
162
+ /* @__PURE__ */ jsx(
163
+ "button",
164
+ {
165
+ type: "button",
166
+ className: "ml-2 rounded-xl ring-1 ring-slate-200 px-2.5 py-1.5 hover:bg-slate-50 active:scale-[0.98] dark:ring-white/10 dark:hover:bg-white/10",
167
+ onClick: () => {
168
+ const t = /* @__PURE__ */ new Date();
169
+ const rounded = Math.round(t.getMinutes() / step) * step % 60;
170
+ const candidate = { hh: t.getHours(), mm: rounded };
171
+ commit(from, candidate);
172
+ },
173
+ children: "Ahora"
174
+ }
175
+ )
176
+ ] })
177
+ ] })
178
+ ] });
179
+ return /* @__PURE__ */ jsxs("div", { ref: anchorRef, className, children: [
180
+ /* @__PURE__ */ jsx(
181
+ Input,
182
+ {
183
+ value: display,
184
+ placeholder,
185
+ onClick: openPopover,
186
+ clearable,
187
+ onClear: () => {
188
+ setFrom(null);
189
+ setTo(null);
190
+ onValueChange == null ? void 0 : onValueChange({ from: null, to: null });
191
+ },
192
+ disabled,
193
+ rightSlot: /* @__PURE__ */ jsx(
194
+ "button",
195
+ {
196
+ type: "button",
197
+ className: "pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-lg border border-slate-200 bg-white text-slate-600 hover:bg-slate-50 active:scale-95 dark:border-white/10 dark:bg-white/5",
198
+ onClick: (e) => {
199
+ e.preventDefault();
200
+ openPopover();
201
+ },
202
+ title: "Abrir selector de horas",
203
+ children: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", className: "h-4.5 w-4.5", fill: "none", stroke: "currentColor", strokeWidth: 2, children: [
204
+ /* @__PURE__ */ jsx("path", { d: "M12 7v5l3 3" }),
205
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9" })
206
+ ] })
207
+ }
208
+ )
209
+ }
210
+ ),
211
+ open && (portal ? portalRoot && createPortal(popover, portalRoot) : popover),
212
+ open && showFromPop && /* @__PURE__ */ jsx(
213
+ TimePopover,
214
+ {
215
+ anchorEl: fromBtnRef.current,
216
+ hh: (_a = from == null ? void 0 : from.hh) != null ? _a : 0,
217
+ mm: (_b = from == null ? void 0 : from.mm) != null ? _b : 0,
218
+ onChange: (H, M) => commit({ hh: H, mm: M }, to),
219
+ onClose: () => setShowFromPop(false),
220
+ step
221
+ }
222
+ ),
223
+ open && showToPop && /* @__PURE__ */ jsx(
224
+ TimePopover,
225
+ {
226
+ anchorEl: toBtnRef.current,
227
+ hh: (_d = to == null ? void 0 : to.hh) != null ? _d : (_c = from == null ? void 0 : from.hh) != null ? _c : 0,
228
+ mm: (_f = to == null ? void 0 : to.mm) != null ? _f : (_e = from == null ? void 0 : from.mm) != null ? _e : 0,
229
+ onChange: (H, M) => commit(from, { hh: H, mm: M }),
230
+ onClose: () => setShowToPop(false),
231
+ step
232
+ }
233
+ )
234
+ ] });
235
+ }
236
+ export {
237
+ TimeRangeField as default
238
+ };
package/dist/index.d.mts CHANGED
@@ -23,9 +23,13 @@ export { default as AvatarSquare } from './AvatarSquare.mjs';
23
23
  export { default as AppTopbar } from './AppTopbar.mjs';
24
24
  export { default as OrderButton } from './OrderButton.mjs';
25
25
  export { default as SearchInput } from './SearchInput.mjs';
26
+ export { default as ReviewHistory, ReviewHistoryDialog } from './ReviewHistory.mjs';
27
+ export { MultiComboOption, default as MultiComboSelect, MultiComboSelectProps } from './MultiComboSelect.mjs';
28
+ export { default as Sidebar } from './Sidebar.mjs';
26
29
  export { default as CalendarPanel, CalendarPanelProps } from './CalendarPanel.mjs';
27
30
  export { MonthPopover, default as TimePopover, WeekPopover } from './TimePopover.mjs';
28
31
  export { default as TimePanel } from './TimePanel.mjs';
32
+ export { TimeRange, default as TimeRangeField, TimeRangeFieldProps } from './TimeRangeField.mjs';
29
33
  export { StepDef, default as Steps, StepsNav } from './Steps.mjs';
30
34
  export { Aficionados, AuditarDocumento, Borrar, CajaDeMano, Cajas, Calendario, ChevronLeftRightIcon, CirculoAdvertencia, CirculoExito, CirculoPeligro, CirculoPorDefecto, ClientsIcon, CloseIcon, ContraseniaDeEmailIcon, Cotizaciones, DashboardIcon, Directorio, Edificio, Editar, Empresa, EscaneoFacial, EyeIcon, FlechaAbajo, FlechaArriba, Imagenes, LlamadaTelefonica, LogoutIcon, MarketingDigital, MediosDeComunicacionSocial, MenuIcon, MenuPuntosVerticalIcon, Nota, Ojo, OrdersIcon, PencilIcon, PermsIcon, ProductsIcon, PromoIcon, Retroalimentacion, RolesIcon, Sobre, Tablero, Tarea, Tickets, TrabajoEnEquipo, TrashIcon, UserIcon, UsersIcon, UsuarioProhibidoIcon, Usuarios } from './iconos/index.mjs';
31
35
  import 'react/jsx-runtime';
package/dist/index.d.ts CHANGED
@@ -23,9 +23,13 @@ export { default as AvatarSquare } from './AvatarSquare.js';
23
23
  export { default as AppTopbar } from './AppTopbar.js';
24
24
  export { default as OrderButton } from './OrderButton.js';
25
25
  export { default as SearchInput } from './SearchInput.js';
26
+ export { default as ReviewHistory, ReviewHistoryDialog } from './ReviewHistory.js';
27
+ export { MultiComboOption, default as MultiComboSelect, MultiComboSelectProps } from './MultiComboSelect.js';
28
+ export { default as Sidebar } from './Sidebar.js';
26
29
  export { default as CalendarPanel, CalendarPanelProps } from './CalendarPanel.js';
27
30
  export { MonthPopover, default as TimePopover, WeekPopover } from './TimePopover.js';
28
31
  export { default as TimePanel } from './TimePanel.js';
32
+ export { TimeRange, default as TimeRangeField, TimeRangeFieldProps } from './TimeRangeField.js';
29
33
  export { StepDef, default as Steps, StepsNav } from './Steps.js';
30
34
  export { Aficionados, AuditarDocumento, Borrar, CajaDeMano, Cajas, Calendario, ChevronLeftRightIcon, CirculoAdvertencia, CirculoExito, CirculoPeligro, CirculoPorDefecto, ClientsIcon, CloseIcon, ContraseniaDeEmailIcon, Cotizaciones, DashboardIcon, Directorio, Edificio, Editar, Empresa, EscaneoFacial, EyeIcon, FlechaAbajo, FlechaArriba, Imagenes, LlamadaTelefonica, LogoutIcon, MarketingDigital, MediosDeComunicacionSocial, MenuIcon, MenuPuntosVerticalIcon, Nota, Ojo, OrdersIcon, PencilIcon, PermsIcon, ProductsIcon, PromoIcon, Retroalimentacion, RolesIcon, Sobre, Tablero, Tarea, Tickets, TrabajoEnEquipo, TrashIcon, UserIcon, UsersIcon, UsuarioProhibidoIcon, Usuarios } from './iconos/index.js';
31
35
  import 'react/jsx-runtime';
package/dist/index.js CHANGED
@@ -49,10 +49,14 @@ __export(index_exports, {
49
49
  Input: () => import_Input.default,
50
50
  Money: () => import_Money.default,
51
51
  MonthPopover: () => import_TimePopover2.MonthPopover,
52
+ MultiComboSelect: () => import_MultiComboSelect.default,
52
53
  OrderButton: () => import_OrderButton.default,
53
54
  Pagination: () => import_Pagination.default,
55
+ ReviewHistory: () => import_ReviewHistory.default,
56
+ ReviewHistoryDialog: () => import_ReviewHistory2.ReviewHistoryDialog,
54
57
  SearchInput: () => import_SearchInput.default,
55
58
  Select: () => import_Select.default,
59
+ Sidebar: () => import_Sidebar.default,
56
60
  SortTh: () => import_Table.SortTh,
57
61
  StatCard: () => import_StatCard.default,
58
62
  Steps: () => import_Steps.default,
@@ -62,6 +66,7 @@ __export(index_exports, {
62
66
  TimeAgo: () => import_TimeAgo.default,
63
67
  TimePanel: () => import_TimePanel.default,
64
68
  TimePopover: () => import_TimePopover.default,
69
+ TimeRangeField: () => import_TimeRangeField.default,
65
70
  WeekPopover: () => import_TimePopover2.WeekPopover
66
71
  });
67
72
  module.exports = __toCommonJS(index_exports);
@@ -92,10 +97,15 @@ var import_AvatarSquare = __toESM(require("./AvatarSquare"));
92
97
  var import_AppTopbar = __toESM(require("./AppTopbar"));
93
98
  var import_OrderButton = __toESM(require("./OrderButton"));
94
99
  var import_SearchInput = __toESM(require("./SearchInput"));
100
+ var import_ReviewHistory = __toESM(require("./ReviewHistory"));
101
+ var import_ReviewHistory2 = require("./ReviewHistory");
102
+ var import_MultiComboSelect = __toESM(require("./MultiComboSelect"));
103
+ var import_Sidebar = __toESM(require("./Sidebar"));
95
104
  var import_CalendarPanel = __toESM(require("./CalendarPanel"));
96
105
  var import_TimePopover = __toESM(require("./TimePopover"));
97
106
  var import_TimePopover2 = require("./TimePopover");
98
107
  var import_TimePanel = __toESM(require("./TimePanel"));
108
+ var import_TimeRangeField = __toESM(require("./TimeRangeField"));
99
109
  var import_Steps = __toESM(require("./Steps"));
100
110
  var import_Steps2 = require("./Steps");
101
111
  __reExport(index_exports, require("./iconos"), module.exports);
@@ -121,10 +131,14 @@ __reExport(index_exports, require("./iconos"), module.exports);
121
131
  Input,
122
132
  Money,
123
133
  MonthPopover,
134
+ MultiComboSelect,
124
135
  OrderButton,
125
136
  Pagination,
137
+ ReviewHistory,
138
+ ReviewHistoryDialog,
126
139
  SearchInput,
127
140
  Select,
141
+ Sidebar,
128
142
  SortTh,
129
143
  StatCard,
130
144
  Steps,
@@ -134,6 +148,7 @@ __reExport(index_exports, require("./iconos"), module.exports);
134
148
  TimeAgo,
135
149
  TimePanel,
136
150
  TimePopover,
151
+ TimeRangeField,
137
152
  WeekPopover,
138
153
  ...require("./Dialog"),
139
154
  ...require("./Dropdown"),
package/dist/index.mjs CHANGED
@@ -25,11 +25,16 @@ import { default as default22 } from "./AvatarSquare";
25
25
  import { default as default23 } from "./AppTopbar";
26
26
  import { default as default24 } from "./OrderButton";
27
27
  import { default as default25 } from "./SearchInput";
28
- import { default as default26 } from "./CalendarPanel";
29
- import { default as default27 } from "./TimePopover";
28
+ import { default as default26 } from "./ReviewHistory";
29
+ import { ReviewHistoryDialog } from "./ReviewHistory";
30
+ import { default as default27 } from "./MultiComboSelect";
31
+ import { default as default28 } from "./Sidebar";
32
+ import { default as default29 } from "./CalendarPanel";
33
+ import { default as default30 } from "./TimePopover";
30
34
  import { WeekPopover, MonthPopover } from "./TimePopover";
31
- import { default as default28 } from "./TimePanel";
32
- import { default as default29 } from "./Steps";
35
+ import { default as default31 } from "./TimePanel";
36
+ import { default as default32 } from "./TimeRangeField";
37
+ import { default as default33 } from "./Steps";
33
38
  import { StepsNav } from "./Steps";
34
39
  export * from "./iconos";
35
40
  export {
@@ -40,7 +45,7 @@ export {
40
45
  default17 as BadgeCluster,
41
46
  default18 as Breadcrumb,
42
47
  default2 as Button,
43
- default26 as CalendarPanel,
48
+ default29 as CalendarPanel,
44
49
  default14 as ChartCard,
45
50
  default5 as CheckboxPillsGroup,
46
51
  default8 as ColumnSelector,
@@ -53,18 +58,23 @@ export {
53
58
  default4 as Input,
54
59
  default20 as Money,
55
60
  MonthPopover,
61
+ default27 as MultiComboSelect,
56
62
  default24 as OrderButton,
57
63
  default12 as Pagination,
64
+ default26 as ReviewHistory,
65
+ ReviewHistoryDialog,
58
66
  default25 as SearchInput,
59
67
  default6 as Select,
68
+ default28 as Sidebar,
60
69
  SortTh,
61
70
  default15 as StatCard,
62
- default29 as Steps,
71
+ default33 as Steps,
63
72
  StepsNav,
64
73
  Td,
65
74
  Th,
66
75
  default21 as TimeAgo,
67
- default28 as TimePanel,
68
- default27 as TimePopover,
76
+ default31 as TimePanel,
77
+ default30 as TimePopover,
78
+ default32 as TimeRangeField,
69
79
  WeekPopover
70
80
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "framepexls-ui-lib",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "description": "Componentes UI de Framepexls para React/Next.",