@agroshine/ags-web-ui-kit 1.0.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.
Files changed (109) hide show
  1. package/README.md +75 -0
  2. package/dist/atoms/index.cjs +134 -0
  3. package/dist/atoms/index.cjs.map +1 -0
  4. package/dist/atoms/index.d.cts +583 -0
  5. package/dist/atoms/index.d.ts +583 -0
  6. package/dist/atoms/index.js +9 -0
  7. package/dist/atoms/index.js.map +1 -0
  8. package/dist/chunk-2KRMLIJQ.cjs +52 -0
  9. package/dist/chunk-2KRMLIJQ.cjs.map +1 -0
  10. package/dist/chunk-2TBYPKQ3.cjs +79 -0
  11. package/dist/chunk-2TBYPKQ3.cjs.map +1 -0
  12. package/dist/chunk-5FWELSEZ.js +1296 -0
  13. package/dist/chunk-5FWELSEZ.js.map +1 -0
  14. package/dist/chunk-5PEOJVY7.cjs +1502 -0
  15. package/dist/chunk-5PEOJVY7.cjs.map +1 -0
  16. package/dist/chunk-6LUGTNMH.js +259 -0
  17. package/dist/chunk-6LUGTNMH.js.map +1 -0
  18. package/dist/chunk-6O2IDBTX.js +112 -0
  19. package/dist/chunk-6O2IDBTX.js.map +1 -0
  20. package/dist/chunk-6YUNWKT3.js +26 -0
  21. package/dist/chunk-6YUNWKT3.js.map +1 -0
  22. package/dist/chunk-7R6OXNES.cjs +321 -0
  23. package/dist/chunk-7R6OXNES.cjs.map +1 -0
  24. package/dist/chunk-A3A7PJWG.cjs +13 -0
  25. package/dist/chunk-A3A7PJWG.cjs.map +1 -0
  26. package/dist/chunk-A7TDGQAB.js +557 -0
  27. package/dist/chunk-A7TDGQAB.js.map +1 -0
  28. package/dist/chunk-C4LX3XTN.cjs +1187 -0
  29. package/dist/chunk-C4LX3XTN.cjs.map +1 -0
  30. package/dist/chunk-DZW4GS2T.cjs +1340 -0
  31. package/dist/chunk-DZW4GS2T.cjs.map +1 -0
  32. package/dist/chunk-E3BTK736.cjs +174 -0
  33. package/dist/chunk-E3BTK736.cjs.map +1 -0
  34. package/dist/chunk-ERGKCXM2.cjs +267 -0
  35. package/dist/chunk-ERGKCXM2.cjs.map +1 -0
  36. package/dist/chunk-FOA46NSG.cjs +574 -0
  37. package/dist/chunk-FOA46NSG.cjs.map +1 -0
  38. package/dist/chunk-JTFCE6RA.js +1156 -0
  39. package/dist/chunk-JTFCE6RA.js.map +1 -0
  40. package/dist/chunk-KINOE57L.js +225 -0
  41. package/dist/chunk-KINOE57L.js.map +1 -0
  42. package/dist/chunk-MOED3QPY.js +11 -0
  43. package/dist/chunk-MOED3QPY.js.map +1 -0
  44. package/dist/chunk-NVR34DY2.cjs +4 -0
  45. package/dist/chunk-NVR34DY2.cjs.map +1 -0
  46. package/dist/chunk-PI3IJWBG.js +79 -0
  47. package/dist/chunk-PI3IJWBG.js.map +1 -0
  48. package/dist/chunk-PXAMTGYY.js +3 -0
  49. package/dist/chunk-PXAMTGYY.js.map +1 -0
  50. package/dist/chunk-QAZMI5VH.js +151 -0
  51. package/dist/chunk-QAZMI5VH.js.map +1 -0
  52. package/dist/chunk-QEG27NX6.js +30 -0
  53. package/dist/chunk-QEG27NX6.js.map +1 -0
  54. package/dist/chunk-THTOUSMG.cjs +52 -0
  55. package/dist/chunk-THTOUSMG.cjs.map +1 -0
  56. package/dist/chunk-UAXKB6IH.cjs +32 -0
  57. package/dist/chunk-UAXKB6IH.cjs.map +1 -0
  58. package/dist/chunk-W5IHWAMM.js +48 -0
  59. package/dist/chunk-W5IHWAMM.js.map +1 -0
  60. package/dist/chunk-X2UJQVZJ.cjs +139 -0
  61. package/dist/chunk-X2UJQVZJ.cjs.map +1 -0
  62. package/dist/chunk-X43C5OJD.js +1460 -0
  63. package/dist/chunk-X43C5OJD.js.map +1 -0
  64. package/dist/chunk-XCYSBWV4.js +56 -0
  65. package/dist/chunk-XCYSBWV4.js.map +1 -0
  66. package/dist/chunk-XX4CBCEB.cjs +102 -0
  67. package/dist/chunk-XX4CBCEB.cjs.map +1 -0
  68. package/dist/hooks/index.cjs +33 -0
  69. package/dist/hooks/index.cjs.map +1 -0
  70. package/dist/hooks/index.d.cts +59 -0
  71. package/dist/hooks/index.d.ts +59 -0
  72. package/dist/hooks/index.js +4 -0
  73. package/dist/hooks/index.js.map +1 -0
  74. package/dist/index.cjs +366 -0
  75. package/dist/index.cjs.map +1 -0
  76. package/dist/index.d.cts +13 -0
  77. package/dist/index.d.ts +13 -0
  78. package/dist/index.js +17 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/interface-DnK5S6ww.d.cts +51 -0
  81. package/dist/interface-DnK5S6ww.d.ts +51 -0
  82. package/dist/lib/index.cjs +13 -0
  83. package/dist/lib/index.cjs.map +1 -0
  84. package/dist/lib/index.d.cts +5 -0
  85. package/dist/lib/index.d.ts +5 -0
  86. package/dist/lib/index.js +4 -0
  87. package/dist/lib/index.js.map +1 -0
  88. package/dist/molecules/index.cjs +123 -0
  89. package/dist/molecules/index.cjs.map +1 -0
  90. package/dist/molecules/index.d.cts +449 -0
  91. package/dist/molecules/index.d.ts +449 -0
  92. package/dist/molecules/index.js +10 -0
  93. package/dist/molecules/index.js.map +1 -0
  94. package/dist/organisms/index.cjs +102 -0
  95. package/dist/organisms/index.cjs.map +1 -0
  96. package/dist/organisms/index.d.cts +396 -0
  97. package/dist/organisms/index.d.ts +396 -0
  98. package/dist/organisms/index.js +9 -0
  99. package/dist/organisms/index.js.map +1 -0
  100. package/dist/tooltip-Bl2ZTtfg.d.cts +16 -0
  101. package/dist/tooltip-Bl2ZTtfg.d.ts +16 -0
  102. package/dist/ui/index.cjs +955 -0
  103. package/dist/ui/index.cjs.map +1 -0
  104. package/dist/ui/index.d.cts +252 -0
  105. package/dist/ui/index.d.ts +252 -0
  106. package/dist/ui/index.js +642 -0
  107. package/dist/ui/index.js.map +1 -0
  108. package/package.json +200 -0
  109. package/tailwind.preset.cjs +134 -0
@@ -0,0 +1,1156 @@
1
+ import { FormItem } from './chunk-QEG27NX6.js';
2
+ import { Spinner, Button } from './chunk-QAZMI5VH.js';
3
+ import { Accordion, Calendar as Calendar$1, AccordionItem, AccordionTrigger, AccordionContent } from './chunk-6O2IDBTX.js';
4
+ import { Popover, PopoverTrigger, PopoverContent } from './chunk-6YUNWKT3.js';
5
+ import { cn } from './chunk-MOED3QPY.js';
6
+ import React, { forwardRef, useState, useCallback, useMemo, useRef, useEffect } from 'react';
7
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
+ import clsx from 'clsx';
9
+ import { cva } from 'class-variance-authority';
10
+ import { Search, Calendar, ServerCrash, FileQuestion, Info, AlertTriangle, XCircle, CheckCircle2, ChevronRight } from 'lucide-react';
11
+ import { faArrowLeft, faSearch } from '@fortawesome/free-solid-svg-icons';
12
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
13
+ import dayjs from 'dayjs';
14
+ import { Toaster as Toaster$1 } from 'sonner';
15
+ export { toast } from 'sonner';
16
+
17
+ function ItemNumber({ value }) {
18
+ return /* @__PURE__ */ jsx("span", { className: "grid h-6 w-6 shrink-0 place-items-center rounded-full bg-primary-50 text-xs font-bold text-primary", children: value });
19
+ }
20
+ function renderItems(items, variant) {
21
+ const isCard = variant === "card";
22
+ const defaultItemClass = "border-b border-border first:border-t";
23
+ const cardItemClass = "mb-2 overflow-hidden rounded-md border border-border last:mb-0";
24
+ const cardTriggerClass = "px-4 py-3.5 hover:bg-muted/50 hover:text-foreground data-[state=open]:bg-muted/50 [&:hover>svg]:text-muted-foreground";
25
+ const cardContentClass = "border-t border-border px-4 pb-4 pt-3.5";
26
+ return items.map((item) => /* @__PURE__ */ jsxs(
27
+ AccordionItem,
28
+ {
29
+ value: item.key,
30
+ disabled: item.disabled,
31
+ className: isCard ? cardItemClass : defaultItemClass,
32
+ children: [
33
+ /* @__PURE__ */ jsx(AccordionTrigger, { className: isCard ? cardTriggerClass : void 0, children: /* @__PURE__ */ jsxs("span", { className: "flex flex-1 items-center gap-3 text-left", children: [
34
+ item.number !== void 0 && isCard && /* @__PURE__ */ jsx(ItemNumber, { value: item.number }),
35
+ item.icon ? /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: item.icon }) : null,
36
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children: item.title })
37
+ ] }) }),
38
+ /* @__PURE__ */ jsx(AccordionContent, { className: isCard ? cardContentClass : void 0, children: item.content })
39
+ ]
40
+ },
41
+ item.key
42
+ ));
43
+ }
44
+ var Accordion2 = forwardRef(function Accordion3(props, ref) {
45
+ const { items, className, variant = "default" } = props;
46
+ const children = renderItems(items, variant);
47
+ const rootClass = cn("w-full", className);
48
+ if (props.type === "multiple") {
49
+ const { defaultValue: defaultValue2, value: value2, onChange: onChange2 } = props;
50
+ return /* @__PURE__ */ jsx(
51
+ Accordion,
52
+ {
53
+ ref,
54
+ type: "multiple",
55
+ defaultValue: defaultValue2,
56
+ value: value2,
57
+ onValueChange: onChange2,
58
+ className: rootClass,
59
+ children
60
+ }
61
+ );
62
+ }
63
+ const { defaultValue, value, onChange, collapsible } = props;
64
+ return /* @__PURE__ */ jsx(
65
+ Accordion,
66
+ {
67
+ ref,
68
+ type: "single",
69
+ collapsible: collapsible ?? true,
70
+ defaultValue,
71
+ value,
72
+ onValueChange: onChange,
73
+ className: rootClass,
74
+ children
75
+ }
76
+ );
77
+ });
78
+ Accordion2.displayName = "Accordion";
79
+ var Content = forwardRef(function Content2({ children, padded = true, maxWidth = "full", className }, ref) {
80
+ const isFull = maxWidth === "full";
81
+ const innerStyle = isFull ? void 0 : { maxWidth: typeof maxWidth === "number" ? `${maxWidth}px` : void 0 };
82
+ return /* @__PURE__ */ jsx(
83
+ "main",
84
+ {
85
+ ref,
86
+ className: cn("min-h-0 flex-1 bg-default-50 text-foreground overflow-auto", className),
87
+ children: /* @__PURE__ */ jsx("div", { style: innerStyle, className: cn(padded && "px-6 py-6", !isFull && "mx-auto w-full"), children })
88
+ }
89
+ );
90
+ });
91
+ Content.displayName = "Content";
92
+ var FormCard = ({
93
+ title,
94
+ description,
95
+ disabled = false,
96
+ children
97
+ }) => {
98
+ return /* @__PURE__ */ jsxs(
99
+ "article",
100
+ {
101
+ className: clsx(
102
+ "w-auto border box-border border-primary-100/ px-10 py-5 mb-5",
103
+ "rounded-lg bg-white ",
104
+ disabled && "pointer-events-none bg-gray-200 cursor-not-allowed rounded-md"
105
+ ),
106
+ children: [
107
+ title && /* @__PURE__ */ jsx("h2", { className: "text-black-900 font-semibold text-[18px] mb-[10px]", children: title }),
108
+ description && /* @__PURE__ */ jsx("p", { className: "text-grey-900 text-[14px]", children: description }),
109
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4", children })
110
+ ]
111
+ }
112
+ );
113
+ };
114
+ function BrandLogo({ mark = "A", name = "AgroShine", className }) {
115
+ return /* @__PURE__ */ jsxs(
116
+ "div",
117
+ {
118
+ className: cn(
119
+ "flex h-full min-w-[240px] shrink-0 items-center gap-2.5",
120
+ "border-r border-white/10 pl-[18px] pr-[22px]",
121
+ className
122
+ ),
123
+ children: [
124
+ /* @__PURE__ */ jsx(
125
+ "span",
126
+ {
127
+ "aria-hidden": true,
128
+ className: cn(
129
+ "grid h-7 w-7 place-items-center rounded-md",
130
+ "bg-secondary-500 text-primary-700 text-sm font-bold leading-none"
131
+ ),
132
+ children: mark
133
+ }
134
+ ),
135
+ /* @__PURE__ */ jsx("span", { className: "text-[15px] font-semibold text-white", children: name })
136
+ ]
137
+ }
138
+ );
139
+ }
140
+ function FarmChip({ children, withDot = true, className }) {
141
+ return /* @__PURE__ */ jsxs(
142
+ "span",
143
+ {
144
+ className: cn(
145
+ "inline-flex items-center gap-1.5 rounded-full",
146
+ "border border-white/20 px-3 py-1 text-xs font-medium text-white",
147
+ className
148
+ ),
149
+ children: [
150
+ withDot && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "h-1.5 w-1.5 rounded-full bg-secondary-500" }),
151
+ children
152
+ ]
153
+ }
154
+ );
155
+ }
156
+ var headerItemVariants = cva(
157
+ [
158
+ "inline-flex h-full items-center gap-2 px-[18px]",
159
+ "text-[12.5px] font-medium tracking-[0.06em] uppercase",
160
+ "cursor-pointer select-none outline-none no-underline",
161
+ "border-b-2 border-transparent transition-colors",
162
+ "focus-visible:ring-2 focus-visible:ring-secondary-500 focus-visible:ring-inset"
163
+ ],
164
+ {
165
+ variants: {
166
+ active: {
167
+ true: "text-primary-foreground border-b-secondary-500",
168
+ false: "text-primary-foreground/80 hover:text-primary-foreground"
169
+ }
170
+ },
171
+ defaultVariants: { active: false }
172
+ }
173
+ );
174
+ var SearchBox = forwardRef(function SearchBox2({ placeholder = "Buscar bloque, producto, blanco\u2026", value, onChange, onSubmit, className }, ref) {
175
+ const [internal, setInternal] = useState(value ?? "");
176
+ const isControlled = value !== void 0;
177
+ const current = isControlled ? value : internal;
178
+ const handleChange = useCallback(
179
+ (event) => {
180
+ const next = event.target.value;
181
+ if (!isControlled) setInternal(next);
182
+ onChange?.(next);
183
+ },
184
+ [isControlled, onChange]
185
+ );
186
+ const handleSubmit = useCallback(
187
+ (event) => {
188
+ event.preventDefault();
189
+ onSubmit?.(current ?? "");
190
+ },
191
+ [current, onSubmit]
192
+ );
193
+ return /* @__PURE__ */ jsxs("form", { role: "search", onSubmit: handleSubmit, className: cn("relative w-[260px]", className), children: [
194
+ /* @__PURE__ */ jsx(
195
+ Search,
196
+ {
197
+ "aria-hidden": true,
198
+ className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-white/60"
199
+ }
200
+ ),
201
+ /* @__PURE__ */ jsx(
202
+ "input",
203
+ {
204
+ ref,
205
+ type: "search",
206
+ value: current,
207
+ onChange: handleChange,
208
+ placeholder,
209
+ className: cn(
210
+ "h-8 w-full rounded-md pl-9 pr-3 text-sm text-white",
211
+ "bg-white/10 border border-white/15 placeholder:text-white/50",
212
+ "outline-none focus-visible:ring-2 focus-visible:ring-secondary-500 focus-visible:ring-offset-0",
213
+ "[&::-webkit-search-cancel-button]:hidden"
214
+ )
215
+ }
216
+ )
217
+ ] });
218
+ });
219
+ var Header = forwardRef(function Header2({
220
+ brand,
221
+ items,
222
+ onItemClick,
223
+ search,
224
+ farmChip,
225
+ actions,
226
+ user,
227
+ className,
228
+ sticky = false,
229
+ height = 60
230
+ }, ref) {
231
+ const style = { height };
232
+ const handleClick = useCallback(
233
+ (item) => {
234
+ item.onClick?.();
235
+ onItemClick?.(item);
236
+ },
237
+ [onItemClick]
238
+ );
239
+ const renderItem = (item) => {
240
+ const itemClassName = headerItemVariants({ active: !!item.active });
241
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
242
+ item.icon && /* @__PURE__ */ jsx("span", { className: "shrink-0", children: item.icon }),
243
+ /* @__PURE__ */ jsx("span", { children: item.label })
244
+ ] });
245
+ if (item.href) {
246
+ return /* @__PURE__ */ jsx(
247
+ "a",
248
+ {
249
+ href: item.href,
250
+ className: itemClassName,
251
+ "aria-current": item.active ? "page" : void 0,
252
+ onClick: () => handleClick(item),
253
+ children: content
254
+ },
255
+ item.key
256
+ );
257
+ }
258
+ return /* @__PURE__ */ jsx(
259
+ "button",
260
+ {
261
+ type: "button",
262
+ className: cn(itemClassName, "bg-transparent"),
263
+ "aria-current": item.active ? "page" : void 0,
264
+ onClick: () => handleClick(item),
265
+ children: content
266
+ },
267
+ item.key
268
+ );
269
+ };
270
+ const searchProps = search ? search : null;
271
+ const hasItems = !!items && items.length > 0;
272
+ return /* @__PURE__ */ jsxs(
273
+ "header",
274
+ {
275
+ ref,
276
+ style,
277
+ className: cn(
278
+ "flex items-stretch bg-primary-500 text-primary-foreground",
279
+ "border-b border-primary-700",
280
+ sticky && "sticky top-0 z-30",
281
+ className
282
+ ),
283
+ children: [
284
+ brand ? /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center", children: brand }) : /* @__PURE__ */ jsx(BrandLogo, {}),
285
+ hasItems && /* @__PURE__ */ jsx("nav", { "aria-label": "Navegaci\xF3n principal", className: "hidden flex-1 items-stretch pl-2 md:flex", children: items.map(renderItem) }),
286
+ !hasItems && /* @__PURE__ */ jsx("div", { className: "flex-1" }),
287
+ /* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-3.5 px-5", children: [
288
+ searchProps && /* @__PURE__ */ jsx("div", { className: "hidden lg:block", children: /* @__PURE__ */ jsx(SearchBox, { ...searchProps }) }),
289
+ farmChip !== void 0 && farmChip !== null && /* @__PURE__ */ jsx("div", { className: "hidden md:flex", children: typeof farmChip === "string" ? /* @__PURE__ */ jsx(FarmChip, { children: farmChip }) : farmChip }),
290
+ actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: actions }),
291
+ user && /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center", children: user })
292
+ ] })
293
+ ]
294
+ }
295
+ );
296
+ });
297
+ Header.displayName = "Header";
298
+ function UserAvatar({ initials, label, className, onClick }) {
299
+ const classes = cn(
300
+ "inline-flex h-8 w-8 items-center justify-center rounded-full",
301
+ "bg-white/15 border border-white/20 text-xs font-semibold text-white",
302
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-secondary-500",
303
+ onClick && "cursor-pointer transition-colors hover:bg-white/25",
304
+ className
305
+ );
306
+ if (onClick) {
307
+ return /* @__PURE__ */ jsx("button", { type: "button", "aria-label": label ?? initials, className: classes, onClick, children: initials });
308
+ }
309
+ return /* @__PURE__ */ jsx("span", { role: "img", "aria-label": label ?? initials, className: classes, children: initials });
310
+ }
311
+ var Layout = forwardRef(function Layout2({ header, sidebar, footer, children, hasHeader, hasSidebar, sidebarCollapsed = false, className }, ref) {
312
+ const renderHeader = hasHeader ?? !!header;
313
+ const renderSidebar = hasSidebar ?? !!sidebar;
314
+ return /* @__PURE__ */ jsxs(
315
+ "div",
316
+ {
317
+ ref,
318
+ className: cn("flex h-screen w-full flex-col bg-default-50 text-foreground", className),
319
+ children: [
320
+ renderHeader && header && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: header }),
321
+ /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1", children: [
322
+ renderSidebar && sidebar && /* @__PURE__ */ jsxs(Fragment, { children: [
323
+ /* @__PURE__ */ jsx("aside", { className: "hidden shrink-0 lg:flex", children: sidebar }),
324
+ !sidebarCollapsed && /* @__PURE__ */ jsx("aside", { className: "fixed inset-y-0 left-0 z-40 flex lg:hidden", "aria-hidden": "false", children: sidebar })
325
+ ] }),
326
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
327
+ /* @__PURE__ */ jsx(Content, { padded: true, children }),
328
+ footer && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: footer })
329
+ ] })
330
+ ] })
331
+ ]
332
+ }
333
+ );
334
+ });
335
+ Layout.displayName = "Layout";
336
+ var PageHeader = ({
337
+ title,
338
+ subtitle,
339
+ onBack,
340
+ headerLeft,
341
+ extra,
342
+ children
343
+ }) => {
344
+ return /* @__PURE__ */ jsxs("div", { className: "p-7 flex flex-col gap-5", children: [
345
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-4", children: [
346
+ onBack && /* @__PURE__ */ jsx(Button, { onPress: onBack, isIconOnly: true, "aria-label": "Back", color: "primary", variant: "bordered", children: /* @__PURE__ */ jsx(FontAwesomeIcon, { icon: faArrowLeft }) }),
347
+ /* @__PURE__ */ jsxs("div", { children: [
348
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold", children: title }),
349
+ subtitle && /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mt-1", children: subtitle })
350
+ ] })
351
+ ] }),
352
+ /* @__PURE__ */ jsxs("div", { className: "px-2 rounded-md py-3 flex items-center justify-between gap-4", children: [
353
+ /* @__PURE__ */ jsx("div", { className: "flex items-start gap-4", children: headerLeft }),
354
+ extra && Array.isArray(extra) ? /* @__PURE__ */ jsx("div", { className: "shrink-0", children: extra.map((item, index) => /* @__PURE__ */ jsx("div", { children: item }, index)) }) : /* @__PURE__ */ jsx("div", { className: "shrink-0", children: extra })
355
+ ] }),
356
+ children && /* @__PURE__ */ jsx("div", { className: "mt-2", children })
357
+ ] });
358
+ };
359
+ var DEFAULT_FORMAT = "DD/MM/YYYY";
360
+ var DEFAULT_FORMATS = ["DD/MM/YYYY", "DD-MM-YYYY", "YYYY-MM-DD"];
361
+ function normalizeFormat(format) {
362
+ if (!format) return DEFAULT_FORMAT;
363
+ return Array.isArray(format) ? format[0] : format;
364
+ }
365
+ function dayjsToDate(value) {
366
+ if (!value || !value.isValid()) return void 0;
367
+ return value.toDate();
368
+ }
369
+ function dateToDayjs(value) {
370
+ if (!value) return null;
371
+ const parsed = dayjs(value);
372
+ return parsed.isValid() ? parsed : null;
373
+ }
374
+ function formatDateValue(value, format) {
375
+ const parsed = dateToDayjs(value ?? null);
376
+ if (!parsed) return "";
377
+ return parsed.format(normalizeFormat(format));
378
+ }
379
+ function formatRangeDateValue(value, format) {
380
+ if (!value) return ["", ""];
381
+ return [formatDateValue(value.from, format), formatDateValue(value.to, format)];
382
+ }
383
+ function dayjsRangeToDateRange(value) {
384
+ if (!value?.[0] || !value?.[1]) return void 0;
385
+ const from = dayjsToDate(value[0]);
386
+ const to = dayjsToDate(value[1]);
387
+ if (!from || !to) return void 0;
388
+ return { from, to };
389
+ }
390
+ function dateRangeToDayjsRange(value) {
391
+ if (!value || !value.from || !value.to) return null;
392
+ return [dateToDayjs(value.from), dateToDayjs(value.to)];
393
+ }
394
+ var POPUP_ALIGN_MAP = {
395
+ bottomLeft: "start",
396
+ bottomRight: "end",
397
+ topLeft: "start",
398
+ topRight: "end"
399
+ };
400
+ var POPUP_SIDE_MAP = {
401
+ bottomLeft: "bottom",
402
+ bottomRight: "bottom",
403
+ topLeft: "top",
404
+ topRight: "top"
405
+ };
406
+ var DatePicker = React.forwardRef(
407
+ ({
408
+ className,
409
+ defaultValue,
410
+ value,
411
+ disabled = false,
412
+ format = "DD/MM/YYYY",
413
+ open,
414
+ defaultOpen = false,
415
+ onOpenChange,
416
+ placement = "bottomLeft",
417
+ size = "medium",
418
+ status,
419
+ minDate,
420
+ maxDate,
421
+ isDateUnavailable,
422
+ onChange,
423
+ externalLabel,
424
+ help,
425
+ errorMessage
426
+ }, ref) => {
427
+ const mergedFormat = useMemo(() => normalizeFormat(format), [format]);
428
+ const hasError = status === "error" || Boolean(errorMessage);
429
+ const sizeClass = size === "large" ? "h-10" : size === "small" ? "h-8" : "h-9";
430
+ const [internalOpen, setInternalOpen] = useState(defaultOpen);
431
+ const isOpen = open !== void 0 ? open : internalOpen;
432
+ const setOpen = (next) => {
433
+ if (open === void 0) setInternalOpen(next);
434
+ onOpenChange?.(next);
435
+ };
436
+ const selected = dayjsToDate(value) ?? dayjsToDate(defaultValue);
437
+ const display = selected ? dateToDayjs(selected)?.format(mergedFormat) : "";
438
+ return /* @__PURE__ */ jsx(FormItem, { label: externalLabel, help, validateStatus: hasError ? "error" : "default", children: /* @__PURE__ */ jsx("div", { ref, children: /* @__PURE__ */ jsxs(Popover, { open: isOpen, onOpenChange: setOpen, children: [
439
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
440
+ "button",
441
+ {
442
+ type: "button",
443
+ disabled,
444
+ "aria-label": externalLabel ?? "Fecha",
445
+ "aria-invalid": hasError || void 0,
446
+ className: cn(
447
+ // Mismas clases que ui/input · canon Components.html
448
+ "flex w-full items-center justify-between gap-2 rounded-md border border-input bg-background px-3 py-1 text-sm text-foreground transition-colors",
449
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0",
450
+ "aria-invalid:border-destructive aria-invalid:focus-visible:ring-destructive",
451
+ "disabled:cursor-not-allowed disabled:bg-muted disabled:opacity-60",
452
+ sizeClass,
453
+ className
454
+ ),
455
+ children: [
456
+ /* @__PURE__ */ jsx("span", { className: cn(!display && "text-muted-foreground"), children: display || mergedFormat }),
457
+ /* @__PURE__ */ jsx(
458
+ Calendar,
459
+ {
460
+ className: "h-4 w-4 shrink-0 text-muted-foreground",
461
+ "aria-hidden": "true"
462
+ }
463
+ )
464
+ ]
465
+ }
466
+ ) }),
467
+ /* @__PURE__ */ jsx(
468
+ PopoverContent,
469
+ {
470
+ align: POPUP_ALIGN_MAP[placement],
471
+ side: POPUP_SIDE_MAP[placement],
472
+ className: "w-auto p-0 z-[9999]",
473
+ children: /* @__PURE__ */ jsx(
474
+ Calendar$1,
475
+ {
476
+ mode: "single",
477
+ selected,
478
+ fromDate: dayjsToDate(minDate),
479
+ toDate: dayjsToDate(maxDate),
480
+ disabled: isDateUnavailable ? (date) => Boolean(isDateUnavailable(date)) : void 0,
481
+ onSelect: (d) => {
482
+ const parsed = dateToDayjs(d ?? null);
483
+ onChange?.(parsed, parsed ? parsed.format(mergedFormat) : "");
484
+ setOpen(false);
485
+ }
486
+ }
487
+ )
488
+ }
489
+ )
490
+ ] }) }) });
491
+ }
492
+ );
493
+ DatePicker.displayName = "DatePicker";
494
+ var PickerPanel = ({
495
+ value,
496
+ defaultValue,
497
+ minDate,
498
+ maxDate,
499
+ onChange,
500
+ isDateUnavailable,
501
+ className
502
+ }) => {
503
+ const selected = dayjsToDate(value) ?? dayjsToDate(defaultValue);
504
+ return /* @__PURE__ */ jsx(
505
+ Calendar$1,
506
+ {
507
+ mode: "single",
508
+ className,
509
+ selected,
510
+ fromDate: dayjsToDate(minDate),
511
+ toDate: dayjsToDate(maxDate),
512
+ disabled: isDateUnavailable ? (date) => Boolean(isDateUnavailable(date)) : void 0,
513
+ onSelect: (d) => onChange?.(dateToDayjs(d ?? null))
514
+ }
515
+ );
516
+ };
517
+ var POPUP_ALIGN_MAP2 = {
518
+ bottomLeft: "start",
519
+ bottomRight: "end",
520
+ topLeft: "start",
521
+ topRight: "end"
522
+ };
523
+ var POPUP_SIDE_MAP2 = {
524
+ bottomLeft: "bottom",
525
+ bottomRight: "bottom",
526
+ topLeft: "top",
527
+ topRight: "top"
528
+ };
529
+ var RangePicker = React.forwardRef(
530
+ ({
531
+ className,
532
+ defaultValue,
533
+ value,
534
+ disabled = false,
535
+ format = "DD/MM/YYYY",
536
+ open,
537
+ defaultOpen = false,
538
+ onOpenChange,
539
+ placement = "bottomLeft",
540
+ size = "medium",
541
+ status,
542
+ minDate,
543
+ maxDate,
544
+ isDateUnavailable,
545
+ visibleMonths = 1,
546
+ onChange,
547
+ onCalendarChange,
548
+ externalLabel,
549
+ help,
550
+ errorMessage
551
+ }, ref) => {
552
+ const mergedFormat = useMemo(() => normalizeFormat(format), [format]);
553
+ const hasError = status === "error" || Boolean(errorMessage);
554
+ const sizeClass = size === "large" ? "h-10" : size === "small" ? "h-8" : "h-9";
555
+ const [internalOpen, setInternalOpen] = useState(defaultOpen);
556
+ const isOpen = open !== void 0 ? open : internalOpen;
557
+ const setOpen = (next) => {
558
+ if (open === void 0) setInternalOpen(next);
559
+ onOpenChange?.(next);
560
+ };
561
+ const range = dayjsRangeToDateRange(value) ?? dayjsRangeToDateRange(defaultValue);
562
+ const formatted = formatRangeDateValue(range, mergedFormat);
563
+ const display = range ? `${formatted[0]} \u2013 ${formatted[1]}` : "";
564
+ return /* @__PURE__ */ jsx(FormItem, { label: externalLabel, help, validateStatus: hasError ? "error" : "default", children: /* @__PURE__ */ jsx("div", { ref, children: /* @__PURE__ */ jsxs(Popover, { open: isOpen, onOpenChange: setOpen, children: [
565
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
566
+ "button",
567
+ {
568
+ type: "button",
569
+ disabled,
570
+ "aria-label": externalLabel ?? "Rango de fechas",
571
+ "aria-invalid": hasError || void 0,
572
+ className: cn(
573
+ // Mismas clases que ui/input · canon Components.html
574
+ "flex w-full items-center justify-between gap-2 rounded-md border border-input bg-background px-3 py-1 text-sm text-foreground transition-colors",
575
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0",
576
+ "aria-invalid:border-destructive aria-invalid:focus-visible:ring-destructive",
577
+ "disabled:cursor-not-allowed disabled:bg-muted disabled:opacity-60",
578
+ sizeClass,
579
+ className
580
+ ),
581
+ children: [
582
+ /* @__PURE__ */ jsx("span", { className: cn(!display && "text-muted-foreground"), children: display || `${mergedFormat} \u2013 ${mergedFormat}` }),
583
+ /* @__PURE__ */ jsx(
584
+ Calendar,
585
+ {
586
+ className: "h-4 w-4 shrink-0 text-muted-foreground",
587
+ "aria-hidden": "true"
588
+ }
589
+ )
590
+ ]
591
+ }
592
+ ) }),
593
+ /* @__PURE__ */ jsx(
594
+ PopoverContent,
595
+ {
596
+ align: POPUP_ALIGN_MAP2[placement],
597
+ side: POPUP_SIDE_MAP2[placement],
598
+ className: "w-auto p-0 z-[9999]",
599
+ children: /* @__PURE__ */ jsx(
600
+ Calendar$1,
601
+ {
602
+ mode: "range",
603
+ numberOfMonths: visibleMonths,
604
+ selected: range,
605
+ fromDate: dayjsToDate(minDate),
606
+ toDate: dayjsToDate(maxDate),
607
+ disabled: isDateUnavailable ? (date) => Boolean(isDateUnavailable(date)) : void 0,
608
+ onSelect: (next) => {
609
+ const dayjsRange = dateRangeToDayjsRange(next ?? null);
610
+ const dateStrings = formatRangeDateValue(next ?? null, mergedFormat);
611
+ onChange?.(dayjsRange, dateStrings);
612
+ if (dayjsRange) onCalendarChange?.(dayjsRange, dateStrings, {});
613
+ }
614
+ }
615
+ )
616
+ }
617
+ )
618
+ ] }) }) });
619
+ }
620
+ );
621
+ RangePicker.displayName = "RangePicker";
622
+ var ICON_MAP = {
623
+ success: /* @__PURE__ */ jsx(CheckCircle2, { className: "h-14 w-14" }),
624
+ error: /* @__PURE__ */ jsx(XCircle, { className: "h-14 w-14" }),
625
+ warning: /* @__PURE__ */ jsx(AlertTriangle, { className: "h-14 w-14" }),
626
+ info: /* @__PURE__ */ jsx(Info, { className: "h-14 w-14" }),
627
+ "404": /* @__PURE__ */ jsx(FileQuestion, { className: "h-14 w-14" }),
628
+ "500": /* @__PURE__ */ jsx(ServerCrash, { className: "h-14 w-14" })
629
+ };
630
+ var COLOR_MAP = {
631
+ success: "text-success-500",
632
+ error: "text-destructive",
633
+ warning: "text-warning-500",
634
+ info: "text-primary",
635
+ "404": "text-muted-foreground",
636
+ "500": "text-destructive"
637
+ };
638
+ var Result = forwardRef(function Result2({ status, title, description, icon, extra, className }, ref) {
639
+ return /* @__PURE__ */ jsxs(
640
+ "div",
641
+ {
642
+ ref,
643
+ className: cn("flex flex-col items-center justify-center px-6 py-10 text-center", className),
644
+ children: [
645
+ /* @__PURE__ */ jsx(
646
+ "div",
647
+ {
648
+ className: cn(
649
+ "mb-3 inline-flex items-center justify-center leading-none",
650
+ COLOR_MAP[status]
651
+ ),
652
+ children: icon ?? ICON_MAP[status]
653
+ }
654
+ ),
655
+ /* @__PURE__ */ jsx("h3", { className: "mb-2 text-[22px] font-semibold leading-tight text-foreground", children: title }),
656
+ description && /* @__PURE__ */ jsx("p", { className: "mx-auto max-w-[400px] text-sm leading-normal text-muted-foreground", children: description }),
657
+ extra && /* @__PURE__ */ jsx("div", { className: "mt-5 flex flex-wrap items-center justify-center gap-2", children: extra })
658
+ ]
659
+ }
660
+ );
661
+ });
662
+ Result.displayName = "Result";
663
+ function getErrorMessage(error) {
664
+ if (!error) return void 0;
665
+ if (typeof error === "string") return error;
666
+ if (error instanceof Error) return error.message;
667
+ if (typeof error === "object" && "message" in error) {
668
+ const msg = error.message;
669
+ return typeof msg === "string" ? msg : void 0;
670
+ }
671
+ return void 0;
672
+ }
673
+ var QueryState = forwardRef(function QueryState2({
674
+ loading,
675
+ error,
676
+ empty,
677
+ emptyTitle = "Sin resultados",
678
+ emptyDescription,
679
+ emptyAction,
680
+ errorTitle = "Algo sali\xF3 mal",
681
+ errorDescription,
682
+ onRetry,
683
+ loadingFallback,
684
+ children,
685
+ className
686
+ }, ref) {
687
+ if (loading) {
688
+ return /* @__PURE__ */ jsx("div", { ref, className: cn("flex w-full items-center justify-center", className), children: loadingFallback ?? /* @__PURE__ */ jsx(Spinner, {}) });
689
+ }
690
+ if (error) {
691
+ const description = errorDescription ?? getErrorMessage(error);
692
+ return /* @__PURE__ */ jsx("div", { ref, className, children: /* @__PURE__ */ jsx(
693
+ Result,
694
+ {
695
+ status: "error",
696
+ title: errorTitle,
697
+ description,
698
+ extra: onRetry && /* @__PURE__ */ jsx(Button, { color: "primary", variant: "bordered", onPress: onRetry, children: "Reintentar" })
699
+ }
700
+ ) });
701
+ }
702
+ if (empty) {
703
+ return /* @__PURE__ */ jsx("div", { ref, className, children: /* @__PURE__ */ jsx(
704
+ Result,
705
+ {
706
+ status: "info",
707
+ title: emptyTitle,
708
+ description: emptyDescription,
709
+ extra: emptyAction
710
+ }
711
+ ) });
712
+ }
713
+ return /* @__PURE__ */ jsx(Fragment, { children });
714
+ });
715
+ QueryState.displayName = "QueryState";
716
+ function SearchFilterBar({
717
+ options,
718
+ selectedOption,
719
+ onOptionChange,
720
+ searchValue,
721
+ onSearchChange,
722
+ searchPlaceholder = "Buscar...",
723
+ className = ""
724
+ }) {
725
+ const [isOpen, setIsOpen] = useState(false);
726
+ const dropdownRef = useRef(null);
727
+ const selectedLabel = useMemo(
728
+ () => options.find((option) => String(option.value) === selectedOption)?.label ?? selectedOption,
729
+ [options, selectedOption]
730
+ );
731
+ useEffect(() => {
732
+ const onClickOutside = (event) => {
733
+ if (!dropdownRef.current) return;
734
+ if (!dropdownRef.current.contains(event.target)) {
735
+ setIsOpen(false);
736
+ }
737
+ };
738
+ document.addEventListener("mousedown", onClickOutside);
739
+ return () => document.removeEventListener("mousedown", onClickOutside);
740
+ }, []);
741
+ return /* @__PURE__ */ jsxs(
742
+ "div",
743
+ {
744
+ className: `flex w-full flex-col gap-3 sm:flex-row sm:items-stretch sm:gap-0 ${className}`,
745
+ children: [
746
+ /* @__PURE__ */ jsxs("div", { className: "relative w-full sm:w-[180px] sm:min-w-[180px]", ref: dropdownRef, children: [
747
+ /* @__PURE__ */ jsxs(
748
+ "button",
749
+ {
750
+ type: "button",
751
+ onClick: () => setIsOpen((prev) => !prev),
752
+ className: "flex h-10 w-full items-center justify-between rounded-md border border-primary-500 bg-white px-4 text-left text-sm font-semibold text-primary-500 sm:rounded-r-none sm:border-r-0",
753
+ "aria-haspopup": "listbox",
754
+ "aria-expanded": isOpen,
755
+ children: [
756
+ /* @__PURE__ */ jsx("span", { className: "text-sm leading-tight", children: selectedLabel }),
757
+ /* @__PURE__ */ jsx(
758
+ "svg",
759
+ {
760
+ className: "h-4 w-4 flex-shrink-0 text-primary-500",
761
+ viewBox: "0 0 20 20",
762
+ fill: "currentColor",
763
+ "aria-hidden": "true",
764
+ children: /* @__PURE__ */ jsx(
765
+ "path",
766
+ {
767
+ fillRule: "evenodd",
768
+ d: "M5.23 7.21a.75.75 0 0 1 1.06.02L10 11.168l3.71-3.938a.75.75 0 1 1 1.08 1.04l-4.25 4.5a.75.75 0 0 1-1.08 0l-4.25-4.5a.75.75 0 0 1 .02-1.06Z",
769
+ clipRule: "evenodd"
770
+ }
771
+ )
772
+ }
773
+ )
774
+ ]
775
+ }
776
+ ),
777
+ isOpen && /* @__PURE__ */ jsx(
778
+ "ul",
779
+ {
780
+ role: "listbox",
781
+ className: "absolute z-20 mt-1 max-h-60 w-full overflow-y-auto rounded-md border border-[#d1d5db] bg-white py-1 shadow-lg",
782
+ children: options.map((option) => {
783
+ const value = String(option.value);
784
+ const isSelected = value === selectedOption;
785
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
786
+ "button",
787
+ {
788
+ type: "button",
789
+ onClick: () => {
790
+ onOptionChange(value);
791
+ setIsOpen(false);
792
+ },
793
+ className: `w-full px-4 py-2 text-left text-sm hover:bg-blue-50 ${isSelected ? "bg-blue-50 font-medium text-primary-500" : "text-[#374151]"}`,
794
+ children: option.label
795
+ }
796
+ ) }, value);
797
+ })
798
+ }
799
+ )
800
+ ] }),
801
+ /* @__PURE__ */ jsx("div", { className: "w-full sm:max-w-[360px] sm:flex-1", children: /* @__PURE__ */ jsxs("div", { className: "relative flex h-10 w-full items-center rounded-md border border-[#d1d5db] bg-white px-4 sm:rounded-l-none", children: [
802
+ /* @__PURE__ */ jsx(
803
+ "input",
804
+ {
805
+ type: "text",
806
+ value: searchValue,
807
+ onChange: (event) => onSearchChange(event.target.value),
808
+ placeholder: searchPlaceholder,
809
+ className: "w-full bg-transparent pr-8 text-sm text-gray-500-500 placeholder:text-[#9ca3af] focus:outline-none"
810
+ }
811
+ ),
812
+ /* @__PURE__ */ jsx(
813
+ FontAwesomeIcon,
814
+ {
815
+ icon: faSearch,
816
+ className: "pointer-events-none absolute right-3 text-[#c4c8d0]"
817
+ }
818
+ )
819
+ ] }) })
820
+ ]
821
+ }
822
+ );
823
+ }
824
+ var sidebarItemVariants = cva(
825
+ [
826
+ "group/sb-item relative flex items-center gap-2.5 text-[13px] cursor-pointer select-none outline-none",
827
+ "pl-8 pr-[18px] py-2",
828
+ "border-l-2 border-l-transparent",
829
+ "transition-colors"
830
+ ],
831
+ {
832
+ variants: {
833
+ active: {
834
+ true: "bg-primary-50 text-primary-500 font-semibold border-l-primary-500",
835
+ false: "text-muted-foreground hover:bg-muted hover:text-foreground"
836
+ },
837
+ disabled: {
838
+ true: "opacity-40 pointer-events-none",
839
+ false: ""
840
+ }
841
+ },
842
+ defaultVariants: { active: false, disabled: false }
843
+ }
844
+ );
845
+ var sidebarGroupLabelVariants = cva(
846
+ "flex items-center justify-between gap-2 px-[18px] pt-3.5 pb-1.5 text-[10.5px] font-semibold uppercase tracking-[0.1em] text-muted-foreground cursor-pointer select-none"
847
+ );
848
+ var sidebarDotVariants = cva("h-[5px] w-[5px] shrink-0 rounded-full transition-colors", {
849
+ variants: {
850
+ active: {
851
+ true: "bg-primary-500 opacity-100",
852
+ false: "bg-muted-foreground opacity-40 group-hover/sb-item:opacity-60"
853
+ }
854
+ },
855
+ defaultVariants: { active: false }
856
+ });
857
+ var sidebarBadgeVariants = cva(
858
+ "ml-auto rounded-full px-[7px] py-px text-[10.5px] font-semibold leading-tight",
859
+ {
860
+ variants: {
861
+ active: {
862
+ true: "bg-background text-primary-500 border border-primary-100",
863
+ false: "bg-muted text-muted-foreground"
864
+ }
865
+ },
866
+ defaultVariants: { active: false }
867
+ }
868
+ );
869
+ function Chevron({ open, className }) {
870
+ return /* @__PURE__ */ jsx(
871
+ "svg",
872
+ {
873
+ viewBox: "0 0 16 16",
874
+ fill: "none",
875
+ "aria-hidden": "true",
876
+ className: cn(
877
+ "h-2.5 w-2.5 shrink-0 transition-transform duration-200",
878
+ open ? "rotate-180" : "",
879
+ className
880
+ ),
881
+ children: /* @__PURE__ */ jsx(
882
+ "path",
883
+ {
884
+ d: "M4 6l4 4 4-4",
885
+ stroke: "currentColor",
886
+ strokeWidth: "1.8",
887
+ strokeLinecap: "round",
888
+ strokeLinejoin: "round"
889
+ }
890
+ )
891
+ }
892
+ );
893
+ }
894
+ function ItemRow({ item, onClick }) {
895
+ const isActive = !!item.active;
896
+ const itemClass = sidebarItemVariants({ active: isActive, disabled: !!item.disabled });
897
+ const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
898
+ item.icon ?? /* @__PURE__ */ jsx("span", { className: sidebarDotVariants({ active: isActive }), "aria-hidden": "true" }),
899
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: item.label }),
900
+ item.badge != null && /* @__PURE__ */ jsx("span", { className: sidebarBadgeVariants({ active: isActive }), children: item.badge })
901
+ ] });
902
+ if (item.href) {
903
+ return /* @__PURE__ */ jsx(
904
+ "a",
905
+ {
906
+ href: item.href,
907
+ "aria-current": isActive ? "page" : void 0,
908
+ "aria-disabled": item.disabled || void 0,
909
+ onClick: (e) => {
910
+ if (item.disabled) e.preventDefault();
911
+ onClick?.(item);
912
+ },
913
+ className: cn(itemClass, "no-underline"),
914
+ children: inner
915
+ }
916
+ );
917
+ }
918
+ return /* @__PURE__ */ jsx(
919
+ "button",
920
+ {
921
+ type: "button",
922
+ disabled: item.disabled,
923
+ "aria-current": isActive ? "page" : void 0,
924
+ onClick: () => onClick?.(item),
925
+ className: cn(itemClass, "w-full bg-transparent text-left"),
926
+ children: inner
927
+ }
928
+ );
929
+ }
930
+ function GroupBlock({ group, onItemClick }) {
931
+ const isCollapsible = group.collapsible ?? true;
932
+ const [open, setOpen] = useState(group.defaultOpen ?? true);
933
+ return /* @__PURE__ */ jsxs("div", { className: "py-1", children: [
934
+ group.label && /* @__PURE__ */ jsxs(
935
+ "div",
936
+ {
937
+ className: sidebarGroupLabelVariants(),
938
+ onClick: isCollapsible ? () => setOpen((v) => !v) : void 0,
939
+ role: isCollapsible ? "button" : void 0,
940
+ "aria-expanded": isCollapsible ? open : void 0,
941
+ children: [
942
+ /* @__PURE__ */ jsx("span", { children: group.label }),
943
+ isCollapsible && /* @__PURE__ */ jsx(Chevron, { open })
944
+ ]
945
+ }
946
+ ),
947
+ (open || !isCollapsible) && /* @__PURE__ */ jsx("div", { className: "flex flex-col", children: group.items.map((item) => /* @__PURE__ */ jsx(ItemRow, { item, onClick: onItemClick }, item.key)) })
948
+ ] });
949
+ }
950
+ var Sidebar = forwardRef(function Sidebar2({
951
+ groups,
952
+ context,
953
+ brand,
954
+ footer,
955
+ onItemClick,
956
+ onCollapsedChange,
957
+ collapsed = false,
958
+ width = 260,
959
+ className
960
+ }, ref) {
961
+ const style = { width };
962
+ const handleItemClick = useCallback(
963
+ (item) => {
964
+ if (item.disabled) return;
965
+ onItemClick?.(item);
966
+ },
967
+ [onItemClick]
968
+ );
969
+ if (collapsed) {
970
+ return /* @__PURE__ */ jsxs(
971
+ "aside",
972
+ {
973
+ ref,
974
+ style: { width: 64 },
975
+ className: cn(
976
+ "flex h-full flex-col overflow-y-auto border-r border-border bg-default-50 py-3.5",
977
+ className
978
+ ),
979
+ children: [
980
+ brand && /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center pb-3", children: brand }),
981
+ onCollapsedChange && /* @__PURE__ */ jsx(
982
+ "button",
983
+ {
984
+ type: "button",
985
+ onClick: () => onCollapsedChange(false),
986
+ "aria-label": "Expandir sidebar",
987
+ className: "mx-auto mb-2 rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground",
988
+ children: /* @__PURE__ */ jsx(Chevron, { open: true, className: "-rotate-90" })
989
+ }
990
+ )
991
+ ]
992
+ }
993
+ );
994
+ }
995
+ return /* @__PURE__ */ jsxs(
996
+ "aside",
997
+ {
998
+ ref,
999
+ style,
1000
+ className: cn(
1001
+ // Canon `.ls-light`: bg, border-right, padding 14 0 24
1002
+ "flex h-full flex-col overflow-y-auto border-r border-border bg-default-50 pt-3.5 pb-6",
1003
+ className
1004
+ ),
1005
+ children: [
1006
+ brand && /* @__PURE__ */ jsx("div", { className: "px-[18px] pb-3", children: brand }),
1007
+ context && /* @__PURE__ */ jsxs("div", { className: "px-[18px] pb-3.5 pt-2", children: [
1008
+ context.label && /* @__PURE__ */ jsx("div", { className: "text-[10.5px] font-semibold uppercase tracking-[0.1em] text-muted-foreground", children: context.label }),
1009
+ /* @__PURE__ */ jsx("div", { className: "mt-1 text-[18px] font-bold leading-tight text-foreground", children: context.title }),
1010
+ context.sub && /* @__PURE__ */ jsx("div", { className: "mt-0.5 text-xs text-muted-foreground", children: context.sub })
1011
+ ] }),
1012
+ /* @__PURE__ */ jsx("nav", { className: "flex-1", children: groups.map((group) => /* @__PURE__ */ jsx(GroupBlock, { group, onItemClick: handleItemClick }, group.key)) }),
1013
+ footer && /* @__PURE__ */ jsx("div", { className: "mt-2 border-t border-border px-[18px] pt-3 text-xs text-muted-foreground", children: footer })
1014
+ ]
1015
+ }
1016
+ );
1017
+ });
1018
+ Sidebar.displayName = "Sidebar";
1019
+ var Toaster = forwardRef(function Toaster2({ className, position = "top-right", theme = "light", ...rest }, _ref) {
1020
+ return /* @__PURE__ */ jsx(
1021
+ Toaster$1,
1022
+ {
1023
+ position,
1024
+ theme,
1025
+ richColors: false,
1026
+ closeButton: true,
1027
+ toastOptions: {
1028
+ classNames: {
1029
+ toast: cn(
1030
+ // Canon `.toast`: grid icon · texto · acción, bg-background,
1031
+ // border, radius-md, padding 14/16, shadow-lg, items-start.
1032
+ "group toast",
1033
+ "group-[.toaster]:grid group-[.toaster]:grid-cols-[18px_1fr_auto] group-[.toaster]:gap-3 group-[.toaster]:items-start",
1034
+ "group-[.toaster]:bg-background group-[.toaster]:text-foreground",
1035
+ "group-[.toaster]:border group-[.toaster]:border-border",
1036
+ "group-[.toaster]:rounded-md group-[.toaster]:px-4 group-[.toaster]:py-3.5",
1037
+ "group-[.toaster]:shadow-lg",
1038
+ className
1039
+ ),
1040
+ title: "text-sm font-semibold text-foreground",
1041
+ description: "group-[.toast]:text-sm group-[.toast]:text-muted-foreground",
1042
+ actionButton: "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground group-[.toast]:rounded-sm group-[.toast]:px-2.5 group-[.toast]:py-1 group-[.toast]:text-[13px] group-[.toast]:font-semibold",
1043
+ cancelButton: "group-[.toast]:bg-muted group-[.toast]:text-foreground group-[.toast]:rounded-sm group-[.toast]:px-2.5 group-[.toast]:py-1 group-[.toast]:text-[13px]",
1044
+ closeButton: "group-[.toast]:border-border group-[.toast]:bg-background group-[.toast]:text-muted-foreground hover:group-[.toast]:text-foreground",
1045
+ // Variantes — paletas semánticas AgroShine (no `richColors`)
1046
+ success: "group-[.toaster]:bg-success-50 group-[.toaster]:text-success-700 group-[.toaster]:border-success-200",
1047
+ error: "group-[.toaster]:bg-danger-50 group-[.toaster]:text-danger-700 group-[.toaster]:border-danger-200",
1048
+ warning: "group-[.toaster]:bg-warning-50 group-[.toaster]:text-warning-800 group-[.toaster]:border-warning-200",
1049
+ info: "group-[.toaster]:bg-primary-50 group-[.toaster]:text-primary-700 group-[.toaster]:border-primary-200"
1050
+ }
1051
+ },
1052
+ ...rest
1053
+ }
1054
+ );
1055
+ });
1056
+ Toaster.displayName = "Toaster";
1057
+ var TreeNodeRow = ({
1058
+ node,
1059
+ level,
1060
+ expandedSet,
1061
+ selectedKey,
1062
+ showLine,
1063
+ onToggle,
1064
+ onSelect
1065
+ }) => {
1066
+ const hasChildren = !!node.children && node.children.length > 0;
1067
+ const isExpanded = expandedSet.has(node.key);
1068
+ const isSelected = selectedKey === node.key;
1069
+ const selectable = node.selectable !== false && !node.disabled;
1070
+ return /* @__PURE__ */ jsxs("div", { className: cn(showLine && level > 0 && "ml-3 border-l border-border pl-1"), children: [
1071
+ /* @__PURE__ */ jsxs(
1072
+ "div",
1073
+ {
1074
+ role: selectable ? "button" : void 0,
1075
+ tabIndex: selectable ? 0 : -1,
1076
+ onClick: () => {
1077
+ if (hasChildren) onToggle(node.key);
1078
+ if (selectable) onSelect?.(node.key, node);
1079
+ },
1080
+ onKeyDown: (e) => {
1081
+ if (e.key === "Enter" || e.key === " ") {
1082
+ e.preventDefault();
1083
+ if (hasChildren) onToggle(node.key);
1084
+ if (selectable) onSelect?.(node.key, node);
1085
+ }
1086
+ },
1087
+ style: { paddingLeft: `${level * 20 + 6}px` },
1088
+ className: cn(
1089
+ "flex items-center gap-1.5 rounded-sm px-1.5 py-1.5 text-sm transition-colors",
1090
+ selectable && "cursor-pointer hover:bg-muted",
1091
+ isSelected && "bg-primary-50 font-medium text-primary-700",
1092
+ node.disabled && "cursor-not-allowed opacity-50"
1093
+ ),
1094
+ children: [
1095
+ /* @__PURE__ */ jsx(
1096
+ ChevronRight,
1097
+ {
1098
+ "aria-hidden": "true",
1099
+ className: cn(
1100
+ "h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform duration-150",
1101
+ isExpanded && "rotate-90",
1102
+ !hasChildren && "invisible"
1103
+ )
1104
+ }
1105
+ ),
1106
+ node.icon && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-sm", children: node.icon }),
1107
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: node.title })
1108
+ ]
1109
+ }
1110
+ ),
1111
+ hasChildren && isExpanded && /* @__PURE__ */ jsx("div", { className: "flex flex-col", children: node.children.map((child) => /* @__PURE__ */ jsx(
1112
+ TreeNodeRow,
1113
+ {
1114
+ node: child,
1115
+ level: level + 1,
1116
+ expandedSet,
1117
+ selectedKey,
1118
+ showLine,
1119
+ onToggle,
1120
+ onSelect
1121
+ },
1122
+ child.key
1123
+ )) })
1124
+ ] });
1125
+ };
1126
+ var Tree = forwardRef(function Tree2({ data, defaultExpanded, expanded, onExpandedChange, selectedKey, onSelect, showLine, className }, ref) {
1127
+ const [internal, setInternal] = useState(defaultExpanded ?? []);
1128
+ const current = expanded ?? internal;
1129
+ const set = useMemo(() => new Set(current), [current]);
1130
+ const handleToggle = useCallback(
1131
+ (key) => {
1132
+ const next = set.has(key) ? current.filter((k) => k !== key) : [...current, key];
1133
+ if (expanded === void 0) setInternal(next);
1134
+ onExpandedChange?.(next);
1135
+ },
1136
+ [current, expanded, onExpandedChange, set]
1137
+ );
1138
+ return /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col text-sm text-foreground", className), children: data.map((node) => /* @__PURE__ */ jsx(
1139
+ TreeNodeRow,
1140
+ {
1141
+ node,
1142
+ level: 0,
1143
+ expandedSet: set,
1144
+ selectedKey,
1145
+ showLine,
1146
+ onToggle: handleToggle,
1147
+ onSelect
1148
+ },
1149
+ node.key
1150
+ )) });
1151
+ });
1152
+ Tree.displayName = "Tree";
1153
+
1154
+ export { Accordion2 as Accordion, BrandLogo, Content, DEFAULT_FORMAT, DEFAULT_FORMATS, DatePicker, FarmChip, FormCard, Header, Layout, PageHeader, PickerPanel, QueryState, RangePicker, Result, SearchBox, SearchFilterBar, Sidebar, Toaster, Tree, UserAvatar };
1155
+ //# sourceMappingURL=chunk-JTFCE6RA.js.map
1156
+ //# sourceMappingURL=chunk-JTFCE6RA.js.map