framepexls-ui-lib 0.1.4

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.
Files changed (125) hide show
  1. package/dist/ActionIconButton.d.mts +11 -0
  2. package/dist/ActionIconButton.d.ts +11 -0
  3. package/dist/ActionIconButton.js +71 -0
  4. package/dist/ActionIconButton.mjs +41 -0
  5. package/dist/AppTopbar.d.mts +17 -0
  6. package/dist/AppTopbar.d.ts +17 -0
  7. package/dist/AppTopbar.js +51 -0
  8. package/dist/AppTopbar.mjs +31 -0
  9. package/dist/AvatarSquare.d.mts +16 -0
  10. package/dist/AvatarSquare.d.ts +16 -0
  11. package/dist/AvatarSquare.js +82 -0
  12. package/dist/AvatarSquare.mjs +52 -0
  13. package/dist/Badge.d.mts +13 -0
  14. package/dist/Badge.d.ts +13 -0
  15. package/dist/Badge.js +65 -0
  16. package/dist/Badge.mjs +45 -0
  17. package/dist/BadgeCluster.d.mts +17 -0
  18. package/dist/BadgeCluster.d.ts +17 -0
  19. package/dist/BadgeCluster.js +125 -0
  20. package/dist/BadgeCluster.mjs +95 -0
  21. package/dist/Breadcrumb.d.mts +11 -0
  22. package/dist/Breadcrumb.d.ts +11 -0
  23. package/dist/Breadcrumb.js +42 -0
  24. package/dist/Breadcrumb.mjs +12 -0
  25. package/dist/Button.d.mts +15 -0
  26. package/dist/Button.d.ts +15 -0
  27. package/dist/Button.js +72 -0
  28. package/dist/Button.mjs +52 -0
  29. package/dist/CalendarPanel.d.mts +13 -0
  30. package/dist/CalendarPanel.d.ts +13 -0
  31. package/dist/CalendarPanel.js +110 -0
  32. package/dist/CalendarPanel.mjs +90 -0
  33. package/dist/ChartCard.d.mts +15 -0
  34. package/dist/ChartCard.d.ts +15 -0
  35. package/dist/ChartCard.js +44 -0
  36. package/dist/ChartCard.mjs +24 -0
  37. package/dist/CheckboxPillsGroup.d.mts +28 -0
  38. package/dist/CheckboxPillsGroup.d.ts +28 -0
  39. package/dist/CheckboxPillsGroup.js +186 -0
  40. package/dist/CheckboxPillsGroup.mjs +156 -0
  41. package/dist/ColumnSelector.d.mts +17 -0
  42. package/dist/ColumnSelector.d.ts +17 -0
  43. package/dist/ColumnSelector.js +74 -0
  44. package/dist/ColumnSelector.mjs +54 -0
  45. package/dist/ComboSelect.d.mts +46 -0
  46. package/dist/ComboSelect.d.ts +46 -0
  47. package/dist/ComboSelect.js +442 -0
  48. package/dist/ComboSelect.mjs +412 -0
  49. package/dist/DateTimeField.d.mts +22 -0
  50. package/dist/DateTimeField.d.ts +22 -0
  51. package/dist/DateTimeField.js +409 -0
  52. package/dist/DateTimeField.mjs +379 -0
  53. package/dist/Dialog.d.mts +82 -0
  54. package/dist/Dialog.d.ts +82 -0
  55. package/dist/Dialog.js +408 -0
  56. package/dist/Dialog.mjs +368 -0
  57. package/dist/Dropdown.d.mts +52 -0
  58. package/dist/Dropdown.d.ts +52 -0
  59. package/dist/Dropdown.js +333 -0
  60. package/dist/Dropdown.mjs +313 -0
  61. package/dist/EmptyState.d.mts +8 -0
  62. package/dist/EmptyState.d.ts +8 -0
  63. package/dist/EmptyState.js +35 -0
  64. package/dist/EmptyState.mjs +15 -0
  65. package/dist/InfoGrid.d.mts +20 -0
  66. package/dist/InfoGrid.d.ts +20 -0
  67. package/dist/InfoGrid.js +67 -0
  68. package/dist/InfoGrid.mjs +47 -0
  69. package/dist/Input.d.mts +20 -0
  70. package/dist/Input.d.ts +20 -0
  71. package/dist/Input.js +85 -0
  72. package/dist/Input.mjs +55 -0
  73. package/dist/Money.d.mts +8 -0
  74. package/dist/Money.d.ts +8 -0
  75. package/dist/Money.js +30 -0
  76. package/dist/Money.mjs +10 -0
  77. package/dist/OrderButton.d.mts +11 -0
  78. package/dist/OrderButton.d.ts +11 -0
  79. package/dist/OrderButton.js +39 -0
  80. package/dist/OrderButton.mjs +19 -0
  81. package/dist/Pagination.d.mts +12 -0
  82. package/dist/Pagination.d.ts +12 -0
  83. package/dist/Pagination.js +71 -0
  84. package/dist/Pagination.mjs +51 -0
  85. package/dist/SearchInput.d.mts +17 -0
  86. package/dist/SearchInput.d.ts +17 -0
  87. package/dist/SearchInput.js +116 -0
  88. package/dist/SearchInput.mjs +86 -0
  89. package/dist/Select.d.mts +31 -0
  90. package/dist/Select.d.ts +31 -0
  91. package/dist/Select.js +293 -0
  92. package/dist/Select.mjs +263 -0
  93. package/dist/StatCard.d.mts +15 -0
  94. package/dist/StatCard.d.ts +15 -0
  95. package/dist/StatCard.js +47 -0
  96. package/dist/StatCard.mjs +27 -0
  97. package/dist/Steps.d.mts +31 -0
  98. package/dist/Steps.d.ts +31 -0
  99. package/dist/Steps.js +123 -0
  100. package/dist/Steps.mjs +99 -0
  101. package/dist/Table.d.mts +31 -0
  102. package/dist/Table.d.ts +31 -0
  103. package/dist/Table.js +153 -0
  104. package/dist/Table.mjs +117 -0
  105. package/dist/TimeAgo.d.mts +12 -0
  106. package/dist/TimeAgo.d.ts +12 -0
  107. package/dist/TimeAgo.js +104 -0
  108. package/dist/TimeAgo.mjs +74 -0
  109. package/dist/TimePanel.d.mts +14 -0
  110. package/dist/TimePanel.d.ts +14 -0
  111. package/dist/TimePanel.js +145 -0
  112. package/dist/TimePanel.mjs +125 -0
  113. package/dist/TimePopover.d.mts +33 -0
  114. package/dist/TimePopover.d.ts +33 -0
  115. package/dist/TimePopover.js +441 -0
  116. package/dist/TimePopover.mjs +406 -0
  117. package/dist/iconos/index.d.mts +60 -0
  118. package/dist/iconos/index.d.ts +60 -0
  119. package/dist/iconos/index.js +621 -0
  120. package/dist/iconos/index.mjs +548 -0
  121. package/dist/index.d.mts +32 -0
  122. package/dist/index.d.ts +32 -0
  123. package/dist/index.js +141 -0
  124. package/dist/index.mjs +70 -0
  125. package/package.json +178 -0
@@ -0,0 +1,263 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import React from "react";
4
+ const S = {
5
+ sm: { h: "h-8", text: "text-[13px]", radius: "rounded-xl", padX: "px-3", itemPad: "px-3 py-1.5" },
6
+ md: { h: "h-10", text: "text-sm", radius: "rounded-2xl", padX: "px-3.5", itemPad: "px-3.5 py-2" },
7
+ lg: { h: "h-11", text: "text-base", radius: "rounded-2xl", padX: "px-4", itemPad: "px-4 py-2.5" }
8
+ };
9
+ function ModernSelect({
10
+ value,
11
+ onChange,
12
+ options,
13
+ id,
14
+ label,
15
+ hint,
16
+ placeholder = "Selecciona una opci\xF3n\u2026",
17
+ title,
18
+ className,
19
+ fullWidth = true,
20
+ disabled = false,
21
+ error = false,
22
+ size = "md",
23
+ clearable = false,
24
+ closeOnSelect = false,
25
+ minWidthClasses,
26
+ fit = true
27
+ }) {
28
+ var _a, _b;
29
+ const s = S[size];
30
+ const hasError = Boolean(error);
31
+ const autoId = React.useId();
32
+ const selectId = id != null ? id : autoId;
33
+ const hintId = hint ? `${selectId}-hint` : void 0;
34
+ const errorId = hasError ? `${selectId}-err` : void 0;
35
+ const [open, setOpen] = React.useState(false);
36
+ const [active, setActive] = React.useState(() => {
37
+ const idx = options.findIndex((o) => String(o.value) === String(value));
38
+ return Math.max(0, idx);
39
+ });
40
+ const btnRef = React.useRef(null);
41
+ const listRef = React.useRef(null);
42
+ const rootRef = React.useRef(null);
43
+ const [menuPos, setMenuPos] = React.useState({ top: 0, left: 0, width: 0 });
44
+ const updateMenuPosition = React.useCallback(() => {
45
+ const el = btnRef.current;
46
+ if (!el) return;
47
+ const r = el.getBoundingClientRect();
48
+ setMenuPos({
49
+ top: Math.round(r.bottom + window.scrollY + 6),
50
+ left: Math.round(r.left + window.scrollX),
51
+ width: Math.round(r.width)
52
+ });
53
+ }, []);
54
+ React.useEffect(() => {
55
+ const onDoc = (e) => {
56
+ if (!rootRef.current) return;
57
+ if (!rootRef.current.contains(e.target)) setOpen(false);
58
+ };
59
+ document.addEventListener("mousedown", onDoc);
60
+ return () => document.removeEventListener("mousedown", onDoc);
61
+ }, []);
62
+ React.useEffect(() => {
63
+ if (!open) return;
64
+ updateMenuPosition();
65
+ const onScroll = () => updateMenuPosition();
66
+ const onResize = () => updateMenuPosition();
67
+ window.addEventListener("scroll", onScroll, { passive: true });
68
+ window.addEventListener("resize", onResize);
69
+ return () => {
70
+ window.removeEventListener("scroll", onScroll);
71
+ window.removeEventListener("resize", onResize);
72
+ };
73
+ }, [open, updateMenuPosition]);
74
+ React.useEffect(() => {
75
+ var _a2;
76
+ if (!open) return;
77
+ const el = (_a2 = listRef.current) == null ? void 0 : _a2.querySelector(`[data-idx="${active}"]`);
78
+ el == null ? void 0 : el.focus();
79
+ }, [open, active]);
80
+ const selected = (_a = options.find((o) => String(o.value) === String(value))) != null ? _a : null;
81
+ const setSelected = (o) => {
82
+ if (o.disabled) return;
83
+ onChange(o.value);
84
+ setActive(options.findIndex((x) => String(x.value) === String(o.value)));
85
+ if (closeOnSelect) setOpen(false);
86
+ };
87
+ const clear = () => {
88
+ var _a2;
89
+ onChange("");
90
+ setActive(0);
91
+ (_a2 = btnRef.current) == null ? void 0 : _a2.focus();
92
+ };
93
+ const onKeyBtn = (e) => {
94
+ if (disabled) return;
95
+ if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
96
+ e.preventDefault();
97
+ setOpen(true);
98
+ }
99
+ };
100
+ const onKeyList = (e) => {
101
+ var _a2;
102
+ if (!open) return;
103
+ if (e.key === "Escape") {
104
+ e.preventDefault();
105
+ setOpen(false);
106
+ (_a2 = btnRef.current) == null ? void 0 : _a2.focus();
107
+ return;
108
+ }
109
+ if (e.key === "ArrowDown") {
110
+ e.preventDefault();
111
+ setActive((i) => Math.min(i + 1, options.length - 1));
112
+ } else if (e.key === "ArrowUp") {
113
+ e.preventDefault();
114
+ setActive((i) => Math.max(i - 1, 0));
115
+ } else if (e.key === "Home") {
116
+ e.preventDefault();
117
+ setActive(0);
118
+ } else if (e.key === "End") {
119
+ e.preventDefault();
120
+ setActive(options.length - 1);
121
+ } else if (e.key === "Enter") {
122
+ e.preventDefault();
123
+ const o = options[active];
124
+ if (o) setSelected(o);
125
+ }
126
+ };
127
+ const widthBtn = fit ? "w-full min-w-[12rem] md:min-w-[16rem]" : `w-full ${minWidthClasses != null ? minWidthClasses : "min-w-full sm:min-w-[12rem] lg:min-w-[16rem]"}`;
128
+ return /* @__PURE__ */ jsxs("label", { className: fullWidth ? "block w-full" : "inline-block", ref: rootRef, children: [
129
+ label && /* @__PURE__ */ jsx("div", { className: "mb-1.5 text-[13px] font-semibold", children: label }),
130
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
131
+ /* @__PURE__ */ jsx(
132
+ "button",
133
+ {
134
+ ref: btnRef,
135
+ id: selectId,
136
+ type: "button",
137
+ title: (_b = selected == null ? void 0 : selected.label) != null ? _b : title,
138
+ disabled,
139
+ "aria-haspopup": "listbox",
140
+ "aria-expanded": open,
141
+ "aria-controls": `${selectId}-listbox`,
142
+ "aria-describedby": hintId != null ? hintId : hasError ? errorId : void 0,
143
+ onClick: () => !disabled && setOpen((o) => !o),
144
+ onKeyDown: onKeyBtn,
145
+ className: [
146
+ "text-left bg-white dark:bg-[#0e0d0e] border transition shadow-sm",
147
+ s.radius,
148
+ s.h,
149
+ s.text,
150
+ s.padX,
151
+ "pr-12",
152
+ widthBtn,
153
+ hasError ? "border-blue-500 focus:ring-2 ring-blue-300" : "border-slate-200 dark:border-white/10 focus:ring-2 ring-blue-300",
154
+ disabled ? "opacity-60 cursor-not-allowed" : "cursor-pointer",
155
+ "whitespace-nowrap overflow-hidden text-ellipsis",
156
+ className != null ? className : ""
157
+ ].join(" "),
158
+ children: /* @__PURE__ */ jsx("span", { className: selected ? "text-slate-900 dark:text-slate-100" : "text-slate-400", children: selected ? selected.label : placeholder })
159
+ }
160
+ ),
161
+ /* @__PURE__ */ jsx(
162
+ "svg",
163
+ {
164
+ className: `pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 h-5 w-5 transition ${open ? "rotate-180 opacity-70" : "opacity-70"}`,
165
+ viewBox: "0 0 20 20",
166
+ fill: "currentColor",
167
+ "aria-hidden": "true",
168
+ children: /* @__PURE__ */ jsx("path", { d: "M5.23 7.21a.75.75 0 011.06.02L10 10.2l3.71-2.97a.75.75 0 111.04 1.08l-4.24 3.4a.75.75 0 01-.94 0L5.21 8.31a.75.75 0 01.02-1.1z" })
169
+ }
170
+ ),
171
+ clearable && value !== "" && !disabled && /* @__PURE__ */ jsx(
172
+ "button",
173
+ {
174
+ type: "button",
175
+ onClick: clear,
176
+ className: "absolute right-9 top-1/2 -translate-y-1/2 grid h-6 w-6 place-items-center rounded-md text-slate-400 hover:text-slate-700 hover:bg-slate-100 dark:hover:bg-white/10",
177
+ "aria-label": "Limpiar selecci\xF3n",
178
+ title: "Limpiar",
179
+ children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 20 20", className: "h-4 w-4", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
180
+ "path",
181
+ {
182
+ fillRule: "evenodd",
183
+ d: "M10 8.586l3.536-3.536a1 1 0 111.414 1.414L11.414 10l3.536 3.536a1 1 0 01-1.414 1.414L10 11.414l-3.536 3.536a1 1 0 01-1.414-1.414L8.586 10 5.05 6.464A1 1 0 116.464 5.05L10 8.586z",
184
+ clipRule: "evenodd"
185
+ }
186
+ ) })
187
+ }
188
+ )
189
+ ] }),
190
+ open && /* @__PURE__ */ jsxs(
191
+ "ul",
192
+ {
193
+ id: `${selectId}-listbox`,
194
+ role: "listbox",
195
+ ref: listRef,
196
+ tabIndex: -1,
197
+ onKeyDown: onKeyList,
198
+ "aria-labelledby": selectId,
199
+ className: [
200
+ "fixed z-[1000] max-h-72 overflow-auto",
201
+ "rounded-2xl border border-slate-200/80 bg-white/90 backdrop-blur-md shadow-2xl ring-1 ring-black/5",
202
+ "dark:border-white/10 dark:bg-[#0f0d0e]/90 dark:ring-white/10"
203
+ ].join(" "),
204
+ style: {
205
+ top: menuPos.top,
206
+ left: menuPos.left,
207
+ width: menuPos.width,
208
+ maxWidth: "calc(100vw - 24px)"
209
+ },
210
+ children: [
211
+ /* @__PURE__ */ jsx(
212
+ "li",
213
+ {
214
+ role: "presentation",
215
+ className: `${S[size].itemPad} sticky top-0 bg-white/90 dark:bg-[#0f0d0e]/90 backdrop-blur-md text-slate-400 select-none`,
216
+ children: placeholder
217
+ }
218
+ ),
219
+ options.map((o, idx) => {
220
+ const isSelected = String(value) === String(o.value);
221
+ const isDisabled = Boolean(o.disabled);
222
+ return /* @__PURE__ */ jsxs(
223
+ "li",
224
+ {
225
+ role: "option",
226
+ "aria-selected": isSelected,
227
+ "aria-disabled": isDisabled,
228
+ tabIndex: -1,
229
+ "data-idx": idx,
230
+ onMouseDown: (e) => e.preventDefault(),
231
+ onClick: () => !isDisabled && setSelected(o),
232
+ className: [
233
+ S[size].itemPad,
234
+ "flex items-start justify-between gap-3",
235
+ "cursor-pointer focus:outline-none",
236
+ "hover:bg-slate-50 dark:hover:bg-white/5",
237
+ isSelected ? "bg-slate-50/70 dark:bg-white/10" : "",
238
+ isDisabled ? "opacity-50 cursor-not-allowed" : ""
239
+ ].join(" "),
240
+ children: [
241
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 leading-snug whitespace-normal break-words line-clamp-2", children: o.label }),
242
+ isSelected && /* @__PURE__ */ jsx("svg", { className: "ml-3 h-4 w-4 shrink-0 opacity-80", viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
243
+ "path",
244
+ {
245
+ fillRule: "evenodd",
246
+ d: "M16.707 5.293a1 1 0 010 1.414l-7.25 7.25a1 1 0 01-1.414 0l-3.25-3.25a1 1 0 111.414-1.414l2.543 2.543 6.543-6.543a1 1 0 011.414 0z",
247
+ clipRule: "evenodd"
248
+ }
249
+ ) })
250
+ ]
251
+ },
252
+ String(o.value)
253
+ );
254
+ })
255
+ ]
256
+ }
257
+ ),
258
+ hasError ? /* @__PURE__ */ jsx("div", { id: errorId, className: "mt-1 text-[12px] text-blue-600", children: typeof error === "string" ? error : "Corrige este campo" }) : hint ? /* @__PURE__ */ jsx("div", { id: hintId, className: "mt-1 text-[12px] text-slate-500", children: hint }) : null
259
+ ] });
260
+ }
261
+ export {
262
+ ModernSelect as default
263
+ };
@@ -0,0 +1,15 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React__default from 'react';
3
+
4
+ type Spark = {
5
+ values: number[];
6
+ color?: string;
7
+ };
8
+ declare function StatCard({ title, value, hint, spark }: {
9
+ title: string;
10
+ value: React__default.ReactNode;
11
+ hint?: string;
12
+ spark?: Spark;
13
+ }): react_jsx_runtime.JSX.Element;
14
+
15
+ export { StatCard as default };
@@ -0,0 +1,15 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React__default from 'react';
3
+
4
+ type Spark = {
5
+ values: number[];
6
+ color?: string;
7
+ };
8
+ declare function StatCard({ title, value, hint, spark }: {
9
+ title: string;
10
+ value: React__default.ReactNode;
11
+ hint?: string;
12
+ spark?: Spark;
13
+ }): react_jsx_runtime.JSX.Element;
14
+
15
+ export { StatCard as default };
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ "use client";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var StatCard_exports = {};
21
+ __export(StatCard_exports, {
22
+ default: () => StatCard
23
+ });
24
+ module.exports = __toCommonJS(StatCard_exports);
25
+ var import_jsx_runtime = require("react/jsx-runtime");
26
+ var import_framer_motion = require("framer-motion");
27
+ var import_react = require("react");
28
+ var import_recharts = require("recharts");
29
+ function StatCard({ title, value, hint, spark }) {
30
+ var _a;
31
+ const gid = (0, import_react.useId)();
32
+ const color = (_a = spark == null ? void 0 : spark.color) != null ? _a : "#10b981";
33
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_framer_motion.motion.div, { initial: { opacity: 0, y: 8 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.25 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "h-full group relative overflow-hidden rounded-2xl border border-slate-200 bg-white/80 p-4 shadow-sm ring-1 ring-black/5 backdrop-blur transition hover:shadow-md dark:border-white/10 dark:bg-white/5", children: [
34
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative z-10", children: [
35
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-xs font-medium text-slate-500", children: title }),
36
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mt-1 text-2xl font-semibold tracking-tight", children: value }),
37
+ hint && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mt-1 text-xs text-slate-400", children: hint })
38
+ ] }),
39
+ spark && spark.values.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "pointer-events-none absolute inset-y-0 right-0 w-1/2 opacity-90", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_recharts.AreaChart, { data: spark.values.map((v, i) => ({ i, v })), margin: { top: 8, bottom: 0, left: 0, right: 0 }, children: [
40
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("linearGradient", { id: `${gid}-sg`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
41
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("stop", { offset: "0%", stopColor: color, stopOpacity: 0.5 }),
42
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("stop", { offset: "100%", stopColor: color, stopOpacity: 0.05 })
43
+ ] }) }),
44
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_recharts.Area, { type: "monotone", dataKey: "v", stroke: color, strokeWidth: 2, fill: `url(#${gid}-sg)`, isAnimationActive: true, animationDuration: 600, animationEasing: "ease-out" })
45
+ ] }) }) })
46
+ ] }) });
47
+ }
@@ -0,0 +1,27 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { motion } from "framer-motion";
4
+ import { useId } from "react";
5
+ import { Area, AreaChart, ResponsiveContainer } from "recharts";
6
+ function StatCard({ title, value, hint, spark }) {
7
+ var _a;
8
+ const gid = useId();
9
+ const color = (_a = spark == null ? void 0 : spark.color) != null ? _a : "#10b981";
10
+ return /* @__PURE__ */ jsx(motion.div, { initial: { opacity: 0, y: 8 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.25 }, children: /* @__PURE__ */ jsxs("div", { className: "h-full group relative overflow-hidden rounded-2xl border border-slate-200 bg-white/80 p-4 shadow-sm ring-1 ring-black/5 backdrop-blur transition hover:shadow-md dark:border-white/10 dark:bg-white/5", children: [
11
+ /* @__PURE__ */ jsxs("div", { className: "relative z-10", children: [
12
+ /* @__PURE__ */ jsx("div", { className: "text-xs font-medium text-slate-500", children: title }),
13
+ /* @__PURE__ */ jsx("div", { className: "mt-1 text-2xl font-semibold tracking-tight", children: value }),
14
+ hint && /* @__PURE__ */ jsx("div", { className: "mt-1 text-xs text-slate-400", children: hint })
15
+ ] }),
16
+ spark && spark.values.length > 1 && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-y-0 right-0 w-1/2 opacity-90", children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(AreaChart, { data: spark.values.map((v, i) => ({ i, v })), margin: { top: 8, bottom: 0, left: 0, right: 0 }, children: [
17
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: `${gid}-sg`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
18
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: color, stopOpacity: 0.5 }),
19
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: color, stopOpacity: 0.05 })
20
+ ] }) }),
21
+ /* @__PURE__ */ jsx(Area, { type: "monotone", dataKey: "v", stroke: color, strokeWidth: 2, fill: `url(#${gid}-sg)`, isAnimationActive: true, animationDuration: 600, animationEasing: "ease-out" })
22
+ ] }) }) })
23
+ ] }) });
24
+ }
25
+ export {
26
+ StatCard as default
27
+ };
@@ -0,0 +1,31 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ type StepDef = {
4
+ key: string;
5
+ label: string;
6
+ description?: string;
7
+ /** Si quieres bloquear saltos hacia adelante */
8
+ disabled?: boolean;
9
+ };
10
+ type StepsProps = {
11
+ steps: StepDef[];
12
+ current: number;
13
+ onChange?: (nextIndex: number) => void;
14
+ className?: string;
15
+ clickable?: boolean;
16
+ compact?: boolean;
17
+ };
18
+ declare function Steps({ steps, current, onChange, className, clickable, compact, }: StepsProps): react_jsx_runtime.JSX.Element;
19
+ /** Footer de navegación opcional (siguiente/anterior) */
20
+ declare function StepsNav({ current, total, onPrev, onNext, nextLabel, finishLabel, disableNext, formId, }: {
21
+ current: number;
22
+ total: number;
23
+ onPrev?: () => void;
24
+ onNext?: () => void;
25
+ nextLabel?: string;
26
+ finishLabel?: string;
27
+ disableNext?: boolean;
28
+ formId?: string;
29
+ }): react_jsx_runtime.JSX.Element;
30
+
31
+ export { type StepDef, StepsNav, Steps as default };
@@ -0,0 +1,31 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ type StepDef = {
4
+ key: string;
5
+ label: string;
6
+ description?: string;
7
+ /** Si quieres bloquear saltos hacia adelante */
8
+ disabled?: boolean;
9
+ };
10
+ type StepsProps = {
11
+ steps: StepDef[];
12
+ current: number;
13
+ onChange?: (nextIndex: number) => void;
14
+ className?: string;
15
+ clickable?: boolean;
16
+ compact?: boolean;
17
+ };
18
+ declare function Steps({ steps, current, onChange, className, clickable, compact, }: StepsProps): react_jsx_runtime.JSX.Element;
19
+ /** Footer de navegación opcional (siguiente/anterior) */
20
+ declare function StepsNav({ current, total, onPrev, onNext, nextLabel, finishLabel, disableNext, formId, }: {
21
+ current: number;
22
+ total: number;
23
+ onPrev?: () => void;
24
+ onNext?: () => void;
25
+ nextLabel?: string;
26
+ finishLabel?: string;
27
+ disableNext?: boolean;
28
+ formId?: string;
29
+ }): react_jsx_runtime.JSX.Element;
30
+
31
+ export { type StepDef, StepsNav, Steps as default };
package/dist/Steps.js ADDED
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ "use client";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var Steps_exports = {};
21
+ __export(Steps_exports, {
22
+ StepsNav: () => StepsNav,
23
+ default: () => Steps
24
+ });
25
+ module.exports = __toCommonJS(Steps_exports);
26
+ var import_jsx_runtime = require("react/jsx-runtime");
27
+ const cx = (...a) => a.filter(Boolean).join(" ");
28
+ function Steps({
29
+ steps,
30
+ current,
31
+ onChange,
32
+ className,
33
+ clickable = true,
34
+ compact = false
35
+ }) {
36
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
37
+ "nav",
38
+ {
39
+ "aria-label": "Progreso",
40
+ className: cx(
41
+ "w-full rounded-2xl border border-slate-200/80 bg-white/50 p-3 dark:border-white/10 dark:bg-white/[0.04]",
42
+ className
43
+ ),
44
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "grid grid-cols-1 gap-3 sm:grid-cols-4", children: steps.map((s, i) => {
45
+ const state = i < current ? "done" : i === current ? "current" : "upcoming";
46
+ const canClick = clickable && i <= current && !s.disabled && onChange;
47
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { className: "min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
48
+ "button",
49
+ {
50
+ type: "button",
51
+ disabled: !canClick,
52
+ onClick: () => canClick && (onChange == null ? void 0 : onChange(i)),
53
+ className: cx(
54
+ "group flex w-full items-center gap-3 rounded-xl border px-3 py-2 text-left transition",
55
+ state === "current" && "border-blue-300/70 bg-blue-50/50 text-blue-900 dark:border-blue-300/20 dark:bg-blue-300/5 dark:text-blue-100",
56
+ state === "done" && "border-emerald-300/50 bg-emerald-50/40 text-emerald-900 hover:bg-emerald-50 dark:border-emerald-300/20 dark:bg-emerald-300/5 dark:text-emerald-100",
57
+ state === "upcoming" && "border-slate-200/80 bg-white hover:bg-slate-50 dark:border-white/10 dark:bg-white/5"
58
+ ),
59
+ "aria-current": state === "current" ? "step" : void 0,
60
+ children: [
61
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
62
+ "span",
63
+ {
64
+ className: cx(
65
+ "inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-[13px] font-semibold ring-1",
66
+ state === "current" && "bg-blue-600 text-white ring-black/0",
67
+ state === "done" && "bg-emerald-600 text-white ring-black/0",
68
+ state === "upcoming" && "bg-slate-100 text-slate-700 ring-black/5 dark:bg-white/10 dark:text-slate-200"
69
+ ),
70
+ children: state === "done" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", fill: "none", stroke: "currentColor", strokeWidth: 3, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m5 12 4 4L19 6" }) }) : i + 1
71
+ }
72
+ ),
73
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "min-w-0", children: [
74
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "block truncate text-[13px] font-semibold", children: s.label }),
75
+ !compact && s.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "block truncate text-[12px] text-slate-500", children: s.description })
76
+ ] })
77
+ ]
78
+ }
79
+ ) }, s.key);
80
+ }) })
81
+ }
82
+ );
83
+ }
84
+ function StepsNav({
85
+ current,
86
+ total,
87
+ onPrev,
88
+ onNext,
89
+ nextLabel = "Siguiente",
90
+ finishLabel = "Finalizar",
91
+ disableNext,
92
+ formId
93
+ // <- NUEVO
94
+ }) {
95
+ const last = current === total - 1;
96
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [
97
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
98
+ "button",
99
+ {
100
+ type: "button",
101
+ disabled: current === 0,
102
+ onClick: onPrev,
103
+ className: "inline-flex h-9 items-center rounded-xl border border-slate-200 bg-white px-3 text-sm hover:bg-slate-50 disabled:opacity-50 dark:border-white/10 dark:bg-white/5",
104
+ children: "Atr\xE1s"
105
+ }
106
+ ),
107
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
108
+ "button",
109
+ {
110
+ type: "submit",
111
+ form: formId,
112
+ disabled: disableNext,
113
+ className: "inline-flex h-9 items-center rounded-xl bg-blue-600 px-3 text-sm font-semibold text-white hover:bg-blue-700 disabled:opacity-50",
114
+ onClick: onNext,
115
+ children: last ? finishLabel : nextLabel
116
+ }
117
+ )
118
+ ] });
119
+ }
120
+ // Annotate the CommonJS export names for ESM import in node:
121
+ 0 && (module.exports = {
122
+ StepsNav
123
+ });
package/dist/Steps.mjs ADDED
@@ -0,0 +1,99 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ const cx = (...a) => a.filter(Boolean).join(" ");
4
+ function Steps({
5
+ steps,
6
+ current,
7
+ onChange,
8
+ className,
9
+ clickable = true,
10
+ compact = false
11
+ }) {
12
+ return /* @__PURE__ */ jsx(
13
+ "nav",
14
+ {
15
+ "aria-label": "Progreso",
16
+ className: cx(
17
+ "w-full rounded-2xl border border-slate-200/80 bg-white/50 p-3 dark:border-white/10 dark:bg-white/[0.04]",
18
+ className
19
+ ),
20
+ children: /* @__PURE__ */ jsx("ol", { className: "grid grid-cols-1 gap-3 sm:grid-cols-4", children: steps.map((s, i) => {
21
+ const state = i < current ? "done" : i === current ? "current" : "upcoming";
22
+ const canClick = clickable && i <= current && !s.disabled && onChange;
23
+ return /* @__PURE__ */ jsx("li", { className: "min-w-0", children: /* @__PURE__ */ jsxs(
24
+ "button",
25
+ {
26
+ type: "button",
27
+ disabled: !canClick,
28
+ onClick: () => canClick && (onChange == null ? void 0 : onChange(i)),
29
+ className: cx(
30
+ "group flex w-full items-center gap-3 rounded-xl border px-3 py-2 text-left transition",
31
+ state === "current" && "border-blue-300/70 bg-blue-50/50 text-blue-900 dark:border-blue-300/20 dark:bg-blue-300/5 dark:text-blue-100",
32
+ state === "done" && "border-emerald-300/50 bg-emerald-50/40 text-emerald-900 hover:bg-emerald-50 dark:border-emerald-300/20 dark:bg-emerald-300/5 dark:text-emerald-100",
33
+ state === "upcoming" && "border-slate-200/80 bg-white hover:bg-slate-50 dark:border-white/10 dark:bg-white/5"
34
+ ),
35
+ "aria-current": state === "current" ? "step" : void 0,
36
+ children: [
37
+ /* @__PURE__ */ jsx(
38
+ "span",
39
+ {
40
+ className: cx(
41
+ "inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-[13px] font-semibold ring-1",
42
+ state === "current" && "bg-blue-600 text-white ring-black/0",
43
+ state === "done" && "bg-emerald-600 text-white ring-black/0",
44
+ state === "upcoming" && "bg-slate-100 text-slate-700 ring-black/5 dark:bg-white/10 dark:text-slate-200"
45
+ ),
46
+ children: state === "done" ? /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", fill: "none", stroke: "currentColor", strokeWidth: 3, children: /* @__PURE__ */ jsx("path", { d: "m5 12 4 4L19 6" }) }) : i + 1
47
+ }
48
+ ),
49
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
50
+ /* @__PURE__ */ jsx("span", { className: "block truncate text-[13px] font-semibold", children: s.label }),
51
+ !compact && s.description && /* @__PURE__ */ jsx("span", { className: "block truncate text-[12px] text-slate-500", children: s.description })
52
+ ] })
53
+ ]
54
+ }
55
+ ) }, s.key);
56
+ }) })
57
+ }
58
+ );
59
+ }
60
+ function StepsNav({
61
+ current,
62
+ total,
63
+ onPrev,
64
+ onNext,
65
+ nextLabel = "Siguiente",
66
+ finishLabel = "Finalizar",
67
+ disableNext,
68
+ formId
69
+ // <- NUEVO
70
+ }) {
71
+ const last = current === total - 1;
72
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
73
+ /* @__PURE__ */ jsx(
74
+ "button",
75
+ {
76
+ type: "button",
77
+ disabled: current === 0,
78
+ onClick: onPrev,
79
+ className: "inline-flex h-9 items-center rounded-xl border border-slate-200 bg-white px-3 text-sm hover:bg-slate-50 disabled:opacity-50 dark:border-white/10 dark:bg-white/5",
80
+ children: "Atr\xE1s"
81
+ }
82
+ ),
83
+ /* @__PURE__ */ jsx(
84
+ "button",
85
+ {
86
+ type: "submit",
87
+ form: formId,
88
+ disabled: disableNext,
89
+ className: "inline-flex h-9 items-center rounded-xl bg-blue-600 px-3 text-sm font-semibold text-white hover:bg-blue-700 disabled:opacity-50",
90
+ onClick: onNext,
91
+ children: last ? finishLabel : nextLabel
92
+ }
93
+ )
94
+ ] });
95
+ }
96
+ export {
97
+ StepsNav,
98
+ Steps as default
99
+ };