@fayz-ai/ui 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/analytics/derive.d.ts +1 -9
  2. package/dist/analytics/derive.d.ts.map +1 -1
  3. package/dist/{chunk-DFOAKWYB.js → chunk-5NEADAIP.js} +3 -3
  4. package/dist/{chunk-DFOAKWYB.js.map → chunk-5NEADAIP.js.map} +1 -1
  5. package/dist/{chunk-Z2ITFPGL.js → chunk-5WSKZU7M.js} +547 -74
  6. package/dist/chunk-5WSKZU7M.js.map +1 -0
  7. package/dist/{chunk-OBIU37AX.js → chunk-6YFPPK7X.js} +28 -14
  8. package/dist/chunk-6YFPPK7X.js.map +1 -0
  9. package/dist/{chunk-ZLPYNHXH.js → chunk-ERSX3C7T.js} +3 -3
  10. package/dist/{chunk-ZLPYNHXH.js.map → chunk-ERSX3C7T.js.map} +1 -1
  11. package/dist/{chunk-3OVZ5JJQ.js → chunk-GLRLWBBF.js} +4 -3
  12. package/dist/chunk-GLRLWBBF.js.map +1 -0
  13. package/dist/{chunk-AASANYXN.js → chunk-OB2ULDBD.js} +6 -4
  14. package/dist/chunk-OB2ULDBD.js.map +1 -0
  15. package/dist/chunk-SB6DWHXI.js +199 -0
  16. package/dist/chunk-SB6DWHXI.js.map +1 -0
  17. package/dist/dashboard/index.js +2 -2
  18. package/dist/icons.d.ts.map +1 -1
  19. package/dist/icons.js +1 -1
  20. package/dist/index.d.ts +2 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +11 -25
  23. package/dist/index.js.map +1 -1
  24. package/dist/layout/AppShell.d.ts +7 -1
  25. package/dist/layout/AppShell.d.ts.map +1 -1
  26. package/dist/layout/SaveBar.d.ts +10 -1
  27. package/dist/layout/SaveBar.d.ts.map +1 -1
  28. package/dist/layout/Sidebar.d.ts.map +1 -1
  29. package/dist/layout/index.js +3 -3
  30. package/dist/lib/error-message.d.ts +2 -0
  31. package/dist/lib/error-message.d.ts.map +1 -0
  32. package/dist/primitives/brand-marks.d.ts +11 -0
  33. package/dist/primitives/brand-marks.d.ts.map +1 -0
  34. package/dist/primitives/button.d.ts +1 -1
  35. package/dist/primitives/dot-badge.d.ts +27 -0
  36. package/dist/primitives/dot-badge.d.ts.map +1 -0
  37. package/dist/primitives/draft-commit-bar.d.ts +27 -0
  38. package/dist/primitives/draft-commit-bar.d.ts.map +1 -0
  39. package/dist/primitives/filter-check-list.d.ts +65 -0
  40. package/dist/primitives/filter-check-list.d.ts.map +1 -0
  41. package/dist/primitives/header-tabs.d.ts +19 -0
  42. package/dist/primitives/header-tabs.d.ts.map +1 -1
  43. package/dist/primitives/image-drop.d.ts.map +1 -1
  44. package/dist/primitives/index.d.ts +6 -0
  45. package/dist/primitives/index.d.ts.map +1 -1
  46. package/dist/primitives/index.js +4 -4
  47. package/dist/primitives/list-chrome.d.ts +5 -1
  48. package/dist/primitives/list-chrome.d.ts.map +1 -1
  49. package/dist/primitives/mini-calendar.d.ts +36 -0
  50. package/dist/primitives/mini-calendar.d.ts.map +1 -0
  51. package/dist/primitives/multi-select.d.ts +21 -0
  52. package/dist/primitives/multi-select.d.ts.map +1 -0
  53. package/dist/primitives/select.d.ts.map +1 -1
  54. package/dist/primitives/stock-entry-form.d.ts +52 -0
  55. package/dist/primitives/stock-entry-form.d.ts.map +1 -0
  56. package/dist/styles.css +100 -0
  57. package/dist/tailwind.cjs +1 -1
  58. package/dist/tailwind.cjs.map +1 -1
  59. package/dist/tailwind.js +1 -1
  60. package/dist/tailwind.js.map +1 -1
  61. package/dist/wizard/index.js +2 -2
  62. package/dist/wizard/useWizard.d.ts.map +1 -1
  63. package/package.json +2 -2
  64. package/dist/chunk-3OVZ5JJQ.js.map +0 -1
  65. package/dist/chunk-4GK6IHOI.js +0 -177
  66. package/dist/chunk-4GK6IHOI.js.map +0 -1
  67. package/dist/chunk-AASANYXN.js.map +0 -1
  68. package/dist/chunk-OBIU37AX.js.map +0 -1
  69. package/dist/chunk-Z2ITFPGL.js.map +0 -1
@@ -1,8 +1,8 @@
1
- import { useSaveBarVisible, useCrossModuleBack, useBackHandler, PageHeaderActions } from './chunk-OBIU37AX.js';
2
- import { useIsWide, Dropdown, DropdownTrigger, DropdownContent, DropdownSeparator, DropdownItem, Card, DataTable } from './chunk-E44WOPCR.js';
1
+ import { useSaveBarVisible, useCrossModuleBack, useBackHandler, PageHeaderActions } from './chunk-6YFPPK7X.js';
2
+ import { useIsWide, Dropdown, DropdownTrigger, DropdownContent, DropdownSeparator, DropdownItem, Card, DataTable, Checkbox } from './chunk-E44WOPCR.js';
3
3
  import { cn, Button } from './chunk-OKZ6WQB3.js';
4
- import * as React16 from 'react';
5
- import { useState, useRef, useEffect, useMemo, useCallback } from 'react';
4
+ import * as React18 from 'react';
5
+ import React18__default, { useState, useRef, useEffect, useMemo, useCallback } from 'react';
6
6
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
7
  import { cva } from 'class-variance-authority';
8
8
  import * as DialogPrimitive from '@radix-ui/react-dialog';
@@ -17,9 +17,9 @@ import { createPortal } from 'react-dom';
17
17
  import { useTranslation, getCountry, unmaskPhone, maskPhone, getCurrentLocale } from '@fayz-ai/core';
18
18
  import * as PopoverPrimitive from '@radix-ui/react-popover';
19
19
 
20
- var Input = React16.forwardRef(
20
+ var Input = React18.forwardRef(
21
21
  ({ className, type, error, description, id, ...props }, ref) => {
22
- const inputId = id ?? React16.useId();
22
+ const inputId = id ?? React18.useId();
23
23
  const descriptionId = description ? `${inputId}-description` : void 0;
24
24
  const errorId = error ? `${inputId}-error` : void 0;
25
25
  return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
@@ -107,7 +107,7 @@ var Modal = DialogPrimitive.Root;
107
107
  var ModalTrigger = DialogPrimitive.Trigger;
108
108
  var ModalClose = DialogPrimitive.Close;
109
109
  var ModalPortal = DialogPrimitive.Portal;
110
- var ModalOverlay = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
110
+ var ModalOverlay = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
111
111
  DialogPrimitive.Overlay,
112
112
  {
113
113
  ref,
@@ -120,7 +120,7 @@ var ModalOverlay = React16.forwardRef(({ className, ...props }, ref) => /* @__PU
120
120
  }
121
121
  ));
122
122
  ModalOverlay.displayName = "ModalOverlay";
123
- var ModalContent = React16.forwardRef(({ className, children, size = "lg", hideClose, noPadding, onPointerDownOutside, onInteractOutside, onCloseAutoFocus, ...props }, ref) => /* @__PURE__ */ jsx(ModalPortal, { children: /* @__PURE__ */ jsx(ModalOverlay, { children: /* @__PURE__ */ jsxs(
123
+ var ModalContent = React18.forwardRef(({ className, children, size = "lg", hideClose, noPadding, onPointerDownOutside, onInteractOutside, onCloseAutoFocus, ...props }, ref) => /* @__PURE__ */ jsx(ModalPortal, { children: /* @__PURE__ */ jsx(ModalOverlay, { children: /* @__PURE__ */ jsxs(
124
124
  DialogPrimitive.Content,
125
125
  {
126
126
  ref,
@@ -175,14 +175,14 @@ function ModalBody({ className, ...props }) {
175
175
  function ModalFooter({ className, ...props }) {
176
176
  return /* @__PURE__ */ jsx("div", { className: cn("mt-auto flex flex-col-reverse gap-2 sm:mt-0 sm:flex-row sm:justify-end sm:gap-0 sm:space-x-2 shrink-0", className), ...props });
177
177
  }
178
- var ModalTitle = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Title, { ref, className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props }));
178
+ var ModalTitle = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Title, { ref, className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props }));
179
179
  ModalTitle.displayName = "ModalTitle";
180
- var ModalDescription = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
180
+ var ModalDescription = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
181
181
  ModalDescription.displayName = "ModalDescription";
182
182
  var Select = SelectPrimitive.Root;
183
183
  var SelectGroup = SelectPrimitive.Group;
184
184
  var SelectValue = SelectPrimitive.Value;
185
- var SelectTrigger = React16.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
185
+ var SelectTrigger = React18.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
186
186
  SelectPrimitive.Trigger,
187
187
  {
188
188
  ref,
@@ -198,7 +198,7 @@ var SelectTrigger = React16.forwardRef(({ className, children, ...props }, ref)
198
198
  }
199
199
  ));
200
200
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
201
- var SelectScrollUpButton = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
201
+ var SelectScrollUpButton = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
202
202
  SelectPrimitive.ScrollUpButton,
203
203
  {
204
204
  ref,
@@ -211,7 +211,7 @@ var SelectScrollUpButton = React16.forwardRef(({ className, ...props }, ref) =>
211
211
  }
212
212
  ));
213
213
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
214
- var SelectScrollDownButton = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
214
+ var SelectScrollDownButton = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
215
215
  SelectPrimitive.ScrollDownButton,
216
216
  {
217
217
  ref,
@@ -224,7 +224,7 @@ var SelectScrollDownButton = React16.forwardRef(({ className, ...props }, ref) =
224
224
  }
225
225
  ));
226
226
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
227
- var SelectContent = React16.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
227
+ var SelectContent = React18.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
228
228
  SelectPrimitive.Content,
229
229
  {
230
230
  ref,
@@ -252,16 +252,19 @@ var SelectContent = React16.forwardRef(({ className, children, position = "poppe
252
252
  }
253
253
  ) }));
254
254
  SelectContent.displayName = SelectPrimitive.Content.displayName;
255
- var SelectLabel = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
255
+ var SelectLabel = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
256
256
  SelectPrimitive.Label,
257
257
  {
258
258
  ref,
259
- className: cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className),
259
+ className: cn(
260
+ "mt-1.5 px-2 py-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground first:mt-0",
261
+ className
262
+ ),
260
263
  ...props
261
264
  }
262
265
  ));
263
266
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
264
- var SelectItem = React16.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
267
+ var SelectItem = React18.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
265
268
  SelectPrimitive.Item,
266
269
  {
267
270
  ref,
@@ -277,7 +280,7 @@ var SelectItem = React16.forwardRef(({ className, children, ...props }, ref) =>
277
280
  }
278
281
  ));
279
282
  SelectItem.displayName = SelectPrimitive.Item.displayName;
280
- var SelectSeparator = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
283
+ var SelectSeparator = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
281
284
  SelectPrimitive.Separator,
282
285
  {
283
286
  ref,
@@ -315,7 +318,7 @@ function ToastProvider({
315
318
  );
316
319
  }
317
320
  var Tabs = TabsPrimitive.Root;
318
- var TabsList = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
321
+ var TabsList = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
319
322
  TabsPrimitive.List,
320
323
  {
321
324
  ref,
@@ -329,7 +332,7 @@ var TabsList = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__
329
332
  }
330
333
  ));
331
334
  TabsList.displayName = TabsPrimitive.List.displayName;
332
- var TabsTrigger = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
335
+ var TabsTrigger = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
333
336
  TabsPrimitive.Trigger,
334
337
  {
335
338
  ref,
@@ -341,7 +344,7 @@ var TabsTrigger = React16.forwardRef(({ className, ...props }, ref) => /* @__PUR
341
344
  }
342
345
  ));
343
346
  TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
344
- var TabsContent = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
347
+ var TabsContent = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
345
348
  TabsPrimitive.Content,
346
349
  {
347
350
  ref,
@@ -353,7 +356,7 @@ var TabsContent = React16.forwardRef(({ className, ...props }, ref) => /* @__PUR
353
356
  }
354
357
  ));
355
358
  TabsContent.displayName = TabsPrimitive.Content.displayName;
356
- var Separator2 = React16.forwardRef(
359
+ var Separator2 = React18.forwardRef(
357
360
  ({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
358
361
  SeparatorPrimitive.Root,
359
362
  {
@@ -404,7 +407,7 @@ function formatPhone(digits, fallback, countryCode) {
404
407
  const tail = rest.length === 9 ? rest.slice(5) : rest.slice(4);
405
408
  return `+55 (${ddd}) ${head}-${tail}`;
406
409
  }
407
- var PhoneLink = React16.forwardRef(
410
+ var PhoneLink = React18.forwardRef(
408
411
  ({ phone, message, countryCode, raw, className, children, ...props }, ref) => {
409
412
  const { e164, display } = normalizePhone(phone, countryCode);
410
413
  const label = children ?? (raw ? phone ?? "" : display);
@@ -467,7 +470,7 @@ function Breadcrumb({ parent, current, onBack }) {
467
470
  var TooltipProvider = TooltipPrimitive.Provider;
468
471
  var Tooltip = TooltipPrimitive.Root;
469
472
  var TooltipTrigger = TooltipPrimitive.Trigger;
470
- var TooltipContent = React16.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
473
+ var TooltipContent = React18.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
471
474
  TooltipPrimitive.Content,
472
475
  {
473
476
  ref,
@@ -601,9 +604,9 @@ function PageActionFab({ actions }) {
601
604
  ] });
602
605
  }
603
606
  function useScrim(open) {
604
- const [mounted, setMounted] = React16.useState(open);
605
- const [visible, setVisible] = React16.useState(open);
606
- React16.useEffect(() => {
607
+ const [mounted, setMounted] = React18.useState(open);
608
+ const [visible, setVisible] = React18.useState(open);
609
+ React18.useEffect(() => {
607
610
  if (open) {
608
611
  setMounted(true);
609
612
  const frame = requestAnimationFrame(() => setVisible(true));
@@ -617,7 +620,7 @@ function useScrim(open) {
617
620
  }
618
621
  var SCRIM_MS = 200;
619
622
  function FabButton({ actions, tone, mini }) {
620
- const [open, setOpen] = React16.useState(false);
623
+ const [open, setOpen] = React18.useState(false);
621
624
  const scrim = useScrim(open);
622
625
  if (actions.length === 0) return null;
623
626
  const isCreate = tone === "primary";
@@ -729,7 +732,7 @@ function RowActions({
729
732
  const Icon2 = a.icon;
730
733
  const isDanger = a.intent === "danger";
731
734
  const prevSafe = i > 0 && overflow[i - 1].intent !== "danger";
732
- return /* @__PURE__ */ jsxs(React16.Fragment, { children: [
735
+ return /* @__PURE__ */ jsxs(React18.Fragment, { children: [
733
736
  isDanger && prevSafe && /* @__PURE__ */ jsx(DropdownSeparator, {}),
734
737
  /* @__PURE__ */ jsxs(
735
738
  DropdownItem,
@@ -753,8 +756,8 @@ var rowActionsLabel = "A\xE7\xF5es";
753
756
  function setRowActionsLabel(label) {
754
757
  rowActionsLabel = label;
755
758
  }
756
- function SearchField({ value, onChange, placeholder, ...rest }) {
757
- return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
759
+ function SearchField({ value, onChange, placeholder, className, ...rest }) {
760
+ return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
758
761
  /* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" }),
759
762
  /* @__PURE__ */ jsx(
760
763
  "input",
@@ -897,6 +900,46 @@ function BulkActionBar({
897
900
  );
898
901
  }
899
902
  BulkActionBar.displayName = "BulkActionBar";
903
+ function DraftCommitBar({
904
+ open,
905
+ title,
906
+ hint,
907
+ icon: Icon2,
908
+ commitLabel,
909
+ onCommit,
910
+ discardLabel,
911
+ onDiscard,
912
+ busy,
913
+ commitDisabledReason,
914
+ className
915
+ }) {
916
+ if (!open) return null;
917
+ return /* @__PURE__ */ jsxs(
918
+ "div",
919
+ {
920
+ role: "region",
921
+ "aria-label": title,
922
+ className: cn(
923
+ "sticky bottom-3 z-10 flex flex-wrap items-center gap-3 rounded-card border bg-card px-4 py-2.5 shadow-lg",
924
+ className
925
+ ),
926
+ children: [
927
+ Icon2 && /* @__PURE__ */ jsx(Icon2, { className: "h-4 w-4 shrink-0 text-primary" }),
928
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
929
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: title }),
930
+ (commitDisabledReason || hint) && /* @__PURE__ */ jsx("p", { className: cn("text-[11px]", commitDisabledReason ? "text-warning" : "text-muted-foreground"), children: commitDisabledReason || hint })
931
+ ] }),
932
+ onDiscard && discardLabel && /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: onDiscard, disabled: busy, children: discardLabel }),
933
+ /* @__PURE__ */ jsxs(Button, { size: "sm", onClick: onCommit, disabled: busy || Boolean(commitDisabledReason), children: [
934
+ /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5" }),
935
+ " ",
936
+ commitLabel
937
+ ] })
938
+ ]
939
+ }
940
+ );
941
+ }
942
+ DraftCommitBar.displayName = "DraftCommitBar";
900
943
  var SIZE_CLASSES = {
901
944
  sm: "h-8 w-8 rounded",
902
945
  md: "h-9 w-9 rounded",
@@ -908,8 +951,8 @@ var ICON_CLASSES = {
908
951
  lg: "h-5 w-5"
909
952
  };
910
953
  function Thumbnail({ src, alt = "", size = "md", icon: Icon2 = ImageIcon, className }) {
911
- const [failed, setFailed] = React16.useState(false);
912
- React16.useEffect(() => {
954
+ const [failed, setFailed] = React18.useState(false);
955
+ React18.useEffect(() => {
913
956
  setFailed(false);
914
957
  }, [src]);
915
958
  const base = cn("shrink-0 overflow-hidden", SIZE_CLASSES[size], className);
@@ -936,9 +979,9 @@ function Thumbnail({ src, alt = "", size = "md", icon: Icon2 = ImageIcon, classN
936
979
  }
937
980
  Thumbnail.displayName = "Thumbnail";
938
981
  function RefreshButton({ onRefresh, fromCache, label, labelCached, className, ...rest }) {
939
- const [phase, setPhase] = React16.useState("idle");
940
- const alive = React16.useRef(true);
941
- React16.useEffect(() => () => {
982
+ const [phase, setPhase] = React18.useState("idle");
983
+ const alive = React18.useRef(true);
984
+ React18.useEffect(() => () => {
942
985
  alive.current = false;
943
986
  }, []);
944
987
  const title = fromCache ? labelCached ?? label : label;
@@ -1032,8 +1075,8 @@ function StatTiles({ tiles, loading, className }) {
1032
1075
  ] }, tile.id);
1033
1076
  }) });
1034
1077
  }
1035
- var Hint = React16.forwardRef(function Hint2({ label, children, side = "top", delayDuration = 0, ...rest }, ref) {
1036
- if (!label) return React16.cloneElement(children, { ...rest, ref });
1078
+ var Hint = React18.forwardRef(function Hint2({ label, children, side = "top", delayDuration = 0, ...rest }, ref) {
1079
+ if (!label) return React18.cloneElement(children, { ...rest, ref });
1037
1080
  return /* @__PURE__ */ jsx(TooltipPrimitive.Provider, { delayDuration, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
1038
1081
  /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, ...rest, ref, children }),
1039
1082
  /* @__PURE__ */ jsx(TooltipContent, { side, className: "px-2 py-1 text-xs font-medium", children: label })
@@ -1160,27 +1203,27 @@ function useRowSelection({
1160
1203
  getRowId,
1161
1204
  enabled = true
1162
1205
  }) {
1163
- const identify = React16.useCallback(
1206
+ const identify = React18.useCallback(
1164
1207
  (row) => getRowId ? getRowId(row) : String(row?.id ?? ""),
1165
1208
  [getRowId]
1166
1209
  );
1167
- const visible = React16.useMemo(() => rows ?? [], [rows]);
1168
- const [rawSelection, setRawSelection] = React16.useState([]);
1169
- const visibleIds = React16.useMemo(() => new Set(visible.map(identify)), [visible, identify]);
1170
- const selectedIds = React16.useMemo(
1210
+ const visible = React18.useMemo(() => rows ?? [], [rows]);
1211
+ const [rawSelection, setRawSelection] = React18.useState([]);
1212
+ const visibleIds = React18.useMemo(() => new Set(visible.map(identify)), [visible, identify]);
1213
+ const selectedIds = React18.useMemo(
1171
1214
  () => rawSelection.filter((id) => visibleIds.has(id)),
1172
1215
  [rawSelection, visibleIds]
1173
1216
  );
1174
- const selectedRows = React16.useMemo(() => {
1217
+ const selectedRows = React18.useMemo(() => {
1175
1218
  const picked = new Set(selectedIds);
1176
1219
  return visible.filter((row) => picked.has(identify(row)));
1177
1220
  }, [visible, selectedIds, identify]);
1178
- const clear = React16.useCallback(() => setRawSelection([]), []);
1179
- const selectAll = React16.useCallback(
1221
+ const clear = React18.useCallback(() => setRawSelection([]), []);
1222
+ const selectAll = React18.useCallback(
1180
1223
  () => setRawSelection(visible.map(identify)),
1181
1224
  [visible, identify]
1182
1225
  );
1183
- const barActions = React16.useMemo(
1226
+ const barActions = React18.useMemo(
1184
1227
  () => (actions ?? []).map((action) => ({
1185
1228
  id: action.id,
1186
1229
  label: action.label,
@@ -1595,7 +1638,180 @@ function DatePicker({ value, onChange, className, variant = "input", defaultOpen
1595
1638
  )
1596
1639
  ] });
1597
1640
  }
1598
- var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React16.useLayoutEffect : React16.useEffect;
1641
+ var DAY_LABELS2 = {
1642
+ en: ["S", "M", "T", "W", "T", "F", "S"],
1643
+ "pt-BR": ["D", "S", "T", "Q", "Q", "S", "S"]
1644
+ };
1645
+ function isSameDay2(a, b) {
1646
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
1647
+ }
1648
+ function isToday2(d) {
1649
+ return isSameDay2(d, /* @__PURE__ */ new Date());
1650
+ }
1651
+ function toDateLocale2(locale) {
1652
+ if (locale === "pt-BR") return "pt-BR";
1653
+ return "en-US";
1654
+ }
1655
+ function toLocalISODate(d) {
1656
+ const month = String(d.getMonth() + 1).padStart(2, "0");
1657
+ const day = String(d.getDate()).padStart(2, "0");
1658
+ return `${d.getFullYear()}-${month}-${day}`;
1659
+ }
1660
+ function MiniCalendar({ selectedDate, onDateSelect, onMonthChange, markers }) {
1661
+ const locale = getCurrentLocale();
1662
+ const [viewMonth, setViewMonth] = React18__default.useState(() => new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1));
1663
+ const monthLabel = viewMonth.toLocaleDateString(toDateLocale2(locale), { month: "long", year: "numeric" });
1664
+ const dayLabels = DAY_LABELS2[locale] ?? DAY_LABELS2.en;
1665
+ const weeks = useMemo(() => {
1666
+ const year = viewMonth.getFullYear();
1667
+ const month = viewMonth.getMonth();
1668
+ const firstDay = new Date(year, month, 1);
1669
+ const startOffset = firstDay.getDay();
1670
+ const daysInMonth = new Date(year, month + 1, 0).getDate();
1671
+ const cells = [];
1672
+ for (let i = 0; i < startOffset; i++) cells.push(null);
1673
+ for (let d = 1; d <= daysInMonth; d++) cells.push(new Date(year, month, d));
1674
+ while (cells.length % 7 !== 0) cells.push(null);
1675
+ const rows = [];
1676
+ for (let i = 0; i < cells.length; i += 7) rows.push(cells.slice(i, i + 7));
1677
+ return rows;
1678
+ }, [viewMonth]);
1679
+ function prevMonth() {
1680
+ const d = new Date(viewMonth.getFullYear(), viewMonth.getMonth() - 1, 1);
1681
+ setViewMonth(d);
1682
+ onMonthChange?.(d);
1683
+ }
1684
+ function nextMonth() {
1685
+ const d = new Date(viewMonth.getFullYear(), viewMonth.getMonth() + 1, 1);
1686
+ setViewMonth(d);
1687
+ onMonthChange?.(d);
1688
+ }
1689
+ const hasMarkers = !!markers;
1690
+ return /* @__PURE__ */ jsxs("div", { className: "select-none", children: [
1691
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2", children: [
1692
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium capitalize", children: monthLabel }),
1693
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
1694
+ /* @__PURE__ */ jsx("button", { onClick: prevMonth, "aria-label": "Previous month", className: "flex h-6 w-6 items-center justify-center rounded-full hover:bg-muted transition-colors", children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-3.5 w-3.5" }) }),
1695
+ /* @__PURE__ */ jsx("button", { onClick: nextMonth, "aria-label": "Next month", className: "flex h-6 w-6 items-center justify-center rounded-full hover:bg-muted transition-colors", children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5" }) })
1696
+ ] })
1697
+ ] }),
1698
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 mb-0.5", children: dayLabels.map((label, i) => /* @__PURE__ */ jsx("div", { className: "flex h-6 w-6 items-center justify-center text-[10px] font-medium text-muted-foreground mx-auto", children: label }, i)) }),
1699
+ weeks.map((week, wi) => /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7", children: week.map((date, di) => {
1700
+ if (!date) return /* @__PURE__ */ jsx("div", { className: hasMarkers ? "h-9 w-6 mx-auto" : "h-6 w-6 mx-auto" }, di);
1701
+ const selected = isSameDay2(date, selectedDate);
1702
+ const today = isToday2(date);
1703
+ const dots = markers?.[toLocalISODate(date)] ?? [];
1704
+ return /* @__PURE__ */ jsxs("div", { className: hasMarkers ? "flex h-9 flex-col items-center" : "contents", children: [
1705
+ /* @__PURE__ */ jsx(
1706
+ "button",
1707
+ {
1708
+ onClick: () => onDateSelect(date),
1709
+ "aria-label": dots.length ? dots.map((m) => m.label).filter(Boolean).join(", ") || void 0 : void 0,
1710
+ className: `flex h-6 w-6 items-center justify-center rounded-full text-[11px] mx-auto transition-colors ${selected ? "bg-primary text-primary-foreground" : today ? "bg-primary/10 text-primary font-semibold" : "hover:bg-muted text-foreground"}`,
1711
+ children: date.getDate()
1712
+ }
1713
+ ),
1714
+ hasMarkers && /* @__PURE__ */ jsx("div", { className: "flex h-2 items-center gap-[2px]", children: dots.slice(0, 3).map((m, i) => /* @__PURE__ */ jsx("span", { className: "h-1 w-1 rounded-full", style: { backgroundColor: m.color } }, i)) })
1715
+ ] }, di);
1716
+ }) }, wi))
1717
+ ] });
1718
+ }
1719
+ function DotBadge({ label, color, hideDot, className }) {
1720
+ return /* @__PURE__ */ jsxs(
1721
+ "span",
1722
+ {
1723
+ className: `inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium whitespace-nowrap ${className ?? ""}`,
1724
+ style: {
1725
+ backgroundColor: `${color}15`,
1726
+ color,
1727
+ border: `1px solid ${color}30`
1728
+ },
1729
+ children: [
1730
+ !hideDot && /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 shrink-0 rounded-full", style: { backgroundColor: color } }),
1731
+ label
1732
+ ]
1733
+ }
1734
+ );
1735
+ }
1736
+ function FilterSection({
1737
+ title,
1738
+ defaultOpen = true,
1739
+ children
1740
+ }) {
1741
+ const [open, setOpen] = React18__default.useState(defaultOpen);
1742
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1743
+ /* @__PURE__ */ jsxs(
1744
+ "button",
1745
+ {
1746
+ type: "button",
1747
+ onClick: () => setOpen((p) => !p),
1748
+ "aria-expanded": open,
1749
+ className: "flex items-center justify-between w-full text-xs font-medium text-muted-foreground hover:text-foreground py-1 transition-colors",
1750
+ children: [
1751
+ /* @__PURE__ */ jsx("span", { children: title }),
1752
+ /* @__PURE__ */ jsx(ChevronDown, { className: `h-3.5 w-3.5 transition-transform ${open ? "" : "-rotate-90"}` })
1753
+ ]
1754
+ }
1755
+ ),
1756
+ open && /* @__PURE__ */ jsx("div", { className: "mt-1.5 space-y-0.5", children })
1757
+ ] });
1758
+ }
1759
+ function CheckMark({ className }) {
1760
+ return /* @__PURE__ */ jsx("svg", { className, viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M2 6l3 3 5-5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) });
1761
+ }
1762
+ function FilterCheckBox({ checked, color }) {
1763
+ if (!color) {
1764
+ return /* @__PURE__ */ jsx("span", { className: `flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border-2 transition-colors ${checked ? "border-primary bg-primary" : "border-muted-foreground/30"}`, children: checked && /* @__PURE__ */ jsx(CheckMark, { className: "h-2.5 w-2.5 text-primary-foreground" }) });
1765
+ }
1766
+ return /* @__PURE__ */ jsx(
1767
+ "span",
1768
+ {
1769
+ className: "flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border-2 transition-colors",
1770
+ style: { borderColor: checked ? color : color + "40", backgroundColor: checked ? color : "transparent" },
1771
+ children: checked && /* @__PURE__ */ jsx(CheckMark, { className: "h-2.5 w-2.5 text-white" })
1772
+ }
1773
+ );
1774
+ }
1775
+ function FilterCheckRow({
1776
+ option,
1777
+ checked,
1778
+ onToggle
1779
+ }) {
1780
+ return /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2.5 rounded px-1 py-1 cursor-pointer hover:bg-muted/50 transition-colors", children: [
1781
+ /* @__PURE__ */ jsx(FilterCheckBox, { checked, color: option.color }),
1782
+ option.adornment,
1783
+ /* @__PURE__ */ jsx("span", { className: `min-w-0 flex-1 truncate text-xs ${checked ? "text-foreground" : "text-muted-foreground"}`, children: option.label }),
1784
+ option.count != null && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: option.count }),
1785
+ /* @__PURE__ */ jsx("input", { type: "checkbox", className: "sr-only", checked, onChange: onToggle })
1786
+ ] });
1787
+ }
1788
+ function FilterCheckList({
1789
+ label,
1790
+ options,
1791
+ selected,
1792
+ onChange,
1793
+ className
1794
+ }) {
1795
+ const all = selected.length === 0;
1796
+ function toggle(value) {
1797
+ const next = selected.includes(value) ? selected.filter((v) => v !== value) : [...selected, value];
1798
+ onChange(next.length === options.length ? [] : next);
1799
+ }
1800
+ const rows = options.map((option) => /* @__PURE__ */ jsx(
1801
+ FilterCheckRow,
1802
+ {
1803
+ option,
1804
+ checked: all || selected.includes(option.value),
1805
+ onToggle: () => toggle(option.value)
1806
+ },
1807
+ option.value
1808
+ ));
1809
+ if (label) {
1810
+ return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx(FilterSection, { title: label, children: rows }) });
1811
+ }
1812
+ return /* @__PURE__ */ jsx("div", { className: className ? `${className} space-y-0.5` : "space-y-0.5", children: rows });
1813
+ }
1814
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React18.useLayoutEffect : React18.useEffect;
1599
1815
  function SearchSelect({
1600
1816
  value,
1601
1817
  displayValue,
@@ -1618,18 +1834,18 @@ function SearchSelect({
1618
1834
  disabled
1619
1835
  }) {
1620
1836
  const canCreate = !!onCreate && allowCreate !== false;
1621
- const [open, setOpen] = React16.useState(false);
1622
- const [query, setQuery] = React16.useState("");
1623
- const [results, setResults] = React16.useState([]);
1624
- const [loading, setLoading] = React16.useState(false);
1625
- const [creating, setCreating] = React16.useState(false);
1626
- const [selectedLabel, setSelectedLabel] = React16.useState(displayValue ?? "");
1627
- const containerRef = React16.useRef(null);
1628
- const inputRef = React16.useRef(null);
1629
- const timerRef = React16.useRef();
1630
- const [rect, setRect] = React16.useState(null);
1631
- const dropdownRef = React16.useRef(null);
1632
- React16.useEffect(() => {
1837
+ const [open, setOpen] = React18.useState(false);
1838
+ const [query, setQuery] = React18.useState("");
1839
+ const [results, setResults] = React18.useState([]);
1840
+ const [loading, setLoading] = React18.useState(false);
1841
+ const [creating, setCreating] = React18.useState(false);
1842
+ const [selectedLabel, setSelectedLabel] = React18.useState(displayValue ?? "");
1843
+ const containerRef = React18.useRef(null);
1844
+ const inputRef = React18.useRef(null);
1845
+ const timerRef = React18.useRef();
1846
+ const [rect, setRect] = React18.useState(null);
1847
+ const dropdownRef = React18.useRef(null);
1848
+ React18.useEffect(() => {
1633
1849
  function handler(e) {
1634
1850
  const target = e.target;
1635
1851
  if (containerRef.current?.contains(target)) return;
@@ -1639,10 +1855,10 @@ function SearchSelect({
1639
1855
  document.addEventListener("mousedown", handler);
1640
1856
  return () => document.removeEventListener("mousedown", handler);
1641
1857
  }, []);
1642
- React16.useEffect(() => {
1858
+ React18.useEffect(() => {
1643
1859
  if (displayValue !== void 0) setSelectedLabel(displayValue);
1644
1860
  }, [displayValue]);
1645
- React16.useEffect(() => {
1861
+ React18.useEffect(() => {
1646
1862
  if (open && loadOnOpen && query.length === 0 && results.length === 0 && !loading) {
1647
1863
  setLoading(true);
1648
1864
  Promise.resolve(onSearch("")).then(setResults).catch(() => setResults([])).finally(() => setLoading(false));
@@ -1700,7 +1916,7 @@ function SearchSelect({
1700
1916
  setResults([]);
1701
1917
  setTimeout(() => inputRef.current?.focus(), 0);
1702
1918
  }
1703
- const groups = React16.useMemo(() => {
1919
+ const groups = React18.useMemo(() => {
1704
1920
  const map = /* @__PURE__ */ new Map();
1705
1921
  for (const opt of results) {
1706
1922
  const group = opt.group ?? "";
@@ -1795,7 +2011,7 @@ function SearchSelect({
1795
2011
  /* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
1796
2012
  " ",
1797
2013
  searchingLabel
1798
- ] }) : results.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-4 py-4 text-center", children: /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: noResultsLabel ?? (query ? `No results for "${query}"` : "No results") }) }) : /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-auto py-1", children: [...groups.entries()].map(([group, options]) => /* @__PURE__ */ jsxs(React16.Fragment, { children: [
2014
+ ] }) : results.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-4 py-4 text-center", children: /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: noResultsLabel ?? (query ? `No results for "${query}"` : "No results") }) }) : /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-auto py-1", children: [...groups.entries()].map(([group, options]) => /* @__PURE__ */ jsxs(React18.Fragment, { children: [
1799
2015
  group && /* @__PURE__ */ jsx("div", { className: "sticky top-0 bg-muted/50 px-3 py-1 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: group }),
1800
2016
  options.map((opt) => /* @__PURE__ */ jsx(
1801
2017
  "button",
@@ -1857,9 +2073,9 @@ function CurrencyInput({
1857
2073
  className,
1858
2074
  disabled
1859
2075
  }) {
1860
- const inputRef = React16.useRef(null);
1861
- const [focused, setFocused] = React16.useState(false);
1862
- const format = React16.useCallback((v) => {
2076
+ const inputRef = React18.useRef(null);
2077
+ const [focused, setFocused] = React18.useState(false);
2078
+ const format = React18.useCallback((v) => {
1863
2079
  return new Intl.NumberFormat(locale, {
1864
2080
  minimumFractionDigits: 2,
1865
2081
  maximumFractionDigits: 2
@@ -1932,7 +2148,7 @@ function CurrencyInput({
1932
2148
  var Popover = PopoverPrimitive.Root;
1933
2149
  var PopoverTrigger = PopoverPrimitive.Trigger;
1934
2150
  var PopoverAnchor = PopoverPrimitive.Anchor;
1935
- var PopoverContent = React16.forwardRef(({ className, align = "start", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
2151
+ var PopoverContent = React18.forwardRef(({ className, align = "start", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
1936
2152
  PopoverPrimitive.Content,
1937
2153
  {
1938
2154
  ref,
@@ -1992,6 +2208,101 @@ function SegmentedControl({
1992
2208
  }
1993
2209
  );
1994
2210
  }
2211
+ function MultiSelect({
2212
+ options,
2213
+ value,
2214
+ onChange,
2215
+ allLabel = "Todos",
2216
+ searchPlaceholder = "Buscar\u2026",
2217
+ emptyLabel = "Nada encontrado",
2218
+ disabled,
2219
+ className,
2220
+ searchThreshold = 8
2221
+ }) {
2222
+ const [query, setQuery] = React18.useState("");
2223
+ const selected = React18.useMemo(() => new Set(value), [value]);
2224
+ const filtered = React18.useMemo(() => {
2225
+ const q = query.trim().toLowerCase();
2226
+ if (!q) return options;
2227
+ return options.filter((o) => o.label.toLowerCase().includes(q));
2228
+ }, [options, query]);
2229
+ function toggle(v) {
2230
+ onChange(selected.has(v) ? value.filter((x) => x !== v) : [...value, v]);
2231
+ }
2232
+ const label = value.length === 0 ? allLabel : value.length === 1 ? options.find((o) => o.value === value[0])?.label ?? "1 selecionado" : `${value.length} selecionados`;
2233
+ return /* @__PURE__ */ jsxs(Dropdown, { children: [
2234
+ /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, disabled, children: /* @__PURE__ */ jsxs(
2235
+ "button",
2236
+ {
2237
+ type: "button",
2238
+ disabled,
2239
+ className: cn(
2240
+ "flex h-9 w-full items-center justify-between gap-2 rounded-input border border-input bg-card px-3 py-1.5 text-xs",
2241
+ "shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] transition-colors hover:bg-muted/40",
2242
+ "disabled:cursor-not-allowed disabled:opacity-50",
2243
+ value.length === 0 && "text-muted-foreground",
2244
+ className
2245
+ ),
2246
+ children: [
2247
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: label }),
2248
+ /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [
2249
+ value.length > 0 && // Limpar dentro do gatilho: a alternativa é desmarcar cinco itens
2250
+ // um a um para voltar a "todos", e é o caminho de volta mais
2251
+ // comum de todos.
2252
+ /* @__PURE__ */ jsx(
2253
+ "span",
2254
+ {
2255
+ role: "button",
2256
+ tabIndex: -1,
2257
+ "aria-label": "Limpar sele\xE7\xE3o",
2258
+ onClick: (e) => {
2259
+ e.preventDefault();
2260
+ e.stopPropagation();
2261
+ onChange([]);
2262
+ },
2263
+ className: "rounded-full p-0.5 text-muted-foreground hover:bg-muted hover:text-foreground",
2264
+ children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
2265
+ }
2266
+ ),
2267
+ /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5 shrink-0 opacity-50" })
2268
+ ] })
2269
+ ]
2270
+ }
2271
+ ) }),
2272
+ /* @__PURE__ */ jsxs(DropdownContent, { align: "start", className: "w-[--radix-dropdown-menu-trigger-width] p-0", children: [
2273
+ options.length >= searchThreshold && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b px-2 py-1.5", children: [
2274
+ /* @__PURE__ */ jsx(Search, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
2275
+ /* @__PURE__ */ jsx(
2276
+ "input",
2277
+ {
2278
+ value: query,
2279
+ onChange: (e) => setQuery(e.target.value),
2280
+ placeholder: searchPlaceholder,
2281
+ onKeyDown: (e) => e.stopPropagation(),
2282
+ className: "w-full bg-transparent text-xs outline-none placeholder:text-muted-foreground"
2283
+ }
2284
+ )
2285
+ ] }),
2286
+ /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-y-auto py-1", children: filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-4 text-center text-xs text-muted-foreground", children: emptyLabel }) : filtered.map((o) => /* @__PURE__ */ jsxs(
2287
+ "button",
2288
+ {
2289
+ type: "button",
2290
+ onClick: (e) => {
2291
+ e.preventDefault();
2292
+ toggle(o.value);
2293
+ },
2294
+ className: "flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs transition-colors hover:bg-muted",
2295
+ children: [
2296
+ /* @__PURE__ */ jsx(Checkbox, { checked: selected.has(o.value), onChange: () => toggle(o.value) }),
2297
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: o.label }),
2298
+ o.hint && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: o.hint })
2299
+ ]
2300
+ },
2301
+ o.value
2302
+ )) })
2303
+ ] })
2304
+ ] });
2305
+ }
1995
2306
  var INLINE_TOKEN = /(\*\*[^*]+\*\*|\*[^*]+\*|`[^`]+`)/g;
1996
2307
  function renderInline(text, keyPrefix) {
1997
2308
  return text.split(INLINE_TOKEN).map((part, i) => {
@@ -2005,7 +2316,7 @@ function renderInline(text, keyPrefix) {
2005
2316
  if (part.startsWith("`") && part.endsWith("`") && part.length > 2) {
2006
2317
  return /* @__PURE__ */ jsx("code", { className: "rounded bg-muted px-1 py-0.5 font-mono text-[0.85em]", children: part.slice(1, -1) }, key);
2007
2318
  }
2008
- return part === "" ? null : /* @__PURE__ */ jsx(React16.Fragment, { children: part }, key);
2319
+ return part === "" ? null : /* @__PURE__ */ jsx(React18.Fragment, { children: part }, key);
2009
2320
  });
2010
2321
  }
2011
2322
  function parseBlocks(source) {
@@ -2089,7 +2400,7 @@ function renderMarkdown(source) {
2089
2400
  case "ol":
2090
2401
  return /* @__PURE__ */ jsx("ol", { className: "list-decimal space-y-1 pl-5", children: block.items.map((item, li) => /* @__PURE__ */ jsx("li", { children: renderInline(item, `${key}-${li}`) }, `${key}-${li}`)) }, key);
2091
2402
  case "p":
2092
- return /* @__PURE__ */ jsx("p", { children: block.lines.map((l, li) => /* @__PURE__ */ jsxs(React16.Fragment, { children: [
2403
+ return /* @__PURE__ */ jsx("p", { children: block.lines.map((l, li) => /* @__PURE__ */ jsxs(React18.Fragment, { children: [
2093
2404
  li > 0 && /* @__PURE__ */ jsx("br", {}),
2094
2405
  renderInline(l, `${key}-${li}`)
2095
2406
  ] }, `${key}-${li}`)) }, key);
@@ -2110,7 +2421,7 @@ function MarkdownEditor({
2110
2421
  renderPreview,
2111
2422
  className
2112
2423
  }) {
2113
- const [mode, setMode] = React16.useState(
2424
+ const [mode, setMode] = React18.useState(
2114
2425
  defaultMode === "preview" && value.trim() === "" ? "edit" : defaultMode
2115
2426
  );
2116
2427
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
@@ -2370,7 +2681,169 @@ function SearchCombobox({
2370
2681
  )
2371
2682
  ] });
2372
2683
  }
2684
+ var DEFAULT_LABELS = {
2685
+ title: "Lan\xE7ar movimento",
2686
+ description: "O raz\xE3o n\xE3o se edita: um erro se corrige com o movimento contr\xE1rio.",
2687
+ quantity: "Quantidade",
2688
+ reason: "Motivo",
2689
+ reasonDefault: "Padr\xE3o",
2690
+ whenArrived: "Chegou em",
2691
+ when: "Quando",
2692
+ note: "Observa\xE7\xE3o",
2693
+ notePlaceholder: "Nota fiscal, quem entregou\u2026",
2694
+ addNote: "+ observa\xE7\xE3o",
2695
+ staysAt: "Fica em",
2696
+ notEnough: "n\xE3o h\xE1 tudo isso",
2697
+ sayHowMany: "Diga quantas unidades",
2698
+ cancel: "Cancelar",
2699
+ submit: "Lan\xE7ar",
2700
+ submitting: "Lan\xE7ando\u2026"
2701
+ };
2702
+ var field = "mt-1 w-full rounded-md border bg-background px-2.5 py-1.5 text-sm outline-none focus:border-primary";
2703
+ var todayISO = () => (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2704
+ function StockEntryForm({
2705
+ verb,
2706
+ onVerbChange,
2707
+ onClose,
2708
+ verbs,
2709
+ reasons = [],
2710
+ available,
2711
+ saving = false,
2712
+ onSubmit,
2713
+ labels: overrides
2714
+ }) {
2715
+ const labels = { ...DEFAULT_LABELS, ...overrides };
2716
+ const [quantity, setQuantity] = React18.useState("");
2717
+ const [reasonCode, setReasonCode] = React18.useState("");
2718
+ const [occurredOn, setOccurredOn] = React18.useState(todayISO());
2719
+ const [note, setNote] = React18.useState("");
2720
+ const [noteOpen, setNoteOpen] = React18.useState(false);
2721
+ const quantityRef = React18.useRef(null);
2722
+ React18.useEffect(() => {
2723
+ if (verb === null) return;
2724
+ setQuantity("");
2725
+ setReasonCode("");
2726
+ setOccurredOn(todayISO());
2727
+ setNote("");
2728
+ setNoteOpen(false);
2729
+ const timer = setTimeout(() => quantityRef.current?.focus(), 30);
2730
+ return () => clearTimeout(timer);
2731
+ }, [verb]);
2732
+ const amount = Math.max(0, Math.trunc(Number(quantity) || 0));
2733
+ const spec = verbs.find((v) => v.value === verb);
2734
+ const effect = spec?.effect ?? "increase";
2735
+ const nextBalance = amount === 0 ? null : effect === "set" ? amount : effect === "decrease" ? available - amount : available + amount;
2736
+ const submit = () => {
2737
+ if (amount === 0 || saving) return;
2738
+ void onSubmit({ verb, quantity: amount, reasonCode, occurredOn, note });
2739
+ };
2740
+ return /* @__PURE__ */ jsx(Modal, { open: verb !== null, onOpenChange: (open) => {
2741
+ if (!open) onClose();
2742
+ }, children: /* @__PURE__ */ jsxs(ModalContent, { className: "sm:max-w-lg", children: [
2743
+ /* @__PURE__ */ jsxs(ModalHeader, { children: [
2744
+ /* @__PURE__ */ jsx(ModalTitle, { children: labels.title }),
2745
+ /* @__PURE__ */ jsx(ModalDescription, { children: labels.description })
2746
+ ] }),
2747
+ /* @__PURE__ */ jsxs("div", { className: "p-1", children: [
2748
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: verbs.map((v) => /* @__PURE__ */ jsx(
2749
+ "button",
2750
+ {
2751
+ type: "button",
2752
+ onClick: () => onVerbChange(v.value),
2753
+ className: `fz-tap rounded-button px-3 py-1.5 text-xs font-medium transition-colors ${verb === v.value ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground"}`,
2754
+ children: v.label
2755
+ },
2756
+ v.value
2757
+ )) }),
2758
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-3", children: [
2759
+ /* @__PURE__ */ jsxs("label", { className: "block", children: [
2760
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: labels.quantity }),
2761
+ /* @__PURE__ */ jsx(
2762
+ "input",
2763
+ {
2764
+ ref: quantityRef,
2765
+ type: "number",
2766
+ inputMode: "numeric",
2767
+ min: effect === "set" ? 0 : 1,
2768
+ value: quantity,
2769
+ onChange: (e) => setQuantity(e.target.value),
2770
+ onKeyDown: (e) => {
2771
+ if (e.key === "Enter") {
2772
+ e.preventDefault();
2773
+ submit();
2774
+ }
2775
+ if (e.key === "Escape") {
2776
+ e.preventDefault();
2777
+ onClose();
2778
+ }
2779
+ },
2780
+ placeholder: "0",
2781
+ className: `${field} font-semibold tabular-nums`
2782
+ }
2783
+ ),
2784
+ /* @__PURE__ */ jsx("span", { "aria-live": "polite", className: "mt-1 block text-xs text-muted-foreground", children: nextBalance === null ? /* @__PURE__ */ jsxs(Fragment, { children: [
2785
+ labels.staysAt,
2786
+ " ",
2787
+ /* @__PURE__ */ jsx("span", { className: "font-medium tabular-nums text-foreground", children: available })
2788
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
2789
+ /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: available }),
2790
+ /* @__PURE__ */ jsx("span", { className: "mx-1.5", children: "\u2192" }),
2791
+ /* @__PURE__ */ jsx("span", { className: `text-base font-semibold tabular-nums ${nextBalance < 0 ? "text-destructive" : "text-foreground"}`, children: nextBalance }),
2792
+ nextBalance < 0 && /* @__PURE__ */ jsx("span", { className: "ml-2 text-destructive", children: labels.notEnough })
2793
+ ] }) })
2794
+ ] }),
2795
+ reasons.length > 0 && /* @__PURE__ */ jsxs("label", { className: "block", children: [
2796
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: labels.reason }),
2797
+ /* @__PURE__ */ jsxs("select", { value: reasonCode, onChange: (e) => setReasonCode(e.target.value), className: field, children: [
2798
+ /* @__PURE__ */ jsx("option", { value: "", children: labels.reasonDefault }),
2799
+ reasons.map((r) => /* @__PURE__ */ jsx("option", { value: r.key, children: r.label }, r.key))
2800
+ ] })
2801
+ ] }),
2802
+ /* @__PURE__ */ jsxs("label", { className: "block", children: [
2803
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: effect === "increase" ? labels.whenArrived : labels.when }),
2804
+ /* @__PURE__ */ jsx(
2805
+ "input",
2806
+ {
2807
+ type: "date",
2808
+ value: occurredOn,
2809
+ max: todayISO(),
2810
+ onChange: (e) => setOccurredOn(e.target.value || todayISO()),
2811
+ className: field
2812
+ }
2813
+ )
2814
+ ] })
2815
+ ] }),
2816
+ noteOpen ? /* @__PURE__ */ jsxs("label", { className: "mt-3 block", children: [
2817
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: labels.note }),
2818
+ /* @__PURE__ */ jsx(
2819
+ "input",
2820
+ {
2821
+ autoFocus: true,
2822
+ value: note,
2823
+ onChange: (e) => setNote(e.target.value),
2824
+ className: field,
2825
+ placeholder: labels.notePlaceholder
2826
+ }
2827
+ )
2828
+ ] }) : /* @__PURE__ */ jsx(
2829
+ "button",
2830
+ {
2831
+ type: "button",
2832
+ onClick: () => setNoteOpen(true),
2833
+ className: "mt-2 text-xs font-medium text-muted-foreground underline-offset-2 hover:text-foreground hover:underline",
2834
+ children: labels.addNote
2835
+ }
2836
+ )
2837
+ ] }),
2838
+ /* @__PURE__ */ jsxs(ModalFooter, { children: [
2839
+ amount === 0 && // Why the button is dim, next to the button.
2840
+ /* @__PURE__ */ jsx("span", { className: "mr-auto text-xs text-muted-foreground", children: labels.sayHowMany }),
2841
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: onClose, disabled: saving, children: labels.cancel }),
2842
+ /* @__PURE__ */ jsx(Button, { onClick: submit, disabled: saving || amount === 0, children: saving ? labels.submitting : labels.submit })
2843
+ ] })
2844
+ ] }) });
2845
+ }
2373
2846
 
2374
- export { Badge, Breadcrumb, BulkActionBar, ChevronPager, CurrencyInput, DatePicker, FilterChip, Hint, Input, ListView, Markdown, MarkdownEditor, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, PageActionBar, PhoneField, PhoneLink, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, RefreshButton, RowActions, SearchCombobox, SearchField, SearchSelect, SegmentedControl, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator2 as Separator, StatTiles, Tabs, TabsContent, TabsList, TabsTrigger, Thumbnail, TimePicker, ToastProvider, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, WHATSAPP_BRAND_COLOR, WhatsAppIcon, badgeVariants, formatPhone2 as formatPhone, normalizePhone, renderMarkdown, setActionsMenuLabel, setRowActionsLabel, useRowSelection };
2375
- //# sourceMappingURL=chunk-Z2ITFPGL.js.map
2376
- //# sourceMappingURL=chunk-Z2ITFPGL.js.map
2847
+ export { Badge, Breadcrumb, BulkActionBar, ChevronPager, CurrencyInput, DatePicker, DotBadge, DraftCommitBar, FilterCheckBox, FilterCheckList, FilterCheckRow, FilterChip, FilterSection, Hint, Input, ListView, Markdown, MarkdownEditor, MiniCalendar, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, MultiSelect, PageActionBar, PhoneField, PhoneLink, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, RefreshButton, RowActions, SearchCombobox, SearchField, SearchSelect, SegmentedControl, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator2 as Separator, StatTiles, StockEntryForm, Tabs, TabsContent, TabsList, TabsTrigger, Thumbnail, TimePicker, ToastProvider, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, WHATSAPP_BRAND_COLOR, WhatsAppIcon, badgeVariants, formatPhone2 as formatPhone, normalizePhone, renderMarkdown, setActionsMenuLabel, setRowActionsLabel, toLocalISODate, useRowSelection };
2848
+ //# sourceMappingURL=chunk-5WSKZU7M.js.map
2849
+ //# sourceMappingURL=chunk-5WSKZU7M.js.map