@doscientos/ui 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -32,12 +32,12 @@ function useAutosave({
32
32
  }, []);
33
33
  useEffect(() => {
34
34
  if (!enabled) return;
35
- const snapshot = serializeRef.current(data);
35
+ const snapshot2 = serializeRef.current(data);
36
36
  if (lastSaved.current === null) {
37
- lastSaved.current = snapshot;
37
+ lastSaved.current = snapshot2;
38
38
  return;
39
39
  }
40
- if (snapshot === lastSaved.current) return;
40
+ if (snapshot2 === lastSaved.current) return;
41
41
  const timeout = window.setTimeout(() => void save(data), debounceMs);
42
42
  return () => window.clearTimeout(timeout);
43
43
  }, [data, debounceMs, enabled, save]);
@@ -141,9 +141,90 @@ function getTextMatchParts(text, query) {
141
141
  return parts.length ? parts : [{ text, match: false }];
142
142
  }
143
143
 
144
- // src/ui/badge.tsx
144
+ // src/ui/accordion/accordion.tsx
145
+ import { Disclosure as AriaDisclosure, DisclosureGroup as AriaDisclosureGroup, DisclosurePanel as AriaDisclosurePanel, Button } from "react-aria-components";
146
+ import { CaretDownIcon } from "@phosphor-icons/react";
147
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
148
+ function Accordion({ className, ...props }) {
149
+ return /* @__PURE__ */ jsx(AriaDisclosureGroup, { "data-slot": "accordion", className: cn("flex w-full flex-col", className), ...props });
150
+ }
151
+ function AccordionItem({ className, ...props }) {
152
+ return /* @__PURE__ */ jsx(AriaDisclosure, { "data-slot": "accordion-item", className: cn("border-b border-border last:border-0", className), ...props });
153
+ }
154
+ function AccordionTrigger({ className, children, ...props }) {
155
+ return /* @__PURE__ */ jsx(Button, { "data-slot": "accordion-trigger", className: cn("group/accordion-trigger flex w-full items-center justify-between py-3 text-left text-sm font-medium outline-none transition-colors hover:text-primary focus-visible:ring-3 focus-visible:ring-ring/50", className), ...props, children: (values) => /* @__PURE__ */ jsxs(Fragment, { children: [
156
+ /* @__PURE__ */ jsx("span", { children: typeof children === "function" ? children(values) : children }),
157
+ /* @__PURE__ */ jsx(CaretDownIcon, { "aria-hidden": "true", weight: "bold", className: "size-4 transition-transform group-data-expanded/accordion-trigger:rotate-180 motion-reduce:transition-none" })
158
+ ] }) });
159
+ }
160
+ function AccordionContent({ className, ...props }) {
161
+ return /* @__PURE__ */ jsx(AriaDisclosurePanel, { "data-slot": "accordion-content", className: cn("overflow-hidden pb-3 text-sm text-muted-foreground", className), ...props });
162
+ }
163
+
164
+ // src/ui/alert/alert.tsx
165
+ import { jsx as jsx2 } from "react/jsx-runtime";
166
+ var variants = {
167
+ default: "border-border bg-card text-foreground",
168
+ destructive: "border-destructive/30 bg-destructive/5 text-destructive",
169
+ success: "border-success/30 bg-success/5 text-success",
170
+ warning: "border-warning/30 bg-warning/5 text-warning"
171
+ };
172
+ function Alert({ className, variant = "default", ...props }) {
173
+ return /* @__PURE__ */ jsx2("div", { role: "alert", "data-slot": "alert", "data-variant": variant, className: cn("grid w-full gap-1 rounded-lg border px-3 py-2.5 text-sm [&>svg]:size-4", variants[variant], className), ...props });
174
+ }
175
+ function AlertTitle({ className, ...props }) {
176
+ return /* @__PURE__ */ jsx2("div", { "data-slot": "alert-title", className: cn("font-medium", className), ...props });
177
+ }
178
+ function AlertDescription({ className, ...props }) {
179
+ return /* @__PURE__ */ jsx2("div", { "data-slot": "alert-description", className: cn("text-sm opacity-90", className), ...props });
180
+ }
181
+ function AlertAction({ className, children, ...props }) {
182
+ return /* @__PURE__ */ jsx2("div", { "data-slot": "alert-action", className: cn("absolute top-2 right-2", className), ...props, children });
183
+ }
184
+
185
+ // src/ui/app-shell/app-shell.tsx
186
+ import { jsx as jsx3 } from "react/jsx-runtime";
187
+ function AppShell({ className, ...props }) {
188
+ return /* @__PURE__ */ jsx3("div", { "data-slot": "app-shell", className: cn("flex min-h-screen w-full bg-muted/30 text-foreground", className), ...props });
189
+ }
190
+ function AppShellMain({ className, ...props }) {
191
+ return /* @__PURE__ */ jsx3("main", { "data-slot": "app-shell-main", className: cn("min-w-0 flex-1", className), ...props });
192
+ }
193
+ function AppShellHeader({ className, ...props }) {
194
+ return /* @__PURE__ */ jsx3("header", { "data-slot": "app-shell-header", className: cn("sticky top-0 z-10 flex min-h-14 items-center border-b border-border bg-background/85 px-4 backdrop-blur-md supports-[backdrop-filter]:bg-background/70", className), ...props });
195
+ }
196
+ function AppShellContent({ className, ...props }) {
197
+ return /* @__PURE__ */ jsx3("div", { "data-slot": "app-shell-content", className: cn("mx-auto w-full max-w-[1600px] p-4 md:p-6", className), ...props });
198
+ }
199
+
200
+ // src/ui/avatar/avatar.tsx
201
+ import { useState as useState4 } from "react";
202
+ import { jsx as jsx4 } from "react/jsx-runtime";
203
+ var sizes = { xs: "size-5 text-[10px]", sm: "size-6 text-xs", default: "size-8 text-sm", lg: "size-10 text-base" };
204
+ function Avatar({ className, size = "default", ...props }) {
205
+ return /* @__PURE__ */ jsx4("div", { "data-slot": "avatar", "data-size": size, className: cn("group/avatar relative flex shrink-0 overflow-hidden rounded-full bg-muted text-muted-foreground", sizes[size], className), ...props });
206
+ }
207
+ function AvatarImage({ className, ...props }) {
208
+ const [failed, setFailed] = useState4(false);
209
+ if (failed) return null;
210
+ return /* @__PURE__ */ jsx4("img", { "data-slot": "avatar-image", className: cn("aspect-square size-full object-cover", className), onError: () => setFailed(true), ...props });
211
+ }
212
+ function AvatarFallback({ className, ...props }) {
213
+ return /* @__PURE__ */ jsx4("span", { "data-slot": "avatar-fallback", className: cn("flex size-full items-center justify-center font-medium", className), ...props });
214
+ }
215
+ function AvatarBadge({ className, ...props }) {
216
+ return /* @__PURE__ */ jsx4("span", { "data-slot": "avatar-badge", className: cn("absolute right-0 bottom-0 size-2.5 rounded-full bg-success ring-2 ring-background", className), ...props });
217
+ }
218
+ function AvatarGroup({ className, ...props }) {
219
+ return /* @__PURE__ */ jsx4("div", { "data-slot": "avatar-group", className: cn("flex -space-x-2 [&>[data-slot=avatar]]:ring-2 [&>[data-slot=avatar]]:ring-background", className), ...props });
220
+ }
221
+ function AvatarGroupCount({ className, ...props }) {
222
+ return /* @__PURE__ */ jsx4("span", { "data-slot": "avatar-group-count", className: cn("flex size-8 items-center justify-center rounded-full bg-muted text-xs font-medium text-muted-foreground ring-2 ring-background", className), ...props });
223
+ }
224
+
225
+ // src/ui/badge/badge.tsx
145
226
  import { cva } from "class-variance-authority";
146
- import { jsx } from "react/jsx-runtime";
227
+ import { jsx as jsx5 } from "react/jsx-runtime";
147
228
  var badgeVariants = cva("inline-flex w-fit items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium", {
148
229
  variants: {
149
230
  variant: {
@@ -159,15 +240,34 @@ var badgeVariants = cva("inline-flex w-fit items-center gap-1 rounded-full px-2
159
240
  defaultVariants: { variant: "default" }
160
241
  });
161
242
  function Badge({ className, variant, ...props }) {
162
- return /* @__PURE__ */ jsx("span", { "data-slot": "badge", className: cn(badgeVariants({ variant }), className), ...props });
243
+ return /* @__PURE__ */ jsx5("span", { "data-slot": "badge", className: cn(badgeVariants({ variant }), className), ...props });
244
+ }
245
+
246
+ // src/ui/breadcrumb/breadcrumb.tsx
247
+ import { Breadcrumb as AriaBreadcrumb, Breadcrumbs as AriaBreadcrumbs, Link as AriaLink } from "react-aria-components";
248
+ import { jsx as jsx6 } from "react/jsx-runtime";
249
+ function Breadcrumbs({ className, ...props }) {
250
+ return /* @__PURE__ */ jsx6(AriaBreadcrumbs, { "data-slot": "breadcrumbs", className: cn("flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground", className), ...props });
251
+ }
252
+ function Breadcrumb({ className, ...props }) {
253
+ return /* @__PURE__ */ jsx6(AriaBreadcrumb, { "data-slot": "breadcrumb", className: cn("inline-flex items-center gap-1.5", className), ...props });
254
+ }
255
+ function BreadcrumbLink({ className, ...props }) {
256
+ return /* @__PURE__ */ jsx6(AriaLink, { "data-slot": "breadcrumb-link", className: cn("transition-colors hover:text-foreground", className), ...props });
257
+ }
258
+ function BreadcrumbPage({ className, ...props }) {
259
+ return /* @__PURE__ */ jsx6("span", { "data-slot": "breadcrumb-page", "aria-current": "page", className: cn("font-medium text-foreground", className), ...props });
260
+ }
261
+ function BreadcrumbSeparator({ children = "/", className, ...props }) {
262
+ return /* @__PURE__ */ jsx6("span", { "data-slot": "breadcrumb-separator", "aria-hidden": "true", className: cn("text-muted-foreground/60", className), ...props, children });
163
263
  }
164
264
 
165
- // src/ui/button.tsx
265
+ // src/ui/button/button.tsx
166
266
  import { cva as cva2 } from "class-variance-authority";
167
267
  import { Button as AriaButton } from "react-aria-components";
168
- import { jsx as jsx2 } from "react/jsx-runtime";
268
+ import { jsx as jsx7 } from "react/jsx-runtime";
169
269
  var buttonVariants = cva2(
170
- "inline-flex shrink-0 items-center justify-center gap-1.5 rounded-lg border border-transparent text-sm font-medium whitespace-nowrap transition-colors outline-none focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
270
+ "inline-flex shrink-0 cursor-pointer items-center justify-center gap-1.5 rounded-lg border border-transparent text-sm font-medium whitespace-nowrap transition-[background-color,border-color,color,box-shadow,transform] duration-150 outline-none focus-visible:ring-3 focus-visible:ring-ring/50 data-pressed:scale-[0.98] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 motion-reduce:transition-none motion-reduce:data-pressed:transform-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
171
271
  {
172
272
  variants: {
173
273
  variant: {
@@ -189,306 +289,955 @@ var buttonVariants = cva2(
189
289
  defaultVariants: { variant: "default", size: "default" }
190
290
  }
191
291
  );
192
- function Button({ className, variant, size, ...props }) {
193
- return /* @__PURE__ */ jsx2(AriaButton, { "data-slot": "button", className: cn(buttonVariants({ variant, size }), className), ...props });
292
+ function Button2({ className, variant, size, ...props }) {
293
+ return /* @__PURE__ */ jsx7(AriaButton, { "data-slot": "button", className: cn(buttonVariants({ variant, size }), className), ...props });
194
294
  }
195
295
 
196
- // src/ui/card.tsx
197
- import { jsx as jsx3 } from "react/jsx-runtime";
296
+ // src/ui/button-group/button-group.tsx
297
+ import { jsx as jsx8 } from "react/jsx-runtime";
298
+ function ButtonGroup({ className, ...props }) {
299
+ return /* @__PURE__ */ jsx8("div", { role: "group", "data-slot": "button-group", className: cn("inline-flex items-center gap-2", className), ...props });
300
+ }
301
+ function ButtonGroupText({ className, ...props }) {
302
+ return /* @__PURE__ */ jsx8("span", { "data-slot": "button-group-text", className: cn("text-sm text-muted-foreground", className), ...props });
303
+ }
304
+
305
+ // src/ui/card/card.tsx
306
+ import { jsx as jsx9 } from "react/jsx-runtime";
198
307
  function Card({ className, ...props }) {
199
- return /* @__PURE__ */ jsx3("section", { "data-slot": "card", className: cn("rounded-xl border border-border bg-card text-foreground shadow-sm", className), ...props });
308
+ return /* @__PURE__ */ jsx9("section", { "data-slot": "card", className: cn("rounded-xl border border-border bg-card text-foreground shadow-sm", className), ...props });
200
309
  }
201
310
  function CardHeader({ className, ...props }) {
202
- return /* @__PURE__ */ jsx3("header", { "data-slot": "card-header", className: cn("flex flex-col gap-1.5 p-5", className), ...props });
311
+ return /* @__PURE__ */ jsx9("header", { "data-slot": "card-header", className: cn("flex flex-col gap-1.5 p-5", className), ...props });
203
312
  }
204
313
  function CardTitle({ className, ...props }) {
205
- return /* @__PURE__ */ jsx3("h2", { "data-slot": "card-title", className: cn("text-base font-semibold", className), ...props });
314
+ return /* @__PURE__ */ jsx9("h2", { "data-slot": "card-title", className: cn("text-base font-semibold", className), ...props });
206
315
  }
207
316
  function CardDescription({ className, ...props }) {
208
- return /* @__PURE__ */ jsx3("p", { "data-slot": "card-description", className: cn("text-sm text-muted-foreground", className), ...props });
317
+ return /* @__PURE__ */ jsx9("p", { "data-slot": "card-description", className: cn("text-sm text-muted-foreground", className), ...props });
209
318
  }
210
319
  function CardContent({ className, ...props }) {
211
- return /* @__PURE__ */ jsx3("div", { "data-slot": "card-content", className: cn("p-5 pt-0", className), ...props });
320
+ return /* @__PURE__ */ jsx9("div", { "data-slot": "card-content", className: cn("p-5 pt-0", className), ...props });
212
321
  }
213
322
  function CardFooter({ className, ...props }) {
214
- return /* @__PURE__ */ jsx3("footer", { "data-slot": "card-footer", className: cn("flex items-center gap-2 border-t border-border p-5", className), ...props });
323
+ return /* @__PURE__ */ jsx9("footer", { "data-slot": "card-footer", className: cn("flex items-center gap-2 border-t border-border p-5", className), ...props });
215
324
  }
216
325
 
217
- // src/ui/checkbox.tsx
326
+ // src/ui/checkbox/checkbox.tsx
218
327
  import {
219
328
  Checkbox as AriaCheckbox
220
329
  } from "react-aria-components";
221
- import { Fragment, jsx as jsx4, jsxs } from "react/jsx-runtime";
330
+ import { CheckIcon } from "@phosphor-icons/react";
331
+ import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs2 } from "react/jsx-runtime";
222
332
  function Checkbox({ className, children, ...props }) {
223
- return /* @__PURE__ */ jsx4(AriaCheckbox, { "data-slot": "checkbox", className: cn("group inline-flex items-center gap-2 text-sm text-foreground data-disabled:cursor-not-allowed data-disabled:opacity-50", className), ...props, children: (state) => /* @__PURE__ */ jsxs(Fragment, { children: [
224
- /* @__PURE__ */ jsx4("span", { "aria-hidden": "true", className: "grid size-4 place-items-center rounded border border-border bg-background text-xs text-primary-foreground group-data-selected:border-primary group-data-selected:bg-primary group-data-focus-visible:ring-3 group-data-focus-visible:ring-ring/50", children: "\u2713" }),
333
+ return /* @__PURE__ */ jsx10(AriaCheckbox, { "data-slot": "checkbox", className: cn("group inline-flex items-center gap-2 text-sm text-foreground data-disabled:cursor-not-allowed data-disabled:opacity-50", className), ...props, children: (state) => /* @__PURE__ */ jsxs2(Fragment2, { children: [
334
+ /* @__PURE__ */ jsx10("span", { "aria-hidden": "true", className: "grid size-4 place-items-center rounded border border-border bg-background text-primary-foreground transition-colors group-data-selected:border-primary group-data-selected:bg-primary group-data-focus-visible:ring-3 group-data-focus-visible:ring-ring/50", children: /* @__PURE__ */ jsx10(CheckIcon, { weight: "bold", className: "size-3 opacity-0 transition-opacity group-data-selected:opacity-100 motion-reduce:transition-none" }) }),
225
335
  typeof children === "function" ? children(state) : children
226
336
  ] }) });
227
337
  }
228
338
 
229
- // src/ui/combobox.tsx
230
- import { Fragment as Fragment2 } from "react";
231
- import {
232
- ComboBox as AriaComboBox,
233
- ComboBoxValue,
234
- Input,
235
- ListBox,
236
- ListBoxItem,
237
- Popover
238
- } from "react-aria-components";
239
- import { jsx as jsx5 } from "react/jsx-runtime";
339
+ // src/ui/combobox/combobox.tsx
340
+ import { Fragment as Fragment3, useMemo, useState as useState5 } from "react";
341
+ import { ComboBox as AriaComboBox, ComboBoxValue, FieldError, Input, Label, ListBox, ListBoxItem, Popover, Text } from "react-aria-components";
342
+ import { jsx as jsx11, jsxs as jsxs3 } from "react/jsx-runtime";
240
343
  var Combobox = AriaComboBox;
241
344
  function ComboboxInput({ className, ...props }) {
242
- return /* @__PURE__ */ jsx5(Input, { "data-slot": "combobox-input", className: cn("h-8 w-full rounded-lg border border-border bg-background px-2.5 text-sm text-foreground outline-none placeholder:text-muted-foreground focus-visible:ring-3 focus-visible:ring-ring/50", className), ...props });
345
+ return /* @__PURE__ */ jsx11(Input, { "data-slot": "combobox-input", className: cn("h-9 w-full rounded-lg border border-border bg-background px-2.5 text-sm text-foreground outline-none placeholder:text-muted-foreground focus-visible:ring-3 focus-visible:ring-ring/50", className), ...props });
243
346
  }
244
347
  function ComboboxContent({ className, ...props }) {
245
- return /* @__PURE__ */ jsx5(Popover, { "data-slot": "combobox-content", className: cn("max-h-72 w-(--trigger-width) overflow-hidden rounded-xl border border-border bg-background p-1.5 text-foreground shadow-lg", className), ...props });
348
+ return /* @__PURE__ */ jsx11(Popover, { "data-slot": "combobox-content", className: cn("max-h-72 w-(--trigger-width) overflow-hidden rounded-xl border border-border bg-background p-1.5 text-foreground shadow-lg motion-safe:data-entering:animate-ui-surface-in motion-safe:data-exiting:animate-ui-surface-out", className), ...props });
246
349
  }
247
350
  function ComboboxList({ className, emptyState, ...props }) {
248
- return /* @__PURE__ */ jsx5(ListBox, { "data-slot": "combobox-list", className: cn("max-h-64 overflow-y-auto", className), renderEmptyState: emptyState ? () => emptyState : void 0, ...props });
351
+ return /* @__PURE__ */ jsx11(ListBox, { "data-slot": "combobox-list", className: cn("max-h-64 overflow-y-auto", className), renderEmptyState: emptyState ? () => emptyState : void 0, ...props });
249
352
  }
250
353
  function ComboboxItem({ className, children, ...props }) {
251
- return /* @__PURE__ */ jsx5(ListBoxItem, { "data-slot": "combobox-item", className: cn("flex w-full cursor-default items-center justify-between rounded-md px-2 py-1.5 text-sm outline-none data-focused:bg-muted data-disabled:pointer-events-none data-disabled:opacity-50", className), ...props, children });
354
+ return /* @__PURE__ */ jsx11(ListBoxItem, { "data-slot": "combobox-item", className: cn("flex w-full cursor-default items-center justify-between rounded-md px-2 py-2 text-sm outline-none transition-colors data-focused:bg-muted data-focused:text-foreground data-hovered:bg-muted data-disabled:pointer-events-none data-disabled:opacity-50", className), ...props, children });
252
355
  }
253
356
  function HighlightMatch({ text, query, className }) {
254
- return /* @__PURE__ */ jsx5("span", { className, children: getTextMatchParts(text, query).map((part, index) => part.match ? /* @__PURE__ */ jsx5("mark", { className: "rounded bg-accent px-0.5 text-accent-foreground", children: part.text }, `${part.text}-${index}`) : /* @__PURE__ */ jsx5(Fragment2, { children: part.text }, `${part.text}-${index}`)) });
357
+ return /* @__PURE__ */ jsx11("span", { className, children: getTextMatchParts(text, query).map((part, index) => part.match ? /* @__PURE__ */ jsx11("mark", { className: "rounded bg-accent px-0.5 text-accent-foreground", children: part.text }, `${part.text}-${index}`) : /* @__PURE__ */ jsx11(Fragment3, { children: part.text }, `${part.text}-${index}`)) });
358
+ }
359
+ function AutocompleteCombobox({ items, getItemKey, getItemLabel, renderItem, inputValue: controlledInputValue, onInputChange, selectedKey, onSelectionChange, label, description, errorMessage, emptyState = /* @__PURE__ */ jsx11("p", { className: "px-3 py-7 text-center text-sm text-muted-foreground", children: "No hay resultados." }), suggestion = true, placeholder, className, onKeyDown: _onKeyDown, ...props }) {
360
+ const [internalInputValue, setInternalInputValue] = useState5("");
361
+ const inputValue = controlledInputValue ?? internalInputValue;
362
+ const setInputValue = (value) => {
363
+ setInternalInputValue(value);
364
+ onInputChange?.(value);
365
+ };
366
+ const normalizedQuery = inputValue.trim().toLocaleLowerCase();
367
+ const filteredItems = useMemo(() => normalizedQuery ? items.filter((item) => getItemLabel(item).toLocaleLowerCase().includes(normalizedQuery)) : [...items], [getItemLabel, items, normalizedQuery]);
368
+ const suggestedItem = useMemo(() => !suggestion || !normalizedQuery ? void 0 : items.find((item) => getItemLabel(item).toLocaleLowerCase().startsWith(normalizedQuery) && getItemLabel(item).length > inputValue.length), [getItemLabel, inputValue.length, items, normalizedQuery, suggestion]);
369
+ const suggestionLabel = suggestedItem ? getItemLabel(suggestedItem) : void 0;
370
+ const acceptSuggestion = () => {
371
+ if (!suggestedItem || !suggestionLabel) return false;
372
+ setInputValue(suggestionLabel);
373
+ onSelectionChange?.(getItemKey(suggestedItem), suggestedItem);
374
+ return true;
375
+ };
376
+ const handleKeyDown = (event) => {
377
+ if ((event.key === "Tab" || event.key === "Enter") && acceptSuggestion()) event.preventDefault();
378
+ };
379
+ return /* @__PURE__ */ jsxs3(AriaComboBox, { ...props, className: cn("group/combobox flex w-full flex-col gap-1.5", className), items: filteredItems, selectedKey, inputValue, onInputChange: setInputValue, onSelectionChange: (key) => {
380
+ const item = filteredItems.find((candidate) => String(getItemKey(candidate)) === String(key));
381
+ if (item) setInputValue(getItemLabel(item));
382
+ onSelectionChange?.(key, item);
383
+ }, children: [
384
+ label && /* @__PURE__ */ jsx11(Label, { className: "text-sm font-medium text-foreground", children: label }),
385
+ /* @__PURE__ */ jsxs3("div", { className: "relative", children: [
386
+ suggestionLabel && /* @__PURE__ */ jsxs3("span", { "aria-hidden": "true", className: "pointer-events-none absolute inset-y-0 left-2.5 z-0 flex items-center whitespace-pre text-sm text-muted-foreground/60", children: [
387
+ /* @__PURE__ */ jsx11("span", { className: "text-transparent", children: inputValue }),
388
+ suggestionLabel.slice(inputValue.length)
389
+ ] }),
390
+ /* @__PURE__ */ jsx11(ComboboxInput, { "aria-autocomplete": suggestionLabel ? "both" : "list", placeholder, onKeyDown: handleKeyDown, className: "relative z-10 bg-transparent" })
391
+ ] }),
392
+ description && /* @__PURE__ */ jsx11(Text, { slot: "description", className: "text-xs text-muted-foreground", children: description }),
393
+ errorMessage && /* @__PURE__ */ jsx11(FieldError, { className: "text-xs text-destructive", children: errorMessage }),
394
+ /* @__PURE__ */ jsx11(ComboboxContent, { children: /* @__PURE__ */ jsx11(ComboboxList, { emptyState, children: (item) => /* @__PURE__ */ jsx11(ComboboxItem, { id: getItemKey(item), textValue: getItemLabel(item), children: renderItem ? renderItem(item, inputValue) : /* @__PURE__ */ jsx11(HighlightMatch, { text: getItemLabel(item), query: inputValue }) }) }) })
395
+ ] });
255
396
  }
256
397
 
257
- // src/ui/dialog.tsx
398
+ // src/ui/command/command.tsx
399
+ import { ComboBox as AriaComboBox2, Input as AriaInput, ListBox as ListBox2, ListBoxItem as ListBoxItem2, Popover as Popover2 } from "react-aria-components";
400
+ import { jsx as jsx12 } from "react/jsx-runtime";
401
+ function Command({ className, ...props }) {
402
+ return /* @__PURE__ */ jsx12(AriaComboBox2, { "data-slot": "command", className: cn("w-full", className), ...props });
403
+ }
404
+ function CommandInput({ className, ...props }) {
405
+ return /* @__PURE__ */ jsx12(AriaInput, { "data-slot": "command-input", className: cn("h-9 w-full border-0 bg-transparent px-3 text-sm text-foreground outline-none placeholder:text-muted-foreground", className), ...props });
406
+ }
407
+ function CommandContent({ className, ...props }) {
408
+ return /* @__PURE__ */ jsx12(Popover2, { "data-slot": "command-content", className: cn("w-(--trigger-width) overflow-hidden rounded-xl border border-border bg-background p-1.5 shadow-lg outline-none", className), ...props });
409
+ }
410
+ function CommandList({ className, ...props }) {
411
+ return /* @__PURE__ */ jsx12(ListBox2, { "data-slot": "command-list", className: cn("max-h-72 overflow-y-auto", className), ...props });
412
+ }
413
+ function CommandItem({ className, ...props }) {
414
+ return /* @__PURE__ */ jsx12(ListBoxItem2, { "data-slot": "command-item", className: cn("flex cursor-default items-center rounded-md px-2 py-1.5 text-sm outline-none data-focused:bg-muted data-disabled:pointer-events-none data-disabled:opacity-50", className), ...props });
415
+ }
416
+
417
+ // src/ui/dialog/dialog.tsx
258
418
  import { createContext, useContext } from "react";
419
+ import { XIcon } from "@phosphor-icons/react";
259
420
  import {
260
421
  Dialog as AriaDialog,
261
422
  Heading,
262
423
  Modal,
263
424
  ModalOverlay,
264
- Text
425
+ Text as Text2
265
426
  } from "react-aria-components";
266
- import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
427
+ import { jsx as jsx13, jsxs as jsxs4 } from "react/jsx-runtime";
267
428
  var DialogCloseContext = createContext(null);
268
429
  function Dialog({ open, children, ...props }) {
269
- return /* @__PURE__ */ jsx6(ModalOverlay, { isOpen: open, className: "fixed inset-0 z-50 grid place-items-center bg-black/20 p-4 backdrop-blur-[1px]", ...props, children });
430
+ return /* @__PURE__ */ jsx13(ModalOverlay, { isOpen: open, className: "fixed inset-0 z-50 grid place-items-center bg-black/20 p-4 backdrop-blur-[1px] motion-safe:data-entering:animate-ui-overlay-in motion-safe:data-exiting:animate-ui-overlay-out", ...props, children });
270
431
  }
271
432
  function DialogClose({ onPress, ...props }) {
272
433
  const close = useContext(DialogCloseContext);
273
- return /* @__PURE__ */ jsx6(Button, { onPress: (event) => {
434
+ return /* @__PURE__ */ jsx13(Button2, { onPress: (event) => {
274
435
  onPress?.(event);
275
436
  close?.();
276
437
  }, ...props });
277
438
  }
278
439
  function DialogContent({ className, children, showCloseButton = true, ...props }) {
279
- return /* @__PURE__ */ jsx6(Modal, { className: "w-full max-w-md outline-none", children: /* @__PURE__ */ jsx6(AriaDialog, { "data-slot": "dialog-content", className: cn("relative grid max-h-[calc(100dvh-2rem)] gap-4 overflow-y-auto rounded-xl bg-background p-5 text-foreground shadow-xl outline-none", className), ...props, children: ({ close }) => /* @__PURE__ */ jsxs2(DialogCloseContext.Provider, { value: close, children: [
440
+ return /* @__PURE__ */ jsx13(Modal, { className: "w-full max-w-md outline-none motion-safe:data-entering:animate-ui-surface-in motion-safe:data-exiting:animate-ui-surface-out", children: /* @__PURE__ */ jsx13(AriaDialog, { "data-slot": "dialog-content", className: cn("relative grid max-h-[calc(100dvh-2rem)] gap-4 overflow-y-auto rounded-xl bg-background p-5 text-foreground shadow-xl outline-none", className), ...props, children: ({ close }) => /* @__PURE__ */ jsxs4(DialogCloseContext.Provider, { value: close, children: [
280
441
  typeof children === "function" ? children({ close }) : children,
281
- showCloseButton && /* @__PURE__ */ jsx6(DialogClose, { "aria-label": "Cerrar di\xE1logo", variant: "ghost", size: "icon", className: "absolute top-2 right-2", children: "\xD7" })
442
+ showCloseButton && /* @__PURE__ */ jsx13(DialogClose, { "aria-label": "Cerrar di\xE1logo", variant: "ghost", size: "icon", className: "absolute top-2 right-2", children: /* @__PURE__ */ jsx13(XIcon, { "aria-hidden": "true", weight: "bold", className: "size-4" }) })
282
443
  ] }) }) });
283
444
  }
284
445
  function DialogHeader({ className, ...props }) {
285
- return /* @__PURE__ */ jsx6("div", { "data-slot": "dialog-header", className: cn("flex flex-col gap-2", className), ...props });
446
+ return /* @__PURE__ */ jsx13("div", { "data-slot": "dialog-header", className: cn("flex flex-col gap-2", className), ...props });
286
447
  }
287
448
  function DialogFooter({ className, ...props }) {
288
- return /* @__PURE__ */ jsx6("div", { "data-slot": "dialog-footer", className: cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className), ...props });
449
+ return /* @__PURE__ */ jsx13("div", { "data-slot": "dialog-footer", className: cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className), ...props });
289
450
  }
290
451
  function DialogTitle({ className, ...props }) {
291
- return /* @__PURE__ */ jsx6(Heading, { slot: "title", className: cn("text-base font-semibold", className), ...props });
452
+ return /* @__PURE__ */ jsx13(Heading, { slot: "title", className: cn("text-base font-semibold", className), ...props });
292
453
  }
293
454
  function DialogDescription({ className, ...props }) {
294
- return /* @__PURE__ */ jsx6(Text, { slot: "description", className: cn("text-sm text-muted-foreground", className), ...props });
455
+ return /* @__PURE__ */ jsx13(Text2, { slot: "description", className: cn("text-sm text-muted-foreground", className), ...props });
295
456
  }
296
457
 
297
- // src/ui/confirm-dialog.tsx
298
- import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
458
+ // src/ui/confirm-dialog/confirm-dialog.tsx
459
+ import { jsx as jsx14, jsxs as jsxs5 } from "react/jsx-runtime";
299
460
  function ConfirmDialog({ open, onOpenChange, title, description, confirmLabel = "Confirmar", cancelLabel = "Cancelar", destructive = false, pending = false, onConfirm }) {
300
- return /* @__PURE__ */ jsx7(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs3(DialogContent, { showCloseButton: false, children: [
301
- /* @__PURE__ */ jsxs3(DialogHeader, { children: [
302
- /* @__PURE__ */ jsx7(DialogTitle, { children: title }),
303
- description && /* @__PURE__ */ jsx7(DialogDescription, { children: description })
461
+ return /* @__PURE__ */ jsx14(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs5(DialogContent, { showCloseButton: false, children: [
462
+ /* @__PURE__ */ jsxs5(DialogHeader, { children: [
463
+ /* @__PURE__ */ jsx14(DialogTitle, { children: title }),
464
+ description && /* @__PURE__ */ jsx14(DialogDescription, { children: description })
304
465
  ] }),
305
- /* @__PURE__ */ jsxs3(DialogFooter, { children: [
306
- /* @__PURE__ */ jsx7(Button, { variant: "outline", isDisabled: pending, onPress: () => onOpenChange(false), children: cancelLabel }),
307
- /* @__PURE__ */ jsx7(Button, { variant: destructive ? "destructive" : "default", isDisabled: pending, onPress: onConfirm, children: confirmLabel })
466
+ /* @__PURE__ */ jsxs5(DialogFooter, { children: [
467
+ /* @__PURE__ */ jsx14(Button2, { variant: "outline", isDisabled: pending, onPress: () => onOpenChange(false), children: cancelLabel }),
468
+ /* @__PURE__ */ jsx14(Button2, { variant: destructive ? "destructive" : "default", isDisabled: pending, onPress: onConfirm, children: confirmLabel })
308
469
  ] })
309
470
  ] }) });
310
471
  }
311
472
 
312
- // src/ui/empty-state.tsx
313
- import { jsx as jsx8 } from "react/jsx-runtime";
473
+ // src/ui/drawer/drawer.tsx
474
+ import { Dialog as AriaDialog2, Modal as Modal2, ModalOverlay as ModalOverlay2 } from "react-aria-components";
475
+ import { jsx as jsx15 } from "react/jsx-runtime";
476
+ var sideStyles = { left: "inset-y-0 left-0 h-full w-[min(22rem,calc(100%-2rem))] data-entering:animate-ui-surface-in", right: "inset-y-0 right-0 h-full w-[min(22rem,calc(100%-2rem))] data-entering:animate-ui-surface-in", bottom: "inset-x-0 bottom-0 max-h-[85vh] w-full data-entering:animate-ui-surface-in" };
477
+ function Drawer({ children, side = "right", className, ...props }) {
478
+ return /* @__PURE__ */ jsx15(ModalOverlay2, { isDismissable: true, className: "fixed inset-0 z-50 bg-black/20 backdrop-blur-[1px] motion-safe:data-entering:animate-ui-overlay-in motion-safe:data-exiting:animate-ui-overlay-out", ...props, children: /* @__PURE__ */ jsx15(Modal2, { className: cn("absolute grid gap-4 overflow-y-auto rounded-xl border border-border bg-background p-5 text-foreground shadow-xl outline-none", sideStyles[side], className), children: /* @__PURE__ */ jsx15(AriaDialog2, { "data-slot": "drawer", className: "outline-none", children }) }) });
479
+ }
480
+ function DrawerHeader({ className, ...props }) {
481
+ return /* @__PURE__ */ jsx15("div", { "data-slot": "drawer-header", className: cn("flex flex-col gap-1.5", className), ...props });
482
+ }
483
+ function DrawerFooter({ className, ...props }) {
484
+ return /* @__PURE__ */ jsx15("div", { "data-slot": "drawer-footer", className: cn("mt-auto flex flex-col-reverse gap-2 pt-4 sm:flex-row sm:justify-end", className), ...props });
485
+ }
486
+ function DrawerTitle({ className, ...props }) {
487
+ return /* @__PURE__ */ jsx15("h2", { "data-slot": "drawer-title", className: cn("text-base font-semibold", className), ...props });
488
+ }
489
+ function DrawerDescription({ className, ...props }) {
490
+ return /* @__PURE__ */ jsx15("p", { "data-slot": "drawer-description", className: cn("text-sm text-muted-foreground", className), ...props });
491
+ }
492
+
493
+ // src/ui/dropdown-menu/dropdown-menu.tsx
494
+ import { Menu as AriaMenu, MenuItem as AriaMenuItem, MenuTrigger as AriaMenuTrigger, Popover as AriaPopover, Separator as AriaSeparator } from "react-aria-components";
495
+ import { jsx as jsx16 } from "react/jsx-runtime";
496
+ var DropdownMenu = AriaMenu;
497
+ var DropdownMenuTrigger = AriaMenuTrigger;
498
+ function DropdownMenuContent({ className, ...props }) {
499
+ return /* @__PURE__ */ jsx16(AriaPopover, { "data-slot": "dropdown-menu-content", offset: 6, className: cn("min-w-40 overflow-hidden rounded-xl border border-border bg-background p-1.5 text-foreground shadow-lg outline-none motion-safe:data-entering:animate-ui-surface-in motion-safe:data-exiting:animate-ui-surface-out", className), ...props });
500
+ }
501
+ function DropdownMenuItem({ className, ...props }) {
502
+ return /* @__PURE__ */ jsx16(AriaMenuItem, { "data-slot": "dropdown-menu-item", className: cn("flex cursor-default items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none data-focused:bg-muted data-disabled:pointer-events-none data-disabled:opacity-50", className), ...props });
503
+ }
504
+ function DropdownMenuSeparator({ className, ...props }) {
505
+ return /* @__PURE__ */ jsx16(AriaSeparator, { "data-slot": "dropdown-menu-separator", className: cn("my-1 h-px bg-border", className), ...props });
506
+ }
507
+
508
+ // src/ui/empty-state/empty-state.tsx
509
+ import { jsx as jsx17 } from "react/jsx-runtime";
314
510
  function EmptyState({ className, ...props }) {
315
- return /* @__PURE__ */ jsx8("div", { "data-slot": "empty-state", className: cn("flex min-h-44 w-full flex-col items-center justify-center gap-3 rounded-xl border border-dashed border-border p-6 text-center", className), ...props });
511
+ return /* @__PURE__ */ jsx17("div", { "data-slot": "empty-state", className: cn("flex min-h-44 w-full flex-col items-center justify-center gap-3 rounded-xl border border-dashed border-border p-6 text-center", className), ...props });
316
512
  }
317
513
  function EmptyStateTitle({ className, ...props }) {
318
- return /* @__PURE__ */ jsx8("h3", { "data-slot": "empty-state-title", className: cn("text-sm font-medium text-foreground", className), ...props });
514
+ return /* @__PURE__ */ jsx17("h3", { "data-slot": "empty-state-title", className: cn("text-sm font-medium text-foreground", className), ...props });
319
515
  }
320
516
  function EmptyStateDescription({ className, ...props }) {
321
- return /* @__PURE__ */ jsx8("p", { "data-slot": "empty-state-description", className: cn("max-w-sm text-sm text-muted-foreground", className), ...props });
517
+ return /* @__PURE__ */ jsx17("p", { "data-slot": "empty-state-description", className: cn("max-w-sm text-sm text-muted-foreground", className), ...props });
322
518
  }
323
519
 
324
- // src/ui/label.tsx
520
+ // src/ui/label/label.tsx
325
521
  import { forwardRef } from "react";
326
522
  import { Label as LabelPrimitive } from "react-aria-components";
327
- import { jsx as jsx9 } from "react/jsx-runtime";
328
- var Label = forwardRef(function Label2({ className, ...props }, ref) {
329
- return /* @__PURE__ */ jsx9(LabelPrimitive, { ref, "data-slot": "label", className: cn("flex items-center gap-2 text-sm font-medium leading-none select-none", className), ...props });
523
+ import { jsx as jsx18 } from "react/jsx-runtime";
524
+ var Label2 = forwardRef(function Label3({ className, ...props }, ref) {
525
+ return /* @__PURE__ */ jsx18(LabelPrimitive, { ref, "data-slot": "label", className: cn("flex items-center gap-2 text-sm font-medium leading-none select-none", className), ...props });
330
526
  });
331
527
 
332
- // src/ui/field.tsx
333
- import { jsx as jsx10 } from "react/jsx-runtime";
528
+ // src/ui/field/field.tsx
529
+ import { jsx as jsx19 } from "react/jsx-runtime";
334
530
  function Field({ className, ...props }) {
335
- return /* @__PURE__ */ jsx10("div", { "data-slot": "field", className: cn("flex w-full flex-col gap-2", className), ...props });
531
+ return /* @__PURE__ */ jsx19("div", { "data-slot": "field", className: cn("flex w-full flex-col gap-2", className), ...props });
336
532
  }
337
533
  function FieldLabel({ className, ...props }) {
338
- return /* @__PURE__ */ jsx10(Label, { "data-slot": "field-label", className: cn("text-foreground", className), ...props });
534
+ return /* @__PURE__ */ jsx19(Label2, { "data-slot": "field-label", className: cn("text-foreground", className), ...props });
339
535
  }
340
536
  function FieldDescription({ className, ...props }) {
341
- return /* @__PURE__ */ jsx10("p", { "data-slot": "field-description", className: cn("text-sm text-muted-foreground", className), ...props });
537
+ return /* @__PURE__ */ jsx19("p", { "data-slot": "field-description", className: cn("text-sm text-muted-foreground", className), ...props });
342
538
  }
343
- function FieldError({ className, children, ...props }) {
539
+ function FieldError2({ className, children, ...props }) {
344
540
  if (!children) return null;
345
- return /* @__PURE__ */ jsx10("p", { role: "alert", "data-slot": "field-error", className: cn("text-sm text-destructive", className), ...props, children });
541
+ return /* @__PURE__ */ jsx19("p", { role: "alert", "data-slot": "field-error", className: cn("text-sm text-destructive", className), ...props, children });
542
+ }
543
+
544
+ // src/ui/form-feedback/form-feedback.tsx
545
+ import { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef3, useState as useState6 } from "react";
546
+ import { CheckCircleIcon, CircleNotchIcon, WarningCircleIcon } from "@phosphor-icons/react";
547
+ import { jsx as jsx20, jsxs as jsxs6 } from "react/jsx-runtime";
548
+ function useFormFeedback(options) {
549
+ const resetMs = options?.successResetMs ?? 2500;
550
+ const [state, setState] = useState6({ status: "idle" });
551
+ const timer = useRef3(null);
552
+ const clearTimer = useCallback3(() => {
553
+ if (timer.current) clearTimeout(timer.current);
554
+ timer.current = null;
555
+ }, []);
556
+ useEffect3(() => () => clearTimer(), [clearTimer]);
557
+ const setPending = useCallback3(() => {
558
+ clearTimer();
559
+ setState({ status: "pending" });
560
+ }, [clearTimer]);
561
+ const setSuccess = useCallback3((message) => {
562
+ clearTimer();
563
+ setState({ status: "success", message });
564
+ if (resetMs > 0) timer.current = setTimeout(() => setState({ status: "idle" }), resetMs);
565
+ }, [clearTimer, resetMs]);
566
+ const setError = useCallback3((message) => {
567
+ clearTimer();
568
+ setState({ status: "error", message });
569
+ }, [clearTimer]);
570
+ const reset = useCallback3(() => {
571
+ clearTimer();
572
+ setState({ status: "idle" });
573
+ }, [clearTimer]);
574
+ return { state, pending: state.status === "pending", setPending, setSuccess, setError, reset };
575
+ }
576
+ function FormFeedback({ state, className, pendingLabel = "Guardando\u2026", successLabel = "Guardado" }) {
577
+ if (state.status === "idle") return /* @__PURE__ */ jsx20("span", { "aria-hidden": "true", className: cn("inline-flex h-5 items-center", className) });
578
+ const error = state.status === "error";
579
+ const success = state.status === "success";
580
+ return /* @__PURE__ */ jsxs6("span", { role: error ? "alert" : "status", "aria-live": "polite", className: cn("inline-flex h-5 items-center gap-1.5 text-xs", error && "text-destructive", success && "text-success", state.status === "pending" && "text-muted-foreground", className), children: [
581
+ state.status === "pending" && /* @__PURE__ */ jsx20(CircleNotchIcon, { "aria-hidden": "true", className: "size-3.5 animate-spin" }),
582
+ success && /* @__PURE__ */ jsx20(CheckCircleIcon, { "aria-hidden": "true", className: "size-3.5", weight: "fill" }),
583
+ error && /* @__PURE__ */ jsx20(WarningCircleIcon, { "aria-hidden": "true", className: "size-3.5", weight: "fill" }),
584
+ /* @__PURE__ */ jsx20("span", { children: state.status === "pending" ? pendingLabel : success ? state.message ?? successLabel : state.message })
585
+ ] });
586
+ }
587
+
588
+ // src/ui/form-row/form-row.tsx
589
+ import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs7 } from "react/jsx-runtime";
590
+ function FormRow({ label, htmlFor, required, hint, error, className, children }) {
591
+ const hintId = hint ? `${htmlFor}-hint` : void 0;
592
+ const errorId = error ? `${htmlFor}-error` : void 0;
593
+ return /* @__PURE__ */ jsxs7("div", { "data-slot": "form-row", className: cn("flex flex-col gap-1.5", className), children: [
594
+ /* @__PURE__ */ jsxs7("label", { htmlFor, className: "text-sm font-medium text-foreground", children: [
595
+ label,
596
+ required && /* @__PURE__ */ jsxs7(Fragment4, { children: [
597
+ /* @__PURE__ */ jsx21("span", { "aria-hidden": "true", className: "ml-0.5 text-destructive", children: "*" }),
598
+ /* @__PURE__ */ jsx21("span", { className: "sr-only", children: " (obligatorio)" })
599
+ ] })
600
+ ] }),
601
+ children,
602
+ hint && /* @__PURE__ */ jsx21("p", { id: hintId, className: "text-xs text-muted-foreground", children: hint }),
603
+ error && /* @__PURE__ */ jsx21("p", { id: errorId, role: "alert", className: "text-xs font-medium text-destructive", children: error })
604
+ ] });
346
605
  }
347
606
 
348
- // src/ui/input.tsx
607
+ // src/ui/icon-button/icon-button.tsx
608
+ import { Link } from "react-aria-components";
609
+
610
+ // src/ui/tooltip/tooltip.tsx
611
+ import {
612
+ Tooltip as AriaTooltip,
613
+ TooltipTrigger as AriaTooltipTrigger
614
+ } from "react-aria-components";
615
+ import { jsx as jsx22 } from "react/jsx-runtime";
616
+ var TooltipTrigger = AriaTooltipTrigger;
617
+ function Tooltip({ className, ...props }) {
618
+ return /* @__PURE__ */ jsx22(AriaTooltip, { "data-slot": "tooltip", offset: 6, className: cn("max-w-xs rounded-md bg-foreground px-2.5 py-1.5 text-xs text-background shadow-md outline-none motion-safe:data-entering:animate-ui-surface-in motion-safe:data-exiting:animate-ui-surface-out", className), ...props });
619
+ }
620
+ var TooltipContent = Tooltip;
621
+
622
+ // src/ui/icon-button/icon-button.tsx
623
+ import { jsx as jsx23, jsxs as jsxs8 } from "react/jsx-runtime";
624
+ function IconButton({
625
+ label,
626
+ children,
627
+ href,
628
+ className,
629
+ variant,
630
+ ...props
631
+ }) {
632
+ const linkClassName = cn(
633
+ buttonVariants({ variant, size: "icon" }),
634
+ className
635
+ );
636
+ return /* @__PURE__ */ jsxs8(TooltipTrigger, { children: [
637
+ href ? /* @__PURE__ */ jsx23(
638
+ Link,
639
+ {
640
+ "data-slot": "icon-button",
641
+ "aria-label": label,
642
+ href,
643
+ className: linkClassName,
644
+ children
645
+ }
646
+ ) : /* @__PURE__ */ jsx23(
647
+ Button2,
648
+ {
649
+ "data-slot": "icon-button",
650
+ "aria-label": label,
651
+ variant,
652
+ size: "icon",
653
+ className,
654
+ ...props,
655
+ children
656
+ }
657
+ ),
658
+ /* @__PURE__ */ jsx23(Tooltip, { children: label })
659
+ ] });
660
+ }
661
+
662
+ // src/ui/input/input.tsx
349
663
  import { forwardRef as forwardRef2 } from "react";
350
- import { Input as AriaInput } from "react-aria-components";
351
- import { jsx as jsx11 } from "react/jsx-runtime";
664
+ import { Input as AriaInput2 } from "react-aria-components";
665
+ import { jsx as jsx24 } from "react/jsx-runtime";
352
666
  var InputImpl = forwardRef2(function Input2({ className, type, ...props }, ref) {
353
- return /* @__PURE__ */ jsx11(AriaInput, { ref, type, "data-slot": "input", className: cn("h-8 w-full min-w-0 rounded-lg border border-border bg-background px-2.5 py-1 text-sm text-foreground outline-none placeholder:text-muted-foreground focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive", className), ...props });
667
+ return /* @__PURE__ */ jsx24(AriaInput2, { ref, type, "data-slot": "input", className: cn("h-8 w-full min-w-0 rounded-lg border border-border bg-background px-2.5 py-1 text-sm text-foreground outline-none placeholder:text-muted-foreground focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive", className), ...props });
354
668
  });
355
669
  var Input3 = InputImpl;
356
670
 
357
- // src/ui/kbd.tsx
358
- import { jsx as jsx12 } from "react/jsx-runtime";
671
+ // src/ui/input-group/input-group.tsx
672
+ import { cva as cva3 } from "class-variance-authority";
673
+
674
+ // src/ui/textarea/textarea.tsx
675
+ import { forwardRef as forwardRef3 } from "react";
676
+ import { TextArea as AriaTextArea } from "react-aria-components";
677
+ import { jsx as jsx25 } from "react/jsx-runtime";
678
+ var TextareaImpl = forwardRef3(function Textarea({ className, ...props }, ref) {
679
+ return /* @__PURE__ */ jsx25(AriaTextArea, { ref, "data-slot": "textarea", className: cn("min-h-20 w-full rounded-lg border border-border bg-background px-2.5 py-2 text-sm text-foreground outline-none placeholder:text-muted-foreground focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive", className), ...props });
680
+ });
681
+ var Textarea2 = TextareaImpl;
682
+
683
+ // src/ui/input-group/input-group.tsx
684
+ import { jsx as jsx26 } from "react/jsx-runtime";
685
+ function InputGroup({ className, ...props }) {
686
+ return /* @__PURE__ */ jsx26("div", { role: "group", "data-slot": "input-group", className: cn("group/input-group flex min-h-8 w-full min-w-0 items-center rounded-lg border border-border transition-colors has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive", className), ...props });
687
+ }
688
+ var addonVariants = cva3("flex items-center justify-center gap-2 px-2 text-sm text-muted-foreground", { variants: { align: { "inline-start": "order-first", "inline-end": "order-last", "block-start": "w-full justify-start border-b py-2", "block-end": "w-full justify-start border-t py-2" } }, defaultVariants: { align: "inline-start" } });
689
+ function InputGroupAddon({ className, align, ...props }) {
690
+ return /* @__PURE__ */ jsx26("div", { "data-slot": "input-group-addon", "data-align": align, className: cn(addonVariants({ align }), className), ...props });
691
+ }
692
+ function InputGroupButton({ className, ...props }) {
693
+ return /* @__PURE__ */ jsx26(Button2, { "data-slot": "input-group-button", size: "icon", variant: "ghost", className: cn("size-7 shrink-0", className), ...props });
694
+ }
695
+ function InputGroupText({ className, ...props }) {
696
+ return /* @__PURE__ */ jsx26("span", { "data-slot": "input-group-text", className: cn("px-2 text-sm text-muted-foreground", className), ...props });
697
+ }
698
+ function InputGroupInput({ className, ...props }) {
699
+ return /* @__PURE__ */ jsx26(Input3, { "data-slot": "input-group-control", className: cn("flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0", className), ...props });
700
+ }
701
+ function InputGroupTextarea({ className, ...props }) {
702
+ return /* @__PURE__ */ jsx26(Textarea2, { "data-slot": "input-group-control", className: cn("flex-1 resize-none rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0", className), ...props });
703
+ }
704
+
705
+ // src/ui/kbd/kbd.tsx
706
+ import { jsx as jsx27 } from "react/jsx-runtime";
359
707
  function Kbd({ className, ...props }) {
360
- return /* @__PURE__ */ jsx12("kbd", { "data-slot": "kbd", className: cn("pointer-events-none inline-flex h-5 min-w-5 items-center justify-center gap-1 rounded-sm bg-muted px-1 font-sans text-xs font-medium text-muted-foreground select-none", className), ...props });
708
+ return /* @__PURE__ */ jsx27("kbd", { "data-slot": "kbd", className: cn("pointer-events-none inline-flex h-5 min-w-5 items-center justify-center gap-1 rounded-sm bg-muted px-1 font-sans text-xs font-medium text-muted-foreground select-none", className), ...props });
361
709
  }
362
710
  function KbdGroup({ className, ...props }) {
363
- return /* @__PURE__ */ jsx12("span", { "data-slot": "kbd-group", className: cn("inline-flex items-center gap-1", className), ...props });
711
+ return /* @__PURE__ */ jsx27("span", { "data-slot": "kbd-group", className: cn("inline-flex items-center gap-1", className), ...props });
712
+ }
713
+
714
+ // src/ui/loading-overlay/loading-overlay.tsx
715
+ import { CircleNotchIcon as CircleNotchIcon2 } from "@phosphor-icons/react";
716
+ import { jsx as jsx28, jsxs as jsxs9 } from "react/jsx-runtime";
717
+ function LoadingOverlay({ label = "Cargando", className, ...props }) {
718
+ return /* @__PURE__ */ jsx28("div", { role: "status", "aria-live": "polite", className: cn("absolute inset-0 z-10 flex items-center justify-center bg-background/70 backdrop-blur-[2px]", className), ...props, children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 rounded-lg border border-border bg-background px-3 py-2 text-sm shadow-sm", children: [
719
+ /* @__PURE__ */ jsx28(CircleNotchIcon2, { className: "animate-spin", "aria-hidden": "true" }),
720
+ /* @__PURE__ */ jsx28("span", { children: label })
721
+ ] }) });
364
722
  }
365
723
 
366
- // src/ui/menu.tsx
724
+ // src/ui/menu/menu.tsx
367
725
  import {
368
- Menu as AriaMenu,
369
- MenuItem as AriaMenuItem,
370
- MenuTrigger as AriaMenuTrigger,
371
- Popover as Popover2
726
+ Menu as AriaMenu2,
727
+ MenuItem as AriaMenuItem2,
728
+ MenuTrigger as AriaMenuTrigger2,
729
+ Popover as Popover3
372
730
  } from "react-aria-components";
373
- import { jsx as jsx13 } from "react/jsx-runtime";
374
- var MenuTrigger = AriaMenuTrigger;
731
+ import { jsx as jsx29 } from "react/jsx-runtime";
732
+ var MenuTrigger = AriaMenuTrigger2;
375
733
  function MenuContent({ className, ...props }) {
376
- return /* @__PURE__ */ jsx13(Popover2, { "data-slot": "menu-content", className: cn("min-w-40 overflow-hidden rounded-xl border border-border bg-background p-1.5 text-foreground shadow-lg", className), ...props });
734
+ return /* @__PURE__ */ jsx29(Popover3, { "data-slot": "menu-content", className: cn("min-w-40 overflow-hidden rounded-xl border border-border bg-background p-1.5 text-foreground shadow-lg motion-safe:data-entering:animate-ui-surface-in motion-safe:data-exiting:animate-ui-surface-out", className), ...props });
377
735
  }
378
736
  function Menu({ className, ...props }) {
379
- return /* @__PURE__ */ jsx13(AriaMenu, { "data-slot": "menu", className: cn("outline-none", className), ...props });
737
+ return /* @__PURE__ */ jsx29(AriaMenu2, { "data-slot": "menu", className: cn("outline-none", className), ...props });
380
738
  }
381
739
  function MenuItem({ className, children, ...props }) {
382
- return /* @__PURE__ */ jsx13(AriaMenuItem, { "data-slot": "menu-item", className: cn("flex cursor-default items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none data-focused:bg-muted data-disabled:pointer-events-none data-disabled:opacity-50", className), ...props, children });
740
+ return /* @__PURE__ */ jsx29(AriaMenuItem2, { "data-slot": "menu-item", className: cn("flex cursor-default items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none data-focused:bg-muted data-disabled:pointer-events-none data-disabled:opacity-50", className), ...props, children });
383
741
  }
384
742
 
385
- // src/ui/popover.tsx
743
+ // src/ui/page-header/page-header.tsx
744
+ import { jsx as jsx30 } from "react/jsx-runtime";
745
+ function PageHeader({ className, ...props }) {
746
+ return /* @__PURE__ */ jsx30("header", { "data-slot": "page-header", className: cn("flex flex-col gap-4 py-2 sm:flex-row sm:items-center sm:justify-between", className), ...props });
747
+ }
748
+ function PageHeaderHeading({ className, ...props }) {
749
+ return /* @__PURE__ */ jsx30("div", { "data-slot": "page-header-heading", className: cn("min-w-0", className), ...props });
750
+ }
751
+ function PageHeaderTitle({ className, ...props }) {
752
+ return /* @__PURE__ */ jsx30("h1", { "data-slot": "page-header-title", className: cn("truncate text-xl font-semibold tracking-tight md:text-2xl", className), ...props });
753
+ }
754
+ function PageHeaderDescription({ className, ...props }) {
755
+ return /* @__PURE__ */ jsx30("p", { "data-slot": "page-header-description", className: cn("mt-1 text-sm text-muted-foreground", className), ...props });
756
+ }
757
+ function PageHeaderActions({ className, ...props }) {
758
+ return /* @__PURE__ */ jsx30("div", { "data-slot": "page-header-actions", className: cn("flex shrink-0 items-center gap-2", className), ...props });
759
+ }
760
+
761
+ // src/ui/pagination/pagination.tsx
762
+ import { CaretLeftIcon, CaretRightIcon } from "@phosphor-icons/react";
763
+ import { jsx as jsx31, jsxs as jsxs10 } from "react/jsx-runtime";
764
+ function Pagination({ page, pageCount, onPageChange, className }) {
765
+ const pages = Array.from({ length: pageCount }, (_, index) => index + 1);
766
+ return /* @__PURE__ */ jsxs10("nav", { "aria-label": "Paginaci\xF3n", className: cn("flex items-center justify-between gap-4", className), children: [
767
+ /* @__PURE__ */ jsxs10("p", { className: "text-sm text-muted-foreground", children: [
768
+ "P\xE1gina ",
769
+ page,
770
+ " de ",
771
+ pageCount
772
+ ] }),
773
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1", children: [
774
+ /* @__PURE__ */ jsx31(Button2, { "aria-label": "P\xE1gina anterior", isDisabled: page <= 1, onPress: () => onPageChange(page - 1), size: "icon", variant: "ghost", children: /* @__PURE__ */ jsx31(CaretLeftIcon, {}) }),
775
+ pages.map((item) => /* @__PURE__ */ jsx31(Button2, { "aria-current": item === page ? "page" : void 0, "aria-label": `P\xE1gina ${item}`, onPress: () => onPageChange(item), size: "icon", variant: item === page ? "secondary" : "ghost", children: item }, item)),
776
+ /* @__PURE__ */ jsx31(Button2, { "aria-label": "P\xE1gina siguiente", isDisabled: page >= pageCount, onPress: () => onPageChange(page + 1), size: "icon", variant: "ghost", children: /* @__PURE__ */ jsx31(CaretRightIcon, {}) })
777
+ ] })
778
+ ] });
779
+ }
780
+
781
+ // src/ui/popover/popover.tsx
386
782
  import {
387
783
  DialogTrigger as AriaDialogTrigger,
388
- Popover as AriaPopover
784
+ Popover as AriaPopover2
389
785
  } from "react-aria-components";
390
- import { jsx as jsx14 } from "react/jsx-runtime";
786
+ import { jsx as jsx32 } from "react/jsx-runtime";
391
787
  var PopoverTrigger = AriaDialogTrigger;
392
- function Popover3({ className, ...props }) {
393
- return /* @__PURE__ */ jsx14(AriaPopover, { "data-slot": "popover", offset: 6, className: cn("min-w-48 rounded-xl border border-border bg-background p-1.5 text-foreground shadow-lg outline-none data-entering:animate-in data-entering:fade-in-0 data-entering:zoom-in-95 data-exiting:animate-out data-exiting:fade-out-0 data-exiting:zoom-out-95", className), ...props });
788
+ function Popover4({ className, ...props }) {
789
+ return /* @__PURE__ */ jsx32(AriaPopover2, { "data-slot": "popover", offset: 6, className: cn("min-w-48 rounded-xl border border-border bg-background p-1.5 text-foreground shadow-lg outline-none motion-safe:data-entering:animate-ui-surface-in motion-safe:data-exiting:animate-ui-surface-out", className), ...props });
790
+ }
791
+ var PopoverContent = Popover4;
792
+
793
+ // src/ui/quantity-input/quantity-input.tsx
794
+ import { MinusIcon, PlusIcon } from "@phosphor-icons/react";
795
+ import {
796
+ Button as AriaButton2,
797
+ Group as AriaGroup,
798
+ Input as AriaInput3,
799
+ NumberField as AriaNumberField
800
+ } from "react-aria-components";
801
+ import { jsx as jsx33, jsxs as jsxs11 } from "react/jsx-runtime";
802
+ function QuantityInput({
803
+ className,
804
+ inputClassName,
805
+ decrementAriaLabel = "Disminuir cantidad",
806
+ incrementAriaLabel = "Aumentar cantidad",
807
+ minValue = 0,
808
+ step = 1,
809
+ ...props
810
+ }) {
811
+ return /* @__PURE__ */ jsx33(
812
+ AriaNumberField,
813
+ {
814
+ ...props,
815
+ minValue,
816
+ step,
817
+ "data-slot": "quantity-input",
818
+ className: cn("group/quantity-input inline-flex min-w-0 data-disabled:cursor-not-allowed data-disabled:opacity-50", className),
819
+ children: /* @__PURE__ */ jsxs11(
820
+ AriaGroup,
821
+ {
822
+ "data-slot": "quantity-input-group",
823
+ className: "flex h-8 min-w-0 items-stretch overflow-hidden rounded-lg border border-border bg-background text-foreground transition-[border-color,box-shadow] focus-within:border-ring focus-within:ring-3 focus-within:ring-ring/50 group-data-invalid/quantity-input:border-destructive",
824
+ children: [
825
+ /* @__PURE__ */ jsx33(AriaButton2, { slot: "decrement", "aria-label": decrementAriaLabel, "data-slot": "quantity-input-decrement", className: "flex size-8 shrink-0 cursor-pointer items-center justify-center border-r border-border text-muted-foreground outline-none transition-colors hover:bg-muted hover:text-foreground data-focus-visible:bg-muted data-pressed:bg-muted data-disabled:pointer-events-none", children: /* @__PURE__ */ jsx33(MinusIcon, { "aria-hidden": "true", weight: "bold", className: "size-4" }) }),
826
+ /* @__PURE__ */ jsx33(AriaInput3, { "data-slot": "quantity-input-value", className: cn("w-14 min-w-0 bg-transparent px-1 text-center text-sm tabular-nums outline-none", inputClassName) }),
827
+ /* @__PURE__ */ jsx33(AriaButton2, { slot: "increment", "aria-label": incrementAriaLabel, "data-slot": "quantity-input-increment", className: "flex size-8 shrink-0 cursor-pointer items-center justify-center border-l border-border text-muted-foreground outline-none transition-colors hover:bg-muted hover:text-foreground data-focus-visible:bg-muted data-pressed:bg-muted data-disabled:pointer-events-none", children: /* @__PURE__ */ jsx33(PlusIcon, { "aria-hidden": "true", weight: "bold", className: "size-4" }) })
828
+ ]
829
+ }
830
+ )
831
+ }
832
+ );
394
833
  }
395
- var PopoverContent = Popover3;
396
834
 
397
- // src/ui/search-field.tsx
835
+ // src/ui/search-field/search-field.tsx
398
836
  import {
399
837
  SearchField as AriaSearchField,
400
- Button as Button2,
838
+ Button as Button3,
401
839
  Input as Input4
402
840
  } from "react-aria-components";
403
- import { jsx as jsx15 } from "react/jsx-runtime";
841
+ import { XIcon as XIcon2 } from "@phosphor-icons/react";
842
+ import { jsx as jsx34 } from "react/jsx-runtime";
404
843
  var SearchField = AriaSearchField;
405
844
  function SearchInput({ className, ...props }) {
406
- return /* @__PURE__ */ jsx15(Input4, { "data-slot": "search-input", className: cn("h-8 w-full min-w-0 rounded-lg border border-border bg-background px-2.5 py-1 text-sm text-foreground outline-none placeholder:text-muted-foreground focus-visible:ring-3 focus-visible:ring-ring/50", className), ...props });
845
+ return /* @__PURE__ */ jsx34(Input4, { "data-slot": "search-input", className: cn("h-8 w-full min-w-0 rounded-lg border border-border bg-background px-2.5 py-1 text-sm text-foreground outline-none placeholder:text-muted-foreground focus-visible:ring-3 focus-visible:ring-ring/50", className), ...props });
407
846
  }
408
- function SearchClearButton({ className, children = "\xD7", ...props }) {
409
- return /* @__PURE__ */ jsx15(Button2, { slot: "clear", "data-slot": "search-clear", className: cn("absolute top-1/2 right-1 -translate-y-1/2 rounded p-1 text-muted-foreground outline-none hover:bg-muted data-focus-visible:ring-2 data-focus-visible:ring-ring", className), ...props, children });
847
+ function SearchClearButton({ className, children = /* @__PURE__ */ jsx34(XIcon2, { "aria-hidden": "true", weight: "bold", className: "size-4" }), ...props }) {
848
+ return /* @__PURE__ */ jsx34(Button3, { slot: "clear", "data-slot": "search-clear", className: cn("absolute top-1/2 right-1 rounded p-1 text-muted-foreground outline-none hover:bg-muted data-focus-visible:ring-2 data-focus-visible:ring-ring", className), ...props, children });
410
849
  }
411
850
 
412
- // src/ui/select.tsx
851
+ // src/ui/select/select.tsx
413
852
  import {
414
- Button as AriaButton2,
853
+ Button as AriaButton3,
415
854
  Select as AriaSelect,
416
855
  SelectValue as AriaSelectValue,
417
- ListBox as ListBox2,
418
- ListBoxItem as ListBoxItem2,
419
- Popover as Popover4
856
+ ListBox as ListBox3,
857
+ ListBoxItem as ListBoxItem3,
858
+ Popover as Popover5
420
859
  } from "react-aria-components";
421
- import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs4 } from "react/jsx-runtime";
860
+ import { CaretDownIcon as CaretDownIcon2 } from "@phosphor-icons/react";
861
+ import { Fragment as Fragment5, jsx as jsx35, jsxs as jsxs12 } from "react/jsx-runtime";
422
862
  var Select = AriaSelect;
423
863
  function SelectTrigger({ className, children, ...props }) {
424
- return /* @__PURE__ */ jsx16(AriaButton2, { "data-slot": "select-trigger", className: cn("flex h-8 w-full min-w-36 items-center gap-2 rounded-lg border border-border bg-background px-2.5 text-left text-sm text-foreground outline-none data-focus-visible:ring-3 data-focus-visible:ring-ring/50 data-disabled:cursor-not-allowed data-disabled:opacity-50", className), ...props, children: (state) => /* @__PURE__ */ jsxs4(Fragment3, { children: [
864
+ return /* @__PURE__ */ jsx35(AriaButton3, { "data-slot": "select-trigger", className: cn("group/select-trigger flex h-8 w-full min-w-36 items-center gap-2 rounded-lg border border-border bg-background px-2.5 text-left text-sm text-foreground outline-none data-focus-visible:ring-3 data-focus-visible:ring-ring/50 data-disabled:cursor-not-allowed data-disabled:opacity-50", className), ...props, children: (state) => /* @__PURE__ */ jsxs12(Fragment5, { children: [
425
865
  typeof children === "function" ? children(state) : children,
426
- /* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: "ml-auto text-muted-foreground", children: "\u2304" })
866
+ /* @__PURE__ */ jsx35(CaretDownIcon2, { "aria-hidden": "true", weight: "bold", className: "ml-auto size-4 text-muted-foreground transition-transform group-data-pressed/select-trigger:rotate-180 motion-reduce:transition-none" })
427
867
  ] }) });
428
868
  }
429
869
  function SelectValue({ className, ...props }) {
430
- return /* @__PURE__ */ jsx16(AriaSelectValue, { "data-slot": "select-value", className: cn("flex-1 truncate data-placeholder:text-muted-foreground", className), ...props });
870
+ return /* @__PURE__ */ jsx35(AriaSelectValue, { "data-slot": "select-value", className: cn("flex-1 truncate data-placeholder:text-muted-foreground", className), ...props });
431
871
  }
432
872
  function SelectContent({ className, ...props }) {
433
- return /* @__PURE__ */ jsx16(Popover4, { "data-slot": "select-content", className: cn("w-(--trigger-width) overflow-hidden rounded-xl border border-border bg-background p-1.5 text-foreground shadow-lg", className), ...props });
873
+ return /* @__PURE__ */ jsx35(Popover5, { "data-slot": "select-content", className: cn("w-(--trigger-width) overflow-hidden rounded-xl border border-border bg-background p-1.5 text-foreground shadow-lg motion-safe:data-entering:animate-ui-surface-in motion-safe:data-exiting:animate-ui-surface-out", className), ...props });
434
874
  }
435
875
  function SelectList({ className, ...props }) {
436
- return /* @__PURE__ */ jsx16(ListBox2, { "data-slot": "select-list", className: cn("max-h-64 overflow-y-auto", className), ...props });
876
+ return /* @__PURE__ */ jsx35(ListBox3, { "data-slot": "select-list", className: cn("max-h-64 overflow-y-auto", className), ...props });
437
877
  }
438
878
  function SelectItem({ className, children, ...props }) {
439
- return /* @__PURE__ */ jsx16(ListBoxItem2, { "data-slot": "select-item", className: cn("flex cursor-default items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none data-focused:bg-muted data-selected:bg-muted data-disabled:pointer-events-none data-disabled:opacity-50", className), ...props, children });
879
+ return /* @__PURE__ */ jsx35(ListBoxItem3, { "data-slot": "select-item", className: cn("flex cursor-default items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none data-focused:bg-muted data-selected:bg-muted data-disabled:pointer-events-none data-disabled:opacity-50", className), ...props, children });
440
880
  }
441
881
 
442
- // src/ui/separator.tsx
443
- import { Separator as AriaSeparator } from "react-aria-components";
444
- import { jsx as jsx17 } from "react/jsx-runtime";
882
+ // src/ui/separator/separator.tsx
883
+ import { Separator as AriaSeparator2 } from "react-aria-components";
884
+ import { jsx as jsx36 } from "react/jsx-runtime";
445
885
  function Separator({ className, orientation = "horizontal", ...props }) {
446
- return /* @__PURE__ */ jsx17(AriaSeparator, { "data-slot": "separator", orientation, className: cn("shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch", className), ...props });
886
+ return /* @__PURE__ */ jsx36(AriaSeparator2, { "data-slot": "separator", orientation, className: cn("shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch", className), ...props });
447
887
  }
448
888
 
449
- // src/ui/skeleton.tsx
450
- import { jsx as jsx18 } from "react/jsx-runtime";
889
+ // src/ui/sidebar/sidebar.tsx
890
+ import {
891
+ CaretLeftIcon as CaretLeftIcon2,
892
+ CaretRightIcon as CaretRightIcon2,
893
+ DotsThreeIcon,
894
+ MagnifyingGlassIcon
895
+ } from "@phosphor-icons/react";
896
+ import {
897
+ createContext as createContext2,
898
+ useContext as useContext2,
899
+ useMemo as useMemo2,
900
+ useState as useState7
901
+ } from "react";
902
+ import { Link as Link2 } from "react-aria-components";
903
+ import { Fragment as Fragment6, jsx as jsx37, jsxs as jsxs13 } from "react/jsx-runtime";
904
+ var SidebarContext = createContext2(null);
905
+ function useSidebar() {
906
+ const context = useContext2(SidebarContext);
907
+ if (!context)
908
+ throw new Error("useSidebar must be used inside SidebarProvider");
909
+ return context;
910
+ }
911
+ function SidebarProvider({
912
+ defaultCollapsed = false,
913
+ children
914
+ }) {
915
+ const [collapsed, setCollapsed] = useState7(defaultCollapsed);
916
+ const value = useMemo2(
917
+ () => ({
918
+ collapsed,
919
+ setCollapsed,
920
+ toggle: () => setCollapsed((current) => !current)
921
+ }),
922
+ [collapsed]
923
+ );
924
+ return /* @__PURE__ */ jsx37(SidebarContext.Provider, { value, children });
925
+ }
926
+ function Sidebar({
927
+ className,
928
+ ...props
929
+ }) {
930
+ const { collapsed } = useSidebar();
931
+ return /* @__PURE__ */ jsx37(
932
+ "aside",
933
+ {
934
+ "data-slot": "sidebar",
935
+ "data-collapsed": collapsed || void 0,
936
+ className: cn(
937
+ "group/sidebar flex h-full w-56 shrink-0 flex-col border-r border-border bg-card text-foreground transition-[width] duration-200 ease-out motion-reduce:transition-none data-[collapsed]:w-16",
938
+ className
939
+ ),
940
+ ...props
941
+ }
942
+ );
943
+ }
944
+ function SidebarHeader({
945
+ className,
946
+ ...props
947
+ }) {
948
+ return /* @__PURE__ */ jsx37(
949
+ "div",
950
+ {
951
+ "data-slot": "sidebar-header",
952
+ className: cn("flex items-center gap-2 px-4 py-5", className),
953
+ ...props
954
+ }
955
+ );
956
+ }
957
+ function SidebarSearch({
958
+ label = "Buscar\u2026",
959
+ shortcut = "\u2318K",
960
+ className,
961
+ ...props
962
+ }) {
963
+ return /* @__PURE__ */ jsxs13(
964
+ "button",
965
+ {
966
+ type: "button",
967
+ "data-slot": "sidebar-search",
968
+ className: cn(
969
+ "group flex w-full items-center gap-2 rounded-md border border-border bg-background px-2.5 py-1.5 text-sm text-muted-foreground transition-colors hover:border-primary/40 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
970
+ className
971
+ ),
972
+ ...props,
973
+ children: [
974
+ /* @__PURE__ */ jsx37(MagnifyingGlassIcon, { className: "size-4 shrink-0" }),
975
+ /* @__PURE__ */ jsx37("span", { className: "flex-1 text-left", children: label }),
976
+ /* @__PURE__ */ jsx37("kbd", { className: "rounded bg-secondary px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground", children: shortcut })
977
+ ]
978
+ }
979
+ );
980
+ }
981
+ function SidebarContent({
982
+ className,
983
+ ...props
984
+ }) {
985
+ return /* @__PURE__ */ jsx37(
986
+ "nav",
987
+ {
988
+ "data-slot": "sidebar-content",
989
+ "aria-label": "Navegaci\xF3n principal",
990
+ className: cn("min-h-0 flex-1 overflow-y-auto px-2 py-1", className),
991
+ ...props
992
+ }
993
+ );
994
+ }
995
+ function SidebarFooter({
996
+ className,
997
+ ...props
998
+ }) {
999
+ return /* @__PURE__ */ jsx37(
1000
+ "div",
1001
+ {
1002
+ "data-slot": "sidebar-footer",
1003
+ className: cn(
1004
+ "mt-auto flex flex-col gap-2 border-t border-border p-2",
1005
+ className
1006
+ ),
1007
+ ...props
1008
+ }
1009
+ );
1010
+ }
1011
+ function SidebarGroup({
1012
+ label,
1013
+ className,
1014
+ children,
1015
+ ...props
1016
+ }) {
1017
+ const { collapsed } = useSidebar();
1018
+ return /* @__PURE__ */ jsxs13(
1019
+ "section",
1020
+ {
1021
+ "data-slot": "sidebar-group",
1022
+ className: cn("mb-4 last:mb-0", className),
1023
+ ...props,
1024
+ children: [
1025
+ label && /* @__PURE__ */ jsx37(
1026
+ "h2",
1027
+ {
1028
+ className: cn(
1029
+ "mb-1 px-3 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground",
1030
+ collapsed && "sr-only"
1031
+ ),
1032
+ children: label
1033
+ }
1034
+ ),
1035
+ children
1036
+ ]
1037
+ }
1038
+ );
1039
+ }
1040
+ function SidebarItem({
1041
+ icon,
1042
+ active,
1043
+ badge,
1044
+ label,
1045
+ children,
1046
+ className,
1047
+ ...props
1048
+ }) {
1049
+ const { collapsed } = useSidebar();
1050
+ const content = typeof children === "function" ? label : children ?? label;
1051
+ return /* @__PURE__ */ jsx37(
1052
+ Link2,
1053
+ {
1054
+ "data-slot": "sidebar-item",
1055
+ "aria-current": active ? "page" : void 0,
1056
+ "aria-label": collapsed && label ? label : void 0,
1057
+ className: cn(
1058
+ "group/item relative flex min-h-9 items-center gap-2.5 rounded-md px-2.5 py-2 text-sm text-muted-foreground outline-none transition-[background-color,color,transform] duration-150 hover:bg-secondary/60 hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/40 data-[current=page]:bg-secondary data-[current=page]:font-medium data-[current=page]:text-foreground data-pressed:scale-[0.98] motion-reduce:transition-none",
1059
+ collapsed && "justify-center px-0",
1060
+ typeof className === "function" ? className : className
1061
+ ),
1062
+ ...props,
1063
+ children: (values) => /* @__PURE__ */ jsxs13(Fragment6, { children: [
1064
+ /* @__PURE__ */ jsx37("span", { className: "flex size-4 shrink-0 items-center justify-center", children: icon }),
1065
+ /* @__PURE__ */ jsx37(
1066
+ "span",
1067
+ {
1068
+ className: cn("min-w-0 flex-1 truncate", collapsed && "sr-only"),
1069
+ children: typeof children === "function" ? children(values) : content
1070
+ }
1071
+ ),
1072
+ badge && !collapsed && /* @__PURE__ */ jsx37("span", { className: "text-xs text-muted-foreground", children: badge })
1073
+ ] })
1074
+ }
1075
+ );
1076
+ }
1077
+ function SidebarSeparator({
1078
+ className,
1079
+ ...props
1080
+ }) {
1081
+ return /* @__PURE__ */ jsx37(
1082
+ "hr",
1083
+ {
1084
+ "data-slot": "sidebar-separator",
1085
+ className: cn("my-2 h-px border-0 bg-border", className),
1086
+ ...props
1087
+ }
1088
+ );
1089
+ }
1090
+ function SidebarTrigger({ className, ...props }) {
1091
+ const { collapsed, toggle } = useSidebar();
1092
+ return /* @__PURE__ */ jsx37(
1093
+ Button2,
1094
+ {
1095
+ "aria-label": collapsed ? "Expandir navegaci\xF3n" : "Colapsar navegaci\xF3n",
1096
+ onPress: toggle,
1097
+ size: "icon",
1098
+ variant: "ghost",
1099
+ className: cn("ml-auto", className),
1100
+ ...props,
1101
+ children: collapsed ? /* @__PURE__ */ jsx37(CaretRightIcon2, {}) : /* @__PURE__ */ jsx37(CaretLeftIcon2, {})
1102
+ }
1103
+ );
1104
+ }
1105
+ function SidebarRail({
1106
+ className,
1107
+ ...props
1108
+ }) {
1109
+ const { toggle } = useSidebar();
1110
+ return /* @__PURE__ */ jsx37(
1111
+ "button",
1112
+ {
1113
+ type: "button",
1114
+ "aria-label": "Alternar navegaci\xF3n",
1115
+ onClick: toggle,
1116
+ className: cn(
1117
+ "absolute inset-y-0 right-0 z-20 hidden w-1 -translate-x-1/2 cursor-ew-resize bg-transparent transition-colors hover:bg-border lg:block",
1118
+ className
1119
+ ),
1120
+ ...props
1121
+ }
1122
+ );
1123
+ }
1124
+ function SidebarMore({ className, ...props }) {
1125
+ return /* @__PURE__ */ jsx37(
1126
+ Button2,
1127
+ {
1128
+ "aria-label": "M\xE1s opciones",
1129
+ size: "icon",
1130
+ variant: "ghost",
1131
+ className: cn("size-7", className),
1132
+ ...props,
1133
+ children: /* @__PURE__ */ jsx37(DotsThreeIcon, { weight: "bold" })
1134
+ }
1135
+ );
1136
+ }
1137
+
1138
+ // src/ui/skeleton/skeleton.tsx
1139
+ import { jsx as jsx38 } from "react/jsx-runtime";
451
1140
  function Skeleton({ className, ...props }) {
452
- return /* @__PURE__ */ jsx18("div", { "aria-hidden": "true", "data-slot": "skeleton", className: cn("animate-pulse rounded-md bg-muted", className), ...props });
1141
+ return /* @__PURE__ */ jsx38("div", { "aria-hidden": "true", "data-slot": "skeleton", className: cn("animate-pulse rounded-md bg-muted", className), ...props });
453
1142
  }
454
1143
 
455
- // src/ui/switch.tsx
1144
+ // src/ui/submit-button/submit-button.tsx
1145
+ import { useFormStatus } from "react-dom";
1146
+ import { CircleNotchIcon as CircleNotchIcon3 } from "@phosphor-icons/react";
1147
+ import { Fragment as Fragment7, jsx as jsx39, jsxs as jsxs14 } from "react/jsx-runtime";
1148
+ function SubmitButton({ pendingLabel = "Guardando\u2026", loading = false, children, isDisabled, size = "sm", ...props }) {
1149
+ const { pending } = useFormStatus();
1150
+ const busy = pending || loading;
1151
+ return /* @__PURE__ */ jsx39(Button2, { type: "submit", size, isDisabled: busy || isDisabled, "aria-busy": busy || void 0, ...props, children: busy ? /* @__PURE__ */ jsxs14(Fragment7, { children: [
1152
+ /* @__PURE__ */ jsx39(CircleNotchIcon3, { "aria-hidden": "true", className: "size-3.5 animate-spin" }),
1153
+ pendingLabel
1154
+ ] }) : children });
1155
+ }
1156
+
1157
+ // src/ui/switch/switch.tsx
456
1158
  import {
457
- Switch as AriaSwitch
1159
+ SwitchButton as AriaSwitchButton,
1160
+ SwitchField as AriaSwitchField
458
1161
  } from "react-aria-components";
459
- import { Fragment as Fragment4, jsx as jsx19, jsxs as jsxs5 } from "react/jsx-runtime";
460
- function Switch({ className, children, ...props }) {
461
- return /* @__PURE__ */ jsx19(AriaSwitch, { "data-slot": "switch", className: cn("group inline-flex items-center gap-2 text-sm text-foreground data-disabled:cursor-not-allowed data-disabled:opacity-50", className), ...props, children: (state) => /* @__PURE__ */ jsxs5(Fragment4, { children: [
462
- /* @__PURE__ */ jsx19("span", { "aria-hidden": "true", className: "flex h-5 w-9 items-center rounded-full bg-muted p-0.5 transition-colors group-data-selected:bg-primary group-data-focus-visible:ring-3 group-data-focus-visible:ring-ring/50", children: /* @__PURE__ */ jsx19("span", { className: "size-4 rounded-full bg-background shadow-sm transition-transform group-data-selected:translate-x-4" }) }),
463
- typeof children === "function" ? children(state) : children
464
- ] }) });
1162
+ import { Fragment as Fragment8, jsx as jsx40, jsxs as jsxs15 } from "react/jsx-runtime";
1163
+ var sizeStyles = {
1164
+ sm: { track: "h-5 w-9 p-0.5", thumb: "size-4", travel: "group-data-selected/switch:translate-x-4" },
1165
+ md: { track: "h-6 w-11 p-0.5", thumb: "size-5", travel: "group-data-selected/switch:translate-x-5" }
1166
+ };
1167
+ function Switch({ className, children, size = "sm", ...props }) {
1168
+ const styles = sizeStyles[size];
1169
+ return /* @__PURE__ */ jsx40(AriaSwitchField, { ...props, children: /* @__PURE__ */ jsx40(
1170
+ AriaSwitchButton,
1171
+ {
1172
+ "data-slot": "switch",
1173
+ "data-size": size,
1174
+ className: (state) => cn(
1175
+ "group/switch inline-flex w-max items-center gap-2 text-sm text-foreground outline-none",
1176
+ "data-disabled:cursor-not-allowed data-disabled:opacity-50",
1177
+ typeof className === "function" ? className(state) : className
1178
+ ),
1179
+ children: (state) => /* @__PURE__ */ jsxs15(Fragment8, { children: [
1180
+ /* @__PURE__ */ jsx40(
1181
+ "span",
1182
+ {
1183
+ "aria-hidden": "true",
1184
+ className: cn(
1185
+ "relative inline-flex shrink-0 items-center rounded-full border border-transparent bg-secondary",
1186
+ "shadow-[inset_0_1px_2px_rgb(0_0_0/0.08)]",
1187
+ "transition-[background-color,box-shadow] duration-200 ease-out",
1188
+ "group-data-selected/switch:bg-primary group-data-hovered/switch:bg-secondary/80",
1189
+ "group-data-selected/switch:group-data-hovered/switch:bg-primary/90",
1190
+ "group-data-focus-visible/switch:ring-3 group-data-focus-visible/switch:ring-ring/40",
1191
+ "group-data-pressed/switch:ring-4 group-data-pressed/switch:ring-primary/10",
1192
+ "motion-reduce:transition-none",
1193
+ styles.track
1194
+ ),
1195
+ children: /* @__PURE__ */ jsx40(
1196
+ "span",
1197
+ {
1198
+ className: cn(
1199
+ "pointer-events-none block rounded-full bg-background shadow-[0_1px_2px_rgb(0_0_0/0.18)]",
1200
+ "transition-[transform,background-color,box-shadow] duration-200 ease-[cubic-bezier(0.22,1,0.36,1)]",
1201
+ "group-data-selected/switch:bg-primary-foreground group-data-selected/switch:shadow-[0_1px_3px_rgb(0_0_0/0.22)]",
1202
+ "group-data-pressed/switch:scale-[0.94] motion-reduce:transition-none",
1203
+ styles.travel,
1204
+ styles.thumb
1205
+ )
1206
+ }
1207
+ )
1208
+ }
1209
+ ),
1210
+ children != null && /* @__PURE__ */ jsx40("span", { className: "select-none font-medium leading-5 text-foreground", children: typeof children === "function" ? children(state) : children })
1211
+ ] })
1212
+ }
1213
+ ) });
465
1214
  }
466
1215
 
467
- // src/ui/table.tsx
468
- import { jsx as jsx20 } from "react/jsx-runtime";
1216
+ // src/ui/table/table.tsx
1217
+ import { jsx as jsx41 } from "react/jsx-runtime";
469
1218
  function Table({ className, ...props }) {
470
- return /* @__PURE__ */ jsx20("div", { "data-slot": "table-container", className: "relative w-full overflow-x-auto", children: /* @__PURE__ */ jsx20("table", { "data-slot": "table", className: cn("w-full caption-bottom text-sm", className), ...props }) });
1219
+ return /* @__PURE__ */ jsx41("div", { "data-slot": "table-container", className: "relative w-full overflow-x-auto", children: /* @__PURE__ */ jsx41("table", { "data-slot": "table", className: cn("w-full caption-bottom text-sm", className), ...props }) });
471
1220
  }
472
1221
  function TableHeader({ className, ...props }) {
473
- return /* @__PURE__ */ jsx20("thead", { "data-slot": "table-header", className: cn("border-b border-border", className), ...props });
1222
+ return /* @__PURE__ */ jsx41("thead", { "data-slot": "table-header", className: cn("border-b border-border", className), ...props });
474
1223
  }
475
1224
  function TableBody({ className, ...props }) {
476
- return /* @__PURE__ */ jsx20("tbody", { "data-slot": "table-body", className: cn("[&_tr:last-child]:border-0", className), ...props });
1225
+ return /* @__PURE__ */ jsx41("tbody", { "data-slot": "table-body", className: cn("[&_tr:last-child]:border-0", className), ...props });
477
1226
  }
478
1227
  function TableRow({ className, ...props }) {
479
- return /* @__PURE__ */ jsx20("tr", { "data-slot": "table-row", className: cn("border-b border-border transition-colors hover:bg-muted/50", className), ...props });
1228
+ return /* @__PURE__ */ jsx41("tr", { "data-slot": "table-row", className: cn("border-b border-border transition-colors hover:bg-muted/50", className), ...props });
480
1229
  }
481
1230
  function TableHead({ className, ...props }) {
482
- return /* @__PURE__ */ jsx20("th", { "data-slot": "table-head", className: cn("h-10 px-3 text-left align-middle text-xs font-medium text-muted-foreground", className), ...props });
1231
+ return /* @__PURE__ */ jsx41("th", { "data-slot": "table-head", className: cn("h-10 px-3 text-left align-middle text-xs font-medium text-muted-foreground", className), ...props });
483
1232
  }
484
1233
  function TableCell({ className, ...props }) {
485
- return /* @__PURE__ */ jsx20("td", { "data-slot": "table-cell", className: cn("p-3 align-middle", className), ...props });
1234
+ return /* @__PURE__ */ jsx41("td", { "data-slot": "table-cell", className: cn("p-3 align-middle", className), ...props });
486
1235
  }
487
1236
  function TableCaption({ className, ...props }) {
488
- return /* @__PURE__ */ jsx20("caption", { "data-slot": "table-caption", className: cn("mt-4 text-sm text-muted-foreground", className), ...props });
1237
+ return /* @__PURE__ */ jsx41("caption", { "data-slot": "table-caption", className: cn("mt-4 text-sm text-muted-foreground", className), ...props });
489
1238
  }
490
1239
 
491
- // src/ui/tabs.tsx
1240
+ // src/ui/tabs/tabs.tsx
492
1241
  import {
493
1242
  Tab as AriaTab,
494
1243
  TabList as AriaTabList,
@@ -497,46 +1246,150 @@ import {
497
1246
  Tabs as AriaTabs,
498
1247
  composeRenderProps
499
1248
  } from "react-aria-components";
500
- import { jsx as jsx21 } from "react/jsx-runtime";
1249
+ import { jsx as jsx42 } from "react/jsx-runtime";
501
1250
  function Tabs({ className, ...props }) {
502
- return /* @__PURE__ */ jsx21(AriaTabs, { "data-slot": "tabs", className: composeRenderProps(className, (value) => cn("flex flex-col gap-2", value)), ...props });
1251
+ return /* @__PURE__ */ jsx42(AriaTabs, { "data-slot": "tabs", className: composeRenderProps(className, (value) => cn("flex flex-col gap-2", value)), ...props });
503
1252
  }
504
1253
  function TabsList({ className, ...props }) {
505
- return /* @__PURE__ */ jsx21(AriaTabList, { "data-slot": "tabs-list", className: composeRenderProps(className, (value) => cn("inline-flex w-fit items-center gap-1 rounded-lg bg-muted p-1 text-muted-foreground", value)), ...props });
1254
+ return /* @__PURE__ */ jsx42(AriaTabList, { "data-slot": "tabs-list", className: composeRenderProps(className, (value) => cn("inline-flex w-fit items-center gap-1 rounded-lg bg-muted p-1 text-muted-foreground", value)), ...props });
506
1255
  }
507
1256
  function TabsTrigger({ className, ...props }) {
508
- return /* @__PURE__ */ jsx21(AriaTab, { "data-slot": "tabs-trigger", className: composeRenderProps(className, (value) => cn("inline-flex h-7 items-center justify-center gap-1.5 rounded-md px-2.5 text-sm font-medium outline-none transition-colors data-hovered:text-foreground data-selected:bg-background data-selected:text-foreground data-selected:shadow-sm data-focus-visible:ring-3 data-focus-visible:ring-ring/50 data-disabled:cursor-not-allowed data-disabled:opacity-50", value)), ...props });
1257
+ return /* @__PURE__ */ jsx42(AriaTab, { "data-slot": "tabs-trigger", className: composeRenderProps(className, (value) => cn("inline-flex h-7 items-center justify-center gap-1.5 rounded-md px-2.5 text-sm font-medium outline-none transition-colors data-hovered:text-foreground data-selected:bg-background data-selected:text-foreground data-selected:shadow-sm data-focus-visible:ring-3 data-focus-visible:ring-ring/50 data-disabled:cursor-not-allowed data-disabled:opacity-50", value)), ...props });
509
1258
  }
510
1259
  function TabsPanels({ className, ...props }) {
511
- return /* @__PURE__ */ jsx21(AriaTabPanels, { "data-slot": "tabs-panels", className: cn("min-w-0", className), ...props });
1260
+ return /* @__PURE__ */ jsx42(AriaTabPanels, { "data-slot": "tabs-panels", className: cn("min-w-0", className), ...props });
512
1261
  }
513
1262
  function TabsContent({ className, ...props }) {
514
- return /* @__PURE__ */ jsx21(AriaTabPanel, { "data-slot": "tabs-content", className: composeRenderProps(className, (value) => cn("text-sm outline-none data-focus-visible:ring-3 data-focus-visible:ring-ring/50", value)), ...props });
1263
+ return /* @__PURE__ */ jsx42(AriaTabPanel, { "data-slot": "tabs-content", className: composeRenderProps(className, (value) => cn("text-sm outline-none data-focus-visible:ring-3 data-focus-visible:ring-ring/50", value)), ...props });
515
1264
  }
516
1265
 
517
- // src/ui/textarea.tsx
518
- import { forwardRef as forwardRef3 } from "react";
519
- import { TextArea as AriaTextArea } from "react-aria-components";
520
- import { jsx as jsx22 } from "react/jsx-runtime";
521
- var TextareaImpl = forwardRef3(function Textarea({ className, ...props }, ref) {
522
- return /* @__PURE__ */ jsx22(AriaTextArea, { ref, "data-slot": "textarea", className: cn("min-h-20 w-full rounded-lg border border-border bg-background px-2.5 py-2 text-sm text-foreground outline-none placeholder:text-muted-foreground focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive", className), ...props });
1266
+ // src/ui/toast/toast.tsx
1267
+ import { useEffect as useEffect4, useSyncExternalStore } from "react";
1268
+ import { CheckCircleIcon as CheckCircleIcon2, InfoIcon, WarningCircleIcon as WarningCircleIcon2, XCircleIcon, XIcon as XIcon3 } from "@phosphor-icons/react";
1269
+ import { Fragment as Fragment9, jsx as jsx43, jsxs as jsxs16 } from "react/jsx-runtime";
1270
+ var records = [];
1271
+ var listeners = /* @__PURE__ */ new Set();
1272
+ var snapshot = () => records;
1273
+ var emit = () => listeners.forEach((listener) => listener());
1274
+ var subscribe = (listener) => {
1275
+ listeners.add(listener);
1276
+ return () => listeners.delete(listener);
1277
+ };
1278
+ var remove = (id) => {
1279
+ records = records.filter((record) => record.id !== id);
1280
+ emit();
1281
+ };
1282
+ function create(options) {
1283
+ const id = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
1284
+ records = [...records, { ...options, id, state: "open", variant: options.variant ?? "default", duration: options.duration ?? 5e3, position: options.position ?? "bottom-right" }];
1285
+ emit();
1286
+ return id;
1287
+ }
1288
+ function dismiss(id) {
1289
+ if (!records.some((record) => record.id === id && record.state === "open")) return;
1290
+ records = records.map((record) => record.id === id ? { ...record, state: "closing" } : record);
1291
+ emit();
1292
+ window.setTimeout(() => remove(id), 180);
1293
+ }
1294
+ function update(id, patch) {
1295
+ records = records.map((record) => record.id === id ? { ...record, ...patch, state: "open" } : record);
1296
+ emit();
1297
+ }
1298
+ var toast = Object.assign((options) => create(options), {
1299
+ success: (title, options) => create({ ...options, title, variant: "success" }),
1300
+ error: (title, options) => create({ ...options, title, variant: "error" }),
1301
+ warning: (title, options) => create({ ...options, title, variant: "warning" }),
1302
+ info: (title, options) => create({ ...options, title, variant: "info" }),
1303
+ dismiss,
1304
+ promise: (promise, options) => {
1305
+ const id = create({ title: options.loading, description: options.description, variant: "default", duration: 0, position: options.position });
1306
+ promise.then((value) => update(id, { title: typeof options.success === "function" ? options.success(value) : options.success, variant: "success", duration: 4e3 })).catch((error) => update(id, { title: typeof options.error === "function" ? options.error(error) : options.error, variant: "error", duration: 6e3 }));
1307
+ return promise;
1308
+ }
523
1309
  });
524
- var Textarea2 = TextareaImpl;
1310
+ function useToast() {
1311
+ return toast;
1312
+ }
1313
+ function ToastProvider({ children }) {
1314
+ return /* @__PURE__ */ jsxs16(Fragment9, { children: [
1315
+ children,
1316
+ /* @__PURE__ */ jsx43(Toaster, {})
1317
+ ] });
1318
+ }
1319
+ var positionClasses = {
1320
+ "top-left": "top-4 left-4 items-start",
1321
+ "top-center": "top-4 left-1/2 -translate-x-1/2 items-center",
1322
+ "top-right": "top-4 right-4 items-end",
1323
+ "bottom-left": "bottom-4 left-4 items-start",
1324
+ "bottom-center": "bottom-4 left-1/2 -translate-x-1/2 items-center",
1325
+ "bottom-right": "bottom-4 right-4 items-end"
1326
+ };
1327
+ function Toaster({ position = "bottom-right" }) {
1328
+ return /* @__PURE__ */ jsx43(Fragment9, { children: Object.keys(positionClasses).map((item) => /* @__PURE__ */ jsx43(ToastViewport, { position: item, visiblePosition: position }, item)) });
1329
+ }
1330
+ function ToastViewport({ position, visiblePosition, className }) {
1331
+ const toasts = useSyncExternalStore(subscribe, snapshot, snapshot).filter((item) => item.position === position);
1332
+ if (visiblePosition && position !== visiblePosition && toasts.length === 0) return null;
1333
+ return /* @__PURE__ */ jsx43("div", { "aria-label": `Notificaciones ${position}`, className: cn("pointer-events-none fixed z-50 flex w-[min(24rem,calc(100vw-2rem))] flex-col gap-2", positionClasses[position], className), children: toasts.map((item) => /* @__PURE__ */ jsx43(Toast, { ...item, onDismiss: () => dismiss(item.id) }, item.id)) });
1334
+ }
1335
+ function Toast({ id, title, description, variant = "default", action, state = "open", duration = 0, onDismiss }) {
1336
+ useEffect4(() => {
1337
+ if (state !== "open" || duration <= 0) return;
1338
+ const timeout = window.setTimeout(() => dismiss(id), duration);
1339
+ return () => window.clearTimeout(timeout);
1340
+ }, [duration, id, state]);
1341
+ const Icon = variant === "success" ? CheckCircleIcon2 : variant === "error" ? XCircleIcon : variant === "warning" ? WarningCircleIcon2 : variant === "info" ? InfoIcon : InfoIcon;
1342
+ return /* @__PURE__ */ jsx43("div", { role: variant === "error" ? "alert" : "status", "data-state": state, className: cn("pointer-events-auto w-full overflow-hidden rounded-xl border border-border/80 bg-background/95 p-3.5 text-foreground shadow-xl shadow-black/10 backdrop-blur-md animate-ui-toast-in", "data-[state=closing]:animate-ui-toast-out motion-reduce:animate-none", variant === "success" && "border-success/30", variant === "error" && "border-destructive/30", variant === "warning" && "border-warning/40"), children: /* @__PURE__ */ jsxs16("div", { className: "flex items-start gap-3", children: [
1343
+ /* @__PURE__ */ jsx43(Icon, { "aria-hidden": "true", weight: "duotone", className: cn("mt-0.5 size-5 shrink-0", variant === "success" && "text-success", variant === "error" && "text-destructive", variant === "warning" && "text-warning", variant === "info" && "text-primary") }),
1344
+ /* @__PURE__ */ jsxs16("div", { className: "min-w-0 flex-1", children: [
1345
+ /* @__PURE__ */ jsx43("p", { className: "animate-ui-toast-title text-sm font-semibold", children: title }),
1346
+ description && /* @__PURE__ */ jsx43("p", { className: "mt-1 max-h-20 animate-ui-toast-description overflow-hidden text-sm leading-5 text-muted-foreground data-[state=closing]:max-h-0", "data-state": state, children: description }),
1347
+ action && /* @__PURE__ */ jsx43(Button2, { size: "sm", variant: "link", onPress: action.onPress, className: "mt-1 h-auto px-0", children: action.label })
1348
+ ] }),
1349
+ /* @__PURE__ */ jsx43(Button2, { "aria-label": "Cerrar notificaci\xF3n", onPress: onDismiss, size: "icon", variant: "ghost", className: "-mr-2 -mt-2 size-7", children: /* @__PURE__ */ jsx43(XIcon3, {}) })
1350
+ ] }) });
1351
+ }
525
1352
 
526
- // src/ui/tooltip.tsx
527
- import {
528
- Tooltip as AriaTooltip,
529
- TooltipTrigger as AriaTooltipTrigger
530
- } from "react-aria-components";
531
- import { jsx as jsx23 } from "react/jsx-runtime";
532
- var TooltipTrigger = AriaTooltipTrigger;
533
- function Tooltip({ className, ...props }) {
534
- return /* @__PURE__ */ jsx23(AriaTooltip, { "data-slot": "tooltip", offset: 6, className: cn("max-w-xs rounded-md bg-foreground px-2.5 py-1.5 text-xs text-background shadow-md outline-none data-entering:animate-in data-entering:fade-in-0 data-entering:zoom-in-95 data-exiting:animate-out data-exiting:fade-out-0 data-exiting:zoom-out-95", className), ...props });
1353
+ // src/ui/toolbar/toolbar.tsx
1354
+ import { jsx as jsx44 } from "react/jsx-runtime";
1355
+ function Toolbar({ className, ...props }) {
1356
+ return /* @__PURE__ */ jsx44("div", { role: "toolbar", "data-slot": "toolbar", className: cn("flex flex-wrap items-center gap-2", className), ...props });
1357
+ }
1358
+ function ToolbarGroup({ className, ...props }) {
1359
+ return /* @__PURE__ */ jsx44("div", { "data-slot": "toolbar-group", className: cn("flex items-center gap-2", className), ...props });
1360
+ }
1361
+ function ToolbarSpacer({ className, ...props }) {
1362
+ return /* @__PURE__ */ jsx44("div", { "aria-hidden": "true", className: cn("hidden flex-1 sm:block", className), ...props });
535
1363
  }
536
- var TooltipContent = Tooltip;
537
1364
  export {
1365
+ Accordion,
1366
+ AccordionContent,
1367
+ AccordionItem,
1368
+ AccordionTrigger,
1369
+ Alert,
1370
+ AlertAction,
1371
+ AlertDescription,
1372
+ AlertTitle,
1373
+ AppShell,
1374
+ AppShellContent,
1375
+ AppShellHeader,
1376
+ AppShellMain,
1377
+ AutocompleteCombobox,
1378
+ Avatar,
1379
+ AvatarBadge,
1380
+ AvatarFallback,
1381
+ AvatarGroup,
1382
+ AvatarGroupCount,
1383
+ AvatarImage,
538
1384
  Badge,
539
- Button,
1385
+ Breadcrumb,
1386
+ BreadcrumbLink,
1387
+ BreadcrumbPage,
1388
+ BreadcrumbSeparator,
1389
+ Breadcrumbs,
1390
+ Button2 as Button,
1391
+ ButtonGroup,
1392
+ ButtonGroupText,
540
1393
  Card,
541
1394
  CardContent,
542
1395
  CardDescription,
@@ -550,6 +1403,11 @@ export {
550
1403
  ComboboxItem,
551
1404
  ComboboxList,
552
1405
  ComboBoxValue as ComboboxValue,
1406
+ Command,
1407
+ CommandContent,
1408
+ CommandInput,
1409
+ CommandItem,
1410
+ CommandList,
553
1411
  ConfirmDialog,
554
1412
  Dialog,
555
1413
  DialogClose,
@@ -558,25 +1416,52 @@ export {
558
1416
  DialogFooter,
559
1417
  DialogHeader,
560
1418
  DialogTitle,
1419
+ Drawer,
1420
+ DrawerDescription,
1421
+ DrawerFooter,
1422
+ DrawerHeader,
1423
+ DrawerTitle,
1424
+ DropdownMenu,
1425
+ DropdownMenuContent,
1426
+ DropdownMenuItem,
1427
+ DropdownMenuSeparator,
1428
+ DropdownMenuTrigger,
561
1429
  EmptyState,
562
1430
  EmptyStateDescription,
563
1431
  EmptyStateTitle,
564
1432
  Field,
565
1433
  FieldDescription,
566
- FieldError,
1434
+ FieldError2 as FieldError,
567
1435
  FieldLabel,
1436
+ FormFeedback,
1437
+ FormRow,
568
1438
  HighlightMatch,
1439
+ IconButton,
569
1440
  Input3 as Input,
1441
+ InputGroup,
1442
+ InputGroupAddon,
1443
+ InputGroupButton,
1444
+ InputGroupInput,
1445
+ InputGroupText,
1446
+ InputGroupTextarea,
570
1447
  Kbd,
571
1448
  KbdGroup,
572
- Label,
1449
+ Label2 as Label,
1450
+ LoadingOverlay,
573
1451
  Menu,
574
1452
  MenuContent,
575
1453
  MenuItem,
576
1454
  MenuTrigger,
577
- Popover3 as Popover,
1455
+ PageHeader,
1456
+ PageHeaderActions,
1457
+ PageHeaderDescription,
1458
+ PageHeaderHeading,
1459
+ PageHeaderTitle,
1460
+ Pagination,
1461
+ Popover4 as Popover,
578
1462
  PopoverContent,
579
1463
  PopoverTrigger,
1464
+ QuantityInput,
580
1465
  SearchClearButton,
581
1466
  SearchField,
582
1467
  SearchInput,
@@ -587,7 +1472,20 @@ export {
587
1472
  SelectTrigger,
588
1473
  SelectValue,
589
1474
  Separator,
1475
+ Sidebar,
1476
+ SidebarContent,
1477
+ SidebarFooter,
1478
+ SidebarGroup,
1479
+ SidebarHeader,
1480
+ SidebarItem,
1481
+ SidebarMore,
1482
+ SidebarProvider,
1483
+ SidebarRail,
1484
+ SidebarSearch,
1485
+ SidebarSeparator,
1486
+ SidebarTrigger,
590
1487
  Skeleton,
1488
+ SubmitButton,
591
1489
  Switch,
592
1490
  Table,
593
1491
  TableBody,
@@ -602,6 +1500,13 @@ export {
602
1500
  TabsPanels,
603
1501
  TabsTrigger,
604
1502
  Textarea2 as Textarea,
1503
+ Toast,
1504
+ ToastProvider,
1505
+ ToastViewport,
1506
+ Toaster,
1507
+ Toolbar,
1508
+ ToolbarGroup,
1509
+ ToolbarSpacer,
605
1510
  Tooltip,
606
1511
  TooltipContent,
607
1512
  TooltipTrigger,
@@ -610,8 +1515,12 @@ export {
610
1515
  cn,
611
1516
  formSnapshot,
612
1517
  getTextMatchParts,
1518
+ toast,
613
1519
  useAutosave,
614
1520
  useDebouncedValue,
615
- useFormDirty
1521
+ useFormDirty,
1522
+ useFormFeedback,
1523
+ useSidebar,
1524
+ useToast
616
1525
  };
617
1526
  //# sourceMappingURL=index.js.map