framepexls-ui-lib 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/AvatarGroup.js +1 -1
  2. package/dist/AvatarGroup.mjs +1 -1
  3. package/dist/Badge.js +12 -12
  4. package/dist/Badge.mjs +12 -12
  5. package/dist/BadgeCluster.js +1 -1
  6. package/dist/BadgeCluster.mjs +1 -1
  7. package/dist/Button.js +1 -1
  8. package/dist/Button.mjs +1 -1
  9. package/dist/Card.js +1 -1
  10. package/dist/Card.mjs +1 -1
  11. package/dist/ChartCard.js +1 -1
  12. package/dist/ChartCard.mjs +1 -1
  13. package/dist/Checkbox.d.mts +1 -1
  14. package/dist/Checkbox.d.ts +1 -1
  15. package/dist/Checkbox.js +1 -1
  16. package/dist/Checkbox.mjs +1 -1
  17. package/dist/CheckboxPillsGroup.js +3 -3
  18. package/dist/CheckboxPillsGroup.mjs +3 -3
  19. package/dist/ComboSelect.js +2 -2
  20. package/dist/ComboSelect.mjs +2 -2
  21. package/dist/DateTimeField.js +1 -1
  22. package/dist/DateTimeField.mjs +1 -1
  23. package/dist/EmptyState.js +1 -1
  24. package/dist/EmptyState.mjs +1 -1
  25. package/dist/FiltersMultiSelect.js +3 -3
  26. package/dist/FiltersMultiSelect.mjs +3 -3
  27. package/dist/Input.js +4 -4
  28. package/dist/Input.mjs +4 -4
  29. package/dist/KpiCard.js +1 -1
  30. package/dist/KpiCard.mjs +1 -1
  31. package/dist/MediaCard.js +1 -1
  32. package/dist/MediaCard.mjs +1 -1
  33. package/dist/MediaSelector.js +235 -135
  34. package/dist/MediaSelector.mjs +235 -135
  35. package/dist/MediaTile.d.mts +18 -0
  36. package/dist/MediaTile.d.ts +18 -0
  37. package/dist/MediaTile.js +146 -0
  38. package/dist/MediaTile.mjs +116 -0
  39. package/dist/MultiComboSelect.js +2 -2
  40. package/dist/MultiComboSelect.mjs +2 -2
  41. package/dist/Pagination.js +8 -6
  42. package/dist/Pagination.mjs +8 -6
  43. package/dist/Sidebar.js +9 -9
  44. package/dist/Sidebar.mjs +9 -9
  45. package/dist/Skeleton.d.mts +34 -0
  46. package/dist/Skeleton.d.ts +34 -0
  47. package/dist/Skeleton.js +92 -0
  48. package/dist/Skeleton.mjs +64 -0
  49. package/dist/StatCard.js +1 -1
  50. package/dist/StatCard.mjs +1 -1
  51. package/dist/Steps.js +2 -2
  52. package/dist/Steps.mjs +2 -2
  53. package/dist/Table.js +5 -5
  54. package/dist/Table.mjs +5 -5
  55. package/dist/Textarea.js +1 -1
  56. package/dist/Textarea.mjs +1 -1
  57. package/dist/TimePanel.js +4 -4
  58. package/dist/TimePanel.mjs +4 -4
  59. package/dist/TimePopover.js +2 -2
  60. package/dist/TimePopover.mjs +2 -2
  61. package/dist/TimeRangeField.js +1 -1
  62. package/dist/TimeRangeField.mjs +1 -1
  63. package/dist/Tooltip.js +1 -1
  64. package/dist/Tooltip.mjs +1 -1
  65. package/dist/UploadCard.js +7 -7
  66. package/dist/UploadCard.mjs +7 -7
  67. package/dist/index.d.mts +2 -0
  68. package/dist/index.d.ts +2 -0
  69. package/dist/index.js +6 -0
  70. package/dist/index.mjs +68 -64
  71. package/dist/theme/ThemeToggle.js +2 -1
  72. package/dist/theme/ThemeToggle.mjs +2 -1
  73. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import { useEffect, useRef, useState } from "react";
3
+ import React from "react";
4
4
  import ChartCard from "./ChartCard";
5
5
  import Button from "./Button";
6
6
  import Input from "./Input";
@@ -18,24 +18,24 @@ function MediaSelector({
18
18
  onClose
19
19
  }) {
20
20
  const { obtenerMedios, items, page, lastPage, setPage, subirMedio } = medios;
21
- const [openPicker, setOpenPicker] = useState(false);
22
- const [uploading, setUploading] = useState(false);
23
- const [progress, setProgress] = useState(0);
24
- const inputRef = useRef(null);
25
- const [linkValue, setLinkValue] = useState(value != null ? value : "");
26
- const [linkLoading, setLinkLoading] = useState(false);
27
- const [linkError, setLinkError] = useState(null);
28
- useEffect(() => {
21
+ const [openPicker, setOpenPicker] = React.useState(false);
22
+ const [uploading, setUploading] = React.useState(false);
23
+ const [progress, setProgress] = React.useState(0);
24
+ const inputRef = React.useRef(null);
25
+ const [linkValue, setLinkValue] = React.useState(value != null ? value : "");
26
+ const [linkLoading, setLinkLoading] = React.useState(false);
27
+ const [linkError, setLinkError] = React.useState(null);
28
+ React.useEffect(() => {
29
29
  if (openPicker) obtenerMedios({ page: page || 1 });
30
30
  }, [openPicker, page, obtenerMedios]);
31
- useEffect(() => {
31
+ React.useEffect(() => {
32
32
  if (autoOpen) setOpenPicker(true);
33
33
  }, [autoOpen]);
34
- useEffect(() => {
34
+ React.useEffect(() => {
35
35
  if (openPicker) setLinkValue(value != null ? value : "");
36
36
  }, [openPicker, value]);
37
37
  const onFiles = async (files) => {
38
- var _a, _b, _c, _d;
38
+ var _a, _b;
39
39
  if (!(files == null ? void 0 : files.length)) return;
40
40
  const file = files[0];
41
41
  setUploading(true);
@@ -43,7 +43,8 @@ function MediaSelector({
43
43
  const res = await subirMedio(file, { onProgress: (p) => setProgress(p.porcentaje) });
44
44
  setUploading(false);
45
45
  if (res.ok) {
46
- const url = (_d = (_c = (_a = res.data) == null ? void 0 : _a.url) != null ? _c : (_b = res.data) == null ? void 0 : _b.url) != null ? _d : null;
46
+ const anyData = (_a = res.data) != null ? _a : res;
47
+ const url = (_b = anyData == null ? void 0 : anyData.url) != null ? _b : null;
47
48
  onChange(url, res.data);
48
49
  }
49
50
  };
@@ -54,141 +55,240 @@ function MediaSelector({
54
55
  return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
55
56
  !dialogOnly && /* @__PURE__ */ jsxs(Fragment, { children: [
56
57
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
57
- /* @__PURE__ */ jsx(Input, { value: value != null ? value : "", onChange: (e) => onChange(e.target.value || null), placeholder: "URL de imagen", clearable: true, onClear: () => onChange(null) }),
58
+ /* @__PURE__ */ jsx(
59
+ Input,
60
+ {
61
+ value: value != null ? value : "",
62
+ onChange: (e) => onChange(e.target.value || null),
63
+ placeholder: "URL de imagen",
64
+ clearable: true,
65
+ onClear: () => onChange(null)
66
+ }
67
+ ),
58
68
  /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => setOpenPicker(true), children: "Elegir" })
59
69
  ] }),
60
- value && /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-2xl border border-slate-200 bg-white/60 p-2 dark:border-white/10 dark:bg-white/5", children: /* @__PURE__ */ jsx("div", { className: "aspect-video w-full overflow-hidden rounded-xl bg-slate-100", children: /* @__PURE__ */ jsx("img", { src: value, alt: "preview", className: "h-full w-full object-cover" }) }) })
70
+ value && /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-2xl border border-slate-200 bg-white/60 p-2 dark:border-white/10 dark:bg-[var(--fx-surface)]", children: /* @__PURE__ */ jsx("div", { className: "aspect-video w-full overflow-hidden rounded-xl bg-slate-100", children: /* @__PURE__ */ jsx("img", { src: value, alt: "preview", className: "h-full w-full object-cover" }) }) })
61
71
  ] }),
62
- /* @__PURE__ */ jsxs(Dialog, { open: openPicker, onClose: () => {
63
- setOpenPicker(false);
64
- onClose == null ? void 0 : onClose();
65
- }, size: "full", children: [
66
- /* @__PURE__ */ jsx(Dialog.Header, { title: "Biblioteca de medios", description: "Selecciona una imagen o sube una nueva", onClose: () => {
67
- setOpenPicker(false);
68
- onClose == null ? void 0 : onClose();
69
- } }),
70
- /* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 lg:grid-cols-2", children: [
71
- /* @__PURE__ */ jsx(ChartCard, { className: "lg:col-span-1", title: "Subir imagen", subtitle: /* @__PURE__ */ jsx("span", { children: "Arrastra una imagen o selecci\xF3nala" }), right: /* @__PURE__ */ jsxs(Fragment, { children: [
72
- /* @__PURE__ */ jsx(Input, { unstyled: true, ref: inputRef, type: "file", accept, className: "hidden", onChange: (e) => onFiles(e.target.files) }),
73
- /* @__PURE__ */ jsx(Button, { onClick: () => {
74
- var _a;
75
- return (_a = inputRef.current) == null ? void 0 : _a.click();
76
- }, disabled: uploading, children: "Seleccionar" })
77
- ] }), children: /* @__PURE__ */ jsxs(
78
- "div",
79
- {
80
- onDragOver: (e) => {
81
- e.preventDefault();
82
- e.dataTransfer.dropEffect = "copy";
83
- },
84
- onDrop: handleDrop,
85
- onClick: () => {
86
- var _a;
87
- return (_a = inputRef.current) == null ? void 0 : _a.click();
88
- },
89
- className: "flex cursor-pointer flex-col items-center justify-center gap-2 rounded-2xl border border-dashed border-slate-300 bg-gradient-to-b from-white/90 to-white/60 p-8 text-center transition hover:border-slate-400 hover:bg-white/80 dark:border-white/10 dark:from-white/10 dark:to-white/5",
90
- children: [
91
- /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "h-8 w-8 text-slate-400", fill: "none", stroke: "currentColor", strokeWidth: "1.6", children: /* @__PURE__ */ jsx("path", { d: "M12 16V4M7 9l5-5 5 5M20 16v3a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-3" }) }),
92
- /* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: "Soltar imagen aqu\xED" }),
93
- uploading && /* @__PURE__ */ jsxs("div", { className: "mt-3 w-full", children: [
94
- /* @__PURE__ */ jsxs("div", { className: "mb-1 text-xs text-slate-500", children: [
95
- progress,
96
- "%"
97
- ] }),
98
- /* @__PURE__ */ jsx("div", { className: "h-2 overflow-hidden rounded-full bg-slate-100 dark:bg-white/10", children: /* @__PURE__ */ jsx(motion.div, { className: "h-full w-full origin-left bg-gradient-to-r from-emerald-500/70 to-emerald-500/20 will-change-transform", initial: { scaleX: 0 }, animate: { scaleX: progress / 100 }, transition: springSm }) })
99
- ] })
100
- ]
101
- }
102
- ) }),
103
- /* @__PURE__ */ jsxs(ChartCard, { className: "lg:col-span-1", title: "Desde enlace", subtitle: /* @__PURE__ */ jsx("span", { children: "Pega una URL http(s) v\xE1lida" }), compact: true, children: [
104
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
105
- /* @__PURE__ */ jsx(
106
- Input,
107
- {
108
- type: "url",
109
- placeholder: "https://\u2026",
110
- value: linkValue,
111
- onChange: (e) => {
112
- setLinkValue(e.target.value);
113
- setLinkError(null);
114
- }
72
+ /* @__PURE__ */ jsxs(
73
+ Dialog,
74
+ {
75
+ open: openPicker,
76
+ onClose: () => {
77
+ setOpenPicker(false);
78
+ onClose == null ? void 0 : onClose();
79
+ },
80
+ size: "full",
81
+ children: [
82
+ /* @__PURE__ */ jsx(
83
+ Dialog.Header,
84
+ {
85
+ title: "Biblioteca de medios",
86
+ description: "Selecciona una imagen o sube una nueva",
87
+ onClose: () => {
88
+ setOpenPicker(false);
89
+ onClose == null ? void 0 : onClose();
115
90
  }
116
- ),
91
+ }
92
+ ),
93
+ /* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 lg:grid-cols-2", children: [
117
94
  /* @__PURE__ */ jsx(
118
- Button,
95
+ ChartCard,
119
96
  {
120
- onClick: async () => {
121
- var _a, _b, _c, _d;
122
- if (!linkValue) return;
123
- setLinkError(null);
124
- const isHttp = /^https?:\/\//i.test(linkValue);
125
- if (!isHttp) {
126
- setLinkError("Ingresa un enlace v\xE1lido (http/https)");
127
- return;
128
- }
129
- const importer = (_a = medios.importFromUrl) != null ? _a : medios.importarMedioDesdeUrl;
130
- if (importer) {
131
- setLinkLoading(true);
132
- const res = await importer(linkValue);
133
- setLinkLoading(false);
134
- if (res && res.ok) {
135
- const d = (_b = res.data) != null ? _b : res;
136
- onChange((_c = d == null ? void 0 : d.url) != null ? _c : null, d != null ? d : null);
137
- setOpenPicker(false);
138
- onClose == null ? void 0 : onClose();
139
- } else {
140
- setLinkError(String((_d = res == null ? void 0 : res.error) != null ? _d : "No se pudo importar el enlace"));
97
+ className: "lg:col-span-1",
98
+ title: "Subir imagen",
99
+ subtitle: /* @__PURE__ */ jsx("span", { children: "Arrastra una imagen o selecci\xF3nala" }),
100
+ right: /* @__PURE__ */ jsxs(Fragment, { children: [
101
+ /* @__PURE__ */ jsx(
102
+ Input,
103
+ {
104
+ unstyled: true,
105
+ ref: inputRef,
106
+ type: "file",
107
+ accept,
108
+ className: "hidden",
109
+ onChange: (e) => onFiles(e.target.files)
141
110
  }
142
- } else {
143
- onChange(linkValue || null, null);
144
- setOpenPicker(false);
145
- onClose == null ? void 0 : onClose();
111
+ ),
112
+ /* @__PURE__ */ jsx(Button, { onClick: () => {
113
+ var _a;
114
+ return (_a = inputRef.current) == null ? void 0 : _a.click();
115
+ }, disabled: uploading, children: "Seleccionar" })
116
+ ] }),
117
+ children: /* @__PURE__ */ jsxs(
118
+ "div",
119
+ {
120
+ onDragOver: (e) => {
121
+ e.preventDefault();
122
+ e.dataTransfer.dropEffect = "copy";
123
+ },
124
+ onDrop: handleDrop,
125
+ onClick: () => {
126
+ var _a;
127
+ return (_a = inputRef.current) == null ? void 0 : _a.click();
128
+ },
129
+ className: "flex cursor-pointer flex-col items-center justify-center gap-2 rounded-2xl border border-dashed border-slate-300 bg-gradient-to-b from-white/90 to-white/60 p-8 text-center transition hover:border-slate-400 hover:bg-white/80 dark:border-white/10 dark:from-white/10 dark:to-white/5",
130
+ children: [
131
+ /* @__PURE__ */ jsx(
132
+ "svg",
133
+ {
134
+ viewBox: "0 0 24 24",
135
+ className: "h-8 w-8 text-slate-400",
136
+ fill: "none",
137
+ stroke: "currentColor",
138
+ strokeWidth: "1.6",
139
+ children: /* @__PURE__ */ jsx("path", { d: "M12 16V4M7 9l5-5 5 5M20 16v3a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-3" })
140
+ }
141
+ ),
142
+ /* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: "Arrastra y suelta archivos aqu\xED o haz clic" }),
143
+ /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500", children: "Formatos: JPG, PNG, WEBP, GIF" }),
144
+ uploading && /* @__PURE__ */ jsxs("div", { className: "mt-3 w-full rounded-xl border border-slate-200 p-2 text-left text-sm dark:border-white/10", children: [
145
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-xs", children: [
146
+ /* @__PURE__ */ jsx("span", { children: "Subiendo\u2026" }),
147
+ /* @__PURE__ */ jsxs("span", { children: [
148
+ progress,
149
+ "%"
150
+ ] })
151
+ ] }),
152
+ /* @__PURE__ */ jsx("div", { className: "h-2 overflow-hidden rounded-full bg-slate-100 dark:bg-white/10", children: /* @__PURE__ */ jsx(
153
+ motion.div,
154
+ {
155
+ className: "h-full w-full origin-left bg-gradient-to-r from-emerald-500/70 to-emerald-500/20 will-change-transform",
156
+ initial: { scaleX: 0 },
157
+ animate: { scaleX: progress / 100 },
158
+ transition: springSm
159
+ }
160
+ ) })
161
+ ] })
162
+ ]
146
163
  }
147
- },
148
- disabled: !linkValue || linkLoading,
149
- children: linkLoading ? "Importando\u2026" : "Usar"
164
+ )
150
165
  }
151
- )
152
- ] }),
153
- linkError && /* @__PURE__ */ jsx("div", { className: "mt-2 rounded-xl border border-rose-300/70 bg-rose-50 px-3 py-2 text-rose-900 text-xs", children: linkError })
154
- ] }),
155
- /* @__PURE__ */ jsxs("div", { className: "lg:col-span-2 space-y-3", children: [
156
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
157
- /* @__PURE__ */ jsxs("div", { className: "text-sm text-slate-500 dark:text-slate-400", children: [
158
- "P\xE1gina ",
159
- page,
160
- " de ",
161
- Math.max(1, lastPage)
162
- ] }),
163
- lastPage > 1 && /* @__PURE__ */ jsx(Pagination, { page, totalPages: lastPage, onPageChange: setPage })
164
- ] }),
165
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-3 sm:grid-cols-3 md:grid-cols-4", children: /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: items.map((m) => {
166
- var _a;
167
- return /* @__PURE__ */ jsx(motion.div, { layout: true, initial: { opacity: 0, y: 8 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: 8 }, transition: springSm, children: /* @__PURE__ */ jsxs(
168
- Button,
166
+ ),
167
+ /* @__PURE__ */ jsxs(
168
+ ChartCard,
169
169
  {
170
- unstyled: true,
171
- className: "group overflow-hidden rounded-2xl border border-slate-200 bg-white/70 p-1 text-left transition hover:shadow-md focus:outline-none focus:ring-2 focus:ring-slate-300 dark:border-white/10 dark:bg-white/5",
172
- onClick: () => {
173
- var _a2;
174
- onChange((_a2 = m.url) != null ? _a2 : null, m);
175
- setOpenPicker(false);
176
- onClose == null ? void 0 : onClose();
177
- },
170
+ className: "lg:col-span-1",
171
+ title: "Desde enlace",
172
+ subtitle: /* @__PURE__ */ jsx("span", { children: "Pega una URL http(s) v\xE1lida" }),
173
+ compact: true,
178
174
  children: [
179
- /* @__PURE__ */ jsx("div", { className: "aspect-square w-full overflow-hidden rounded-xl bg-slate-100", children: /* @__PURE__ */ jsx("img", { src: (_a = m.url) != null ? _a : "", alt: m.nombre, className: "h-full w-full object-cover transition group-hover:scale-105" }) }),
180
- /* @__PURE__ */ jsx("div", { className: "truncate p-1 text-xs", children: m.nombre })
175
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
176
+ /* @__PURE__ */ jsx(
177
+ Input,
178
+ {
179
+ type: "url",
180
+ placeholder: "https://\u2026",
181
+ value: linkValue,
182
+ onChange: (e) => {
183
+ setLinkValue(e.target.value);
184
+ setLinkError(null);
185
+ }
186
+ }
187
+ ),
188
+ /* @__PURE__ */ jsx(
189
+ Button,
190
+ {
191
+ onClick: async () => {
192
+ var _a, _b, _c, _d;
193
+ if (!linkValue) return;
194
+ setLinkError(null);
195
+ const isHttp = /^https?:\/\//i.test(linkValue);
196
+ if (!isHttp) {
197
+ setLinkError("Ingresa un enlace v\xE1lido (http/https)");
198
+ return;
199
+ }
200
+ const importer = (_a = medios.importFromUrl) != null ? _a : medios.importarMedioDesdeUrl;
201
+ if (importer) {
202
+ setLinkLoading(true);
203
+ const res = await importer(linkValue);
204
+ setLinkLoading(false);
205
+ if (res && res.ok) {
206
+ const d = (_b = res.data) != null ? _b : res;
207
+ onChange((_c = d == null ? void 0 : d.url) != null ? _c : null, d != null ? d : null);
208
+ setOpenPicker(false);
209
+ onClose == null ? void 0 : onClose();
210
+ } else {
211
+ setLinkError(String((_d = res == null ? void 0 : res.error) != null ? _d : "No se pudo importar el enlace"));
212
+ }
213
+ } else {
214
+ onChange(linkValue || null, null);
215
+ setOpenPicker(false);
216
+ onClose == null ? void 0 : onClose();
217
+ }
218
+ },
219
+ disabled: !linkValue || linkLoading,
220
+ children: linkLoading ? "Importando\u2026" : "Usar"
221
+ }
222
+ )
223
+ ] }),
224
+ linkError && /* @__PURE__ */ jsx("div", { className: "mt-2 rounded-xl border border-rose-300/70 bg-rose-50 px-3 py-2 text-rose-900 text-xs", children: linkError })
181
225
  ]
182
226
  }
183
- ) }, m.id);
184
- }) }) })
185
- ] })
186
- ] }) }),
187
- /* @__PURE__ */ jsx(Dialog.Footer, { align: "end", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => {
188
- setOpenPicker(false);
189
- onClose == null ? void 0 : onClose();
190
- }, children: "Cerrar" }) })
191
- ] })
227
+ ),
228
+ /* @__PURE__ */ jsxs("div", { className: "lg:col-span-2 space-y-3", children: [
229
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
230
+ /* @__PURE__ */ jsxs("div", { className: "text-sm text-slate-500 dark:text-slate-400", children: [
231
+ "P\xE1gina ",
232
+ page,
233
+ " de ",
234
+ Math.max(1, lastPage)
235
+ ] }),
236
+ lastPage > 1 && /* @__PURE__ */ jsx(Pagination, { page, totalPages: lastPage, onPageChange: setPage })
237
+ ] }),
238
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-3 sm:grid-cols-3 md:grid-cols-4", children: /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: items.map((m) => {
239
+ var _a;
240
+ return /* @__PURE__ */ jsx(
241
+ motion.div,
242
+ {
243
+ layout: true,
244
+ initial: { opacity: 0, y: 8 },
245
+ animate: { opacity: 1, y: 0 },
246
+ exit: { opacity: 0, y: 8 },
247
+ transition: springSm,
248
+ children: /* @__PURE__ */ jsxs(
249
+ Button,
250
+ {
251
+ unstyled: true,
252
+ className: "group overflow-hidden rounded-2xl border border-slate-200 bg-white/70 p-1 text-left transition hover:shadow-md focus:outline-none focus:ring-2 focus:ring-slate-300 dark:border-white/10 dark:bg-[var(--fx-surface)]",
253
+ onClick: () => {
254
+ var _a2;
255
+ onChange((_a2 = m.url) != null ? _a2 : null, m);
256
+ setOpenPicker(false);
257
+ onClose == null ? void 0 : onClose();
258
+ },
259
+ children: [
260
+ /* @__PURE__ */ jsx("div", { className: "aspect-square w-full overflow-hidden rounded-xl bg-slate-100", children: /* @__PURE__ */ jsx(
261
+ "img",
262
+ {
263
+ src: (_a = m.url) != null ? _a : "",
264
+ alt: m.nombre,
265
+ className: "h-full w-full object-cover transition group-hover:scale-105"
266
+ }
267
+ ) }),
268
+ /* @__PURE__ */ jsx("div", { className: "truncate p-1 text-xs", children: m.nombre })
269
+ ]
270
+ }
271
+ )
272
+ },
273
+ String(m.id)
274
+ );
275
+ }) }) })
276
+ ] })
277
+ ] }) }),
278
+ /* @__PURE__ */ jsx(Dialog.Footer, { align: "end", children: /* @__PURE__ */ jsx(
279
+ Button,
280
+ {
281
+ variant: "secondary",
282
+ onClick: () => {
283
+ setOpenPicker(false);
284
+ onClose == null ? void 0 : onClose();
285
+ },
286
+ children: "Cerrar"
287
+ }
288
+ ) })
289
+ ]
290
+ }
291
+ )
192
292
  ] });
193
293
  }
194
294
  export {
@@ -0,0 +1,18 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ type MediaTileProps = {
4
+ imageUrl?: string | null;
5
+ title: string;
6
+ subtitle?: string;
7
+ copyUrl?: string;
8
+ loading?: boolean;
9
+ onPreview?: () => void;
10
+ onRename?: () => void;
11
+ onReplace?: () => void;
12
+ onDelete?: () => void;
13
+ menuSize?: "sm" | "md" | "lg";
14
+ className?: string;
15
+ };
16
+ declare function MediaTile({ imageUrl, title, subtitle, copyUrl, onPreview, onRename, onReplace, onDelete, loading, menuSize, className, }: MediaTileProps): react_jsx_runtime.JSX.Element;
17
+
18
+ export { type MediaTileProps, MediaTile as default };
@@ -0,0 +1,18 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ type MediaTileProps = {
4
+ imageUrl?: string | null;
5
+ title: string;
6
+ subtitle?: string;
7
+ copyUrl?: string;
8
+ loading?: boolean;
9
+ onPreview?: () => void;
10
+ onRename?: () => void;
11
+ onReplace?: () => void;
12
+ onDelete?: () => void;
13
+ menuSize?: "sm" | "md" | "lg";
14
+ className?: string;
15
+ };
16
+ declare function MediaTile({ imageUrl, title, subtitle, copyUrl, onPreview, onRename, onReplace, onDelete, loading, menuSize, className, }: MediaTileProps): react_jsx_runtime.JSX.Element;
17
+
18
+ export { type MediaTileProps, MediaTile as default };
@@ -0,0 +1,146 @@
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 MediaTile_exports = {};
31
+ __export(MediaTile_exports, {
32
+ default: () => MediaTile
33
+ });
34
+ module.exports = __toCommonJS(MediaTile_exports);
35
+ var import_jsx_runtime = require("react/jsx-runtime");
36
+ var import_react = require("react");
37
+ var import_image = __toESM(require("next/image"));
38
+ var import_framer_motion = require("framer-motion");
39
+ var import_animations = require("./animations");
40
+ var import_Dropdown = __toESM(require("./Dropdown"));
41
+ function MediaTile({
42
+ imageUrl,
43
+ title,
44
+ subtitle,
45
+ copyUrl,
46
+ onPreview,
47
+ onRename,
48
+ onReplace,
49
+ onDelete,
50
+ loading,
51
+ menuSize = "md",
52
+ className
53
+ }) {
54
+ const [copied, setCopied] = (0, import_react.useState)(false);
55
+ const copy = async () => {
56
+ if (!copyUrl) return;
57
+ try {
58
+ await navigator.clipboard.writeText(copyUrl);
59
+ setCopied(true);
60
+ setTimeout(() => setCopied(false), 1200);
61
+ } catch {
62
+ }
63
+ };
64
+ const btnSize = menuSize === "lg" ? "h-11 w-11" : menuSize === "sm" ? "h-8 w-8" : "h-9 w-9";
65
+ const iconSize = menuSize === "lg" ? "h-7 w-7" : menuSize === "sm" ? "h-5 w-5" : "h-6 w-6";
66
+ const ImgWrap = onPreview ? (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", onClick: onPreview, ...props }) : (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ...props });
67
+ if (loading) {
68
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
69
+ "div",
70
+ {
71
+ className: [
72
+ "overflow-hidden rounded-2xl border border-slate-200 bg-white/80 shadow-sm ring-1 ring-black/5 backdrop-blur dark:border-white/10 dark:bg-[var(--fx-surface)]",
73
+ className != null ? className : ""
74
+ ].join(" "),
75
+ children: [
76
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "aspect-square w-full", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-full w-full animate-pulse bg-slate-200 dark:bg-white/10" }) }),
77
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "p-2 space-y-2", children: [
78
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-3 w-3/4 animate-pulse rounded bg-slate-200 dark:bg-white/10" }),
79
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-2 w-1/3 animate-pulse rounded bg-slate-200 dark:bg-white/10" })
80
+ ] })
81
+ ]
82
+ }
83
+ );
84
+ }
85
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
86
+ import_framer_motion.motion.div,
87
+ {
88
+ whileHover: { y: -2 },
89
+ transition: import_animations.microTransition,
90
+ className: [
91
+ "group relative overflow-hidden rounded-2xl border border-slate-200 bg-white/80 shadow-sm ring-1 ring-black/5 backdrop-blur dark:border-white/10 dark:bg-[var(--fx-surface)]",
92
+ className != null ? className : ""
93
+ ].join(" "),
94
+ children: [
95
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ImgWrap, { className: "aspect-square w-full bg-slate-100 relative text-left", children: [
96
+ imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
97
+ import_image.default,
98
+ {
99
+ src: imageUrl,
100
+ alt: title,
101
+ fill: true,
102
+ sizes: "(min-width:1024px) 20vw, (min-width:768px) 25vw, (min-width:640px) 33vw, 50vw",
103
+ className: "object-cover transition-transform duration-200 will-change-transform group-hover:scale-105"
104
+ }
105
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-full w-full" }),
106
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "pointer-events-none absolute inset-0 bg-gradient-to-t from-black/30 to-transparent opacity-0 transition-opacity duration-200 group-hover:opacity-100" })
107
+ ] }),
108
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between gap-2 p-2", children: [
109
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-w-0", children: [
110
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "truncate text-sm font-medium", children: title }),
111
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-xs text-slate-500 dark:text-slate-400", children: subtitle })
112
+ ] }),
113
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex items-center gap-1", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_Dropdown.default, { children: [
114
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Dropdown.default.Trigger, { "aria-label": "Acciones", className: [btnSize, "p-0 !gap-0"].join(" "), children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", className: iconSize, fill: "currentColor", children: [
115
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "5", r: "2" }),
116
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "2" }),
117
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "19", r: "2" })
118
+ ] }) }),
119
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_Dropdown.default.Content, { children: [
120
+ onPreview && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Dropdown.default.Item, { onSelect: onPreview, icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "inline-flex h-4 w-4 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
121
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M1 12s4-7 11-7 11 7 11 7-4 7-11 7-11-7-11-7Z" }),
122
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "3" })
123
+ ] }) }), children: "Ver" }),
124
+ copyUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Dropdown.default.Item, { onSelect: copy, icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "inline-flex h-4 w-4 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
125
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
126
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
127
+ ] }) }), children: copied ? "Copiado" : "Copiar URL" }),
128
+ (onRename || onReplace) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Dropdown.default.Separator, {}),
129
+ onRename && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Dropdown.default.Item, { onSelect: onRename, icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "inline-flex h-4 w-4 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
130
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 21v-4l12-12 4 4-12 12z" }),
131
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 7l4 4" })
132
+ ] }) }), children: "Renombrar" }),
133
+ onReplace && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Dropdown.default.Item, { onSelect: onReplace, icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "inline-flex h-4 w-4 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 5v14M5 12h14" }) }) }), children: "Reemplazar" }),
134
+ onDelete && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Dropdown.default.Item, { danger: true, onSelect: onDelete, icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "inline-flex h-4 w-4 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
135
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M3 6h18" }),
136
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 6v14a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2V6" }),
137
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10 11v6M14 11v6" }),
138
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2" })
139
+ ] }) }), children: "Eliminar" })
140
+ ] })
141
+ ] }) })
142
+ ] })
143
+ ]
144
+ }
145
+ );
146
+ }