@fayz-ai/ui 0.36.1 → 0.38.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 (35) hide show
  1. package/dist/{chunk-IA3QZZSC.js → chunk-2D77YTB5.js} +291 -154
  2. package/dist/chunk-2D77YTB5.js.map +1 -0
  3. package/dist/{chunk-URDLBXAS.js → chunk-4LNSCAM4.js} +241 -90
  4. package/dist/chunk-4LNSCAM4.js.map +1 -0
  5. package/dist/{chunk-P4764AWQ.js → chunk-R5DA6AX6.js} +3 -3
  6. package/dist/{chunk-P4764AWQ.js.map → chunk-R5DA6AX6.js.map} +1 -1
  7. package/dist/dashboard/index.js +2 -2
  8. package/dist/index.d.ts +3 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +303 -7
  11. package/dist/index.js.map +1 -1
  12. package/dist/lib/print.d.ts +21 -0
  13. package/dist/lib/print.d.ts.map +1 -0
  14. package/dist/lib/xlsx.d.ts +102 -0
  15. package/dist/lib/xlsx.d.ts.map +1 -0
  16. package/dist/primitives/badge.d.ts +1 -1
  17. package/dist/primitives/choice-list.d.ts +56 -0
  18. package/dist/primitives/choice-list.d.ts.map +1 -0
  19. package/dist/primitives/data-table.d.ts +17 -2
  20. package/dist/primitives/data-table.d.ts.map +1 -1
  21. package/dist/primitives/filter-chip.d.ts +7 -1
  22. package/dist/primitives/filter-chip.d.ts.map +1 -1
  23. package/dist/primitives/filter-menu.d.ts +2 -0
  24. package/dist/primitives/filter-menu.d.ts.map +1 -1
  25. package/dist/primitives/index.d.ts +2 -1
  26. package/dist/primitives/index.d.ts.map +1 -1
  27. package/dist/primitives/index.js +2 -2
  28. package/dist/primitives/list-filter-bar.d.ts +4 -1
  29. package/dist/primitives/list-filter-bar.d.ts.map +1 -1
  30. package/dist/primitives/list-view.d.ts.map +1 -1
  31. package/dist/primitives/search-select.d.ts +5 -1
  32. package/dist/primitives/search-select.d.ts.map +1 -1
  33. package/package.json +6 -5
  34. package/dist/chunk-IA3QZZSC.js.map +0 -1
  35. package/dist/chunk-URDLBXAS.js.map +0 -1
@@ -1,9 +1,9 @@
1
- import { useIsWide, Dropdown, DropdownTrigger, DropdownContent, DropdownSeparator, DropdownItem, Card, FilterMenuRow, FilterMenu, DataTable, Popover, PopoverTrigger, PopoverContent, Checkbox } from './chunk-URDLBXAS.js';
1
+ import { useIsWide, Dropdown, DropdownTrigger, DropdownContent, DropdownSeparator, DropdownItem, Card, Popover, PopoverTrigger, PopoverContent, FilterMenuRow, FilterMenu, DataTable, Checkbox } from './chunk-4LNSCAM4.js';
2
2
  import { COLUMN_WIDTH, useSaveBarVisible, useCrossModuleBack, useBackHandler, Hint, PageHeaderActions, Modal, ModalContent, ModalHeader, ModalTitle, ModalBody, ModalDescription, ModalFooter, SubpageHeader, PageRail, CollapsibleColumn } from './chunk-7SEWMFO3.js';
3
3
  import { Button, cn } from './chunk-FKYFYGAS.js';
4
- import * as React18 from 'react';
5
- import React18__default, { useState, useRef, useEffect, useMemo, useCallback } from 'react';
6
- import { Loader2, Sparkles, ChevronDown, ChevronUp, Check, ArrowLeft, MoreHorizontal, Search, ChevronsLeft, ChevronLeft, ChevronRight, ChevronsRight, ImageIcon, RefreshCw, Clock, X, Plus, Download, Calendar, Pencil, CalendarDays, MicOff, Mic, ArrowRight, MoreVertical } from 'lucide-react';
4
+ import * as React20 from 'react';
5
+ import React20__default, { useState, useRef, useEffect, useMemo, useCallback } from 'react';
6
+ import { Loader2, Sparkles, ChevronDown, ChevronUp, Check, ArrowLeft, MoreHorizontal, Search, ChevronsLeft, ChevronLeft, ChevronRight, ChevronsRight, ImageIcon, RefreshCw, Clock, Settings, X, Plus, Download, Calendar, Pencil, CalendarDays, MicOff, Mic, ArrowRight, MoreVertical } from 'lucide-react';
7
7
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
8
8
  import { cva } from 'class-variance-authority';
9
9
  import * as SelectPrimitive from '@radix-ui/react-select';
@@ -18,7 +18,7 @@ var TONE = {
18
18
  solid: "bg-magic text-magic-foreground border border-magic shadow-button-primary hover:bg-magic/90 active:shadow-button-inset",
19
19
  soft: "border border-magic/30 bg-magic-soft text-magic-soft-foreground shadow-button hover:bg-magic/10 active:shadow-button-inset"
20
20
  };
21
- var AiActionButton = React18.forwardRef(
21
+ var AiActionButton = React20.forwardRef(
22
22
  ({ busy, busyLabel, tone = "solid", className, children, disabled, ...props }, ref) => /* @__PURE__ */ jsxs(
23
23
  Button,
24
24
  {
@@ -50,9 +50,9 @@ function InlineLink({ tone = "solid", className, children, ...rest }) {
50
50
  const button = rest;
51
51
  return /* @__PURE__ */ jsx("button", { type: "button", className: classes, ...button, children });
52
52
  }
53
- var Input = React18.forwardRef(
53
+ var Input = React20.forwardRef(
54
54
  ({ className, type, error, description, id, ...props }, ref) => {
55
- const inputId = id ?? React18.useId();
55
+ const inputId = id ?? React20.useId();
56
56
  const descriptionId = description ? `${inputId}-description` : void 0;
57
57
  const errorId = error ? `${inputId}-error` : void 0;
58
58
  return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
@@ -130,7 +130,7 @@ function Badge({ className, variant, dot, children, ...props }) {
130
130
  var Select = SelectPrimitive.Root;
131
131
  var SelectGroup = SelectPrimitive.Group;
132
132
  var SelectValue = SelectPrimitive.Value;
133
- var SelectTrigger = React18.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
133
+ var SelectTrigger = React20.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
134
134
  SelectPrimitive.Trigger,
135
135
  {
136
136
  ref,
@@ -146,7 +146,7 @@ var SelectTrigger = React18.forwardRef(({ className, children, ...props }, ref)
146
146
  }
147
147
  ));
148
148
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
149
- var SelectScrollUpButton = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
149
+ var SelectScrollUpButton = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
150
150
  SelectPrimitive.ScrollUpButton,
151
151
  {
152
152
  ref,
@@ -159,7 +159,7 @@ var SelectScrollUpButton = React18.forwardRef(({ className, ...props }, ref) =>
159
159
  }
160
160
  ));
161
161
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
162
- var SelectScrollDownButton = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
162
+ var SelectScrollDownButton = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
163
163
  SelectPrimitive.ScrollDownButton,
164
164
  {
165
165
  ref,
@@ -172,7 +172,7 @@ var SelectScrollDownButton = React18.forwardRef(({ className, ...props }, ref) =
172
172
  }
173
173
  ));
174
174
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
175
- var SelectContent = React18.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
175
+ var SelectContent = React20.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
176
176
  SelectPrimitive.Content,
177
177
  {
178
178
  ref,
@@ -200,7 +200,7 @@ var SelectContent = React18.forwardRef(({ className, children, position = "poppe
200
200
  }
201
201
  ) }));
202
202
  SelectContent.displayName = SelectPrimitive.Content.displayName;
203
- var SelectLabel = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
203
+ var SelectLabel = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
204
204
  SelectPrimitive.Label,
205
205
  {
206
206
  ref,
@@ -212,7 +212,7 @@ var SelectLabel = React18.forwardRef(({ className, ...props }, ref) => /* @__PUR
212
212
  }
213
213
  ));
214
214
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
215
- var SelectItem = React18.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
215
+ var SelectItem = React20.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
216
216
  SelectPrimitive.Item,
217
217
  {
218
218
  ref,
@@ -228,7 +228,7 @@ var SelectItem = React18.forwardRef(({ className, children, ...props }, ref) =>
228
228
  }
229
229
  ));
230
230
  SelectItem.displayName = SelectPrimitive.Item.displayName;
231
- var SelectSeparator = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
231
+ var SelectSeparator = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
232
232
  SelectPrimitive.Separator,
233
233
  {
234
234
  ref,
@@ -266,7 +266,7 @@ function ToastProvider({
266
266
  );
267
267
  }
268
268
  var Tabs = TabsPrimitive.Root;
269
- var TabsList = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
269
+ var TabsList = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
270
270
  TabsPrimitive.List,
271
271
  {
272
272
  ref,
@@ -280,7 +280,7 @@ var TabsList = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__
280
280
  }
281
281
  ));
282
282
  TabsList.displayName = TabsPrimitive.List.displayName;
283
- var TabsTrigger = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
283
+ var TabsTrigger = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
284
284
  TabsPrimitive.Trigger,
285
285
  {
286
286
  ref,
@@ -292,7 +292,7 @@ var TabsTrigger = React18.forwardRef(({ className, ...props }, ref) => /* @__PUR
292
292
  }
293
293
  ));
294
294
  TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
295
- var TabsContent = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
295
+ var TabsContent = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
296
296
  TabsPrimitive.Content,
297
297
  {
298
298
  ref,
@@ -304,7 +304,7 @@ var TabsContent = React18.forwardRef(({ className, ...props }, ref) => /* @__PUR
304
304
  }
305
305
  ));
306
306
  TabsContent.displayName = TabsPrimitive.Content.displayName;
307
- var Separator2 = React18.forwardRef(
307
+ var Separator2 = React20.forwardRef(
308
308
  ({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
309
309
  SeparatorPrimitive.Root,
310
310
  {
@@ -355,7 +355,7 @@ function formatPhone(digits, fallback, countryCode) {
355
355
  const tail = rest.length === 9 ? rest.slice(5) : rest.slice(4);
356
356
  return `+55 (${ddd}) ${head}-${tail}`;
357
357
  }
358
- var PhoneLink = React18.forwardRef(
358
+ var PhoneLink = React20.forwardRef(
359
359
  ({ phone, message, countryCode, raw, className, children, ...props }, ref) => {
360
360
  const { e164, display } = normalizePhone(phone, countryCode);
361
361
  const label = children ?? (raw ? phone ?? "" : display);
@@ -543,9 +543,9 @@ function PageActionFab({ actions }) {
543
543
  ] });
544
544
  }
545
545
  function useScrim(open) {
546
- const [mounted, setMounted] = React18.useState(open);
547
- const [visible, setVisible] = React18.useState(open);
548
- React18.useEffect(() => {
546
+ const [mounted, setMounted] = React20.useState(open);
547
+ const [visible, setVisible] = React20.useState(open);
548
+ React20.useEffect(() => {
549
549
  if (open) {
550
550
  setMounted(true);
551
551
  const frame = requestAnimationFrame(() => setVisible(true));
@@ -559,7 +559,7 @@ function useScrim(open) {
559
559
  }
560
560
  var SCRIM_MS = 200;
561
561
  function FabButton({ actions, tone, mini }) {
562
- const [open, setOpen] = React18.useState(false);
562
+ const [open, setOpen] = React20.useState(false);
563
563
  const scrim = useScrim(open);
564
564
  if (actions.length === 0) return null;
565
565
  const isCreate = tone === "primary";
@@ -672,7 +672,7 @@ function RowActions({
672
672
  const Icon2 = a.icon;
673
673
  const isDanger = a.intent === "danger";
674
674
  const prevSafe = i > 0 && overflow[i - 1].intent !== "danger";
675
- return /* @__PURE__ */ jsxs(React18.Fragment, { children: [
675
+ return /* @__PURE__ */ jsxs(React20.Fragment, { children: [
676
676
  isDanger && prevSafe && /* @__PURE__ */ jsx(DropdownSeparator, {}),
677
677
  /* @__PURE__ */ jsxs(
678
678
  DropdownItem,
@@ -923,8 +923,8 @@ var ICON_CLASSES = {
923
923
  lg: "h-5 w-5"
924
924
  };
925
925
  function Thumbnail({ src, alt = "", size = "md", icon: Icon2 = ImageIcon, className }) {
926
- const [failed, setFailed] = React18.useState(false);
927
- React18.useEffect(() => {
926
+ const [failed, setFailed] = React20.useState(false);
927
+ React20.useEffect(() => {
928
928
  setFailed(false);
929
929
  }, [src]);
930
930
  const base = cn("shrink-0 overflow-hidden", SIZE_CLASSES[size], className);
@@ -951,9 +951,9 @@ function Thumbnail({ src, alt = "", size = "md", icon: Icon2 = ImageIcon, classN
951
951
  }
952
952
  Thumbnail.displayName = "Thumbnail";
953
953
  function RefreshButton({ onRefresh, fromCache, label, labelCached, className, ...rest }) {
954
- const [phase, setPhase] = React18.useState("idle");
955
- const alive = React18.useRef(true);
956
- React18.useEffect(() => () => {
954
+ const [phase, setPhase] = React20.useState("idle");
955
+ const alive = React20.useRef(true);
956
+ React20.useEffect(() => () => {
957
957
  alive.current = false;
958
958
  }, []);
959
959
  const title = fromCache ? labelCached ?? label : label;
@@ -1175,27 +1175,27 @@ function useRowSelection({
1175
1175
  getRowId,
1176
1176
  enabled = true
1177
1177
  }) {
1178
- const identify = React18.useCallback(
1178
+ const identify = React20.useCallback(
1179
1179
  (row) => getRowId ? getRowId(row) : String(row?.id ?? ""),
1180
1180
  [getRowId]
1181
1181
  );
1182
- const visible = React18.useMemo(() => rows ?? [], [rows]);
1183
- const [rawSelection, setRawSelection] = React18.useState([]);
1184
- const visibleIds = React18.useMemo(() => new Set(visible.map(identify)), [visible, identify]);
1185
- const selectedIds = React18.useMemo(
1182
+ const visible = React20.useMemo(() => rows ?? [], [rows]);
1183
+ const [rawSelection, setRawSelection] = React20.useState([]);
1184
+ const visibleIds = React20.useMemo(() => new Set(visible.map(identify)), [visible, identify]);
1185
+ const selectedIds = React20.useMemo(
1186
1186
  () => rawSelection.filter((id) => visibleIds.has(id)),
1187
1187
  [rawSelection, visibleIds]
1188
1188
  );
1189
- const selectedRows = React18.useMemo(() => {
1189
+ const selectedRows = React20.useMemo(() => {
1190
1190
  const picked = new Set(selectedIds);
1191
1191
  return visible.filter((row) => picked.has(identify(row)));
1192
1192
  }, [visible, selectedIds, identify]);
1193
- const clear = React18.useCallback(() => setRawSelection([]), []);
1194
- const selectAll = React18.useCallback(
1193
+ const clear = React20.useCallback(() => setRawSelection([]), []);
1194
+ const selectAll = React20.useCallback(
1195
1195
  () => setRawSelection(visible.map(identify)),
1196
1196
  [visible, identify]
1197
1197
  );
1198
- const barActions = React18.useMemo(
1198
+ const barActions = React20.useMemo(
1199
1199
  () => (actions ?? []).map((action) => ({
1200
1200
  id: action.id,
1201
1201
  label: action.label,
@@ -1221,11 +1221,137 @@ function useRowSelection({
1221
1221
  total: visible.length
1222
1222
  };
1223
1223
  }
1224
- function FilterChip({ allLabel, options, value, onChange, label, icon: Icon2, className }) {
1224
+ var CHOICE_SEARCH_THRESHOLD = 8;
1225
+ function choiceSearchable(count, searchable) {
1226
+ return searchable ?? count > CHOICE_SEARCH_THRESHOLD;
1227
+ }
1228
+ function ManageRow({ action, onDone, className }) {
1229
+ return /* @__PURE__ */ jsxs(
1230
+ "button",
1231
+ {
1232
+ type: "button",
1233
+ onClick: () => {
1234
+ onDone?.();
1235
+ action.onSelect();
1236
+ },
1237
+ className: cn(
1238
+ "flex w-full shrink-0 items-center gap-2 border-t px-3 py-2 text-left text-xs text-muted-foreground transition-colors hover:bg-muted/60 hover:text-foreground",
1239
+ className
1240
+ ),
1241
+ children: [
1242
+ /* @__PURE__ */ jsx(Settings, { className: "h-3.5 w-3.5 shrink-0", "aria-hidden": true }),
1243
+ action.label
1244
+ ]
1245
+ }
1246
+ );
1247
+ }
1248
+ function ChoiceList({
1249
+ options,
1250
+ value,
1251
+ onSelect,
1252
+ allLabel,
1253
+ searchable,
1254
+ searchPlaceholder = "Buscar\u2026",
1255
+ emptyLabel = "Nada encontrado",
1256
+ manage,
1257
+ onDone,
1258
+ className
1259
+ }) {
1260
+ const [query, setQuery] = React20.useState("");
1261
+ const withSearch = choiceSearchable(options.length, searchable);
1262
+ const q = query.trim().toLowerCase();
1263
+ const shown = q ? options.filter((o) => o.label.toLowerCase().includes(q)) : options;
1264
+ const pick = (v) => {
1265
+ onSelect(v);
1266
+ onDone?.();
1267
+ };
1268
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex max-h-[min(24rem,70vh)] min-w-[14rem] flex-col", className), children: [
1269
+ withSearch && /* @__PURE__ */ jsxs("div", { className: "relative shrink-0 border-b p-1.5", children: [
1270
+ /* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-3.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground", "aria-hidden": true }),
1271
+ /* @__PURE__ */ jsx(
1272
+ "input",
1273
+ {
1274
+ autoFocus: true,
1275
+ type: "text",
1276
+ value: query,
1277
+ onChange: (e) => setQuery(e.target.value),
1278
+ onKeyDown: (e) => {
1279
+ if (e.key === "Enter" && shown[0]) {
1280
+ e.preventDefault();
1281
+ pick(shown[0].value);
1282
+ }
1283
+ },
1284
+ placeholder: searchPlaceholder,
1285
+ className: "h-8 w-full rounded-md bg-muted/40 pl-7 pr-2 text-xs outline-none"
1286
+ }
1287
+ )
1288
+ ] }),
1289
+ /* @__PURE__ */ jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto p-1", children: [
1290
+ allLabel && !q && /* @__PURE__ */ jsx(Row, { active: value == null || value === "", onClick: () => pick(void 0), children: /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate text-muted-foreground", children: allLabel }) }),
1291
+ shown.map((o) => /* @__PURE__ */ jsxs(Row, { active: o.value === value, onClick: () => pick(o.value), children: [
1292
+ o.dot && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "h-2 w-2 shrink-0 rounded-full", style: { background: o.dot } }),
1293
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: o.label })
1294
+ ] }, o.value)),
1295
+ shown.length === 0 && /* @__PURE__ */ jsx("p", { className: "px-2 py-3 text-center text-xs text-muted-foreground", children: emptyLabel })
1296
+ ] }),
1297
+ manage && /* @__PURE__ */ jsx(ManageRow, { action: manage, onDone })
1298
+ ] });
1299
+ }
1300
+ function Row({ active, onClick, children }) {
1301
+ return /* @__PURE__ */ jsxs(
1302
+ "button",
1303
+ {
1304
+ type: "button",
1305
+ onClick,
1306
+ className: "flex w-full items-center gap-2 rounded-button px-2 py-1.5 text-left text-xs transition-colors hover:bg-muted",
1307
+ children: [
1308
+ children,
1309
+ active && /* @__PURE__ */ jsx(Check, { className: "ml-auto h-3 w-3 shrink-0 text-muted-foreground" })
1310
+ ]
1311
+ }
1312
+ );
1313
+ }
1314
+ function ChoiceSelect({
1315
+ options,
1316
+ value,
1317
+ onChange,
1318
+ allLabel,
1319
+ placeholder = "Selecionar\u2026",
1320
+ icon: Icon2,
1321
+ disabled,
1322
+ className,
1323
+ "aria-label": ariaLabel,
1324
+ ...list
1325
+ }) {
1326
+ const [open, setOpen] = React20.useState(false);
1327
+ const current = options.find((o) => o.value === value);
1328
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
1329
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1330
+ "button",
1331
+ {
1332
+ type: "button",
1333
+ disabled,
1334
+ "aria-label": ariaLabel,
1335
+ className: cn(
1336
+ "flex h-9 w-full items-center gap-2 rounded-input border border-input bg-card px-3 text-left text-sm shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] transition-colors hover:bg-muted/30 disabled:cursor-not-allowed disabled:opacity-50",
1337
+ className
1338
+ ),
1339
+ children: [
1340
+ Icon2 && /* @__PURE__ */ jsx(Icon2, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
1341
+ /* @__PURE__ */ jsx("span", { className: cn("min-w-0 flex-1 truncate", !current && !allLabel && "text-muted-foreground"), children: current?.label ?? allLabel ?? placeholder }),
1342
+ /* @__PURE__ */ jsx(ChevronDown, { className: cn("h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform", open && "rotate-180") })
1343
+ ]
1344
+ }
1345
+ ) }),
1346
+ /* @__PURE__ */ jsx(PopoverContent, { align: "start", className: "w-[var(--radix-popover-trigger-width)] min-w-[14rem] overflow-hidden", children: /* @__PURE__ */ jsx(ChoiceList, { ...list, options, value, onSelect: onChange, allLabel, onDone: () => setOpen(false) }) })
1347
+ ] });
1348
+ }
1349
+ function FilterChip({ allLabel, options, value, onChange, label, icon: Icon2, searchable, searchPlaceholder, manage, className }) {
1350
+ const [open, setOpen] = React20.useState(false);
1225
1351
  const active = value != null && value !== "";
1226
1352
  const current = options.find((o) => o.value === value);
1227
- return /* @__PURE__ */ jsxs(Dropdown, { children: [
1228
- /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1353
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
1354
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1229
1355
  "button",
1230
1356
  {
1231
1357
  type: "button",
@@ -1242,17 +1368,19 @@ function FilterChip({ allLabel, options, value, onChange, label, icon: Icon2, cl
1242
1368
  ]
1243
1369
  }
1244
1370
  ) }),
1245
- /* @__PURE__ */ jsxs(DropdownContent, { align: "start", children: [
1246
- /* @__PURE__ */ jsxs(DropdownItem, { onClick: () => onChange(void 0), children: [
1371
+ /* @__PURE__ */ jsx(PopoverContent, { align: "start", className: "w-auto max-w-[min(22rem,calc(100vw-2rem))] overflow-hidden", children: /* @__PURE__ */ jsx(
1372
+ ChoiceList,
1373
+ {
1374
+ options,
1375
+ value,
1376
+ onSelect: onChange,
1247
1377
  allLabel,
1248
- !active && /* @__PURE__ */ jsx(Check, { className: "ml-auto h-3.5 w-3.5 shrink-0 pl-1" })
1249
- ] }),
1250
- options.map((o) => /* @__PURE__ */ jsxs(DropdownItem, { onClick: () => onChange(o.value), children: [
1251
- o.dot && /* @__PURE__ */ jsx("span", { className: "mr-1.5 h-2 w-2 shrink-0 rounded-full", style: { backgroundColor: o.dot } }),
1252
- o.label,
1253
- value === o.value && /* @__PURE__ */ jsx(Check, { className: "ml-auto h-3.5 w-3.5 shrink-0 pl-1" })
1254
- ] }, o.value))
1255
- ] })
1378
+ searchable,
1379
+ searchPlaceholder,
1380
+ manage,
1381
+ onDone: () => setOpen(false)
1382
+ }
1383
+ ) })
1256
1384
  ] });
1257
1385
  }
1258
1386
  function ListFilterBar({
@@ -1267,17 +1395,18 @@ function ListFilterBar({
1267
1395
  className
1268
1396
  }) {
1269
1397
  const wide = useIsWide();
1270
- const usable = React18.useMemo(() => (filters ?? []).filter((f) => f.options.length > 0), [filters]);
1398
+ const usable = React20.useMemo(() => (filters ?? []).filter((f) => f.options.length > 0), [filters]);
1271
1399
  const active = usable.filter((f) => f.value != null && f.value !== "");
1272
1400
  const total = activeCount ?? active.length;
1273
- const fields = React18.useMemo(() => [
1401
+ const fields = React20.useMemo(() => [
1274
1402
  ...usable.map((f) => ({
1275
1403
  id: f.id,
1276
1404
  label: f.label,
1277
1405
  icon: f.icon,
1278
1406
  activeCount: f.value ? 1 : 0,
1279
- searchable: f.searchable,
1407
+ searchable: choiceSearchable(f.options.length, f.searchable),
1280
1408
  searchPlaceholder: f.searchPlaceholder,
1409
+ footer: f.manage ? (close) => /* @__PURE__ */ jsx(ManageRow, { action: f.manage, onDone: close }) : void 0,
1281
1410
  render: (close, query) => {
1282
1411
  const q = query.trim().toLowerCase();
1283
1412
  const shown = q ? f.options.filter((o) => o.label.toLowerCase().includes(q)) : f.options;
@@ -1308,7 +1437,10 @@ function ListFilterBar({
1308
1437
  allLabel: f.allLabel,
1309
1438
  options: f.options,
1310
1439
  value: f.value,
1311
- onChange: f.onChange
1440
+ onChange: f.onChange,
1441
+ searchable: f.searchable,
1442
+ searchPlaceholder: f.searchPlaceholder,
1443
+ manage: f.manage
1312
1444
  },
1313
1445
  f.id
1314
1446
  )),
@@ -1424,7 +1556,7 @@ function ListView({
1424
1556
  const showSearch = !!onSearchChange;
1425
1557
  const showTags = tags && tags.length > 0 && onTagChange;
1426
1558
  const selection = useRowSelection({ rows: loading ? [] : data, actions: bulkActions, getRowId });
1427
- const allFilters = React18.useMemo(() => [
1559
+ const allFilters = React20.useMemo(() => [
1428
1560
  ...showTags ? [{
1429
1561
  id: "__tag",
1430
1562
  label: tagsLabel ?? allTagLabel,
@@ -1457,7 +1589,7 @@ function ListView({
1457
1589
  )
1458
1590
  ] }) }),
1459
1591
  toolbar,
1460
- /* @__PURE__ */ jsxs(Card, { className: "overflow-hidden", children: [
1592
+ /* @__PURE__ */ jsxs(Card, { style: { overflow: "clip" }, children: [
1461
1593
  (showSearch || allFilters.length > 0 || filters || onRefresh || onExport || selection.hasSelection) && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-2 border-b border-border px-3 py-2", children: selection.hasSelection ? /* @__PURE__ */ jsx(
1462
1594
  BulkActionBar,
1463
1595
  {
@@ -1817,7 +1949,7 @@ function toLocalISODate(d) {
1817
1949
  }
1818
1950
  function MiniCalendar({ selectedDate, onDateSelect, onMonthChange, markers }) {
1819
1951
  const locale = getCurrentLocale();
1820
- const [viewMonth, setViewMonth] = React18__default.useState(() => new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1));
1952
+ const [viewMonth, setViewMonth] = React20__default.useState(() => new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1));
1821
1953
  const monthLabel = viewMonth.toLocaleDateString(toDateLocale2(locale), { month: "long", year: "numeric" });
1822
1954
  const dayLabels = DAY_LABELS2[locale] ?? DAY_LABELS2.en;
1823
1955
  const weeks = useMemo(() => {
@@ -1897,7 +2029,7 @@ function FilterSection({
1897
2029
  count,
1898
2030
  children
1899
2031
  }) {
1900
- const [open, setOpen] = React18__default.useState(defaultOpen);
2032
+ const [open, setOpen] = React20__default.useState(defaultOpen);
1901
2033
  return /* @__PURE__ */ jsxs(Fragment, { children: [
1902
2034
  /* @__PURE__ */ jsxs(
1903
2035
  "button",
@@ -1973,7 +2105,7 @@ function FilterCheckList({
1973
2105
  }
1974
2106
  return /* @__PURE__ */ jsx("div", { className: className ? `${className} space-y-0.5` : "space-y-0.5", children: rows });
1975
2107
  }
1976
- var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React18.useLayoutEffect : React18.useEffect;
2108
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React20.useLayoutEffect : React20.useEffect;
1977
2109
  function SearchSelect({
1978
2110
  value,
1979
2111
  displayValue,
@@ -1993,6 +2125,8 @@ function SearchSelect({
1993
2125
  onCreate,
1994
2126
  onEdit,
1995
2127
  editLabel = "Edit",
2128
+ onManage,
2129
+ manageLabel = "Manage",
1996
2130
  renderOption,
1997
2131
  groupLayout = "stacked",
1998
2132
  loadOnOpen = true,
@@ -2006,19 +2140,19 @@ function SearchSelect({
2006
2140
  }) {
2007
2141
  const isRequiredFilter = variant === "required-filter";
2008
2142
  const canCreate = !!onCreate && allowCreate !== false;
2009
- const [open, setOpen] = React18.useState(false);
2010
- const [query, setQuery] = React18.useState("");
2011
- const [results, setResults] = React18.useState([]);
2012
- const [loading, setLoading] = React18.useState(false);
2013
- const [creating, setCreating] = React18.useState(false);
2014
- const [selectedLabel, setSelectedLabel] = React18.useState(displayValue ?? "");
2015
- const containerRef = React18.useRef(null);
2016
- const inputRef = React18.useRef(null);
2017
- const timerRef = React18.useRef();
2018
- const [rect, setRect] = React18.useState(null);
2019
- const dropdownRef = React18.useRef(null);
2020
- const requestRef = React18.useRef(0);
2021
- React18.useEffect(() => {
2143
+ const [open, setOpen] = React20.useState(false);
2144
+ const [query, setQuery] = React20.useState("");
2145
+ const [results, setResults] = React20.useState([]);
2146
+ const [loading, setLoading] = React20.useState(false);
2147
+ const [creating, setCreating] = React20.useState(false);
2148
+ const [selectedLabel, setSelectedLabel] = React20.useState(displayValue ?? "");
2149
+ const containerRef = React20.useRef(null);
2150
+ const inputRef = React20.useRef(null);
2151
+ const timerRef = React20.useRef();
2152
+ const [rect, setRect] = React20.useState(null);
2153
+ const dropdownRef = React20.useRef(null);
2154
+ const requestRef = React20.useRef(0);
2155
+ React20.useEffect(() => {
2022
2156
  function handler(e) {
2023
2157
  const target = e.target;
2024
2158
  if (containerRef.current?.contains(target)) return;
@@ -2028,10 +2162,10 @@ function SearchSelect({
2028
2162
  document.addEventListener("mousedown", handler);
2029
2163
  return () => document.removeEventListener("mousedown", handler);
2030
2164
  }, []);
2031
- React18.useEffect(() => {
2165
+ React20.useEffect(() => {
2032
2166
  if (displayValue !== void 0) setSelectedLabel(displayValue);
2033
2167
  }, [displayValue]);
2034
- React18.useEffect(() => {
2168
+ React20.useEffect(() => {
2035
2169
  if (open && loadOnOpen && query.length === 0 && results.length === 0 && !loading) {
2036
2170
  const request = ++requestRef.current;
2037
2171
  setLoading(true);
@@ -2099,7 +2233,7 @@ function SearchSelect({
2099
2233
  setResults([]);
2100
2234
  setTimeout(() => inputRef.current?.focus(), 0);
2101
2235
  }
2102
- const groups = React18.useMemo(() => {
2236
+ const groups = React20.useMemo(() => {
2103
2237
  const map = /* @__PURE__ */ new Map();
2104
2238
  for (const opt of results) {
2105
2239
  const group = opt.group ?? "";
@@ -2124,7 +2258,8 @@ function SearchSelect({
2124
2258
  const groupedWidth = groupLayout === "columns" && groups.size > 1 ? Math.min(groups.size * 210, window.innerWidth - 16) : r.width;
2125
2259
  const width = isRequiredFilter ? Math.max(r.width, 288, groupedWidth) : Math.max(r.width, groupedWidth);
2126
2260
  const left = Math.max(8, Math.min(r.left, window.innerWidth - width - 8));
2127
- setRect({ left, top: above ? r.top : r.bottom, width, above });
2261
+ const space = Math.max(160, (above ? r.top : below) - 12);
2262
+ setRect({ left, top: above ? r.top : r.bottom, width, above, space });
2128
2263
  };
2129
2264
  measure();
2130
2265
  window.addEventListener("scroll", measure, true);
@@ -2209,12 +2344,12 @@ function SearchSelect({
2209
2344
  {
2210
2345
  type: "button",
2211
2346
  onClick: handleOpen,
2212
- className: "flex-1 text-left py-2 pr-3 text-sm outline-none",
2347
+ className: "min-w-0 flex-1 truncate text-left py-2 pr-3 text-sm outline-none",
2213
2348
  disabled: disabled || creating,
2214
2349
  children: creating ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
2215
2350
  /* @__PURE__ */ jsx(Loader2, { className: "h-3 w-3 animate-spin" }),
2216
2351
  /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: selectedLabel })
2217
- ] }) : hasValue ? /* @__PURE__ */ jsx("span", { className: "font-medium", children: selectedLabel }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: placeholder })
2352
+ ] }) : hasValue ? /* @__PURE__ */ jsx("span", { className: "block truncate font-medium", children: selectedLabel }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: placeholder })
2218
2353
  }
2219
2354
  ),
2220
2355
  hasValue && !open && /* @__PURE__ */ jsx("button", { onClick: handleClear, className: "pr-3 text-muted-foreground hover:text-foreground", children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" }) }),
@@ -2239,9 +2374,10 @@ function SearchSelect({
2239
2374
  // resultado desenha, e escolher nao faz nada. Mesma armadilha que
2240
2375
  // o PaymentModal ja documentava ("aparece por cima porem surdo").
2241
2376
  pointerEvents: "auto",
2242
- ...rect.above ? { bottom: window.innerHeight - rect.top + 4 } : { top: rect.top + 4 }
2377
+ ...rect.above ? { bottom: window.innerHeight - rect.top + 4 } : { top: rect.top + 4 },
2378
+ maxHeight: rect.space
2243
2379
  },
2244
- className: "fayz-glass-surface z-[110] overflow-hidden rounded-lg border bg-popover shadow-lg",
2380
+ className: "fayz-glass-surface z-[110] flex flex-col overflow-hidden rounded-lg border bg-popover shadow-lg",
2245
2381
  children: [
2246
2382
  isRequiredFilter && /* @__PURE__ */ jsx("div", { className: "border-b p-2", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
2247
2383
  /* @__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" }),
@@ -2293,7 +2429,7 @@ function SearchSelect({
2293
2429
  ]
2294
2430
  },
2295
2431
  group
2296
- )) }) }) : /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-auto py-1", children: [...groups.entries()].map(([group, options]) => /* @__PURE__ */ jsxs(React18.Fragment, { children: [
2432
+ )) }) }) : /* @__PURE__ */ jsx("div", { className: "max-h-64 min-h-0 flex-1 overflow-auto py-1", children: [...groups.entries()].map(([group, options]) => /* @__PURE__ */ jsxs(React20.Fragment, { children: [
2297
2433
  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 }),
2298
2434
  options.map(optionButton)
2299
2435
  ] }, group)) }),
@@ -2317,7 +2453,8 @@ function SearchSelect({
2317
2453
  ]
2318
2454
  }
2319
2455
  )
2320
- ] })
2456
+ ] }),
2457
+ onManage && /* @__PURE__ */ jsx(ManageRow, { action: { label: manageLabel, onSelect: onManage }, onDone: () => setOpen(false) })
2321
2458
  ]
2322
2459
  }
2323
2460
  ),
@@ -2336,9 +2473,9 @@ function CurrencyInput({
2336
2473
  className,
2337
2474
  disabled
2338
2475
  }) {
2339
- const inputRef = React18.useRef(null);
2340
- const [focused, setFocused] = React18.useState(false);
2341
- const format = React18.useCallback((v) => {
2476
+ const inputRef = React20.useRef(null);
2477
+ const [focused, setFocused] = React20.useState(false);
2478
+ const format = React20.useCallback((v) => {
2342
2479
  return new Intl.NumberFormat(locale, {
2343
2480
  minimumFractionDigits: 2,
2344
2481
  maximumFractionDigits: 2
@@ -2398,7 +2535,7 @@ function CurrencyInput({
2398
2535
  placeholder: placeholder ?? format(0),
2399
2536
  disabled,
2400
2537
  readOnly: false,
2401
- className: "h-full flex-1 bg-transparent px-2 text-sm outline-none text-right tabular-nums caret-primary selection:bg-primary/20",
2538
+ className: "h-full min-w-0 flex-1 bg-transparent px-2 text-sm outline-none text-right tabular-nums caret-primary selection:bg-primary/20",
2402
2539
  onChange: () => {
2403
2540
  }
2404
2541
  }
@@ -2465,9 +2602,9 @@ function RequiredFilter({
2465
2602
  className,
2466
2603
  contentClassName
2467
2604
  }) {
2468
- const [open, setOpen] = React18.useState(false);
2605
+ const [open, setOpen] = React20.useState(false);
2469
2606
  const missing = !value;
2470
- const close = React18.useCallback(() => setOpen(false), []);
2607
+ const close = React20.useCallback(() => setOpen(false), []);
2471
2608
  return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
2472
2609
  /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
2473
2610
  "button",
@@ -2513,9 +2650,9 @@ function FilterPanel({
2513
2650
  className
2514
2651
  }) {
2515
2652
  const blocked = Boolean(applyDisabledReason);
2516
- const [aberto, setAberto] = React18.useState(Boolean(advancedCount));
2517
- const jaAbriu = React18.useRef(Boolean(advancedCount));
2518
- React18.useEffect(() => {
2653
+ const [aberto, setAberto] = React20.useState(Boolean(advancedCount));
2654
+ const jaAbriu = React20.useRef(Boolean(advancedCount));
2655
+ React20.useEffect(() => {
2519
2656
  if (advancedCount && !jaAbriu.current) {
2520
2657
  jaAbriu.current = true;
2521
2658
  setAberto(true);
@@ -2590,23 +2727,23 @@ function FilterPanelField({ label, compact, required, className, children }) {
2590
2727
  }
2591
2728
  FilterPanelField.displayName = "FilterPanelField";
2592
2729
  function useFilterDraft(initial) {
2593
- const inicial = React18.useRef(initial);
2594
- const [draft, setDraft] = React18.useState(initial);
2595
- const [applied, setApplied] = React18.useState(initial);
2596
- const dirty = React18.useMemo(
2730
+ const inicial = React20.useRef(initial);
2731
+ const [draft, setDraft] = React20.useState(initial);
2732
+ const [applied, setApplied] = React20.useState(initial);
2733
+ const dirty = React20.useMemo(
2597
2734
  () => JSON.stringify(draft) !== JSON.stringify(applied),
2598
2735
  [draft, applied]
2599
2736
  );
2600
- const patch = React18.useCallback((changes) => {
2737
+ const patch = React20.useCallback((changes) => {
2601
2738
  setDraft((atual) => ({ ...atual, ...changes }));
2602
2739
  }, []);
2603
- const apply = React18.useCallback(() => {
2740
+ const apply = React20.useCallback(() => {
2604
2741
  setDraft((atual) => {
2605
2742
  setApplied(atual);
2606
2743
  return atual;
2607
2744
  });
2608
2745
  }, []);
2609
- const reset = React18.useCallback((value) => {
2746
+ const reset = React20.useCallback((value) => {
2610
2747
  const alvo = value ?? inicial.current;
2611
2748
  setDraft(alvo);
2612
2749
  setApplied(alvo);
@@ -2642,7 +2779,7 @@ function DateRangeChip({
2642
2779
  label,
2643
2780
  className
2644
2781
  }) {
2645
- const [open, setOpen] = React18.useState(false);
2782
+ const [open, setOpen] = React20.useState(false);
2646
2783
  const active = !!(from || to);
2647
2784
  const locale = typeof navigator !== "undefined" ? navigator.language : "en";
2648
2785
  const presetLabel = presets.find((p) => p.value === preset)?.label;
@@ -2747,9 +2884,9 @@ function MultiSelect({
2747
2884
  variant = "field",
2748
2885
  icon: Icon2
2749
2886
  }) {
2750
- const [query, setQuery] = React18.useState("");
2751
- const selected = React18.useMemo(() => new Set(value), [value]);
2752
- const filtered = React18.useMemo(() => {
2887
+ const [query, setQuery] = React20.useState("");
2888
+ const selected = React20.useMemo(() => new Set(value), [value]);
2889
+ const filtered = React20.useMemo(() => {
2753
2890
  const q = query.trim().toLowerCase();
2754
2891
  if (!q) return options;
2755
2892
  return options.filter((o) => o.label.toLowerCase().includes(q));
@@ -2887,8 +3024,8 @@ function hueFor(name) {
2887
3024
  return AVATAR_HUES[h % AVATAR_HUES.length];
2888
3025
  }
2889
3026
  function PersonAvatar({ name, src, size = "sm", className }) {
2890
- const [failed, setFailed] = React18.useState(false);
2891
- React18.useEffect(() => {
3027
+ const [failed, setFailed] = React20.useState(false);
3028
+ React20.useEffect(() => {
2892
3029
  setFailed(false);
2893
3030
  }, [src]);
2894
3031
  const base = cn("shrink-0 overflow-hidden rounded-full", AVATAR_SIZE[size], className);
@@ -2928,7 +3065,7 @@ function ListShell({
2928
3065
  footer,
2929
3066
  children
2930
3067
  }) {
2931
- const filtered = React18.useMemo(() => {
3068
+ const filtered = React20.useMemo(() => {
2932
3069
  const q = query.trim().toLowerCase();
2933
3070
  if (!q) return options;
2934
3071
  return options.filter((o) => o.name.toLowerCase().includes(q));
@@ -2951,7 +3088,7 @@ function ListShell({
2951
3088
  )
2952
3089
  ] }),
2953
3090
  /* @__PURE__ */ jsxs("div", { className: "max-h-72 overflow-y-auto py-1", children: [
2954
- filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-5 text-center text-xs text-muted-foreground", children: emptyLabel }) : filtered.map((o) => /* @__PURE__ */ jsx(React18.Fragment, { children: children(o) }, o.id)),
3091
+ filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-5 text-center text-xs text-muted-foreground", children: emptyLabel }) : filtered.map((o) => /* @__PURE__ */ jsx(React20.Fragment, { children: children(o) }, o.id)),
2955
3092
  footer
2956
3093
  ] })
2957
3094
  ] });
@@ -2986,8 +3123,8 @@ function PersonPicker({
2986
3123
  onClear,
2987
3124
  variant = "input"
2988
3125
  }) {
2989
- const [query, setQuery] = React18.useState("");
2990
- const [open, setOpen] = React18.useState(false);
3126
+ const [query, setQuery] = React20.useState("");
3127
+ const [open, setOpen] = React20.useState(false);
2991
3128
  const current = options.find((o) => o.id === value);
2992
3129
  return /* @__PURE__ */ jsxs(Dropdown, { open, onOpenChange: setOpen, children: [
2993
3130
  /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, disabled, children: /* @__PURE__ */ jsxs("button", { type: "button", disabled, className: cn(TRIGGER_CLASSES[variant], className), children: [
@@ -3065,8 +3202,8 @@ function PersonMultiPicker({
3065
3202
  max,
3066
3203
  variant = "input"
3067
3204
  }) {
3068
- const [query, setQuery] = React18.useState("");
3069
- const selected = React18.useMemo(() => new Set(value), [value]);
3205
+ const [query, setQuery] = React20.useState("");
3206
+ const selected = React20.useMemo(() => new Set(value), [value]);
3070
3207
  const atCeiling = max != null && value.length >= max;
3071
3208
  function toggle(id) {
3072
3209
  if (selected.has(id)) onChange(value.filter((x) => x !== id));
@@ -3165,17 +3302,17 @@ function DictateButton({
3165
3302
  className,
3166
3303
  disabled
3167
3304
  }) {
3168
- const [ouvindo, setOuvindo] = React18.useState(false);
3169
- const [erro, setErro] = React18.useState(null);
3170
- const ref = React18.useRef(null);
3171
- const [suportado, setSuportado] = React18.useState(false);
3172
- React18.useEffect(() => {
3305
+ const [ouvindo, setOuvindo] = React20.useState(false);
3306
+ const [erro, setErro] = React20.useState(null);
3307
+ const ref = React20.useRef(null);
3308
+ const [suportado, setSuportado] = React20.useState(false);
3309
+ React20.useEffect(() => {
3173
3310
  setSuportado(recognitionCtor() !== null);
3174
3311
  }, []);
3175
- React18.useEffect(() => () => {
3312
+ React20.useEffect(() => () => {
3176
3313
  ref.current?.stop();
3177
3314
  }, []);
3178
- const alternar = React18.useCallback(() => {
3315
+ const alternar = React20.useCallback(() => {
3179
3316
  if (ouvindo) {
3180
3317
  ref.current?.stop();
3181
3318
  return;
@@ -3238,7 +3375,7 @@ function renderInline(text, keyPrefix) {
3238
3375
  if (part.startsWith("`") && part.endsWith("`") && part.length > 2) {
3239
3376
  return /* @__PURE__ */ jsx("code", { className: "rounded bg-muted px-1 py-0.5 font-mono text-[0.85em]", children: part.slice(1, -1) }, key);
3240
3377
  }
3241
- return part === "" ? null : /* @__PURE__ */ jsx(React18.Fragment, { children: part }, key);
3378
+ return part === "" ? null : /* @__PURE__ */ jsx(React20.Fragment, { children: part }, key);
3242
3379
  });
3243
3380
  }
3244
3381
  function parseBlocks(source) {
@@ -3322,7 +3459,7 @@ function renderMarkdown(source) {
3322
3459
  case "ol":
3323
3460
  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);
3324
3461
  case "p":
3325
- return /* @__PURE__ */ jsx("p", { children: block.lines.map((l, li) => /* @__PURE__ */ jsxs(React18.Fragment, { children: [
3462
+ return /* @__PURE__ */ jsx("p", { children: block.lines.map((l, li) => /* @__PURE__ */ jsxs(React20.Fragment, { children: [
3326
3463
  li > 0 && /* @__PURE__ */ jsx("br", {}),
3327
3464
  renderInline(l, `${key}-${li}`)
3328
3465
  ] }, `${key}-${li}`)) }, key);
@@ -3343,7 +3480,7 @@ function MarkdownEditor({
3343
3480
  renderPreview,
3344
3481
  className
3345
3482
  }) {
3346
- const [mode, setMode] = React18.useState(
3483
+ const [mode, setMode] = React20.useState(
3347
3484
  defaultMode === "preview" && value.trim() === "" ? "edit" : defaultMode
3348
3485
  );
3349
3486
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
@@ -3628,29 +3765,29 @@ function PickerList({
3628
3765
  listClassName,
3629
3766
  autoFocus = true
3630
3767
  }) {
3631
- const [query, setQuery] = React18.useState("");
3768
+ const [query, setQuery] = React20.useState("");
3632
3769
  const term = normalize(query.trim());
3633
- const sections = React18.useMemo(
3770
+ const sections = React20.useMemo(
3634
3771
  () => groups ?? [{ id: "_", options: options ?? [] }],
3635
3772
  [groups, options]
3636
3773
  );
3637
- const total = React18.useMemo(
3774
+ const total = React20.useMemo(
3638
3775
  () => sections.reduce((n, g) => n + g.options.length, 0),
3639
3776
  [sections]
3640
3777
  );
3641
- const visible = React18.useMemo(() => {
3778
+ const visible = React20.useMemo(() => {
3642
3779
  if (!term) return sections;
3643
3780
  const hits = sections.flatMap((g) => g.options.filter((o) => optionMatches(o, term)));
3644
3781
  return [{ id: "_results", options: hits }];
3645
3782
  }, [sections, term]);
3646
- const flat = React18.useMemo(() => visible.flatMap((g) => g.options), [visible]);
3647
- const [active, setActive] = React18.useState(0);
3648
- const listRef = React18.useRef(null);
3649
- React18.useEffect(() => {
3783
+ const flat = React20.useMemo(() => visible.flatMap((g) => g.options), [visible]);
3784
+ const [active, setActive] = React20.useState(0);
3785
+ const listRef = React20.useRef(null);
3786
+ React20.useEffect(() => {
3650
3787
  const i = flat.findIndex((o) => o.id === value);
3651
3788
  setActive(i >= 0 ? i : 0);
3652
3789
  }, [term]);
3653
- React18.useEffect(() => {
3790
+ React20.useEffect(() => {
3654
3791
  listRef.current?.querySelector(`[data-picker-index="${active}"]`)?.scrollIntoView({ block: "nearest" });
3655
3792
  }, [active]);
3656
3793
  function step(delta) {
@@ -3712,7 +3849,7 @@ function PickerList({
3712
3849
  className: cn("min-h-0 flex-1 overflow-y-auto py-1", listClassName),
3713
3850
  children: [
3714
3851
  flat.length === 0 && /* @__PURE__ */ jsx("p", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: emptyLabel }),
3715
- visible.map((group) => /* @__PURE__ */ jsxs(React18.Fragment, { children: [
3852
+ visible.map((group) => /* @__PURE__ */ jsxs(React20.Fragment, { children: [
3716
3853
  group.label && group.options.length > 0 && /* @__PURE__ */ jsx("p", { className: "px-3 pb-1 pt-2 text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: group.label }),
3717
3854
  group.options.map((o) => {
3718
3855
  index += 1;
@@ -3933,7 +4070,7 @@ function NestedPane({ title, hint, onBack, children, className }) {
3933
4070
  children
3934
4071
  ] });
3935
4072
  }
3936
- var ModalTaskContext = React18.createContext(null);
4073
+ var ModalTaskContext = React20.createContext(null);
3937
4074
  function ModalTaskHeader({ title, hint, stack, onClose }) {
3938
4075
  const popTo = (index) => {
3939
4076
  for (let i = stack.length - 1; i > index; i--) stack[i].onBack();
@@ -3966,7 +4103,7 @@ function ModalTaskHeader({ title, hint, stack, onClose }) {
3966
4103
  children: title
3967
4104
  }
3968
4105
  ),
3969
- stack.map((c, i) => /* @__PURE__ */ jsxs(React18.Fragment, { children: [
4106
+ stack.map((c, i) => /* @__PURE__ */ jsxs(React20.Fragment, { children: [
3970
4107
  /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground/50", "aria-hidden": true }),
3971
4108
  i < stack.length - 1 ? /* @__PURE__ */ jsx(
3972
4109
  "button",
@@ -3992,10 +4129,10 @@ function ModalTaskHeader({ title, hint, stack, onClose }) {
3992
4129
  ] });
3993
4130
  }
3994
4131
  function ModalTaskHost({ children, className, header }) {
3995
- const [stack, setStack] = React18.useState([]);
3996
- const [slot, setSlot] = React18.useState(null);
3997
- const idRef = React18.useRef(0);
3998
- const api = React18.useMemo(() => ({
4132
+ const [stack, setStack] = React20.useState([]);
4133
+ const [slot, setSlot] = React20.useState(null);
4134
+ const idRef = React20.useRef(0);
4135
+ const api = React20.useMemo(() => ({
3999
4136
  open: (meta) => {
4000
4137
  const id = ++idRef.current;
4001
4138
  setStack((s) => [...s, { id, meta }]);
@@ -4004,7 +4141,7 @@ function ModalTaskHost({ children, className, header }) {
4004
4141
  close: (id) => setStack((s) => s.filter((e) => e.id !== id))
4005
4142
  }), []);
4006
4143
  const top = stack.length ? stack[stack.length - 1] : null;
4007
- const value = React18.useMemo(
4144
+ const value = React20.useMemo(
4008
4145
  () => ({ ...api, topId: top?.id ?? null, slot }),
4009
4146
  [api, top?.id, slot]
4010
4147
  );
@@ -4015,14 +4152,14 @@ function ModalTaskHost({ children, className, header }) {
4015
4152
  ] });
4016
4153
  }
4017
4154
  function useInModalTaskHost() {
4018
- return React18.useContext(ModalTaskContext) !== null;
4155
+ return React20.useContext(ModalTaskContext) !== null;
4019
4156
  }
4020
4157
  function ModalTask({ open, title, hint, onClose, width, children }) {
4021
- const host = React18.useContext(ModalTaskContext);
4022
- const onCloseRef = React18.useRef(onClose);
4158
+ const host = React20.useContext(ModalTaskContext);
4159
+ const onCloseRef = React20.useRef(onClose);
4023
4160
  onCloseRef.current = onClose;
4024
- const [myId, setMyId] = React18.useState(null);
4025
- React18.useEffect(() => {
4161
+ const [myId, setMyId] = React20.useState(null);
4162
+ React20.useEffect(() => {
4026
4163
  if (!host || !open) return;
4027
4164
  const id = host.open({ title, hint, onBack: () => onCloseRef.current() });
4028
4165
  setMyId(id);
@@ -4088,13 +4225,13 @@ function StockEntryForm({
4088
4225
  labels: overrides
4089
4226
  }) {
4090
4227
  const labels = { ...DEFAULT_LABELS, ...overrides };
4091
- const [quantity, setQuantity] = React18.useState("");
4092
- const [reasonCode, setReasonCode] = React18.useState("");
4093
- const [occurredOn, setOccurredOn] = React18.useState(todayISO());
4094
- const [note, setNote] = React18.useState("");
4095
- const [noteOpen, setNoteOpen] = React18.useState(false);
4096
- const quantityRef = React18.useRef(null);
4097
- React18.useEffect(() => {
4228
+ const [quantity, setQuantity] = React20.useState("");
4229
+ const [reasonCode, setReasonCode] = React20.useState("");
4230
+ const [occurredOn, setOccurredOn] = React20.useState(todayISO());
4231
+ const [note, setNote] = React20.useState("");
4232
+ const [noteOpen, setNoteOpen] = React20.useState(false);
4233
+ const quantityRef = React20.useRef(null);
4234
+ React20.useEffect(() => {
4098
4235
  if (verb === null) return;
4099
4236
  setQuantity("");
4100
4237
  setReasonCode("");
@@ -4333,7 +4470,7 @@ function FilterRail({
4333
4470
  )
4334
4471
  ] }),
4335
4472
  before,
4336
- visible.map((section, index) => /* @__PURE__ */ jsxs(React18__default.Fragment, { children: [
4473
+ visible.map((section, index) => /* @__PURE__ */ jsxs(React20__default.Fragment, { children: [
4337
4474
  (index > 0 || !!before || !!actions || !!search) && /* @__PURE__ */ jsx("div", { className: "my-4 h-px bg-border" }),
4338
4475
  /* @__PURE__ */ jsx(
4339
4476
  FilterSection,
@@ -4419,6 +4556,6 @@ function AdaptiveFilter({
4419
4556
  );
4420
4557
  }
4421
4558
 
4422
- export { AdaptiveFilter, AiActionButton, Badge, Breadcrumb, BulkActionBar, ChevronPager, ComingSoon, CurrencyInput, DatePicker, DateRangeChip, DictateButton, DotBadge, DraftCommitBar, EmBreve, FILTER_RAIL_WIDTH, FilterCheckBox, FilterCheckList, FilterCheckRow, FilterChip, FilterPanel, FilterPanelField, FilterRail, FilterRailColumn, FilterSection, INLINE_FILTER_MAX, INLINE_LINK_TONE, InlineLink, Input, ListFilterBar, ListView, Markdown, MarkdownEditor, MiniCalendar, ModalFlow, ModalFlowEntry, ModalTask, ModalTaskHeader, ModalTaskHost, MultiSelect, NestedPane, PageActionBar, PersonAvatar, PersonMultiPicker, PersonPicker, PhoneField, PhoneLink, PickerDialog, PickerList, RailWorkspace, RefreshButton, RequiredFilter, 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, WHATSAPP_BRAND_COLOR, WhatsAppIcon, WizardSteps, abbreviatePersonName, badgeVariants, comparePersonNames, formatPhone2 as formatPhone, normalizePhone, personInitials, renderMarkdown, setActionsMenuLabel, setRowActionsLabel, toLocalISODate, useFilterDraft, useInModalTaskHost, useRowSelection };
4423
- //# sourceMappingURL=chunk-IA3QZZSC.js.map
4424
- //# sourceMappingURL=chunk-IA3QZZSC.js.map
4559
+ export { AdaptiveFilter, AiActionButton, Badge, Breadcrumb, BulkActionBar, CHOICE_SEARCH_THRESHOLD, ChevronPager, ChoiceList, ChoiceSelect, ComingSoon, CurrencyInput, DatePicker, DateRangeChip, DictateButton, DotBadge, DraftCommitBar, EmBreve, FILTER_RAIL_WIDTH, FilterCheckBox, FilterCheckList, FilterCheckRow, FilterChip, FilterPanel, FilterPanelField, FilterRail, FilterRailColumn, FilterSection, INLINE_FILTER_MAX, INLINE_LINK_TONE, InlineLink, Input, ListFilterBar, ListView, ManageRow, Markdown, MarkdownEditor, MiniCalendar, ModalFlow, ModalFlowEntry, ModalTask, ModalTaskHeader, ModalTaskHost, MultiSelect, NestedPane, PageActionBar, PersonAvatar, PersonMultiPicker, PersonPicker, PhoneField, PhoneLink, PickerDialog, PickerList, RailWorkspace, RefreshButton, RequiredFilter, 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, WHATSAPP_BRAND_COLOR, WhatsAppIcon, WizardSteps, abbreviatePersonName, badgeVariants, comparePersonNames, formatPhone2 as formatPhone, normalizePhone, personInitials, renderMarkdown, setActionsMenuLabel, setRowActionsLabel, toLocalISODate, useFilterDraft, useInModalTaskHost, useRowSelection };
4560
+ //# sourceMappingURL=chunk-2D77YTB5.js.map
4561
+ //# sourceMappingURL=chunk-2D77YTB5.js.map