framepexls-ui-lib 1.14.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Button.js CHANGED
@@ -87,7 +87,7 @@ const Button = import_react.default.forwardRef(({
87
87
  stone: "bg-stone-600 text-white hover:opacity-90 active:scale-[.98] dark:bg-stone-500",
88
88
  red: "bg-red-600 text-white hover:opacity-90 active:scale-[.98] dark:bg-red-500",
89
89
  orange: "bg-orange-600 text-white hover:opacity-90 active:scale-[.98] dark:bg-orange-500",
90
- amber: "bg-amber-600 text-white hover:opacity-90 active:scale-[.98] dark:bg-amber-500",
90
+ amber: "bg-amber-600 text-slate-950 hover:opacity-90 active:scale-[.98] dark:bg-amber-500 dark:text-slate-950",
91
91
  yellow: "bg-yellow-500 text-slate-900 hover:opacity-95 active:scale-[.98] dark:bg-yellow-400",
92
92
  lime: "bg-lime-600 text-white hover:opacity-90 active:scale-[.98] dark:bg-lime-500",
93
93
  green: "bg-green-600 text-white hover:opacity-90 active:scale-[.98] dark:bg-green-500",
package/dist/Button.mjs CHANGED
@@ -54,7 +54,7 @@ const Button = React.forwardRef(({
54
54
  stone: "bg-stone-600 text-white hover:opacity-90 active:scale-[.98] dark:bg-stone-500",
55
55
  red: "bg-red-600 text-white hover:opacity-90 active:scale-[.98] dark:bg-red-500",
56
56
  orange: "bg-orange-600 text-white hover:opacity-90 active:scale-[.98] dark:bg-orange-500",
57
- amber: "bg-amber-600 text-white hover:opacity-90 active:scale-[.98] dark:bg-amber-500",
57
+ amber: "bg-amber-600 text-slate-950 hover:opacity-90 active:scale-[.98] dark:bg-amber-500 dark:text-slate-950",
58
58
  yellow: "bg-yellow-500 text-slate-900 hover:opacity-95 active:scale-[.98] dark:bg-yellow-400",
59
59
  lime: "bg-lime-600 text-white hover:opacity-90 active:scale-[.98] dark:bg-lime-500",
60
60
  green: "bg-green-600 text-white hover:opacity-90 active:scale-[.98] dark:bg-green-500",
@@ -11,7 +11,7 @@ type CheckboxProps = Omit<React__default.InputHTMLAttributes<HTMLInputElement>,
11
11
  className?: string;
12
12
  inputClassName?: string;
13
13
  };
14
- declare const Checkbox: React__default.ForwardRefExoticComponent<Omit<React__default.InputHTMLAttributes<HTMLInputElement>, "type" | "size"> & {
14
+ declare const Checkbox: React__default.ForwardRefExoticComponent<Omit<React__default.InputHTMLAttributes<HTMLInputElement>, "size" | "type"> & {
15
15
  label?: React__default.ReactNode;
16
16
  description?: React__default.ReactNode;
17
17
  error?: boolean;
@@ -11,7 +11,7 @@ type CheckboxProps = Omit<React__default.InputHTMLAttributes<HTMLInputElement>,
11
11
  className?: string;
12
12
  inputClassName?: string;
13
13
  };
14
- declare const Checkbox: React__default.ForwardRefExoticComponent<Omit<React__default.InputHTMLAttributes<HTMLInputElement>, "type" | "size"> & {
14
+ declare const Checkbox: React__default.ForwardRefExoticComponent<Omit<React__default.InputHTMLAttributes<HTMLInputElement>, "size" | "type"> & {
15
15
  label?: React__default.ReactNode;
16
16
  description?: React__default.ReactNode;
17
17
  error?: boolean;
@@ -11,7 +11,7 @@ type Props = {
11
11
  placeholder?: React__default.ReactNode;
12
12
  /** columnas en sm+ (1|2|3|4). default: 2 */
13
13
  smCols?: 1 | 2 | 3 | 4;
14
- /** columnas en md+ (opcional) */
14
+ /** columnas en md+ */
15
15
  mdCols?: 1 | 2 | 3 | 4;
16
16
  className?: string;
17
17
  };
@@ -11,7 +11,7 @@ type Props = {
11
11
  placeholder?: React__default.ReactNode;
12
12
  /** columnas en sm+ (1|2|3|4). default: 2 */
13
13
  smCols?: 1 | 2 | 3 | 4;
14
- /** columnas en md+ (opcional) */
14
+ /** columnas en md+ */
15
15
  mdCols?: 1 | 2 | 3 | 4;
16
16
  className?: string;
17
17
  };
@@ -116,7 +116,7 @@ function PageScaffold({
116
116
  if (typeof emptyState === "string" || typeof emptyState === "number") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_EmptyState.default, { title: emptyState });
117
117
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_EmptyState.default, { ...emptyState });
118
118
  }, [emptyState]);
119
- const toolbarActions = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
119
+ const toolbarActions = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex w-full flex-col items-stretch gap-2 sm:w-auto sm:flex-row sm:flex-wrap sm:items-center sm:justify-end [&>*]:w-full sm:[&>*]:w-auto", children: [
120
120
  primaryAction && ((_p = tools == null ? void 0 : tools.primaryAction) != null ? _p : true) ? primaryAction.tooltip ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Tooltip.default, { content: primaryAction.tooltip, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
121
121
  import_Button.default,
122
122
  {
@@ -144,7 +144,7 @@ function PageScaffold({
144
144
  ) : null,
145
145
  ((_u = tools == null ? void 0 : tools.actions) != null ? _u : true) ? actions : null
146
146
  ] });
147
- const toolbarControls = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
147
+ const toolbarControls = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex w-full flex-col items-stretch gap-2 sm:flex-row sm:flex-wrap sm:items-center", children: [
148
148
  filters && ((_v = tools == null ? void 0 : tools.filters) != null ? _v : true) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
149
149
  import_FiltersMultiSelect.default,
150
150
  {
@@ -227,9 +227,9 @@ function PageScaffold({
227
227
  disabled: search.disabled || showLoading
228
228
  }
229
229
  ) }),
230
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-wrap items-center justify-end gap-2", children: toolbarActions })
230
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-full lg:w-auto", children: toolbarActions })
231
231
  ] }),
232
- filters || sort || columns || tabs ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-wrap items-center justify-between gap-2", children: toolbarControls }) : null
232
+ filters || sort || columns || tabs ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex flex-col gap-2 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between", children: toolbarControls }) : null
233
233
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between", children: [
234
234
  toolbarControls,
235
235
  toolbarActions
@@ -83,7 +83,7 @@ function PageScaffold({
83
83
  if (typeof emptyState === "string" || typeof emptyState === "number") return /* @__PURE__ */ jsx(EmptyState, { title: emptyState });
84
84
  return /* @__PURE__ */ jsx(EmptyState, { ...emptyState });
85
85
  }, [emptyState]);
86
- const toolbarActions = /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
86
+ const toolbarActions = /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col items-stretch gap-2 sm:w-auto sm:flex-row sm:flex-wrap sm:items-center sm:justify-end [&>*]:w-full sm:[&>*]:w-auto", children: [
87
87
  primaryAction && ((_p = tools == null ? void 0 : tools.primaryAction) != null ? _p : true) ? primaryAction.tooltip ? /* @__PURE__ */ jsx(Tooltip, { content: primaryAction.tooltip, children: /* @__PURE__ */ jsx(
88
88
  Button,
89
89
  {
@@ -111,7 +111,7 @@ function PageScaffold({
111
111
  ) : null,
112
112
  ((_u = tools == null ? void 0 : tools.actions) != null ? _u : true) ? actions : null
113
113
  ] });
114
- const toolbarControls = /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
114
+ const toolbarControls = /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col items-stretch gap-2 sm:flex-row sm:flex-wrap sm:items-center", children: [
115
115
  filters && ((_v = tools == null ? void 0 : tools.filters) != null ? _v : true) ? /* @__PURE__ */ jsx(
116
116
  FiltersMultiSelect,
117
117
  {
@@ -194,9 +194,9 @@ function PageScaffold({
194
194
  disabled: search.disabled || showLoading
195
195
  }
196
196
  ) }),
197
- /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center justify-end gap-2", children: toolbarActions })
197
+ /* @__PURE__ */ jsx("div", { className: "w-full lg:w-auto", children: toolbarActions })
198
198
  ] }),
199
- filters || sort || columns || tabs ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center justify-between gap-2", children: toolbarControls }) : null
199
+ filters || sort || columns || tabs ? /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between", children: toolbarControls }) : null
200
200
  ] }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between", children: [
201
201
  toolbarControls,
202
202
  toolbarActions
@@ -216,7 +216,7 @@ function QuoteEditor({
216
216
  {
217
217
  value: (_f = value.clientId) != null ? _f : "",
218
218
  onChange: readOnly ? void 0 : (e) => update({ clientId: e.currentTarget.value || null }),
219
- placeholder: "ID de cliente (opcional)"
219
+ placeholder: "ID de cliente"
220
220
  }
221
221
  ) })
222
222
  ] })
@@ -253,7 +253,7 @@ function QuoteEditor({
253
253
  value: (_b2 = l.description) != null ? _b2 : "",
254
254
  onChange: readOnly ? void 0 : (e) => updateLine(l.id, { description: e.currentTarget.value || null }),
255
255
  rows: 2,
256
- placeholder: "Descripci\xF3n (opcional)",
256
+ placeholder: "Descripci\xF3n",
257
257
  className: "text-[0.8125rem]"
258
258
  }
259
259
  )
@@ -192,7 +192,7 @@ function QuoteEditor({
192
192
  {
193
193
  value: (_f = value.clientId) != null ? _f : "",
194
194
  onChange: readOnly ? void 0 : (e) => update({ clientId: e.currentTarget.value || null }),
195
- placeholder: "ID de cliente (opcional)"
195
+ placeholder: "ID de cliente"
196
196
  }
197
197
  ) })
198
198
  ] })
@@ -229,7 +229,7 @@ function QuoteEditor({
229
229
  value: (_b2 = l.description) != null ? _b2 : "",
230
230
  onChange: readOnly ? void 0 : (e) => updateLine(l.id, { description: e.currentTarget.value || null }),
231
231
  rows: 2,
232
- placeholder: "Descripci\xF3n (opcional)",
232
+ placeholder: "Descripci\xF3n",
233
233
  className: "text-[0.8125rem]"
234
234
  }
235
235
  )
package/dist/Reviews.js CHANGED
@@ -262,10 +262,10 @@ function Reviews({
262
262
  comment: (_k = labels == null ? void 0 : labels.comment) != null ? _k : "Comentario",
263
263
  commentPlaceholder: (_l = labels == null ? void 0 : labels.commentPlaceholder) != null ? _l : "Cu\xE9ntanos qu\xE9 funcion\xF3 bien y qu\xE9 se puede mejorar\u2026",
264
264
  tags: (_m = labels == null ? void 0 : labels.tags) != null ? _m : "Tags",
265
- tagsHint: (_n = labels == null ? void 0 : labels.tagsHint) != null ? _n : "Separa por comas (opcional).",
265
+ tagsHint: (_n = labels == null ? void 0 : labels.tagsHint) != null ? _n : "Separa por comas.",
266
266
  tagsPlaceholder: (_o = labels == null ? void 0 : labels.tagsPlaceholder) != null ? _o : "ux, rendimiento, dise\xF1o",
267
267
  authorName: (_p = labels == null ? void 0 : labels.authorName) != null ? _p : "Nombre",
268
- authorNamePlaceholder: (_q = labels == null ? void 0 : labels.authorNamePlaceholder) != null ? _q : "Tu nombre (opcional)",
268
+ authorNamePlaceholder: (_q = labels == null ? void 0 : labels.authorNamePlaceholder) != null ? _q : "Tu nombre",
269
269
  submit: (_r = labels == null ? void 0 : labels.submit) != null ? _r : "Publicar",
270
270
  clear: (_s = labels == null ? void 0 : labels.clear) != null ? _s : "Limpiar",
271
271
  emptyTitle: (_t = labels == null ? void 0 : labels.emptyTitle) != null ? _t : "Sin rese\xF1as a\xFAn",
package/dist/Reviews.mjs CHANGED
@@ -229,10 +229,10 @@ function Reviews({
229
229
  comment: (_k = labels == null ? void 0 : labels.comment) != null ? _k : "Comentario",
230
230
  commentPlaceholder: (_l = labels == null ? void 0 : labels.commentPlaceholder) != null ? _l : "Cu\xE9ntanos qu\xE9 funcion\xF3 bien y qu\xE9 se puede mejorar\u2026",
231
231
  tags: (_m = labels == null ? void 0 : labels.tags) != null ? _m : "Tags",
232
- tagsHint: (_n = labels == null ? void 0 : labels.tagsHint) != null ? _n : "Separa por comas (opcional).",
232
+ tagsHint: (_n = labels == null ? void 0 : labels.tagsHint) != null ? _n : "Separa por comas.",
233
233
  tagsPlaceholder: (_o = labels == null ? void 0 : labels.tagsPlaceholder) != null ? _o : "ux, rendimiento, dise\xF1o",
234
234
  authorName: (_p = labels == null ? void 0 : labels.authorName) != null ? _p : "Nombre",
235
- authorNamePlaceholder: (_q = labels == null ? void 0 : labels.authorNamePlaceholder) != null ? _q : "Tu nombre (opcional)",
235
+ authorNamePlaceholder: (_q = labels == null ? void 0 : labels.authorNamePlaceholder) != null ? _q : "Tu nombre",
236
236
  submit: (_r = labels == null ? void 0 : labels.submit) != null ? _r : "Publicar",
237
237
  clear: (_s = labels == null ? void 0 : labels.clear) != null ? _s : "Limpiar",
238
238
  emptyTitle: (_t = labels == null ? void 0 : labels.emptyTitle) != null ? _t : "Sin rese\xF1as a\xFAn",
@@ -387,7 +387,7 @@ function ShareAccess({
387
387
  ] }) }),
388
388
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-4 grid grid-cols-1 gap-3", children: [
389
389
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
390
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mb-1.5 text-sm font-medium", children: "Nombre (opcional)" }),
390
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mb-1.5 text-sm font-medium", children: "Nombre" }),
391
391
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
392
392
  import_Input.default,
393
393
  {
@@ -423,7 +423,7 @@ function ShareAccess({
423
423
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-2 rounded-2xl border border-[var(--border)] bg-[color-mix(in_oklab,var(--surface)_55%,transparent)] p-3 sm:flex-row sm:items-center sm:justify-between", children: [
424
424
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-w-0", children: [
425
425
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-sm font-medium", children: "Usos m\xE1x." }),
426
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mt-1 text-xs text-[var(--muted)]", children: "Opcional. Vac\xEDo = ilimitado." })
426
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mt-1 text-xs text-[var(--muted)]", children: "Vac\xEDo = ilimitado." })
427
427
  ] }),
428
428
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between gap-2 sm:justify-end", children: [
429
429
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Badge.default, { tone: "slate", size: "sm", children: maxUses.trim() ? `${maxUses.trim()} uso(s)` : "Ilimitado" }),
@@ -354,7 +354,7 @@ function ShareAccess({
354
354
  ] }) }),
355
355
  /* @__PURE__ */ jsxs("div", { className: "mt-4 grid grid-cols-1 gap-3", children: [
356
356
  /* @__PURE__ */ jsxs("div", { children: [
357
- /* @__PURE__ */ jsx("div", { className: "mb-1.5 text-sm font-medium", children: "Nombre (opcional)" }),
357
+ /* @__PURE__ */ jsx("div", { className: "mb-1.5 text-sm font-medium", children: "Nombre" }),
358
358
  /* @__PURE__ */ jsx(
359
359
  Input,
360
360
  {
@@ -390,7 +390,7 @@ function ShareAccess({
390
390
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 rounded-2xl border border-[var(--border)] bg-[color-mix(in_oklab,var(--surface)_55%,transparent)] p-3 sm:flex-row sm:items-center sm:justify-between", children: [
391
391
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
392
392
  /* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: "Usos m\xE1x." }),
393
- /* @__PURE__ */ jsx("div", { className: "mt-1 text-xs text-[var(--muted)]", children: "Opcional. Vac\xEDo = ilimitado." })
393
+ /* @__PURE__ */ jsx("div", { className: "mt-1 text-xs text-[var(--muted)]", children: "Vac\xEDo = ilimitado." })
394
394
  ] }),
395
395
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 sm:justify-end", children: [
396
396
  /* @__PURE__ */ jsx(Badge, { tone: "slate", size: "sm", children: maxUses.trim() ? `${maxUses.trim()} uso(s)` : "Ilimitado" }),
package/dist/Sidebar.js CHANGED
@@ -577,7 +577,8 @@ function Sidebar({
577
577
  }
578
578
  };
579
579
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
580
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "sticky top-0 z-40 flex h-14 items-center gap-2 border-b border-[var(--border)] bg-[var(--bg)] px-3 shadow-sm xl:hidden", children: [
580
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { "aria-hidden": "true", className: "h-14 xl:hidden" }),
581
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "fixed inset-x-0 top-0 z-40 flex h-14 items-center gap-2 border-b border-[var(--border)] bg-[var(--bg)] px-3 shadow-sm xl:hidden", children: [
581
582
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
582
583
  import_Button.default,
583
584
  {
@@ -2145,10 +2146,10 @@ function SidebarInner({
2145
2146
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_framer_motion.AnimatePresence, { initial: false, children: !collapsed && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2146
2147
  import_framer_motion.motion.div,
2147
2148
  {
2148
- initial: { opacity: 0, x: -6 },
2149
- animate: { opacity: 1, x: 0 },
2150
- exit: { opacity: 0, x: -6 },
2151
- transition: { duration: 0.16, ease: "easeOut" },
2149
+ initial: { opacity: 0, x: -10, filter: "blur(6px)" },
2150
+ animate: { opacity: 1, x: 0, filter: "blur(0px)" },
2151
+ exit: { opacity: 0, x: -14, filter: "blur(8px)" },
2152
+ transition: { duration: 0.22, ease: [0.22, 1, 0.36, 1] },
2152
2153
  className: "leading-tight",
2153
2154
  children: [
2154
2155
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-lg font-semibold tracking-tight text-left", children: brandTitle }),
package/dist/Sidebar.mjs CHANGED
@@ -556,7 +556,8 @@ function Sidebar({
556
556
  }
557
557
  };
558
558
  return /* @__PURE__ */ jsxs(Fragment, { children: [
559
- /* @__PURE__ */ jsxs("div", { className: "sticky top-0 z-40 flex h-14 items-center gap-2 border-b border-[var(--border)] bg-[var(--bg)] px-3 shadow-sm xl:hidden", children: [
559
+ /* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: "h-14 xl:hidden" }),
560
+ /* @__PURE__ */ jsxs("div", { className: "fixed inset-x-0 top-0 z-40 flex h-14 items-center gap-2 border-b border-[var(--border)] bg-[var(--bg)] px-3 shadow-sm xl:hidden", children: [
560
561
  /* @__PURE__ */ jsx(
561
562
  Button,
562
563
  {
@@ -2124,10 +2125,10 @@ function SidebarInner({
2124
2125
  /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: !collapsed && /* @__PURE__ */ jsxs(
2125
2126
  motion.div,
2126
2127
  {
2127
- initial: { opacity: 0, x: -6 },
2128
- animate: { opacity: 1, x: 0 },
2129
- exit: { opacity: 0, x: -6 },
2130
- transition: { duration: 0.16, ease: "easeOut" },
2128
+ initial: { opacity: 0, x: -10, filter: "blur(6px)" },
2129
+ animate: { opacity: 1, x: 0, filter: "blur(0px)" },
2130
+ exit: { opacity: 0, x: -14, filter: "blur(8px)" },
2131
+ transition: { duration: 0.22, ease: [0.22, 1, 0.36, 1] },
2131
2132
  className: "leading-tight",
2132
2133
  children: [
2133
2134
  /* @__PURE__ */ jsx("div", { className: "text-lg font-semibold tracking-tight text-left", children: brandTitle }),
package/dist/Steps.js CHANGED
@@ -60,7 +60,7 @@ function Steps({
60
60
  children: [
61
61
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: cx("grid grid-cols-1 sm:grid-cols-4", compact ? "gap-2" : "gap-3"), children: steps.map((s, i) => {
62
62
  const state = i < current ? "done" : i === current ? "current" : "upcoming";
63
- const canClick = clickable && i <= current && !s.disabled && onChange;
63
+ const canClick = clickable && !s.disabled && onChange;
64
64
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { className: "min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
65
65
  import_Button.default,
66
66
  {
package/dist/Steps.mjs CHANGED
@@ -26,7 +26,7 @@ function Steps({
26
26
  children: [
27
27
  /* @__PURE__ */ jsx("ol", { className: cx("grid grid-cols-1 sm:grid-cols-4", compact ? "gap-2" : "gap-3"), children: steps.map((s, i) => {
28
28
  const state = i < current ? "done" : i === current ? "current" : "upcoming";
29
- const canClick = clickable && i <= current && !s.disabled && onChange;
29
+ const canClick = clickable && !s.disabled && onChange;
30
30
  return /* @__PURE__ */ jsx("li", { className: "min-w-0", children: /* @__PURE__ */ jsxs(
31
31
  Button,
32
32
  {
package/dist/Table.js CHANGED
@@ -50,19 +50,19 @@ function cx(...a) {
50
50
  return a.filter(Boolean).join(" ");
51
51
  }
52
52
  const Table = import_react.default.forwardRef(function Table2({ className, dense = false, children, ...rest }, ref) {
53
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
53
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-full overflow-x-auto overscroll-x-contain", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
54
54
  "table",
55
55
  {
56
56
  ref,
57
57
  className: cx(
58
- "min-w-full table-auto text-left text-[0.8125rem] sm:text-sm w-full",
58
+ "w-full min-w-full table-auto text-left text-[0.8125rem] sm:text-sm",
59
59
  dense && "text-xs",
60
60
  className
61
61
  ),
62
62
  ...rest,
63
63
  children
64
64
  }
65
- );
65
+ ) });
66
66
  });
67
67
  function Th({
68
68
  children,
package/dist/Table.mjs CHANGED
@@ -13,19 +13,19 @@ function cx(...a) {
13
13
  return a.filter(Boolean).join(" ");
14
14
  }
15
15
  const Table = React.forwardRef(function Table2({ className, dense = false, children, ...rest }, ref) {
16
- return /* @__PURE__ */ jsx(
16
+ return /* @__PURE__ */ jsx("div", { className: "w-full overflow-x-auto overscroll-x-contain", children: /* @__PURE__ */ jsx(
17
17
  "table",
18
18
  {
19
19
  ref,
20
20
  className: cx(
21
- "min-w-full table-auto text-left text-[0.8125rem] sm:text-sm w-full",
21
+ "w-full min-w-full table-auto text-left text-[0.8125rem] sm:text-sm",
22
22
  dense && "text-xs",
23
23
  className
24
24
  ),
25
25
  ...rest,
26
26
  children
27
27
  }
28
- );
28
+ ) });
29
29
  });
30
30
  function Th({
31
31
  children,
@@ -38,6 +38,7 @@ var import_react_dom = require("react-dom");
38
38
  var import_Input = __toESM(require("./Input"));
39
39
  var import_Button = __toESM(require("./Button"));
40
40
  var import_TimePopover = __toESM(require("./TimePopover"));
41
+ var import_ActionIconButton = __toESM(require("./ActionIconButton"));
41
42
  var import_iconos = require("./iconos");
42
43
  const pad2 = (n) => n < 10 ? `0${n}` : String(n);
43
44
  function parseHHmm(v) {
@@ -98,6 +99,8 @@ function TimeRangeField({ value, onValueChange, portal = true, portalId, clearab
98
99
  if (!anchorRef.current) return;
99
100
  setAnchorRect(anchorRef.current.getBoundingClientRect());
100
101
  setOpen(true);
102
+ setShowFromPop(false);
103
+ setShowToPop(false);
101
104
  };
102
105
  (0, import_react.useEffect)(() => {
103
106
  if (!open) return;
@@ -129,7 +132,9 @@ function TimeRangeField({ value, onValueChange, portal = true, portalId, clearab
129
132
  }, [open]);
130
133
  const stylePop = (() => {
131
134
  if (!anchorRect) return { visibility: "hidden" };
132
- const W = 360, GAP = 2, MARGIN = 8;
135
+ const MARGIN = 8;
136
+ const W = Math.min(420, Math.max(280, window.innerWidth - MARGIN * 2));
137
+ const GAP = 4;
133
138
  let left = anchorRect.right - W;
134
139
  left = Math.max(MARGIN, Math.min(left, window.innerWidth - (W + MARGIN)));
135
140
  const spaceAbove = anchorRect.top - MARGIN;
@@ -137,10 +142,10 @@ function TimeRangeField({ value, onValueChange, portal = true, portalId, clearab
137
142
  const placeAbove = spaceAbove >= spaceBelow;
138
143
  if (placeAbove) {
139
144
  const top2 = Math.max(MARGIN, anchorRect.top - GAP);
140
- return { position: "fixed", top: top2, left, zIndex: 1e5, transform: "translateY(-100%)" };
145
+ return { position: "fixed", width: W, top: top2, left, zIndex: 1e5, transform: "translateY(-100%)" };
141
146
  }
142
147
  const top = Math.max(MARGIN, anchorRect.bottom + GAP);
143
- return { position: "fixed", top, left, zIndex: 1e5 };
148
+ return { position: "fixed", width: W, top, left, zIndex: 1e5 };
144
149
  })();
145
150
  const commit = (f, t) => {
146
151
  let f2 = f, t2 = t;
@@ -153,80 +158,122 @@ function TimeRangeField({ value, onValueChange, portal = true, portalId, clearab
153
158
  setTo(t2);
154
159
  onValueChange == null ? void 0 : onValueChange({ from: f2 ? fmtHHmm(f2.hh, f2.mm) : null, to: t2 ? fmtHHmm(t2.hh, t2.mm) : null });
155
160
  };
156
- 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-[var(--fx-surface)]", children: [
157
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between gap-2 px-3 py-2 text-sm", children: [
158
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "font-medium", children: "Selecciona horario" }),
159
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
160
- import_Button.default,
161
- {
162
- unstyled: true,
163
- type: "button",
164
- className: "rounded-xl bg-[var(--primary)] px-3 py-1.5 text-[var(--primary-foreground)] hover:brightness-95 active:scale-[0.98]",
165
- onClick: () => setOpen(false),
166
- children: "Aplicar"
167
- }
168
- )
169
- ] }),
170
- /* @__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: [
171
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
172
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mb-1 text-xs text-slate-500 dark:text-slate-300", children: "Desde" }),
173
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
174
- import_Button.default,
175
- {
176
- unstyled: true,
177
- type: "button",
178
- 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",
179
- onClick: () => setShowFromPop((v) => !v),
180
- ref: fromBtnRef,
181
- children: from ? toAMPM(from.hh, from.mm) : "--:--"
182
- }
183
- ),
184
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
185
- import_Button.default,
186
- {
187
- unstyled: true,
188
- type: "button",
189
- 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",
190
- onClick: () => {
191
- const t = /* @__PURE__ */ new Date();
192
- const rounded = Math.round(t.getMinutes() / step) * step % 60;
193
- commit({ hh: t.getHours(), mm: rounded }, to);
194
- },
195
- children: "Ahora"
196
- }
197
- )
198
- ] }),
199
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
200
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mb-1 text-xs text-slate-500 dark:text-slate-300", children: "Hasta" }),
201
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
202
- import_Button.default,
203
- {
204
- unstyled: true,
205
- type: "button",
206
- 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",
207
- onClick: () => setShowToPop((v) => !v),
208
- ref: toBtnRef,
209
- children: to ? toAMPM(to.hh, to.mm) : "--:--"
210
- }
211
- ),
212
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
213
- import_Button.default,
214
- {
215
- unstyled: true,
216
- type: "button",
217
- 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",
218
- onClick: () => {
219
- const t = /* @__PURE__ */ new Date();
220
- const rounded = Math.round(t.getMinutes() / step) * step % 60;
221
- const candidate = { hh: t.getHours(), mm: rounded };
222
- commit(from, candidate);
223
- },
224
- children: "Ahora"
225
- }
226
- )
227
- ] })
228
- ] })
229
- ] });
161
+ const canClear = clearable && (from || to) && !disabled;
162
+ const popover = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
163
+ "div",
164
+ {
165
+ "data-trf-pop": true,
166
+ style: stylePop,
167
+ className: "overflow-hidden rounded-2xl border border-[var(--border)] bg-[var(--card)] shadow-xl ring-1 ring-black/5",
168
+ role: "dialog",
169
+ "aria-label": "Selector de rango de horas",
170
+ children: [
171
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between gap-2 px-3 py-2", children: [
172
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-w-0", children: [
173
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "truncate text-sm font-semibold text-[var(--foreground)]", children: "Horario" }),
174
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mt-0.5 truncate text-xs text-[var(--muted)]", children: display ? display : "Selecciona desde y hasta" })
175
+ ] }),
176
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2", children: [
177
+ canClear ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
178
+ import_Button.default,
179
+ {
180
+ variant: "outline",
181
+ size: "sm",
182
+ onClick: () => {
183
+ commit(null, null);
184
+ setShowFromPop(false);
185
+ setShowToPop(false);
186
+ },
187
+ children: "Limpiar"
188
+ }
189
+ ) : null,
190
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
191
+ import_Button.default,
192
+ {
193
+ variant: "primary",
194
+ size: "sm",
195
+ onClick: () => {
196
+ setOpen(false);
197
+ setShowFromPop(false);
198
+ setShowToPop(false);
199
+ },
200
+ children: "Listo"
201
+ }
202
+ )
203
+ ] })
204
+ ] }),
205
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-1 gap-3 border-t border-[var(--border)] p-3 sm:grid-cols-2", children: [
206
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "rounded-2xl border border-[var(--border)] bg-[color-mix(in_oklab,var(--surface)_72%,transparent)] p-3", children: [
207
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mb-2 text-xs font-semibold text-[var(--muted)]", children: "Desde" }),
208
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2", children: [
209
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
210
+ import_Button.default,
211
+ {
212
+ variant: "outline",
213
+ size: "sm",
214
+ active: showFromPop,
215
+ className: "flex-1 justify-start font-semibold tabular-nums",
216
+ onClick: () => {
217
+ setShowFromPop((v) => !v);
218
+ setShowToPop(false);
219
+ },
220
+ ref: fromBtnRef,
221
+ children: from ? toAMPM(from.hh, from.mm) : "--:--"
222
+ }
223
+ ),
224
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
225
+ import_Button.default,
226
+ {
227
+ variant: "secondary",
228
+ size: "sm",
229
+ onClick: () => {
230
+ const t = /* @__PURE__ */ new Date();
231
+ const rounded = Math.round(t.getMinutes() / step) * step % 60;
232
+ commit({ hh: t.getHours(), mm: rounded }, to);
233
+ },
234
+ children: "Ahora"
235
+ }
236
+ )
237
+ ] })
238
+ ] }),
239
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "rounded-2xl border border-[var(--border)] bg-[color-mix(in_oklab,var(--surface)_72%,transparent)] p-3", children: [
240
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mb-2 text-xs font-semibold text-[var(--muted)]", children: "Hasta" }),
241
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2", children: [
242
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
243
+ import_Button.default,
244
+ {
245
+ variant: "outline",
246
+ size: "sm",
247
+ active: showToPop,
248
+ className: "flex-1 justify-start font-semibold tabular-nums",
249
+ onClick: () => {
250
+ setShowToPop((v) => !v);
251
+ setShowFromPop(false);
252
+ },
253
+ ref: toBtnRef,
254
+ children: to ? toAMPM(to.hh, to.mm) : "--:--"
255
+ }
256
+ ),
257
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
258
+ import_Button.default,
259
+ {
260
+ variant: "secondary",
261
+ size: "sm",
262
+ onClick: () => {
263
+ const t = /* @__PURE__ */ new Date();
264
+ const rounded = Math.round(t.getMinutes() / step) * step % 60;
265
+ const candidate = { hh: t.getHours(), mm: rounded };
266
+ commit(from, candidate);
267
+ },
268
+ children: "Ahora"
269
+ }
270
+ )
271
+ ] })
272
+ ] })
273
+ ] })
274
+ ]
275
+ }
276
+ );
230
277
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ref: anchorRef, className, children: [
231
278
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
232
279
  import_Input.default,
@@ -241,17 +288,18 @@ function TimeRangeField({ value, onValueChange, portal = true, portalId, clearab
241
288
  onValueChange == null ? void 0 : onValueChange({ from: null, to: null });
242
289
  },
243
290
  disabled,
244
- rightSlot: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
245
- import_Button.default,
291
+ rightAction: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
292
+ import_ActionIconButton.default,
246
293
  {
247
- unstyled: true,
248
- type: "button",
249
- 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-[var(--fx-surface)]",
294
+ size: "sm",
295
+ title: "Abrir selector de horas",
296
+ disabled,
250
297
  onClick: (e) => {
251
298
  e.preventDefault();
299
+ e.stopPropagation();
252
300
  openPopover();
253
301
  },
254
- title: "Abrir selector de horas",
302
+ className: "h-8 w-8 rounded-xl",
255
303
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_iconos.ClockIcon, { "aria-hidden": true, className: "h-4.5 w-4.5" })
256
304
  }
257
305
  )
@@ -5,6 +5,7 @@ import { createPortal } from "react-dom";
5
5
  import Input from "./Input.mjs";
6
6
  import Button from "./Button.mjs";
7
7
  import TimePopover from "./TimePopover.mjs";
8
+ import ActionIconButton from "./ActionIconButton.mjs";
8
9
  import { ClockIcon } from "./iconos/index.mjs";
9
10
  const pad2 = (n) => n < 10 ? `0${n}` : String(n);
10
11
  function parseHHmm(v) {
@@ -65,6 +66,8 @@ function TimeRangeField({ value, onValueChange, portal = true, portalId, clearab
65
66
  if (!anchorRef.current) return;
66
67
  setAnchorRect(anchorRef.current.getBoundingClientRect());
67
68
  setOpen(true);
69
+ setShowFromPop(false);
70
+ setShowToPop(false);
68
71
  };
69
72
  useEffect(() => {
70
73
  if (!open) return;
@@ -96,7 +99,9 @@ function TimeRangeField({ value, onValueChange, portal = true, portalId, clearab
96
99
  }, [open]);
97
100
  const stylePop = (() => {
98
101
  if (!anchorRect) return { visibility: "hidden" };
99
- const W = 360, GAP = 2, MARGIN = 8;
102
+ const MARGIN = 8;
103
+ const W = Math.min(420, Math.max(280, window.innerWidth - MARGIN * 2));
104
+ const GAP = 4;
100
105
  let left = anchorRect.right - W;
101
106
  left = Math.max(MARGIN, Math.min(left, window.innerWidth - (W + MARGIN)));
102
107
  const spaceAbove = anchorRect.top - MARGIN;
@@ -104,10 +109,10 @@ function TimeRangeField({ value, onValueChange, portal = true, portalId, clearab
104
109
  const placeAbove = spaceAbove >= spaceBelow;
105
110
  if (placeAbove) {
106
111
  const top2 = Math.max(MARGIN, anchorRect.top - GAP);
107
- return { position: "fixed", top: top2, left, zIndex: 1e5, transform: "translateY(-100%)" };
112
+ return { position: "fixed", width: W, top: top2, left, zIndex: 1e5, transform: "translateY(-100%)" };
108
113
  }
109
114
  const top = Math.max(MARGIN, anchorRect.bottom + GAP);
110
- return { position: "fixed", top, left, zIndex: 1e5 };
115
+ return { position: "fixed", width: W, top, left, zIndex: 1e5 };
111
116
  })();
112
117
  const commit = (f, t) => {
113
118
  let f2 = f, t2 = t;
@@ -120,80 +125,122 @@ function TimeRangeField({ value, onValueChange, portal = true, portalId, clearab
120
125
  setTo(t2);
121
126
  onValueChange == null ? void 0 : onValueChange({ from: f2 ? fmtHHmm(f2.hh, f2.mm) : null, to: t2 ? fmtHHmm(t2.hh, t2.mm) : null });
122
127
  };
123
- 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-[var(--fx-surface)]", children: [
124
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 px-3 py-2 text-sm", children: [
125
- /* @__PURE__ */ jsx("div", { className: "font-medium", children: "Selecciona horario" }),
126
- /* @__PURE__ */ jsx(
127
- Button,
128
- {
129
- unstyled: true,
130
- type: "button",
131
- className: "rounded-xl bg-[var(--primary)] px-3 py-1.5 text-[var(--primary-foreground)] hover:brightness-95 active:scale-[0.98]",
132
- onClick: () => setOpen(false),
133
- children: "Aplicar"
134
- }
135
- )
136
- ] }),
137
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3 border-t border-slate-100 p-3 text-sm dark:border-white/10", children: [
138
- /* @__PURE__ */ jsxs("div", { children: [
139
- /* @__PURE__ */ jsx("div", { className: "mb-1 text-xs text-slate-500 dark:text-slate-300", children: "Desde" }),
140
- /* @__PURE__ */ jsx(
141
- Button,
142
- {
143
- unstyled: true,
144
- type: "button",
145
- 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",
146
- onClick: () => setShowFromPop((v) => !v),
147
- ref: fromBtnRef,
148
- children: from ? toAMPM(from.hh, from.mm) : "--:--"
149
- }
150
- ),
151
- /* @__PURE__ */ jsx(
152
- Button,
153
- {
154
- unstyled: true,
155
- type: "button",
156
- 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",
157
- onClick: () => {
158
- const t = /* @__PURE__ */ new Date();
159
- const rounded = Math.round(t.getMinutes() / step) * step % 60;
160
- commit({ hh: t.getHours(), mm: rounded }, to);
161
- },
162
- children: "Ahora"
163
- }
164
- )
165
- ] }),
166
- /* @__PURE__ */ jsxs("div", { children: [
167
- /* @__PURE__ */ jsx("div", { className: "mb-1 text-xs text-slate-500 dark:text-slate-300", children: "Hasta" }),
168
- /* @__PURE__ */ jsx(
169
- Button,
170
- {
171
- unstyled: true,
172
- type: "button",
173
- 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",
174
- onClick: () => setShowToPop((v) => !v),
175
- ref: toBtnRef,
176
- children: to ? toAMPM(to.hh, to.mm) : "--:--"
177
- }
178
- ),
179
- /* @__PURE__ */ jsx(
180
- Button,
181
- {
182
- unstyled: true,
183
- type: "button",
184
- 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",
185
- onClick: () => {
186
- const t = /* @__PURE__ */ new Date();
187
- const rounded = Math.round(t.getMinutes() / step) * step % 60;
188
- const candidate = { hh: t.getHours(), mm: rounded };
189
- commit(from, candidate);
190
- },
191
- children: "Ahora"
192
- }
193
- )
194
- ] })
195
- ] })
196
- ] });
128
+ const canClear = clearable && (from || to) && !disabled;
129
+ const popover = /* @__PURE__ */ jsxs(
130
+ "div",
131
+ {
132
+ "data-trf-pop": true,
133
+ style: stylePop,
134
+ className: "overflow-hidden rounded-2xl border border-[var(--border)] bg-[var(--card)] shadow-xl ring-1 ring-black/5",
135
+ role: "dialog",
136
+ "aria-label": "Selector de rango de horas",
137
+ children: [
138
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 px-3 py-2", children: [
139
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
140
+ /* @__PURE__ */ jsx("div", { className: "truncate text-sm font-semibold text-[var(--foreground)]", children: "Horario" }),
141
+ /* @__PURE__ */ jsx("div", { className: "mt-0.5 truncate text-xs text-[var(--muted)]", children: display ? display : "Selecciona desde y hasta" })
142
+ ] }),
143
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
144
+ canClear ? /* @__PURE__ */ jsx(
145
+ Button,
146
+ {
147
+ variant: "outline",
148
+ size: "sm",
149
+ onClick: () => {
150
+ commit(null, null);
151
+ setShowFromPop(false);
152
+ setShowToPop(false);
153
+ },
154
+ children: "Limpiar"
155
+ }
156
+ ) : null,
157
+ /* @__PURE__ */ jsx(
158
+ Button,
159
+ {
160
+ variant: "primary",
161
+ size: "sm",
162
+ onClick: () => {
163
+ setOpen(false);
164
+ setShowFromPop(false);
165
+ setShowToPop(false);
166
+ },
167
+ children: "Listo"
168
+ }
169
+ )
170
+ ] })
171
+ ] }),
172
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-3 border-t border-[var(--border)] p-3 sm:grid-cols-2", children: [
173
+ /* @__PURE__ */ jsxs("div", { className: "rounded-2xl border border-[var(--border)] bg-[color-mix(in_oklab,var(--surface)_72%,transparent)] p-3", children: [
174
+ /* @__PURE__ */ jsx("div", { className: "mb-2 text-xs font-semibold text-[var(--muted)]", children: "Desde" }),
175
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
176
+ /* @__PURE__ */ jsx(
177
+ Button,
178
+ {
179
+ variant: "outline",
180
+ size: "sm",
181
+ active: showFromPop,
182
+ className: "flex-1 justify-start font-semibold tabular-nums",
183
+ onClick: () => {
184
+ setShowFromPop((v) => !v);
185
+ setShowToPop(false);
186
+ },
187
+ ref: fromBtnRef,
188
+ children: from ? toAMPM(from.hh, from.mm) : "--:--"
189
+ }
190
+ ),
191
+ /* @__PURE__ */ jsx(
192
+ Button,
193
+ {
194
+ variant: "secondary",
195
+ size: "sm",
196
+ onClick: () => {
197
+ const t = /* @__PURE__ */ new Date();
198
+ const rounded = Math.round(t.getMinutes() / step) * step % 60;
199
+ commit({ hh: t.getHours(), mm: rounded }, to);
200
+ },
201
+ children: "Ahora"
202
+ }
203
+ )
204
+ ] })
205
+ ] }),
206
+ /* @__PURE__ */ jsxs("div", { className: "rounded-2xl border border-[var(--border)] bg-[color-mix(in_oklab,var(--surface)_72%,transparent)] p-3", children: [
207
+ /* @__PURE__ */ jsx("div", { className: "mb-2 text-xs font-semibold text-[var(--muted)]", children: "Hasta" }),
208
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
209
+ /* @__PURE__ */ jsx(
210
+ Button,
211
+ {
212
+ variant: "outline",
213
+ size: "sm",
214
+ active: showToPop,
215
+ className: "flex-1 justify-start font-semibold tabular-nums",
216
+ onClick: () => {
217
+ setShowToPop((v) => !v);
218
+ setShowFromPop(false);
219
+ },
220
+ ref: toBtnRef,
221
+ children: to ? toAMPM(to.hh, to.mm) : "--:--"
222
+ }
223
+ ),
224
+ /* @__PURE__ */ jsx(
225
+ Button,
226
+ {
227
+ variant: "secondary",
228
+ size: "sm",
229
+ onClick: () => {
230
+ const t = /* @__PURE__ */ new Date();
231
+ const rounded = Math.round(t.getMinutes() / step) * step % 60;
232
+ const candidate = { hh: t.getHours(), mm: rounded };
233
+ commit(from, candidate);
234
+ },
235
+ children: "Ahora"
236
+ }
237
+ )
238
+ ] })
239
+ ] })
240
+ ] })
241
+ ]
242
+ }
243
+ );
197
244
  return /* @__PURE__ */ jsxs("div", { ref: anchorRef, className, children: [
198
245
  /* @__PURE__ */ jsx(
199
246
  Input,
@@ -208,17 +255,18 @@ function TimeRangeField({ value, onValueChange, portal = true, portalId, clearab
208
255
  onValueChange == null ? void 0 : onValueChange({ from: null, to: null });
209
256
  },
210
257
  disabled,
211
- rightSlot: /* @__PURE__ */ jsx(
212
- Button,
258
+ rightAction: /* @__PURE__ */ jsx(
259
+ ActionIconButton,
213
260
  {
214
- unstyled: true,
215
- type: "button",
216
- 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-[var(--fx-surface)]",
261
+ size: "sm",
262
+ title: "Abrir selector de horas",
263
+ disabled,
217
264
  onClick: (e) => {
218
265
  e.preventDefault();
266
+ e.stopPropagation();
219
267
  openPopover();
220
268
  },
221
- title: "Abrir selector de horas",
269
+ className: "h-8 w-8 rounded-xl",
222
270
  children: /* @__PURE__ */ jsx(ClockIcon, { "aria-hidden": true, className: "h-4.5 w-4.5" })
223
271
  }
224
272
  )
@@ -823,7 +823,7 @@ function WordEditor({ value, onChange, disabled = false, className, labels }) {
823
823
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_Dialog.default, { open: imageOpen, onClose: () => setImageOpen(false), size: "md", initialFocusRef: imageUrlRef, children: [
824
824
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Dialog.default.Header, { title: "Insertar imagen", description: "Sube una imagen o pega una URL (https:// o data:image/...).", onClose: () => setImageOpen(false), showClose: true }),
825
825
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Dialog.default.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid gap-3", children: [
826
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Dialog.default.Field, { label: "URL (opcional)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
826
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Dialog.default.Field, { label: "URL", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
827
827
  import_Input.default,
828
828
  {
829
829
  ref: imageUrlRef,
@@ -813,7 +813,7 @@ function WordEditor({ value, onChange, disabled = false, className, labels }) {
813
813
  /* @__PURE__ */ jsxs(Dialog, { open: imageOpen, onClose: () => setImageOpen(false), size: "md", initialFocusRef: imageUrlRef, children: [
814
814
  /* @__PURE__ */ jsx(Dialog.Header, { title: "Insertar imagen", description: "Sube una imagen o pega una URL (https:// o data:image/...).", onClose: () => setImageOpen(false), showClose: true }),
815
815
  /* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
816
- /* @__PURE__ */ jsx(Dialog.Field, { label: "URL (opcional)", children: /* @__PURE__ */ jsx(
816
+ /* @__PURE__ */ jsx(Dialog.Field, { label: "URL", children: /* @__PURE__ */ jsx(
817
817
  Input,
818
818
  {
819
819
  ref: imageUrlRef,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "framepexls-ui-lib",
3
- "version": "1.14.0",
3
+ "version": "1.16.0",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "description": "Componentes UI de Framepexls para React/Next.",